diff options
Diffstat (limited to 'grammar/grammar.go')
-rw-r--r-- | grammar/grammar.go | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/grammar/grammar.go b/grammar/grammar.go index c5726d7..2cdf2b3 100644 --- a/grammar/grammar.go +++ b/grammar/grammar.go @@ -571,12 +571,12 @@ func genLexEntry(prod *spec.ProductionNode) (*mlspec.LexEntry, bool, string, *ve } } - if alt.Directive != nil { + if len(alt.Directives) > 0 { return nil, false, "", &verr.SpecError{ Cause: semErrInvalidAltDir, Detail: "a lexical production cannot have alternative directives", - Row: alt.Directive.Pos.Row, - Col: alt.Directive.Pos.Col, + Row: alt.Directives[0].Pos.Row, + Col: alt.Directives[0].Pos.Col, }, nil } @@ -680,6 +680,16 @@ func (b *GrammarBuilder) genProductionsAndActions(root *spec.RootNode, symTabAnd return nil, fmt.Errorf("symbol '%v' is undefined", prod.LHS) } + if len(prod.Directives) > 0 { + b.errs = append(b.errs, &verr.SpecError{ + Cause: semErrInvalidProdDir, + Detail: "a production cannot have production directives", + Row: prod.Directives[0].Pos.Row, + Col: prod.Directives[0].Pos.Col, + }) + continue + } + LOOP_RHS: for _, alt := range prod.RHS { altSyms := make([]symbol, len(alt.Elements)) @@ -788,8 +798,18 @@ func (b *GrammarBuilder) genProductionsAndActions(root *spec.RootNode, symTabAnd } prods.append(p) - if alt.Directive != nil { - dir := alt.Directive + dirConsumed := map[string]struct{}{} + for _, dir := range alt.Directives { + if _, consumed := dirConsumed[dir.Name]; consumed { + b.errs = append(b.errs, &verr.SpecError{ + Cause: semErrDuplicateDir, + Detail: dir.Name, + Row: dir.Pos.Row, + Col: dir.Pos.Col, + }) + } + dirConsumed[dir.Name] = struct{}{} + switch dir.Name { case "ast": if len(dir.Parameters) == 0 { |