aboutsummaryrefslogtreecommitdiff
path: root/grammar
diff options
context:
space:
mode:
Diffstat (limited to 'grammar')
-rw-r--r--grammar/grammar.go23
-rw-r--r--grammar/semantic_error.go2
2 files changed, 25 insertions, 0 deletions
diff --git a/grammar/grammar.go b/grammar/grammar.go
index 9d1933b..3f1117c 100644
--- a/grammar/grammar.go
+++ b/grammar/grammar.go
@@ -677,6 +677,7 @@ func (b *GrammarBuilder) genProductionsAndActions(root *spec.RootNode, symTabAnd
LOOP_RHS:
for _, alt := range prod.RHS {
altSyms := make([]symbol, len(alt.Elements))
+ labels := map[string]int{}
for i, elem := range alt.Elements {
var sym symbol
if elem.Pattern != "" {
@@ -707,6 +708,28 @@ func (b *GrammarBuilder) genProductionsAndActions(root *spec.RootNode, symTabAnd
}
}
altSyms[i] = sym
+
+ if elem.Label != nil {
+ if _, added := labels[elem.Label.Name]; added {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateLabel,
+ Detail: elem.Label.Name,
+ Row: elem.Label.Pos.Row,
+ Col: elem.Label.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ if _, found := symTab.toSymbol(elem.Label.Name); found {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrInvalidLabel,
+ Detail: elem.Label.Name,
+ Row: elem.Label.Pos.Row,
+ Col: elem.Label.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ labels[elem.Label.Name] = i
+ }
}
p, err := newProduction(lhsSym, altSyms)
diff --git a/grammar/semantic_error.go b/grammar/semantic_error.go
index d540c03..4326d81 100644
--- a/grammar/semantic_error.go
+++ b/grammar/semantic_error.go
@@ -27,6 +27,8 @@ var (
semErrDuplicateTerminal = newSemanticError("duplicate terminal")
semErrDuplicateName = newSemanticError("duplicate names are not allowed between terminals and non-terminals")
semErrErrSymIsReserved = newSemanticError("symbol 'error' is reserved as a terminal symbol")
+ semErrDuplicateLabel = newSemanticError("a label must be unique in an alternative")
+ semErrInvalidLabel = newSemanticError("a label must differ from terminal symbols or non-terminal symbols")
semErrDirInvalidName = newSemanticError("invalid directive name")
semErrDirInvalidParam = newSemanticError("invalid parameter")
)