Some CFL Practicalities CPSC 388 Ellen Walker Hiram College
Grammar for Expressions Exp -> Exp Op Exp | ( Exp ) | number Op -> + | – | * Non-terminals: Exp, Op Terminals: number, +, –, *, (, ) Terminals are tokens not necessarily characters!
Simple Grammar for Statement Stmt -> If-Stmt | … other statements If-Stmt -> if ( Exp ) Stmt | if ( Exp ) Stmt else Stmt Exp -> … on previous slide
More Concise If-Stmt using If-Stmt -> if ( Exp ) Stmt ElsePart ElsePart -> else Stmt |
Epsilon Placement is Significant How do these languages differ? L1: S -> x ; S | x L2: S-> x ; S | L3: S-> x ; S | A A -> x | L4: S-> N | N -> x ; N | x L1: x;x x;x;x x;x;x;x etc L2: empty, x, x; , x;x x;x;
Recursion in Grammars When a rule refers to its own LHS in the RHS, the rule is recursive Left-recursion (LHS is first) Right-recursion (LHS is last) “Exp -> Exp Op Exp” is both left-recursive and right-recursive!
Why Recursion? Without recursion, languages must be finite All possible derivations can be enumerated in advance Example: S-> aB B -> b | Cc C -> c
Recursion in Multiple Rules Stmt -> If-Stmt | … other statements If-Stmt -> if ( Exp ) Stmt | if ( Exp ) Stmt else Stmt Stmt => If-Stmt => if … Stmt … There is a recursion on Stmt, but it takes 2 rules
Ambiguous Grammars If there is a string that has two different derivations (with different parse trees), the grammar is ambiguous. Only one string is needed to determine ambiguity
Exp Grammar is Ambiguous Exp -> Exp Op Exp | ( Exp ) | number Op -> + | – | * Exp Exp Exp Op Exp Exp Op Exp Exp Op Exp Exp Op Exp number + number * number number + number * number
Dangling Else // w true when x!=0 and y=0 If (x!=0) if (y!=0) z=true;
Disambiguating Rule Leave the grammar ambiguous, but create a rule (outside the grammar) that determines which competing parse is “correct” Examples: Multiplication has precedence over addition Subtraction is left-associative Else matches the closest “if”
Modifying the Grammar Create additional non-terminals and rules that prevent ambiguity In this case, the syntax is (again) reflected only by the grammar
Exp Grammar with Precedence Exp -> Exp Adop Exp | Term Term -> Term Mulop Factor | Factor Factor -> ( Exp ) | number Adop -> + | – Mulop -> * * evaluation forced “deeper” into the tree!
If Grammar with “Closest else” Stmt -> MatchedStmt | UnmStmt MatchedStmt -> if (Exp) MatchedStmt else MatchedStmt | Other UnmStmt -> if (Exp) Stmt | if (Exp) MatchedStmt else UnmStmt Other -> { Stmt-list } | … | Stmt-list -> Stmt Stmt-list | Stmt This is sufficiently awkward that real grammars will likely use the disambiguating rule solution
Avoiding the IF ambiguity Require the else part in all if’s This is the LISP solution Require bracketing keywords If-stmt -> if Exp Stmt endif | if Exp Stmt else Stmt endif In some languages “fi” is used instead of “endif”
Abstract Parse Trees Design trees that include only essential aspects of the language (for semantics); remove “syntactic sugar” and intermediate non-terminals
Parse Tree vs. Abstract Parse Tree Exp Exp Op Exp + Exp Op Exp * number + number * number number number number
Extended BNF “Ordinary BNF” is simply a CFG Extensions Non-terminals named like: <expression> Terminals are bare sequences of characters Extensions { x } Repeat x 0 or more times ( x*) [ x ] x is optional (x | )