header { package com.web4math.maxima.parser; import antlr.collections.*; import java.io.*; import java.util.*; } class MaximaOMParser extends Parser; options { k = 3; //two token lookahead //codeGenMakeSwitchThreshold = 5; //codeGenBitsetTestThreshold = 6; buildAST=true; ASTLabelType = "antlr.CommonAST"; // change default of "AST" } tokens { UNARY_MINUS; /* helper token to match unary minus. */ UNARY_PLUS; /* helper token to match unary plus. */ AST_TOP; /* imaginary token */ VAR; DOLLARVAR; LISP_ID; LISP_SYMBOL; MLIST; FUNCTION; BINDING; NUMBER; SIMP_OP; } sExpr : maximaGR { #sExpr = #([AST_TOP, "AST_TOP"], sExpr); } ; maximaGR : NUMBER | ID | LISP_OP | "SIMP" | VAR | DOLLARVAR //| LAMBDA^ {#maximaGR= #([BINDING,"BINDING"],maximaGR);} | maximaList ; // //| LPAREN! LISP_OP SIMP! RPAREN! /* maximaAtom : INT // {#maximaAtom= #([INT,"INT"],maximaAtom);} | ID //{#maximaAtom= #([LISP_ID,"LISP_ID"],maximaAtom);} | LISP_OP //{#maximaAtom= #([LISP_SYMBOL,"LISP_SYMBOL"],maximaAtom);} | VAR //{#maximaAtom= #([VAR,"VAR"],maximaAtom);} | DOLLARVAR //{#maximaAtom= #([DOLLARVAR,"DOLLARVAR"],maximaAtom);} ; */ maximaList : LPAREN! m:maximaGR (maximaGR)* RPAREN! {#maximaList= #([FUNCTION,"APPLICATION"],maximaList);} | LPAREN! LPAREN! LAMBDA "SIMP"! RPAREN! (maximaGR)* RPAREN! {#maximaList= #([BINDING,"BINDING"],maximaList);} | SHARP_QUOTE maximaGR ; //| LPAREN (maximaGR)+ "." maximaGR RPAREN //| LPAREN! LPAREN! LAMBDA "SIMP"! RPAREN! (maximaGR)* RPAREN! {#maximaList= #([BINDING,"BINDING"],maximaList);} /** * The Maxima Lexer.
* * It reads in the input that is said to be maxima input. It tries * to read the tokens that valid maxima input should have. If it * succeeds it generates a sequence of tokens, which in turn can * be read by the maxima parser.
* * @author Olga Caprotti. * @version 1.0 */ class MaximaOMLexer extends Lexer; tokens { LAMBDA = "LAMBDA"; //SIMP = "SIMP"; } SHARP_QUOTE : '#' ; //DOLLAR_SIGN : '$' ; //BAR_SIGN : '|' ; LPAREN : '(' ; RPAREN : ')' ; SEMI : ';' ; LISP_OP : '%'! ID; VAR : '|'! '$'! ID '|'!; DOLLARVAR : '$'! (LISP_OP|ID); /** * Reads whitespace and throws it away.
* * @since 1.0 */ WS : (' '|'\t'|'\n'|'\r') { _ttype = Token.SKIP; } ; protected DIGIT : '0'..'9'; NUMBER : ('-' | ) (DIGIT)+ ('.' (DIGIT)* ('e' ('-'| ) (DIGIT)+ | ) | ); STRING_LITERAL : '"'! (~'"')* '"'! ; ID options { testLiterals = true; } : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* ; /** * Tree walker.
* * Transform the AST-tree to an OpenMath object. * * @author * @version 1.0 */ class MaximaOMTreeWalker extends TreeParser; { /** * Stores the hashtable for CD matching.
* * This hashtable is used to lookup which codecs handles * a given Maxima prefix operator.
* * Eg. ((MPLUS SIMP) 1, 2 ) -> arith1 plus
*/ protected Hashtable mDecodeHashtable = new Hashtable(); protected Hashtable mDecodeHashtable2 = new Hashtable(); /** * Stores the Maxima operators translated by this parser.
*
* @since 1.0
*/
private String[] sNames =
{
"MABS",
"GCD",
"LCM",
"MPLUS",
"MEXPT",
"MNCEXPT",
"PRODUCT",
"SUM",
"MTIMES",
"MNCTIMES",
"RAT",
"MEQUAL",
"MGEQP",
"MGREATERP",
"MLEQP",
"MLESSP",
"MNOTEQUAL",
"SIN",
"COS",
"TAN",
"SEC",
"CSC",
"COT",
"SINH",
"COSH",
"TANH",
"SECH",
"CSCH",
"COTH",
"ASIN",
"ACOS",
"ATAN",
"ASEC",
"ACSC",
"ACOT",
"ASINH",
"ACOSH",
"ATANH",
"ASECH",
"ACSCH",
"ACOTH",
"EXP",
"LOG",
"LAMBDA",
};
public String[] sNames2 =
{
"MATRIX",
"UND",
"INF",
"MINF",
};
public void fillTable ()
{
mDecodeHashtable.put( "MABS", "arith1:abs");
mDecodeHashtable.put( "GCD", "arith1:gcd" );
mDecodeHashtable.put( "LCM", "arith1:lcm" );
mDecodeHashtable.put( "MPLUS", "arith1:plus" );
mDecodeHashtable.put( "MEXPT", "arith1:power" );
mDecodeHashtable.put( "MNCEXPT", "arith1:power" );
mDecodeHashtable.put( "PRODUCT", "arith1:product" );
mDecodeHashtable.put( "SUM", "arith1:sum" );
mDecodeHashtable.put( "MTIMES", "arith1:times" );
mDecodeHashtable.put( "MNCTIMES", "arith1:times" );
mDecodeHashtable.put( "MQUOTIENT", "arith1:divide"); // internally does as
//mDecodeHashtable.put( "MMINUS", "arith1:unary_minus" ); // internally done with mtimes -1
//mDecodeHashtable.put( "SQRT", "arith1" ); //internally done as exp
mDecodeHashtable.put( "RAT", "nums1:rational"); // encode a rational as a integer division
mDecodeHashtable.put( "MEQUAL", "relation1:equal" );
mDecodeHashtable.put( "MGEQP", "relation1:" );
mDecodeHashtable.put( "MGREATERP", "relation1" );
mDecodeHashtable.put( "MLEQP", "relation1" );
mDecodeHashtable.put( "MLESSP", "relation1" );
mDecodeHashtable.put( "MNOTEQUAL", "relation1" );
mDecodeHashtable.put( "SIN", "transc1:sin" );
mDecodeHashtable.put( "COS", "transc1:cos" );
mDecodeHashtable.put( "TAN", "transc1:tan" );
mDecodeHashtable.put( "SEC", "transc1:sec" );
mDecodeHashtable.put( "CSC", "transc1:csc");
mDecodeHashtable.put( "COT", "transc1:cot" );
mDecodeHashtable.put( "SINH", "transc1:sinh" );
mDecodeHashtable.put( "COSH", "transc1:cosh" );
mDecodeHashtable.put( "TANH", "transc1:tanh" );
mDecodeHashtable.put( "SECH", "transc1:sech" );
mDecodeHashtable.put( "CSCH", "transc1:csch" );
mDecodeHashtable.put( "COTH", "transc1:coth" );
mDecodeHashtable.put( "ASIN", "transc1:arcsin" );
mDecodeHashtable.put( "ACOS", "transc1:arccos" );
mDecodeHashtable.put( "ATAN", "transc1:arctan" );
mDecodeHashtable.put( "ASEC", "transc1:arcsec" );
mDecodeHashtable.put( "ACSC", "transc1:arccsc" );
mDecodeHashtable.put( "ACOT", "transc1:arccoth" );
mDecodeHashtable.put( "ASINH", "transc1:arcsinh" );
mDecodeHashtable.put( "ACOSH", "transc1:arccosh" );
mDecodeHashtable.put( "ATANH", "transc1:arctanh" );
mDecodeHashtable.put( "ASECH", "transc1:arcsech" );
mDecodeHashtable.put( "ACSCH", "transc1:arccsch" );
mDecodeHashtable.put( "ACOTH", "transc1:arccoth" );
mDecodeHashtable.put( "EXP", "transc1:exp" );
mDecodeHashtable.put( "LOG", "transc1:ln" );
mDecodeHashtable.put( "LAMBDA", "fns1:lambda" );
mDecodeHashtable.put( "INF", "nums1:infinity" );
mDecodeHashtable.put( "ForAll", "quant1" );
mDecodeHashtable.put( "INTEGRATE", "calculus1:int" );
mDecodeHashtable.put( "Derivative", "calculus1" );
mDecodeHashtable.put( "D", "calculus1" );
mDecodeHashtable.put( "DERIVATIVE", "calculus1:diff" );
mDecodeHashtable.put( "Arg", "complex1" );
mDecodeHashtable.put( "Complex", "complex1" );
mDecodeHashtable.put( "Conjugate", "complex1" );
mDecodeHashtable.put( "Im", "complex1" );
mDecodeHashtable.put( "REALPART", "complex1" );
mDecodeHashtable.put( "MFACTORIAL", "integer1:factorial" );
mDecodeHashtable.put( "Quotient", "integer1" );
mDecodeHashtable.put( "Mod", "integer1" );
mDecodeHashtable.put( "MLIST", "list1:list" );
mDecodeHashtable.put( "DETERMINANT", "linalg1:det" );
mDecodeHashtable.put( "GAMMA", "nums1:gamma" );
mDecodeHashtable.put( "INF", "nums1:infinity" );
mDecodeHashtable.put( "T", "logic1:true" );
mDecodeHashtable.put( "NIL", "logic1:false" );
mDecodeHashtable2.put( "MATRIX", "list1:list" );
mDecodeHashtable2.put( "UND", "nums1:NaN" );
mDecodeHashtable2.put( "INF", "nums1:infinity" );
mDecodeHashtable2.put( "MINF", "!
*/
AST tChild = tList.getFirstChild();
tResult = "