keyword_shadow.ebnf (1060B)
1 // RED FIXTURE — does not compile; preserved on purpose. 2 // 3 // The natural mistake: write the %lex block (defining the broad IDENT rule) 4 // first, then declare keyword tokens afterwards. Token priority is global source 5 // order, and on a same-length tie the lowest (earliest) priority wins — so 6 // IDENT, declared before IF, would win "if" and the IF token could never be 7 // produced. 8 // 9 // This used to compile SILENTLY and mis-tokenize every keyword as IDENT. The 10 // generator now rejects it with a located error that names the shadower and 11 // suggests the fix (declare keywords first, or use a %keywords block): 12 // 13 // red/keyword_shadow.ebnf:18:1: error: string literal token IF ("if") is 14 // shadowed by IDENT and can never be produced; declare it before the broader 15 // rule, or list it in a %keywords block 16 // 17 // The same case is regression-tested under test/errors/lex_keyword_shadow.ebnf. 18 %lex { 19 %skip WS = [ \t\r\n]+; 20 IDENT = [A-Za-z_] [A-Za-z0-9_]*; 21 } 22 %token IF = "if"; 23 %token WHILE = "while"; 24 25 stmt = "if" IDENT | "while" IDENT | IDENT;