options { LOOKAHEAD=1; } PARSER_BEGIN(Parser) package edu.jsu.leathrum.mathlets.shared; // import java.io.*; import java.util.Stack; import java.text.ParsePosition; public class Parser { static Stack argStack = new Stack(); public final static int PLUS = '+'; public final static int MINUS = '-'; public final static int MULT = '*'; public final static int DIV = '/'; public final static int POW = '^'; public final static int NEG = '!'; public final static int PI = 'p'; public final static int E = 'e'; public final static int VARX = 'x'; public final static int VARY = 'y'; public final static int VARZ = 'z'; public final static int VARU = 'u'; public final static int VARV = 'v'; public final static int VARR = '1'; public final static int VARS = '2'; public final static int VART = '3'; public final static int VARN = '4'; public final static int VARC = '5'; public final static int ABS = '|'; public final static int SQRT = '%'; public final static int NRT = 'N'; public final static int SIN = 's'; public final static int COS = 'c'; public final static int TAN = 't'; public final static int SEC = 'q'; public final static int CSC = 'w'; public final static int COT = 'b'; public final static int LN = 'l'; public final static int LOG = 'g'; public final static int EXP = '@'; public final static int ASIN = 'S'; public final static int ACOS = 'C'; public final static int ATAN = 'T'; public final static int ASEC = 'Q'; public final static int MIN = 'n'; public final static int MAX = 'm'; public final static int INT = 'i'; public final static int ALT = 'a'; public final static int DBL = 'd'; public final static int FACT = 'f'; public final static int COND = '?'; public final static int AND = '&'; public final static int OR = 'V'; public final static int NOT = '~'; public final static int LESS = '<'; public final static int GRT = '>'; public final static int EQ = '='; public final static int INFTY = '$'; public final static int ERROR = 'X'; public Stack getStack() { try{ try { if (one_line() != 1) { argStack.push(new Integer(Parser.ERROR)); } } catch (ParseException z) { argStack.push(new Integer(Parser.ERROR)); } } catch (TokenMgrError e) { argStack.push(new Integer(Parser.ERROR)); } return (Stack) argStack.clone(); } } PARSER_END(Parser) SKIP : { " " | "\r" | "\t" } TOKEN : { < EOL: "\n" > } TOKEN : /* OPERATORS */ { < PLUSt: "+" > | < MINUSt: "-" > | < MULTIPLY: "*" > | < DIVIDE: "/" > | < EXPt: "^" > | < FACTt: "!" > | < ANDt: "&" > | < ORt: "|" > | < LESSt: "<" > | < GRTt: ">" > | < EQt: "=" > } TOKEN : /* numeric constants */ { < CONSTANT: | ( ["e","E"] ([ "-","+"])? )? > | < #FLOAT: | ( [".",","] )? | [".",","] > | < #INTEGER: ( )+ > | < #DIGIT: ["0" - "9"] > } TOKEN : /* Function names */ { < ID: ( )+ ( | )* > | < #LETTER: ["a"-"z", "A"-"Z"] > } int one_line() : {} { logical() { return 1; } | { return 0; } | { return -1; } } void sum() : {Token x; boolean q = false;} { [ {q=true;} ] term() {if (q) {argStack.push(new Integer(Parser.NEG)); q=false;} } ( ( x = | x = ) term() { if ( x.kind == PLUSt ) argStack.push(new Integer(Parser.PLUS)); else argStack.push(new Integer(Parser.MINUS)); } )* } void term() : {Token x;} { ( LOOKAHEAD(2) numconst() exp() {argStack.push(new Integer(Parser.MULT));} | exp() ) ( ( x = | x = ) exp() { if ( x.kind == MULTIPLY ) argStack.push(new Integer(Parser.MULT)); else argStack.push(new Integer(Parser.DIV)); } )* } void exp() : { } { fact() ( fact() { argStack.push(new Integer(Parser.POW)); } )* } void fact() : { } { element() ( { argStack.push(new Integer(Parser.FACT)); } )* } void element() : {} { LOOKAHEAD(2) function() | numconst() | idconst() | "(" logical() ")" } void numconst() : {} { { try { argStack.push(AMathlet.getNumberFormat().parse(token.image, new ParsePosition(0))); } catch (NumberFormatException ee) { argStack.push(new Double(Double.NaN)); } argStack.push(new Integer(Parser.DBL)); } } void idconst() : { String idname;} { { idname = token.image; if (idname.equalsIgnoreCase("pi")) { argStack.push(new Integer(Parser.PI)); } else if (idname.equalsIgnoreCase("e")) { argStack.push(new Integer(Parser.E)); } else if (idname.equalsIgnoreCase("infty")) { argStack.push(new Integer(Parser.INFTY)); } else if (idname.equalsIgnoreCase("x")) { argStack.push(new Integer(Parser.VARX)); } else if (idname.equalsIgnoreCase("y")) { argStack.push(new Integer(Parser.VARY)); } else if (idname.equalsIgnoreCase("z")) { argStack.push(new Integer(Parser.VARZ)); } else if (idname.equalsIgnoreCase("u")) { argStack.push(new Integer(Parser.VARU)); } else if (idname.equalsIgnoreCase("v")) { argStack.push(new Integer(Parser.VARV)); } else if (idname.equalsIgnoreCase("r")) { argStack.push(new Integer(Parser.VARR)); } else if (idname.equalsIgnoreCase("s")) { argStack.push(new Integer(Parser.VARS)); } else if (idname.equalsIgnoreCase("t")) { argStack.push(new Integer(Parser.VART)); } else if (idname.equalsIgnoreCase("n")) { argStack.push(new Integer(Parser.VARN)); } else if (idname.equalsIgnoreCase("c")) { argStack.push(new Integer(Parser.VARC)); } else argStack.push(new Integer(Parser.ERROR)); } } void function() : { String funcname; double args = 0; } { {funcname = token.image;} "(" [ logical() {args++;} ( "," logical() {args++;})* ] ")" { double a, b; if (funcname.equalsIgnoreCase("abs")) { if (args != 1) { System.err.println("Wrong number of arguments to abs()"); throw new ParseException(); } argStack.push(new Integer(Parser.ABS)); } else if (funcname.equalsIgnoreCase("sqrt")) { if (args != 1) { System.err.println("Wrong number of arguments to sqrt()"); throw new ParseException(); } argStack.push(new Integer(Parser.SQRT)); } else if (funcname.equalsIgnoreCase("nrt")) { if (args != 2) { System.err.println("Wrong number of arguments to nrt()"); throw new ParseException(); } argStack.push(new Integer(Parser.NRT)); } else if (funcname.equalsIgnoreCase("sin")) { if (args != 1) { System.err.println("Wrong number of arguments to sin()"); throw new ParseException(); } argStack.push(new Integer(Parser.SIN)); } else if (funcname.equalsIgnoreCase("cos")) { if (args != 1) { System.err.println("Wrong number of arguments to cos()"); throw new ParseException(); } argStack.push(new Integer(Parser.COS)); } else if (funcname.equalsIgnoreCase("tan")) { if (args != 1) { System.err.println("Wrong number of arguments to tan()"); throw new ParseException(); } argStack.push(new Integer(Parser.TAN)); } else if (funcname.equalsIgnoreCase("sec")) { if (args != 1) { System.err.println("Wrong number of arguments to sec()"); throw new ParseException(); } argStack.push(new Integer(Parser.SEC)); } else if (funcname.equalsIgnoreCase("csc")) { if (args != 1) { System.err.println("Wrong number of arguments to csc()"); throw new ParseException(); } argStack.push(new Integer(Parser.CSC)); } else if (funcname.equalsIgnoreCase("tan")) { if (args != 1) { System.err.println("Wrong number of arguments to tan()"); throw new ParseException(); } argStack.push(new Integer(Parser.TAN)); } else if (funcname.equalsIgnoreCase("ln")) { if (args != 1) { System.err.println("Wrong number of arguments to ln()"); throw new ParseException(); } argStack.push(new Integer(Parser.LN)); } else if (funcname.equalsIgnoreCase("log")) { if (args != 1) { System.err.println("Wrong number of arguments to log()"); throw new ParseException(); } argStack.push(new Integer(Parser.LOG)); } else if (funcname.equalsIgnoreCase("exp")) { if (args != 1) { System.err.println("Wrong number of arguments to exp()"); throw new ParseException(); } argStack.push(new Integer(Parser.EXP)); } else if (funcname.equalsIgnoreCase("asin") || funcname.equalsIgnoreCase("arcsin")) { if (args != 1) { System.err.println("Wrong number of arguments to arcsin()"); throw new ParseException(); } argStack.push(new Integer(Parser.ASIN)); } else if (funcname.equalsIgnoreCase("acos") || funcname.equalsIgnoreCase("arccos")) { if (args != 1) { System.err.println("Wrong number of arguments to arccos()"); throw new ParseException(); } argStack.push(new Integer(Parser.ACOS)); } else if (funcname.equalsIgnoreCase("atan") || funcname.equalsIgnoreCase("arctan")) { if (args != 1) { System.err.println("Wrong number of arguments to arctan()"); throw new ParseException(); } argStack.push(new Integer(Parser.ATAN)); } else if (funcname.equalsIgnoreCase("asec") || funcname.equalsIgnoreCase("arcsec")) { if (args != 1) { System.err.println("Wrong number of arguments to arcsec()"); throw new ParseException(); } argStack.push(new Integer(Parser.ASEC)); } else if (funcname.equalsIgnoreCase("min")) { if (args != 2) { System.err.println("Wrong number of arguments to min()"); throw new ParseException(); } argStack.push(new Integer(Parser.MIN)); } else if (funcname.equalsIgnoreCase("max")) { if (args != 2) { System.err.println("Wrong number of arguments to max()"); throw new ParseException(); } argStack.push(new Integer(Parser.MAX)); } else if (funcname.equalsIgnoreCase("int")) { if (args != 1) { System.err.println("Wrong number of arguments to int()"); throw new ParseException(); } argStack.push(new Integer(Parser.INT)); } else if (funcname.equalsIgnoreCase("alt")) { if (args != 1) { System.err.println("Wrong number of arguments to alt()"); throw new ParseException(); } argStack.push(new Integer(Parser.ALT)); } else { argStack.push(new Integer(Parser.ERROR)); } } } void logical() : { } { test() [ "?" test() ":" test() { argStack.push(new Integer(Parser.COND)); } ] } void test() : {Token x;} { unarytest() ( ( x = | x = ) unarytest() { if ( x.kind == ANDt ) argStack.push(new Integer(Parser.AND)); else argStack.push(new Integer(Parser.OR)); } )* } void unarytest() : { } { "~" atomic() { argStack.push(new Integer(Parser.NOT)); } | atomic() } void atomic() : {Token x; } { sum() [ ( x = | x = | x = ) sum() { if (x.kind == LESSt) argStack.push(new Integer(Parser.LESS)); else if (x.kind == GRTt) argStack.push(new Integer(Parser.GRT)); else argStack.push(new Integer(Parser.EQ)); } ] }