@@ -30,21 +30,8 @@ func Check(grammar *Grammar) error {
3030 for _ , r := range rules {
3131 r .checkLeft (ruleMap , p , & errs )
3232 }
33-
34- var labels []map [string ]* LabelExpr
3533 for _ , r := range rules {
36- ls := check (r , ruleMap , & errs )
37- labels = append (labels , ls )
38- }
39- for i , ls := range labels {
40- rule := rules [i ]
41- for name , expr := range ls {
42- l := Label {Name : name , Type : expr .Type (), N : expr .N }
43- rule .Labels = append (rule .Labels , l )
44- }
45- sort .Slice (rule .Labels , func (i , j int ) bool {
46- return rule .Labels [i ].N < rule .Labels [j ].N
47- })
34+ check (r , ruleMap , & errs )
4835 }
4936 if err := errs .ret (); err != nil {
5037 return err
@@ -238,30 +225,44 @@ func (e *CharClass) checkLeft(rules map[string]*Rule, p path, errs *Errors) {}
238225
239226func (e * Any ) checkLeft (rules map [string ]* Rule , p path , errs * Errors ) {}
240227
241- func check ( rule * Rule , rules map [ string ] * Rule , errs * Errors ) map [ string ] * LabelExpr {
242- labels := make ( map [string ]* LabelExpr )
243- rule . Expr . check ( rules , labels , true , errs )
244- return labels
228+ type ctx struct {
229+ rules map [string ]* Rule
230+ allLabels * [] * LabelExpr
231+ curLabels map [ string ] * LabelExpr
245232}
246233
247- func (e * Choice ) check (rules map [string ]* Rule , labels map [string ]* LabelExpr , valueUsed bool , errs * Errors ) {
248- for _ , sub := range e .Exprs {
249- sub .check (rules , labels , valueUsed , errs )
234+ func check (rule * Rule , rules map [string ]* Rule , errs * Errors ) {
235+ ctx := ctx {
236+ rules : rules ,
237+ allLabels : & rule .Labels ,
238+ curLabels : make (map [string ]* LabelExpr ),
250239 }
240+ rule .Expr .check (ctx , true , errs )
241+ sort .Slice (rule .Labels , func (i , j int ) bool {
242+ return rule .Labels [i ].N < rule .Labels [j ].N
243+ })
244+ }
251245
252- t := e .Type ()
246+ func (e * Choice ) check (ctx ctx , valueUsed bool , errs * Errors ) {
247+ for _ , sub := range e .Exprs {
248+ subCtx := ctx
249+ subCtx .curLabels = make (map [string ]* LabelExpr )
250+ for n , l := range ctx .curLabels {
251+ subCtx .curLabels [n ] = l
252+ }
253+ sub .check (subCtx , valueUsed , errs )
254+ }
255+ t := e .Exprs [0 ].Type ()
253256 for _ , sub := range e .Exprs {
254- // Check types, but if either type is "",
255- // it's from a previous error; don't report again.
256257 if got := sub .Type (); * genActions && valueUsed && got != t && got != "" && t != "" {
257258 errs .add (sub , "type mismatch: got %s, expected %s" , got , t )
258259 }
259260 }
260261}
261262
262- func (e * Action ) check (rules map [ string ] * Rule , labels map [ string ] * LabelExpr , valueUsed bool , errs * Errors ) {
263- e .Expr .check (rules , labels , false , errs )
264- for _ , l := range labels {
263+ func (e * Action ) check (ctx ctx , valueUsed bool , errs * Errors ) {
264+ e .Expr .check (ctx , false , errs )
265+ for _ , l := range ctx . curLabels {
265266 e .Labels = append (e .Labels , l )
266267 }
267268 sort .Slice (e .Labels , func (i , j int ) bool {
@@ -270,9 +271,9 @@ func (e *Action) check(rules map[string]*Rule, labels map[string]*LabelExpr, val
270271}
271272
272273// BUG: figure out what to do about sequence types.
273- func (e * Sequence ) check (rules map [ string ] * Rule , labels map [ string ] * LabelExpr , valueUsed bool , errs * Errors ) {
274+ func (e * Sequence ) check (ctx ctx , valueUsed bool , errs * Errors ) {
274275 for _ , sub := range e .Exprs {
275- sub .check (rules , labels , valueUsed , errs )
276+ sub .check (ctx , valueUsed , errs )
276277 }
277278 t := e .Exprs [0 ].Type ()
278279 for _ , sub := range e .Exprs {
@@ -282,51 +283,52 @@ func (e *Sequence) check(rules map[string]*Rule, labels map[string]*LabelExpr, v
282283 }
283284}
284285
285- func (e * LabelExpr ) check (rules map [ string ] * Rule , labels map [ string ] * LabelExpr , valueUsed bool , errs * Errors ) {
286- e .Expr .check (rules , labels , true , errs )
287- if _ , ok := labels [e .Label .String ()]; ok {
286+ func (e * LabelExpr ) check (ctx ctx , valueUsed bool , errs * Errors ) {
287+ e .Expr .check (ctx , true , errs )
288+ if _ , ok := ctx . curLabels [e .Label .String ()]; ok {
288289 errs .add (e .Label , "label %s redefined" , e .Label .String ())
289290 }
290- e .N = len (labels )
291- labels [e .Label .String ()] = e
291+ e .N = len (* ctx .allLabels )
292+ * ctx .allLabels = append (* ctx .allLabels , e )
293+ ctx .curLabels [e .Label .String ()] = e
292294}
293295
294- func (e * PredExpr ) check (rules map [ string ] * Rule , labels map [ string ] * LabelExpr , valueUsed bool , errs * Errors ) {
295- e .Expr .check (rules , labels , false , errs )
296+ func (e * PredExpr ) check (ctx ctx , valueUsed bool , errs * Errors ) {
297+ e .Expr .check (ctx , false , errs )
296298}
297299
298- func (e * RepExpr ) check (rules map [ string ] * Rule , labels map [ string ] * LabelExpr , valueUsed bool , errs * Errors ) {
299- e .Expr .check (rules , labels , valueUsed , errs )
300+ func (e * RepExpr ) check (ctx ctx , valueUsed bool , errs * Errors ) {
301+ e .Expr .check (ctx , valueUsed , errs )
300302}
301303
302- func (e * OptExpr ) check (rules map [ string ] * Rule , labels map [ string ] * LabelExpr , valueUsed bool , errs * Errors ) {
303- e .Expr .check (rules , labels , valueUsed , errs )
304+ func (e * OptExpr ) check (ctx ctx , valueUsed bool , errs * Errors ) {
305+ e .Expr .check (ctx , valueUsed , errs )
304306}
305307
306- func (e * SubExpr ) check (rules map [ string ] * Rule , labels map [ string ] * LabelExpr , valueUsed bool , errs * Errors ) {
307- e .Expr .check (rules , labels , valueUsed , errs )
308+ func (e * SubExpr ) check (ctx ctx , valueUsed bool , errs * Errors ) {
309+ e .Expr .check (ctx , valueUsed , errs )
308310}
309311
310- func (e * Ident ) check (rules map [ string ] * Rule , _ map [ string ] * LabelExpr , _ bool , errs * Errors ) {
311- r , ok := rules [e .Name .String ()]
312+ func (e * Ident ) check (ctx ctx , _ bool , errs * Errors ) {
313+ r , ok := ctx . rules [e .Name .String ()]
312314 if ! ok {
313315 errs .add (e , "rule %s undefined" , e .Name .String ())
314316 } else {
315317 e .rule = r
316318 }
317319}
318320
319- func (e * PredCode ) check (_ map [ string ] * Rule , labels map [ string ] * LabelExpr , _ bool , _ * Errors ) {
320- for _ , l := range labels {
321+ func (e * PredCode ) check (ctx ctx , _ bool , _ * Errors ) {
322+ for _ , l := range ctx . curLabels {
321323 e .Labels = append (e .Labels , l )
322324 }
323325 sort .Slice (e .Labels , func (i , j int ) bool {
324326 return e .Labels [i ].Label .String () < e .Labels [j ].Label .String ()
325327 })
326328}
327329
328- func (e * Literal ) check (map [ string ] * Rule , map [ string ] * LabelExpr , bool , * Errors ) {}
330+ func (e * Literal ) check (ctx , bool , * Errors ) {}
329331
330- func (e * CharClass ) check (map [ string ] * Rule , map [ string ] * LabelExpr , bool , * Errors ) {}
332+ func (e * CharClass ) check (ctx , bool , * Errors ) {}
331333
332- func (e * Any ) check (map [ string ] * Rule , map [ string ] * LabelExpr , bool , * Errors ) {}
334+ func (e * Any ) check (ctx , bool , * Errors ) {}
0 commit comments