From 9a9444bdc00e2a738fb0aa7cac4afa8a123d679b Mon Sep 17 00:00:00 2001 From: Ryo Nihei Date: Sat, 16 Apr 2022 01:44:33 +0900 Subject: Prohibit using the same element multiple times in the #ast directive --- grammar/grammar.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'grammar/grammar.go') diff --git a/grammar/grammar.go b/grammar/grammar.go index c5b8a0c..b405429 100644 --- a/grammar/grammar.go +++ b/grammar/grammar.go @@ -752,10 +752,11 @@ func (b *GrammarBuilder) genProductionsAndActions(root *spec.RootNode, symTabAnd continue LOOP_RHS } offsets[elem.Label.Name] = i - } else { - if elem.ID != "" { - offsets[elem.ID] = i - } + } + // A symbol having a label can be specified by both the label and the symbol name. + // So record the symbol's position, whether or not it has a label. + if elem.ID != "" { + offsets[elem.ID] = i } } @@ -829,6 +830,7 @@ func (b *GrammarBuilder) genProductionsAndActions(root *spec.RootNode, symTabAnd continue LOOP_RHS } astAct := make([]*astActionEntry, len(dir.Parameters)) + consumedOffsets := map[int]struct{}{} for i, param := range dir.Parameters { if param.ID == "" { b.errs = append(b.errs, &verr.SpecError{ @@ -850,6 +852,16 @@ func (b *GrammarBuilder) genProductionsAndActions(root *spec.RootNode, symTabAnd }) continue LOOP_RHS } + if _, consumed := consumedOffsets[offset]; consumed { + b.errs = append(b.errs, &verr.SpecError{ + Cause: semErrDuplicateElem, + Detail: param.ID, + Row: param.Pos.Row, + Col: param.Pos.Col, + }) + continue LOOP_RHS + } + consumedOffsets[offset] = struct{}{} if param.Expansion { elem := alt.Elements[offset] -- cgit v1.2.3