diff options
author | Ryo Nihei <nihei.dev@gmail.com> | 2021-08-30 18:50:46 +0900 |
---|---|---|
committer | Ryo Nihei <nihei.dev@gmail.com> | 2021-08-30 18:50:46 +0900 |
commit | 3584af7bc0bdf7388bc43aaa60d432b98afb752d (patch) | |
tree | d8ea05f3ab25d4ce6384692f6ec5096afab8f658 /driver/parser_test.go | |
parent | Add precedences and associativities to the description file (diff) | |
download | cotia-3584af7bc0bdf7388bc43aaa60d432b98afb752d.tar.gz cotia-3584af7bc0bdf7388bc43aaa60d432b98afb752d.tar.xz |
Add #prec directive to set precedence and associativity of productions
Diffstat (limited to 'driver/parser_test.go')
-rw-r--r-- | driver/parser_test.go | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/driver/parser_test.go b/driver/parser_test.go index 224f12e..4779a00 100644 --- a/driver/parser_test.go +++ b/driver/parser_test.go @@ -447,6 +447,98 @@ a: 'a'; `, specErr: true, }, + // The 'prec' directive can set precedence and associativity of a production. + { + specSrc: ` +%left mul div +%left add sub + +expr + : expr add expr + | expr sub expr + | expr mul expr + | expr div expr + | sub expr #prec mul // This 'sub' means a unary minus symbol. + | int + ; + +ws: "[\u{0009}\u{0020}]+" #skip; +int: "0|[1-9][0-9]*"; +add: '+'; +sub: '-'; +mul: '*'; +div: '/'; +`, + // This source is recognized as the following structure because the production `expr → sub expr` + // has the `#prec mul` directive and has the same precedence and associativity of the symbol `mul`. + // + // (((-1) * 20) / 5) + // + // If the production doesn't have the `#prec` directive, this source will be recognized as + // the following structure. + // + // (- ((1 * 20) / 5)) + src: `-1*20/5`, + cst: nonTermNode("expr", + nonTermNode("expr", + nonTermNode("expr", + termNode("sub", "-"), + nonTermNode("expr", + termNode("int", "1"), + ), + ), + termNode("mul", "*"), + nonTermNode("expr", + termNode("int", "20"), + ), + ), + termNode("div", "/"), + nonTermNode("expr", + termNode("int", "5"), + ), + ), + }, + // The 'prec' directive needs an ID parameter. + { + specSrc: ` +s + : a #prec + ; + +a: 'a'; +`, + specErr: true, + }, + // The 'prec' directive cannot take an unknown symbol. + { + specSrc: ` +s + : a #prec foo + ; + +a: 'a'; +`, + specErr: true, + }, + // The 'prec' directive cannot take a non-terminal symbol. + { + specSrc: ` +s + : foo #prec bar + | bar + ; +foo + : a + ; +bar + : b + ; + +a: 'a'; +b: 'b'; +`, + specErr: true, + }, // The grammar can contain the 'error' symbol. { specSrc: ` |