KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jfun > parsec > Expressions


1 /*****************************************************************************
2  * Copyright (C) Zephyr Business Solutions Corp. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  *****************************************************************************/

8 /*
9  * Created on Nov 19, 2004
10  *
11  * Author Ben Yu
12  */

13 package jfun.parsec;
14
15 /**
16  * Expressions provides helper functions to build parser for a operator-precedence expression grammar. <br>
17  * It supports prefix unary, postfix unary, infix left associative binary,
18  * infix right associative binary and infix non-associative binary operators.
19  * <br>
20  * @author Ben Yu
21  *
22  * Nov 19, 2004
23  */

24 public final class Expressions {
25   /**
26    * Creates a Parser object based on information described by OperatorTable.
27    * @param term parser for the terminals.
28    * @param table the operator table.
29    * @return the expression parser.
30    */

31   public static <E,T extends E> Parser<E> buildExpressionParser(final Parser<T> term, final OperatorTable<E> table){
32     return buildExpressionParser("expression", term, table);
33   }
34   /**
35    * Creates a Parser object based on information described by OperatorTable.
36    * @param name the name of the parser.
37    * @param term parser for the terminals.
38    * @param table the operator table.
39    * @return the expression parser.
40    */

41   public static <E,T extends E> Parser<E> buildExpressionParser(final String JavaDoc name,
42       final Parser<T> term, final OperatorTable<E> table){
43     final OperatorTable.Operator[] ops = table.getOperators();
44     if(ops.length == 0) return term.convert();//Parsers.subsume(term);
45
int begin = 0;
46     int prec = ops[0].getPrecedence();
47     int kind = ops[0].getKind();
48     int end = 0;
49     Parser ret = term;
50     for(int i=1; i<ops.length; i++){
51       final OperatorTable.Operator op = ops[i];
52       end = i;
53       if(op.getPrecedence() == prec && op.getKind() == kind){
54         continue;
55       }
56       else{
57         end = i;
58         final Parser p = slice(name, ops, begin, end);
59         ret = build(name, p, kind, ret);
60         begin = i;
61         prec = ops[i].getPrecedence();
62         kind = ops[i].getKind();
63       }
64     }
65     if(end != ops.length){
66       end = ops.length;
67       kind = ops[begin].getKind();
68       final Parser p = slice(name, ops, begin, end);
69       ret = build(name, p, kind, ret);
70     }
71     return ret;
72   }
73   private static Parser slice(final String JavaDoc name, final OperatorTable.Operator[] ops, final int begin, final int end){
74     final Parser[] ps = new Parser[end-begin];
75     for(int i=0; i<ps.length; i++){
76       ps[i] = ops[i+begin].getOp();
77     }
78     return Parsers.sum(name, ps);
79   }
80   private static <E, T extends E> Parser<E> build(final String JavaDoc name,
81       final Parser op, final int kind, final Parser<T> operand){
82     switch(kind){
83       case OperatorTable.PREFIX:
84         return Parsers.prefix(name, op, operand);
85       case OperatorTable.POSTFIX:
86         return Parsers.postfix(name, op, operand);
87       case OperatorTable.LASSOC:
88         return Parsers.infixl(name, op, operand);
89       case OperatorTable.RASSOC:
90         return Parsers.infixr(name, op, operand);
91       case OperatorTable.NASSOC:
92         return Parsers.infixn(name, op, operand);
93       default:
94         return operand.convert();//Parsers.subsume(operand);
95
}
96   }
97 }
98
Popular Tags