diff options
author | Ryo Nihei <nihei.dev@gmail.com> | 2021-08-22 15:39:27 +0900 |
---|---|---|
committer | Ryo Nihei <nihei.dev@gmail.com> | 2021-08-22 15:44:03 +0900 |
commit | 4d879b95d5368d578a39baaefba0de743a764105 (patch) | |
tree | a0e78f5c9916405545f1e7b139f9427b1cd190cc /driver/conflict_test.go | |
parent | Resolve conflicts by default rules (diff) | |
download | cotia-4d879b95d5368d578a39baaefba0de743a764105.tar.gz cotia-4d879b95d5368d578a39baaefba0de743a764105.tar.xz |
Support %left and %right to specify precedences and associativities
Diffstat (limited to 'driver/conflict_test.go')
-rw-r--r-- | driver/conflict_test.go | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/driver/conflict_test.go b/driver/conflict_test.go index 750ed4e..46eeaba 100644 --- a/driver/conflict_test.go +++ b/driver/conflict_test.go @@ -68,6 +68,251 @@ id: "[A-Za-z0-9_]+"; ), ), }, + { + caption: "left associativities defined earlier in the grammar have higher precedence", + specSrc: ` +%left mul +%left add + +expr + : expr add expr + | expr mul expr + | id + ; + +id: "[A-Za-z0-9_]+"; +add: '+'; +mul: '*'; +`, + src: `a+b*c*d+e`, + cst: nonTermNode("expr", + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "a"), + ), + termNode("add", "+"), + nonTermNode("expr", + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "b"), + ), + termNode("mul", "*"), + nonTermNode("expr", + termNode("id", "c"), + ), + ), + termNode("mul", "*"), + nonTermNode("expr", + termNode("id", "d"), + ), + ), + ), + termNode("add", "+"), + nonTermNode("expr", + termNode("id", "e"), + ), + ), + }, + { + caption: "left associativities defined in the same line have the same precedence", + specSrc: ` +%left add sub + +expr + : expr add expr + | expr sub expr + | id + ; + +id: "[A-Za-z0-9_]+"; +add: '+'; +sub: '-'; +`, + src: `a-b+c+d-e`, + cst: nonTermNode("expr", + nonTermNode("expr", + nonTermNode("expr", + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "a"), + ), + termNode("sub", "-"), + nonTermNode("expr", + termNode("id", "b"), + ), + ), + termNode("add", "+"), + nonTermNode("expr", + termNode("id", "c"), + ), + ), + termNode("add", "+"), + nonTermNode("expr", + termNode("id", "d"), + ), + ), + termNode("sub", "-"), + nonTermNode("expr", + termNode("id", "e"), + ), + ), + }, + { + caption: "right associativities defined earlier in the grammar have higher precedence", + specSrc: ` +%right r1 +%right r2 + +expr + : expr r2 expr + | expr r1 expr + | id + ; + +whitespaces: "[\u{0009}\u{0020}]+" #skip; +r1: 'r1'; +r2: 'r2'; +id: "[A-Za-z0-9_]+"; +`, + src: `a r2 b r1 c r1 d r2 e`, + cst: nonTermNode("expr", + nonTermNode("expr", + termNode("id", "a"), + ), + termNode("r2", "r2"), + nonTermNode("expr", + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "b"), + ), + termNode("r1", "r1"), + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "c"), + ), + termNode("r1", "r1"), + nonTermNode("expr", + termNode("id", "d"), + ), + ), + ), + termNode("r2", "r2"), + nonTermNode("expr", + termNode("id", "e"), + ), + ), + ), + }, + { + caption: "right associativities defined in the same line have the same precedence", + specSrc: ` +%right r1 r2 + +expr + : expr r2 expr + | expr r1 expr + | id + ; + +whitespaces: "[\u{0009}\u{0020}]+" #skip; +r1: 'r1'; +r2: 'r2'; +id: "[A-Za-z0-9_]+"; +`, + src: `a r2 b r1 c r1 d r2 e`, + cst: nonTermNode("expr", + nonTermNode("expr", + termNode("id", "a"), + ), + termNode("r2", "r2"), + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "b"), + ), + termNode("r1", "r1"), + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "c"), + ), + termNode("r1", "r1"), + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "d"), + ), + termNode("r2", "r2"), + nonTermNode("expr", + termNode("id", "e"), + ), + ), + ), + ), + ), + }, + { + caption: "left and right associativities can be mixed", + specSrc: ` +%left mul div +%left add sub +%right assign + +expr + : expr add expr + | expr sub expr + | expr mul expr + | expr div expr + | expr assign expr + | id + ; + +id: "[A-Za-z0-9_]+"; +add: '+'; +sub: '-'; +mul: '*'; +div: '/'; +assign: '='; +`, + src: `x=y=a+b*c-d/e`, + cst: nonTermNode( + "expr", + nonTermNode("expr", + termNode("id", "x"), + ), + termNode("assign", "="), + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "y"), + ), + termNode("assign", "="), + nonTermNode("expr", + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "a"), + ), + termNode("add", "+"), + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "b"), + ), + termNode("mul", "*"), + nonTermNode("expr", + termNode("id", "c"), + ), + ), + ), + termNode("sub", "-"), + nonTermNode("expr", + nonTermNode("expr", + termNode("id", "d"), + ), + termNode("div", "/"), + nonTermNode("expr", + termNode("id", "e"), + ), + ), + ), + ), + ), + }, } for _, tt := range tests { |