diff options
author | Ryo Nihei <nihei.dev@gmail.com> | 2021-07-18 01:24:34 +0900 |
---|---|---|
committer | Ryo Nihei <nihei.dev@gmail.com> | 2021-07-18 01:24:34 +0900 |
commit | aedba83693cf1437e0d3295a2f160e43ffcc55ea (patch) | |
tree | 3bd8b4f94c9b77f112ac2db3733139dc2ba3b971 /spec | |
parent | Detect multiple syntax errors in a single parse (diff) | |
download | cotia-aedba83693cf1437e0d3295a2f160e43ffcc55ea.tar.gz cotia-aedba83693cf1437e0d3295a2f160e43ffcc55ea.tar.xz |
Refactor
Diffstat (limited to 'spec')
-rw-r--r-- | spec/parser.go | 24 | ||||
-rw-r--r-- | spec/parser_test.go | 13 |
2 files changed, 31 insertions, 6 deletions
diff --git a/spec/parser.go b/spec/parser.go index 8b825bf..e749d72 100644 --- a/spec/parser.go +++ b/spec/parser.go @@ -8,8 +8,9 @@ import ( ) type RootNode struct { - Productions []*ProductionNode - Fragments []*FragmentNode + Productions []*ProductionNode + LexProductions []*ProductionNode + Fragments []*FragmentNode } type ProductionNode struct { @@ -18,6 +19,13 @@ type ProductionNode struct { RHS []*AlternativeNode } +func (n *ProductionNode) isLexical() bool { + if len(n.RHS) == 1 && len(n.RHS[0].Elements) == 1 && n.RHS[0].Elements[0].Pattern != "" { + return true + } + return false +} + type AlternativeNode struct { Elements []*ElementNode Directive *DirectiveNode @@ -112,6 +120,7 @@ func (p *parser) parseRoot() *RootNode { }() var prods []*ProductionNode + var lexProds []*ProductionNode var fragments []*FragmentNode for { fragment := p.parseFragment() @@ -122,7 +131,11 @@ func (p *parser) parseRoot() *RootNode { prod := p.parseProduction() if prod != nil { - prods = append(prods, prod) + if prod.isLexical() { + lexProds = append(lexProds, prod) + } else { + prods = append(prods, prod) + } continue } @@ -132,8 +145,9 @@ func (p *parser) parseRoot() *RootNode { } return &RootNode{ - Productions: prods, - Fragments: fragments, + Productions: prods, + LexProductions: lexProds, + Fragments: fragments, } } diff --git a/spec/parser_test.go b/spec/parser_test.go index 89cc4d1..c696af0 100644 --- a/spec/parser_test.go +++ b/spec/parser_test.go @@ -82,7 +82,7 @@ func TestParse(t *testing.T) { caption: "single production is a valid grammar", src: `a: "a";`, ast: &RootNode{ - Productions: []*ProductionNode{ + LexProductions: []*ProductionNode{ prod("a", alt(pat("a"))), }, }, @@ -109,6 +109,8 @@ id: "[A-Za-z_][0-9A-Za-z_]*"; alt(pat(`\(`), id("e"), pat(`)`)), alt(id("id")), ), + }, + LexProductions: []*ProductionNode{ prod("id", alt(pat(`[A-Za-z_][0-9A-Za-z_]*`)), ), @@ -177,6 +179,8 @@ fragment words: "[A-Za-z\u{0020}]+"; prod("s", alt(id("tagline")), ), + }, + LexProductions: []*ProductionNode{ prod("tagline", alt(pat(`\f{words} IS OUT THERE.`)), ), @@ -221,6 +225,8 @@ whitespace: "\u{0020}+" #skip; alt(id("pop_m1")), alt(id("pop_m2")), ), + }, + LexProductions: []*ProductionNode{ prod("push_m1", withAltDir( alt(pat(`->`)), @@ -311,6 +317,8 @@ bar: "bar"; dir("ast", treeParam("bar_list", pos(1))), ), ), + }, + LexProductions: []*ProductionNode{ prod("foo", alt(pat("foo")), ), @@ -377,6 +385,9 @@ func testRootNode(t *testing.T, root, expected *RootNode) { for i, prod := range root.Productions { testProductionNode(t, prod, expected.Productions[i]) } + for i, prod := range root.LexProductions { + testProductionNode(t, prod, expected.LexProductions[i]) + } } func testProductionNode(t *testing.T, prod, expected *ProductionNode) { |