Reputation: 23506
I want to write a concrete grammar to parse BNF-like syntax definitions.
Looking at the EXP Concrete Syntax recipe I created this very simple first version:
module BNFParser
lexical Identifier = [a-z]+ ;
syntax GrammarRule = left RuleHead ":" RuleCase* ";" ;
syntax RuleHead = Identifier ;
syntax RuleCase = Identifier ;
and invoked it in the Repl like this:
import BNFParser;
import ParseTree;
parse(#GrammarRule, "foo : bar baz ;");
But this results in a rather arcane error message:
|std:///ParseTree.rsc|(13035,1963,<393,0>,<439,114>): ParseError(|unknown:///|(3,1,<1,3>,<1,4>))
at *** somewhere ***(|std:///ParseTree.rsc|(13035,1963,<393,0>,<439,114>))
at parse(|std:///ParseTree.rsc|(14991,5,<439,107>,<439,112>))
ok
I also tried using the start
keyword ahead of GrammarRule, but that didn't help. What am I doing wrong?
Upvotes: 1
Views: 140
Reputation: 6696
lexical Identifier = [a-z]+ !>> [a-z];
That helps for ambiguous lists of identifiers. The additional !>> constraint declares that identifiers are only acceptable if no further characters can be consumed.
Also this is required for fixing the parse error:
layout Whitespace = [\ \n\r]*;
For all syntax rules in scope it will intermix this nonterminal between all symbols. It leaves the lexical rules alone.
Upvotes: 1