@@ -1056,24 +1056,34 @@ trait Parsers {
10561056 * from the perspective of binary operators). May include
10571057 * unary operators or parentheses.
10581058 * @param binop a parser that matches binary operators.
1059- * @param precedence a function from operators to their precedence levels.
1060- * Operators with higher precedence values bind more
1061- * tightly than those with lower values.
1062- * @param associativity a function from operators to their associativity .
1059+ * @param prec_table a list of tuples, each of which encodes a level of
1060+ * precedence. Precedence is encoded highest to lowest.
1061+ * Each precedence level contains an Associativity value
1062+ * and a list of operators .
10631063 * @param makeBinop a function that combines two operands and an operator
10641064 * into a new expression. The result must have the same type
10651065 * as the operands because intermediate results become
10661066 * operands to other operators.
10671067 */
10681068 class PrecedenceParser [Exp ,Op ,E <: Exp ](primary : Parser [E ],
10691069 binop : Parser [Op ],
1070- precedence : Op => Int ,
1071- associativity : Op => Associativity ,
1070+ prec_table : List [(Associativity , List [Op ])],
10721071 makeBinop : (Exp , Op , Exp ) => Exp ) extends Parser [Exp ] {
1072+ private def decodePrecedence : (Map [Op , Int ], Map [Op , Associativity ]) = {
1073+ var precedence = Map .empty[Op , Int ]
1074+ var associativity = Map .empty[Op , Associativity ]
1075+ var level = prec_table.length
1076+ for ((assoc, ops) <- prec_table) {
1077+ precedence = precedence ++ (for (op <- ops) yield (op, level))
1078+ associativity = associativity ++ (for (op <- ops) yield (op, assoc))
1079+ level -= 1
1080+ }
1081+ (precedence, associativity)
1082+ }
1083+ val (precedence, associativity) = decodePrecedence
10731084 private class ExpandLeftParser (lhs : Exp , minLevel : Int ) extends Parser [Exp ] {
1074- val opPrimary = binop ~ primary;
10751085 def apply (input : Input ): ParseResult [Exp ] = {
1076- opPrimary (input) match {
1086+ (binop ~ primary) (input) match {
10771087 case Success (op ~ rhs, next) if precedence(op) >= minLevel => {
10781088 new ExpandRightParser (rhs, precedence(op), minLevel)(next) match {
10791089 case Success (r, nextInput) => new ExpandLeftParser (makeBinop(lhs, op, r), minLevel)(nextInput);
0 commit comments