grammar-shadowed-alternative

An alternative of an ordered choice that an earlier alternative always wins.

Group
Urscal grammars
Runs
On by default
Level
warning
Reads
Every file
Fix
None: reordering alternatives changes which one a parse takes, so the author chooses

Why

Urscal tries alternatives in order and keeps the first that matches. An earlier alternative that matches wherever a later one would, such as one whose symbols begin the later one's, leaves the later one unused. Put the longer alternative first, or remove the one that never matches.

The fix, as Ur suggests it: put the longer alternative first, or remove the one that never matches.

For agents

In an ordered choice, put no alternative after an earlier one that matches wherever it would.

Example

calc/Calc.rsc
module calc::Calc

track Calc = "1" "2";
dialect Standard uses Calc;
profile "calc-1" = Standard Calc "1";
profile "calc-2" = Standard Calc "2";

lexical Name = [a-z]+ \ Reserved;
lexical Number = [0-9]+;
layout Space = [\  \n]+;
keyword Reserved = "let" | "return";

start syntax Program = Program: Statement* statements;
syntax Statement
  = Let: "let" Name name "=" Expr value
  | Return: "return"
  | ReturnValue: "return" Expr value;
syntax Expr = Variable: Name name | Literal: Number number;
What Ur prints
$ ur lint --rule grammar-shadowed-alternative
warning[grammar-shadowed-alternative]: the alternative `ReturnValue` of `Statement` never matches: the alternative `Return` before it matches wherever it would
  --> ./calc/Calc.rsc:17:5 the alternative `ReturnValue` never matches
  --> ./calc/Calc.rsc:16:5 the alternative `Return` wins first
  = hint: put the longer alternative first, or remove the one that never matches
  = see: Parsing Expression Grammars: A Recognition-Based Syntactic Foundation, Bryan Ford, POPL 2004 (2004-01), https://doi.org/10.1145/964001.964011
0 clone classes and 1 grammar finding in 1 file

Try it in the playground →

Source

Parsing Expression Grammars: A Recognition-Based Syntactic Foundation, Bryan Ford, POPL 2004 (2004-01).