Domanda

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?

È stato utile?

Soluzione

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top