@@ -1035,24 +1035,34 @@ trait Parsers {
10351035 * from the perspective of binary operators). May include
10361036 * unary operators or parentheses.
10371037 * @param binop a parser that matches binary operators.
1038- * @param precedence a function from operators to their precedence levels.
1039- * Operators with higher precedence values bind more
1040- * tightly than those with lower values.
1041- * @param associativity a function from operators to their associativity .
1038+ * @param prec_table a list of tuples, each of which encodes a level of
1039+ * precedence. Precedence is encoded highest to lowest.
1040+ * Each precedence level contains an Associativity value
1041+ * and a list of operators .
10421042 * @param makeBinop a function that combines two operands and an operator
10431043 * into a new expression. The result must have the same type
10441044 * as the operands because intermediate results become
10451045 * operands to other operators.
10461046 */
10471047 class PrecedenceParser [Exp ,Op ,E <: Exp ](primary : Parser [E ],
10481048 binop : Parser [Op ],
1049- precedence : Op => Int ,
1050- associativity : Op => Associativity ,
1049+ prec_table : List [(Associativity , List [Op ])],
10511050 makeBinop : (Exp , Op , Exp ) => Exp ) extends Parser [Exp ] {
1051+ private def decodePrecedence : (Map [Op , Int ], Map [Op , Associativity ]) = {
1052+ var precedence = Map .empty[Op , Int ]
1053+ var associativity = Map .empty[Op , Associativity ]
1054+ var level = prec_table.length
1055+ for ((assoc, ops) <- prec_table) {
1056+ precedence = precedence ++ (for (op <- ops) yield (op, level))
1057+ associativity = associativity ++ (for (op <- ops) yield (op, assoc))
1058+ level -= 1
1059+ }
1060+ (precedence, associativity)
1061+ }
1062+ val (precedence, associativity) = decodePrecedence
10521063 private class ExpandLeftParser (lhs : Exp , minLevel : Int ) extends Parser [Exp ] {
1053- val opPrimary = binop ~ primary;
10541064 def apply (input : Input ): ParseResult [Exp ] = {
1055- opPrimary (input) match {
1065+ (binop ~ primary) (input) match {
10561066 case Success (op ~ rhs, next) if precedence(op) >= minLevel => {
10571067 new ExpandRightParser (rhs, precedence(op), minLevel)(next) match {
10581068 case Success (r, nextInput) => new ExpandLeftParser (makeBinop(lhs, op, r), minLevel)(nextInput);
0 commit comments