Lexon and HyperTalk share a secret: almost no reserved words. The words that matter — parties, fees, fields, chunks — belong to the author, not the language, so a parser cannot know what a token means without knowing what the author has declared. This page records how Lexon and HyperTalk each solve it, and how Ohm can: the double parse.
# Lexon reads on the go The reference compiler is not a double parse. It is C, built with Flex and Bison, and it leans on Bison's GLR mode to carry the temporary ambiguities of natural language forward as parallel candidate parses. Names are quoted once, at declaration — that is how the exact multi word string enters the symbol table — then used bare ever after: declare a text called Description of Goods, and the clause `fixes the Description of Goods` just works. The manual is explicit: the compiler learns the role of new words on the go, clause names are understood en block, definitions must come before use, and capitalisation settles what ambiguity remains. The famous doubling in Lexon is its build bootstrap — `lexccc` compiles the grammar description into Bison in two cycles. A contract is read once.
# HyperTalk trusts position HyperTalk went further: effectively no reserved words at all. `word`, `item` and `char` are chunk keywords in one position and perfectly good variable names in another — the Winkler test weaponises exactly this, and HyperCard parsed it. The trick never fit generated context free tooling: Apple's parser was hand written, LiveCode's engine keeps hand maintained factor and command tables in C++, and every reimplementation built on a parser generator — the ANTLR grammar, WyldCard — ends up admitting it is stricter than HyperCard was.
# Can Ohm do it Not in one pass — and that is a design decision, not a gap. Ohm keeps grammars pure: no semantic actions inside the grammar, and by the maintainers' own words it does not (yet) support semantic predicates, so there is no consulting a growing symbol table mid parse. But Ohm grammars are runtime values. `ohm.grammar(source)` instantiates a grammar from a string, grammars inherit with `<:`, and a child may override a single rule. So the Ohm answer is an honest double parse: pass one discovers the declared names; pass two parses with a generated grammar in which the vocabulary is grammar — the discovered names spliced into the `name` rule as ordered alternatives, longest first.
The repo proves it. `experiments/double-parse.mjs` declares terms once, harvests them, and then parses bare multi word names mid sentence — Lexon's own Licensing Fee and Description of Goods pattern:
const grammarFor = (names) => `DoubleParse { ... Line = art? name Modal Phrase "." Bit = art? name -- name | word -- word name = ${[...names] .sort((a, b) => b.length - a.length) .map((n) => `${JSON.stringify(n)} ~alnum`) .join(" | ")} ... }`
discovered terms: Licensor | Licensee | Licensing Fee | Description of Goods pass 2 with the vocabulary: parses — defined names shown in [brackets] Licensor may fix [Description of Goods] Licensee must pay [Licensing Fee] same grammar, empty vocabulary: does not parse (Line 8, col 7: expected "\u0000")
The empty vocabulary run is the point: without pass one, the document is not even a sentence. The vocabulary is not checked after parsing — it is what makes parsing possible.
# What WikiScript does today Version zero sidesteps the problem: terms are quoted at declaration and Capitalised in use, so one pure pass suffices and the grammar stays tiny. The door to Lexon grade bare prose stays open — when the Agreement Corpus demands names without quotes or capitals, the two pass design above is the route, and the same discovery pass is what lets an editor colour the author's words differently from the language's. See WikiScript Grammar.
# Links
- Lexon compiler README
— GLR, and the case against lookahead orthodoxy
- The Lexon manual
— learns the role of new words on the go
- evaluation.lex
— bare multi word names in the wild
- ANTLR HyperTalk grammar
— somewhat more strict than HyperCard's
- LiveCode lextable.cpp
— the hand maintained factor tables
- The Winkler test
- Ohm philosophy
— grammars are pure
- Ohm issue 158
— context sensitive parsing, open by design
- Modular semantic actions
— the DLS 2016 paper
# Assets
double-parse
# See - WikiScript Grammar and Ohm - HyperTalk and SimpleTalk - Three Livecode Doors