From 389dd0121475bdba7dea54f4cb02287fa48718da Mon Sep 17 00:00:00 2001 From: Ryo Nihei Date: Sat, 16 Apr 2022 00:49:58 +0900 Subject: Prohibit specifying associativity and precedence multiple times for a symbol --- grammar/grammar.go | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'grammar/grammar.go') diff --git a/grammar/grammar.go b/grammar/grammar.go index babfb10..c5b8a0c 100644 --- a/grammar/grammar.go +++ b/grammar/grammar.go @@ -980,7 +980,7 @@ func (b *GrammarBuilder) genPrecAndAssoc(symTab *symbolTable, prods *productionS }) return nil, nil } - + ASSOC_PARAM_LOOP: for _, p := range md.Parameters { if p.ID == "" { b.errs = append(b.errs, &verr.SpecError{ @@ -1011,6 +1011,31 @@ func (b *GrammarBuilder) genPrecAndAssoc(symTab *symbolTable, prods *productionS }) return nil, nil } + if prec, alreadySet := termPrec[sym.num()]; alreadySet { + if prec == precN { + b.errs = append(b.errs, &verr.SpecError{ + Cause: semErrDuplicateAssoc, + Detail: fmt.Sprintf("'%v' already has the same associativity and precedence", p.ID), + Row: p.Pos.Row, + Col: p.Pos.Col, + }) + } else if assoc := termAssoc[sym.num()]; assoc == assocTy { + b.errs = append(b.errs, &verr.SpecError{ + Cause: semErrDuplicateAssoc, + Detail: fmt.Sprintf("'%v' already has different precedence", p.ID), + Row: p.Pos.Row, + Col: p.Pos.Col, + }) + } else { + b.errs = append(b.errs, &verr.SpecError{ + Cause: semErrDuplicateAssoc, + Detail: fmt.Sprintf("'%v' already has different associativity and precedence", p.ID), + Row: p.Pos.Row, + Col: p.Pos.Col, + }) + } + break ASSOC_PARAM_LOOP + } termPrec[sym.num()] = precN termAssoc[sym.num()] = assocTy @@ -1019,6 +1044,9 @@ func (b *GrammarBuilder) genPrecAndAssoc(symTab *symbolTable, prods *productionS precN++ } } + if len(b.errs) > 0 { + return nil, nil + } prodPrec := map[productionNum]int{} prodAssoc := map[productionNum]assocType{} -- cgit v1.2.3