KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > tests > jfun > parsec > Calculator


1 /*****************************************************************************
2  * Copyright (C) Zephyr Business Solution. 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 /*
10  * Created on Oct 10, 2005
11  *
12  * Author Ben Yu
13  * ZBS
14  */

15 package tests.jfun.parsec;
16
17 import jfun.parsec.*;
18 import jfun.parsec.pattern.Pattern;
19 import jfun.parsec.pattern.Patterns;
20 import jfun.parsec.tokens.Tokenizers;
21
22 public class Calculator {
23   private interface Operator{
24     double cal(double a, double b);
25   }
26   private static Binary<Number JavaDoc> toMap2(final Operator op){
27     return new Binary<Number JavaDoc>(){
28       public Double JavaDoc map(Number JavaDoc i1, Number JavaDoc i2){
29         return op.cal(i1.doubleValue(), i2.doubleValue());
30       }
31     };
32   }
33   public Parser<Number JavaDoc> getParser(){
34     final Pattern digits = Patterns.range('0','9').many(1);
35     final Pattern number = digits.seq(Patterns.isChar('.').seq(digits).optional());
36     final Parser<_> s_number = Scanners.isPattern("number", number, "number expected");
37         
38     final Parser<_> s_line_comment = Scanners.javaLineComment();
39     final Parser<_> s_block_comment = Scanners.isBlockComment("/*","*/");
40     final Parser<_> s_whitespace = Scanners.isWhitespaces();
41     
42     final Parser<Tok> l_number = Lexers.lexer(s_number, Tokenizers.forDecimal());
43     final Terms ops = Terms.getOperatorsInstance("+","-","*","/", "(", ")");
44     final Parser<_> s_delim = Parsers.sum(s_line_comment, s_block_comment, s_whitespace)
45       .many();
46     final Parser<Tok> l_tok = Parsers.plus(ops.getLexer(), l_number);
47     final Parser<Tok[]> lexer = Lexers.lexeme(s_delim, l_tok)
48       .followedBy(Parsers.eof());
49     
50     final Operator plus = new Operator(){
51       public double cal(double n1, double n2){
52         return n1+n2;
53       }
54     };
55     final Operator minus = new Operator(){
56       public double cal(double n1, double n2){
57         return n1-n2;
58       }
59     };
60     final Operator mul = new Operator(){
61       public double cal(double n1, double n2){
62         return n1*n2;
63       }
64     };
65     final Operator div = new Operator(){
66       public double cal(double n1, double n2){
67         return n1/n2;
68       }
69     };
70     final Unary<Number JavaDoc> neg = new Unary<Number JavaDoc>(){
71       public Double JavaDoc map(Number JavaDoc n){
72         return -n.doubleValue();
73       }
74     };
75     final Parser<Tok> p_binary_ops = ops.getParser("+","-","*","/");
76     final Parser<?> p_whitespace_mul = p_binary_ops.not();
77     final Parser<Binary<Number JavaDoc>> p_plus = getOperator2(ops, "+", plus);
78     final Parser<Binary<Number JavaDoc>> p_minus = getOperator2(ops, "-", minus);
79     final Parser<Binary<Number JavaDoc>> p_mul = Parsers.sum(ops.getParser("*"), p_whitespace_mul)
80       .seq(Parsers.retn(toMap2(mul)));
81     final Parser<Binary<Number JavaDoc>> p_div = getOperator2(ops, "/", div);
82     final Parser<Unary<Number JavaDoc>> p_neg = getOperator(ops, "-", neg);
83     final Parser<Tok> p_lparen = ops.getParser("(");
84     final Parser<Tok> p_rparen = ops.getParser(")");
85     final Parser<Number JavaDoc> p_number = Terms.decimalParser(new FromString<Number JavaDoc>(){
86       public Number JavaDoc fromString(int from, int len, String JavaDoc s){
87         return Double.valueOf(s);
88       }
89     });
90     final Parser<Number JavaDoc>[] expr_holder = new Parser[1];
91     final Parser<Number JavaDoc> p_lazy_expr = Parsers.lazy(expr_holder);
92     final Parser<Number JavaDoc> p_term = Parsers.plus(
93         Parsers.between(p_lparen, p_rparen, p_lazy_expr),
94         p_number
95     );
96     final OperatorTable<Number JavaDoc> optable = new OperatorTable<Number JavaDoc>()
97       .infixl(p_plus, 10)
98       .infixl(p_minus, 10)
99       .infixl(p_mul, 20)
100       .infixl(p_div, 20)
101       .prefix(p_neg, 30);
102     final Parser<Number JavaDoc> p_expr = Expressions.buildExpressionParser(p_term, optable);
103     expr_holder[0] = p_expr;
104     return Parsers.parseTokens(lexer, p_expr.followedBy(Parsers.eof()), "calculator");
105   }
106   private static Parser<Binary<Number JavaDoc>>
107   getOperator2(Terms ops, String JavaDoc op, Operator v){
108     return getOperator(ops, op, toMap2(v));
109   }
110   private static <T> Parser<T> getOperator(Terms ops, String JavaDoc op, T v){
111     return ops.getParser(op).seq(Parsers.retn(v));
112   }
113 }
Popular Tags