aboutsummaryrefslogtreecommitdiff
path: root/spec/parser_test.go
diff options
context:
space:
mode:
authorRyo Nihei <nihei.dev@gmail.com>2022-03-30 00:44:17 +0900
committerRyo Nihei <nihei.dev@gmail.com>2022-03-30 00:50:06 +0900
commita1e4ae763cbf824f0d32a706cfe0d9603ce99b02 (patch)
treee32f48d6d5d3f56d495a8684653e913f14ca5ec8 /spec/parser_test.go
parentMove directives given to lexical productions (diff)
downloadcotia-a1e4ae763cbf824f0d32a706cfe0d9603ce99b02.tar.gz
cotia-a1e4ae763cbf824f0d32a706cfe0d9603ce99b02.tar.xz
Allow an alternative to have multiple directives
Diffstat (limited to 'spec/parser_test.go')
-rw-r--r--spec/parser_test.go52
1 files changed, 43 insertions, 9 deletions
diff --git a/spec/parser_test.go b/spec/parser_test.go
index e579fad..0772dae 100644
--- a/spec/parser_test.go
+++ b/spec/parser_test.go
@@ -43,8 +43,8 @@ func TestParse(t *testing.T) {
alt.Pos = pos
return alt
}
- withAltDir := func(alt *AlternativeNode, dir *DirectiveNode) *AlternativeNode {
- alt.Directive = dir
+ withAltDir := func(alt *AlternativeNode, dirs ...*DirectiveNode) *AlternativeNode {
+ alt.Directives = dirs
return alt
}
dir := func(name string, params ...*ParameterNode) *DirectiveNode {
@@ -362,6 +362,43 @@ whitespace #mode default m1 m2 #skip
},
},
{
+ caption: "an alternative of a production can have multiple alternative directives",
+ src: `
+s
+ : foo bar #prec baz #ast foo bar
+ ;
+`,
+ ast: &RootNode{
+ Productions: []*ProductionNode{
+ prod("s",
+ withAltDir(
+ alt(id("foo"), id("bar")),
+ dir("prec", idParam("baz")),
+ dir("ast", idParam("foo"), idParam("bar")),
+ ),
+ ),
+ },
+ },
+ },
+ {
+ caption: "a lexical production can have multiple production directives",
+ src: `
+foo #mode a #push b
+ : 'foo';
+`,
+ ast: &RootNode{
+ LexProductions: []*ProductionNode{
+ withProdDir(
+ prod("foo",
+ alt(pat("foo")),
+ ),
+ dir("mode", idParam("a")),
+ dir("push", idParam("b")),
+ ),
+ },
+ },
+ },
+ {
caption: "a production must be followed by a newline",
src: `
s: foo; foo: "foo";
@@ -774,14 +811,11 @@ func testAlternativeNode(t *testing.T, alt, expected *AlternativeNode, checkPosi
for i, elem := range alt.Elements {
testElementNode(t, elem, expected.Elements[i], checkPosition)
}
- if expected.Directive == nil && alt.Directive != nil {
- t.Fatalf("unexpected directive; want: nil, got: %+v", alt.Directive)
+ if len(alt.Directives) != len(expected.Directives) {
+ t.Fatalf("unexpected alternative directive count; want: %v directive, got: %v directive", len(expected.Directives), len(alt.Directives))
}
- if expected.Directive != nil {
- if alt.Directive == nil {
- t.Fatalf("a directive is not set; want: %+v, got: nil", expected.Directive)
- }
- testDirectives(t, []*DirectiveNode{alt.Directive}, []*DirectiveNode{expected.Directive}, checkPosition)
+ if len(alt.Directives) > 0 {
+ testDirectives(t, alt.Directives, expected.Directives, checkPosition)
}
if checkPosition {
testPosition(t, alt.Pos, expected.Pos)