Nov 20, 2013 at 3:21 PM
Edited Nov 20, 2013 at 3:22 PM

My apologies if this has been answered elsewhere. I tried searching around but didn't find an answer. I have my grammar done so that is parses properly without conflicts, but I'm trying to influence how it decides to match expressions. I have a statement
like the following:
2d6+12+#18
Both + and +# are valid operators. I have a binary expression that is fairly typical. I also have what I call a threshold expression that is made up of an expression on the left and a number on the right, while the operator in the middle is either # or +#.
In the above example, the parser sees the threshold expression as 12+#18, where it is then the right hand value in an addition binary operation and the 2d6 is the left. My desire is for the parser to favor parsing 2d6+12 as a binary expression that is then
the left hand value in the threshold expression (essentially matching the most expansive expression possible on the left hand side of the +# operator). Is there some simple application of the PreferShiftHere() or ReduceHere() methods that accomplishes this?
I'm still reading/learning about lalr parsers and there is a lot I don't yet understand. Thank you for your time.



I think all you need to do is set appropriately the operator precedence: the value for '+' should be hire than for '+#'; just like * has higher prec than +



Actually I have already set the precedence in just that fashion. I had hoped doing so would fix my problem, but it did not. I have included my rather short grammar in case it helps. Thank you by the way for building such a nice community project.
this.Root = expression;
binOp.Rule = ToTerm("+")  ""  "/"  "*";
explodeDirectiveExpr.Rule = explodeOp + number  explodeOp;
compoundDirectiveExpr.Rule = compoundOp + number  compoundOp;
rollOptionExpr.Rule = Empty  compoundDirectiveExpr  explodeDirectiveExpr  increasedOp;
dieCodeExpr.Rule = dieOp + number;
diceRollExpr.Rule = number + dieCodeExpr + rollOptionExpr;
binModExpr.Rule = MakePlusRule(binModExpr, binOp + number);
modDiceExpr.Rule = lbrk + diceRollExpr + binModExpr + rbrk;
dropDiceExpr.Rule = (diceRollExpr  modDiceExpr) + (dropOp  keepOp) + number;
highDieExpr.Rule = (diceRollExpr  modDiceExpr) + highDieOp;
lowDieExpr.Rule = (diceRollExpr  modDiceExpr) + lowDieOp;
complexDiceRollExpr.Rule = (diceRollExpr  modDiceExpr  dropDiceExpr  highDieExpr  lowDieExpr);
targetExpr.Rule = ToTerm("#")  "+#";
thresholdExpr.Rule = expression + targetExpr + number;
conditionalExpr.Rule = thresholdExpr + conditionalOp + min_opt + binOp + expression;
parExpression.Rule = lpar + expression + rpar;
binExpr.Rule = expression + binOp + expression;
expression.Rule = complexDiceRollExpr  parExpression  binExpr  number  thresholdExpr  conditionalExpr;
RegisterOperators(4, "d");
RegisterOperators(3, "*", "/");
RegisterOperators(2, "+", "");
RegisterOperators(1, "+#", "#");



try marking binOp as transient, it might be an old bug that still sits there



Thank you, it looks like that solved the problem :)

