@@ -20,6 +20,9 @@ import scala.language.implicitConversions
2020
2121//  TODO: better error handling (labelling like parsec's <?>)
2222
23+ /**  An enumeration of operator associativity values: `Left`, `Right`, and
24+  *  `Non`. 
25+  */  
2326object  Associativity  extends  Enumeration  {
2427  type  Associativity  =  Value 
2528
@@ -1025,18 +1028,34 @@ trait Parsers {
10251028
10261029  import  Associativity ._ 
10271030
1028-   class  PrecedenceParser [Exp ,Op ](primary : Parser [Exp ],
1029-                                  binop : Parser [Op ],
1030-                                  precedence : Op  =>  Int ,
1031-                                  associativity : Op  =>  Associativity ,
1032-                                  makeBinop : (Exp , Op , Exp ) =>  Exp ) extends  Parser [Exp ] {
1033-     class  PrecedenceSuffixParser (lhs : Exp , minLevel : Int ) extends  Parser [Exp ] {
1031+   /**  A parser that respects operator the precedence and associativity 
1032+    *  conventions specified in its constructor. 
1033+    * 
1034+    *  @param  primary  a parser that matches atomic expressions (the atomicity is 
1035+    *                 from the perspective of binary operators). May include 
1036+    *                 unary operators or parentheses. 
1037+    *  @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. 
1042+    * @param  makeBinop  a function that combines two operands and an operator 
1043+    *                  into a new expression. The result must have the same type 
1044+    *                  as the operands because intermediate results become 
1045+    *                  operands to other operators. 
1046+    */  
1047+   class  PrecedenceParser [Exp ,Op ,E  <:  Exp ](primary : Parser [E ],
1048+                                           binop : Parser [Op ],
1049+                                           precedence : Op  =>  Int ,
1050+                                           associativity : Op  =>  Associativity ,
1051+                                           makeBinop : (Exp , Op , Exp ) =>  Exp ) extends  Parser [Exp ] {
1052+     private  class  ExpandLeftParser (lhs : Exp , minLevel : Int ) extends  Parser [Exp ] {
10341053      val  opPrimary  =  binop ~  primary;
1035-       def  parse (input : Input ):  ParseResult [Exp ] =  {
1054+       def  apply (input : Input ):  ParseResult [Exp ] =  {
10361055        opPrimary(input) match  {
10371056          case  Success (op ~  rhs, next) if  precedence(op) >=  minLevel =>  {
1038-             new  PrecedenceRhsSuffixParser (rhs, precedence(op), minLevel)(next) match  {
1039-               case  Success (r, nextInput) =>  new  PrecedenceSuffixParser (makeBinop(lhs, op, r), minLevel)(nextInput);
1057+             new  ExpandRightParser (rhs, precedence(op), minLevel)(next) match  {
1058+               case  Success (r, nextInput) =>  new  ExpandLeftParser (makeBinop(lhs, op, r), minLevel)(nextInput);
10401059              case  ns =>  ns //  dead code
10411060            }
10421061          }
@@ -1047,7 +1066,7 @@ trait Parsers {
10471066      }
10481067    }
10491068
1050-     class  PrecedenceRhsSuffixParser (rhs : Exp , currentLevel : Int , minLevel : Int ) extends  Parser [Exp ] {
1069+     private   class  ExpandRightParser (rhs : Exp , currentLevel : Int , minLevel : Int ) extends  Parser [Exp ] {
10511070      private  def  nextLevel (nextBinop : Op ):  Option [Int ] =  {
10521071        if  (precedence(nextBinop) >  currentLevel) {
10531072          Some (minLevel +  1 )
@@ -1057,14 +1076,14 @@ trait Parsers {
10571076          None 
10581077        }
10591078      }
1060-       def  parse (input : Input ):  ParseResult [Exp ] =  {
1079+       def  apply (input : Input ):  ParseResult [Exp ] =  {
10611080        def  done :  ParseResult [Exp ] =  Success (rhs, input)
10621081        binop(input) match  {
10631082          case  Success (nextBinop,_) =>  {
10641083            nextLevel(nextBinop) match  {
10651084              case  Some (level) =>  {
1066-                 new  PrecedenceSuffixParser (rhs, level)(input) match  {
1067-                   case  Success (r, next) =>  new  PrecedenceRhsSuffixParser (r, currentLevel, minLevel)(next)
1085+                 new  ExpandLeftParser (rhs, level)(input) match  {
1086+                   case  Success (r, next) =>  new  ExpandRightParser (r, currentLevel, minLevel)(next)
10681087                  case  ns =>  ns //  dead code
10691088                }
10701089              }
@@ -1076,10 +1095,12 @@ trait Parsers {
10761095      }
10771096    }
10781097
1079-     def  parse (input : Input ):  ParseResult [Exp ] =  {
1098+     /**  Parse an expression. 
1099+      */  
1100+     def  apply (input : Input ):  ParseResult [Exp ] =  {
10801101      primary(input) match  {
10811102        case  Success (lhs, next) =>  {
1082-           new  PrecedenceSuffixParser (lhs,0 )(next)
1103+           new  ExpandLeftParser (lhs,0 )(next)
10831104        }
10841105        case  noSuccess =>  noSuccess
10851106      }
0 commit comments