How to tell the precedence of operators in a context free grammar
Asked Answered
E

1

5

How can we know which of the following logical operations ( or, and, not ) in the bellow context free grammar have higher precedence? Is there a general approach to this kind of problems?

X → X or Y | Y

Y → Y and Z | Z

Z → not Z | (X) | true | false

Eudemonia answered 20/10, 2014 at 17:52 Comment(0)
B
15

Here's an example approach:

expr -> addExpr;
addExpr -> multExpr (('+'|'-') multExpr)*;
multExpr -> terminalExpr (('*'|'/') terminalExpr)*;
terminalExpr -> integer | variable | '(' expr ')';

But the associativity is ambiguous. Here's a more explicit way in BNF:

expr -> addExpr;
addExpr -> addExpr '+' multExpr | addExpr '-' multExpr | multExpr;
multExpr -> multExpr '*' terminalExpr | multExpr '/' terminalExpr | terminalExpr;
terminalExpr -> integer | variable | '(' expr ')';

These grammars define the operators * and / as having more precedence as + and -. You declare the operation with higher precedence deeper in the parse tree, so they will be tried first by the parser.

Benzol answered 20/10, 2014 at 18:3 Comment(4)
good example. thanks. so what it means is that the operation with higher precedence should be lower in the parsing tree. maybe u can add that to your answer and id plus one it!Eudemonia
@rici huh I don't know what I was thinking :-\ Thanks for noticing this, I've fixed the answer.Benzol
Thanks. So if I want to add an exponential(**) operator to the above grammar(which is having the highest precedence) then I need to add this operation in the second last level of your grammar right?Autumnautumnal
@Autumnautumnal Since exponentiation has a higher precedence than multiplication, you need to add a separate level to the grammar (between multExpr and terminalExpr) in order to handle it correctly.Benzol

© 2022 - 2024 — McMap. All rights reserved.