From 2fcab705ddf787fa0f4edab2f2dc7e579ca982d9 Mon Sep 17 00:00:00 2001 From: Ryo Nihei Date: Wed, 3 Aug 2022 23:07:06 +0900 Subject: [PATCH] Prohibit error node having children --- spec/test/parser.go | 8 +++++ spec/test/parser_test.go | 77 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/spec/test/parser.go b/spec/test/parser.go index 33e035b..e9c557d 100644 --- a/spec/test/parser.go +++ b/spec/test/parser.go @@ -289,6 +289,14 @@ func formatSyntaxError(synErr *SyntaxError, gram Grammar, lineOffset int) []byte } func (tp *treeParser) genTree(node *Node) (*Tree, error) { + // A node labeled 'error' cannot have children. It always must be (error). + if sym := node.Children[0]; sym.Text == "error" { + if len(node.Children) > 1 { + return nil, fmt.Errorf("%v:%v: error node cannot take children", tp.lineOffset+sym.Row+1, sym.Col+1) + } + return NewTerminalNode(sym.Text, ""), nil + } + if len(node.Children) == 2 && node.Children[1].KindName == "string" { var text string str := node.Children[1].Children[0] diff --git a/spec/test/parser_test.go b/spec/test/parser_test.go index 7a8984e..cbf96c0 100644 --- a/spec/test/parser_test.go +++ b/spec/test/parser_test.go @@ -327,6 +327,83 @@ foo foo -- (foo) +`, + parseErr: true, + }, + // A node may have just one string node. + { + src: `test +---- +foo bar +---- +(foo (bar 'bar')) +`, + tc: &TestCase{ + Description: "test", + Source: []byte("foo bar"), + Output: NewNonTerminalTree("foo", + NewTerminalNode("bar", "bar"), + ).Fill(), + }, + }, + // A node may have just one pattern node. + { + src: `test +---- +foo bar +---- +(foo (bar "bar")) +`, + tc: &TestCase{ + Description: "test", + Source: []byte("foo bar"), + Output: NewNonTerminalTree("foo", + NewTerminalNode("bar", "bar"), + ).Fill(), + }, + }, + // A node may be the error node. + { + src: `test +---- +foo x +---- +(foo (error)) +`, + tc: &TestCase{ + Description: "test", + Source: []byte("foo x"), + Output: NewNonTerminalTree("foo", + NewTerminalNode("error", ""), + ).Fill(), + }, + }, + // The error node cannot have a string node. + { + src: `test +---- +foo x +---- +(foo (error 'x')) +`, + parseErr: true, + }, + // The error node cannot have a pattern node. + { + src: `test +---- +foo x +---- +(foo (error "x")) +`, + parseErr: true, + }, + { + src: `test +---- +foo x +---- +(foo (error (_ (x 'x')))) `, parseErr: true, },