Reputation: 724
I'm using Irony to parse a DSL, which has expressions that can be combined with ANDs and ORs:
/* snip */
RegisterOperators(4, orKeyword);
RegisterOperators(5, andKeyword);
RegisterOperators(9, lessThanOperator, lessEqualOperator, equalOperator, notEqualOperator, moreThanOperator, moreEqualOperator);
infixOperator.Rule = andKeyword | orKeyword;
expression_in_parens.Rule = L_PAR + expression + R_PAR;
primaryExpression.Rule = expression_in_parens | methodCall | identifier | numberIdentifier | stringIdentifier;
unaryExpression.Rule = notKeyword + L_PAR + expression + R_PAR;
binaryExpression.Rule = expression + infixOperator + expression;
compareExpression.Rule = expression + compareOperator + expression + ReduceHere();
expression.Rule = primaryExpression | unaryExpression | compareExpression | binaryExpression;
I have the following expression: "A and (B and C or D)". It's parsed as "A and (B and (C or D))", but I need it to be "A and ((B and C) or D)".
I thought registering the and keyword as an operator with a higher priority than the or keyword would do that. What am I missing?
Upvotes: 2
Views: 1139
Reputation: 1
Irony parser checks precedence of operators in terminals orKeyword
, andKeyword
. But there is nonterminal infixOperator
without precedence. So, you have set transient for it: MarkTransient(infixOperator).
Upvotes: 0
Reputation: 724
I got it working by creating separate rules for AND and OR, and putting those in the right order:
binaryAndExpression.Rule = expression + andKeyword + expression;
binaryOrExpression.Rule = expression + orKeyword + expression;
compareExpression.Rule = expression + compareOperator + expression + ReduceHere();
expression.Rule = compareExpression | binaryAndExpression | binaryOrExpression | unaryExpression | primaryExpression;
Upvotes: 1