Reputation: 3653
I'm new to the world of formal grammars. I tried to use ANTLR for JS but couldn't figure out how to run the parser. I'm trying to develop a grammar for a DSL on PEG.js and this is what I have (http://peg.arcanis.fr/3T2PKD/):
start
= expr
operator
= "show" lparen st:string ws rparen { console.log(7)}
/ "show" lparen ex:expr rparen { console.log(8)}
expr
= op: operator ws ex: expr {console.log (1)}
/ st:string ws ex: expr {console.log (2)}
/ st:string ws op:operator {console.log (3)}
/ op:operator ws str:string {console.log (4)}
/ st:string ws {console.log (5)}
/ op:operator ws {console.log (6)}
lparen
= ws "(" ws
rparen
= ws ")" ws
integer "integer"
= digits:[0-9]+ { return parseInt(digits.join(""), 10); }
string "string"
= quotation_mark chars:char* quotation_mark { return chars.join(""); }
ws "whitespace" = [ \t\n\r]*
char
= unescaped
/ escape
sequence:(
'"'
/ "\\"
/ "/"
/ "b" { return "\b"; }
/ "f" { return "\f"; }
/ "n" { return "\n"; }
/ "r" { return "\r"; }
/ "t" { return "\t"; }
/ "u" digits:$(HEXDIG HEXDIG HEXDIG HEXDIG) {
return String.fromCharCode(parseInt(digits, 16));
}
)
{ return sequence; }
escape = "\\"
quotation_mark = '"'
unescaped = [\x20-\x21\x23-\x5B\x5D-\u10FFFF]
/* ----- Core ABNF Rules ----- */
/* See RFC 4234, Appendix B (http://tools.ietf.org/html/rfc4627). */
DIGIT = [0-9]
HEXDIG = [0-9a-f]i
{
;
}
When this is tested on: show ("abc")
Shouldn't the console show
7
6
?
Instead it shows 7 7 7 6
Have been racking my brain for the past 3 days. Someone, somewhere help me get to parsimoniousness!
Upvotes: 1
Views: 174
Reputation: 414086
The parser has to try the rules op: operator ws ex: expr
and op:operator ws str:string
before it finally succeeds with op:operator ws
. It doesn't know that those won't work until it fails to find anything beyond the )
.
Thus, it gets through the operator
rule once, doesn't see another expression, so it backtracks. It then sees the operator
for the second time, and it still doesn't work because there's no string after it. So finally, on the third try, it sees the operator and then that last rule succeeds.
Your calls to console.log(7)
are made because the operator
rule itself succeeds, even though the expr
rules don't.
Upvotes: 1