/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. PtParser.jj */ /*@egen*//* -*- Mode: java -*- */ /* Input file to JJTree and JavaCC to generate Ptolemy II Parser */ options { LOOKAHEAD=1; STATIC = false; } PARSER_BEGIN(PtParser) /* Copyright (c) 1998-2005 The Regents of the University of California. All rights reserved. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. PT_COPYRIGHT_VERSION_2 COPYRIGHTENDKEY Created : May 1998 */ package ptolemy.data.expr; import ptolemy.kernel.*; import ptolemy.kernel.util.*; import ptolemy.data.*; import ptolemy.math.Complex; import java.util.ArrayList; import java.util.Hashtable; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Collections; import java.util.StringTokenizer; import java.io.*; ////////////////////////////////////////////////////////////////////// //// PTParser.jjt /** This file implements an expression parser for Ptolemy II using the JavaCC parser generator. It can handle all the basic arithmetic operators (*, /, +, -, %, ^), relational operators (<, <=, >, >=, == !=), logical operators(&&, ||, !), bitwise operators (&, |, #, ~) and, using reflection, all of the functionality available in the java.lang.Math package.

By editing the ASTFunctionNode file it is also relatively easy to allow references to other functions. This provides an easy mechanism to extend the range to the parser e.g. have a tcl(...) function that passes the string to a Tcl interpreter and retuns the result.

Functional if is supported via the following syntax: (boolean) ? (value1) : (value2)

Extensibility is also supported by allowing method calls on the Tokens, the syntax is (value1).method(comma separated arguments)

JavaCC by itself simply generates a file (and support files) that allow an input to be parsed, it does not return a parse tree. For the purposes of type checking we require a parse tree, and this is obtained using JJTree, a preprocessor for JavaCC.

JJtree operates by annotating the grammar file to support the generation of the parse tree. Thus the process is

X.jjt --> JJTREE --> X.jj --> JAVACC --> X.java + support files

The parser can also be passed a symbol table of ptolemy.data.expr.Variables which the expression to be parsed can reference.

Anything between quotes(") or apostrophes(') is taken to be one string. Strings are allowed to contain newlines or carriage returns. In addition, these characters, as well as other special characters, can be escaped using the standard Java syntax (\n, \t, \077, etc.).

The expressions recognized follow as close as possible the syntax of Java. In particular the operator precedences implemented here follow exactly those in Java. Any type conversions that are performed are lossless. If the user wants lossy conversions, explicit casts will be necessary.

Complex number are specified by an i or j after the imaginary part of the number. Long numbers are specified by an l or L after an integer number.

Users can register constants with the parser and also register classes where functions that may be called are defined. For a more thorough description of what the Parser is designed to do, please consult the Ptolemy II design document (or contact nsmyth@eecs)

Note that the parsers created by JavaCC generally have quite a bit of internal state. On the other hand, the parse trees generated by this parser are much smaller. It is also fairly cheap to traverse a parse tree in order to evaluate it. Thus it is usually preferable to cache parse trees and create a new parser when the cached parse tree becomes invalid. @author Neil Smyth, Steve Neuendorffer @version $Id: PtParser.jj,v 1.81 2005/04/26 03:35:06 cxh Exp $ @since Ptolemy II 1.0 @Pt.ProposedRating Yellow (nsmyth) @Pt.AcceptedRating Yellow (yuhong) @see ptolemy.data.expr.ASTPtBitwiseNode @see ptolemy.data.expr.ASTPtFunctionApplicationNode @see ptolemy.data.expr.ASTPtFunctionDefinitionNode @see ptolemy.data.expr.ASTPtFunctionalIfNode @see ptolemy.data.expr.ASTPtLeafNode @see ptolemy.data.expr.ASTPtLogicalNode @see ptolemy.data.expr.ASTPtMethodCallNode @see ptolemy.data.expr.ASTPtProductNode @see ptolemy.data.expr.ASTPtRelationalNode @see ptolemy.data.expr.ASTPtRootNode @see ptolemy.data.expr.ASTPtSumNode @see ptolemy.data.expr.ASTPtUnaryNode @see ptolemy.data.Token */ public class PtParser/*@bgen(jjtree)*/implements PtParserTreeConstants/*@egen*/ {/*@bgen(jjtree)*/ protected JJTPtParserState jjtree = new JJTPtParserState(); /*@egen*/ boolean debug = false; public PtParser() { this(new StringReader("")); _initialize(); } /** Returns the list of undefined variables after parsing the given String. * @param stringIn The expression to be parsed * @exception IllegalActionException If the parse fails. * @return The list of undefined variables. * @deprecated Use a visitor with a ParseTreeFreeVariableCollector * instead. */ public LinkedList getUndefinedList(String stringIn) throws IllegalActionException { ASTPtRootNode rootNode = generateParseTree(stringIn); ParseTreeFreeVariableCollector collector = new ParseTreeFreeVariableCollector(); Set vars = collector.collectFreeVariables(rootNode); return new LinkedList(vars); } /** Generates a parse tree from the given String. The root node is * returned. To evaluate the parse tree, use a ParseTreeEvaluator. * @param stringIn The expression to be parsed. * @exception IllegalActionException If the parse fails. * @return The root node of the parse tree. */ public ASTPtRootNode generateParseTree(String stringIn) throws IllegalActionException { Reader reader = new StringReader(stringIn); this.ReInit(reader); ASTPtRootNode rootNode; try { // Parse the expression to obtain the parse tree // start() can generate a TokenMgrError if we parse a "\0" rootNode = start(); if (debug) { rootNode.displayParseTree(" "); } } catch (Throwable throwable) { throw new IllegalActionException(null, throwable, "Error parsing expression \"" + stringIn + "\""); } ASTPtRootNode primary = (ASTPtRootNode)rootNode.jjtGetChild(0); primary.jjtSetParent(null); return primary; } /** Generates a parse tree from the given String, which may optionally * contain an assignment. The root node is * returned. If the string represents an assignment, then the * toplevel node will be an ASTPtAssignmentNode. * @param stringIn The expression to be parsed. * @exception IllegalActionException If the parse fails. * @return The root node of the parse tree. */ public ASTPtRootNode generateSimpleAssignmentParseTree(String stringIn) throws IllegalActionException { Reader reader = new StringReader(stringIn); this.ReInit(reader); ASTPtRootNode rootNode; try { // Parse the expression to obtain the parse tree rootNode = startSimpleAssignment(); if (debug) rootNode.displayParseTree(" "); } catch (Throwable throwable) { throw new IllegalActionException(null, throwable, "Error parsing expression \"" + stringIn + "\""); } ASTPtRootNode primary = (ASTPtRootNode)rootNode.jjtGetChild(0); primary.jjtSetParent(null); return primary; } /** Generates a parse tree from the given String, which is interpreted * in "String Mode" instead of as an operator expression. In * string mode, the expression is a literal string, except for * identifiers which are denoted by $param. The root node is * returned. To evaluate the parse tree, use a ParseTreeEvaluator. * @param stringIn The expression to be parsed. * @exception IllegalActionException If the parse fails. * @return The root node of the parse tree. */ public ASTPtRootNode generateStringParseTree(String stringIn) throws IllegalActionException { Reader reader = new StringReader(stringIn); this.ReInit(reader); ASTPtRootNode rootNode; try { // Parse the expression to obtain the parse tree token_source.SwitchTo(StringMode); // startString() can generate a TokenMgrError rootNode = startString(); if (debug) { rootNode.displayParseTree(" "); } } catch (Throwable throwable) { throw new IllegalActionException(null, throwable, "Error parsing expression \"" + stringIn + "\""); } finally { token_source.SwitchTo(DEFAULT); } ASTPtRootNode primary = (ASTPtRootNode)rootNode.jjtGetChild(0); primary.jjtSetParent(null); return primary; } /** Generates a parse tree from the given String. * The string will be parsed according to rules for assignment lists. * The returned node is a RootNode containing one assignment * node for each assignment in the expression. * * @param stringIn The expression to be parsed. * @exception IllegalActionException If the parse fails. * @return The root node of the parse tree. */ public Map generateAssignmentMap(String stringIn) throws IllegalActionException { Reader reader = new StringReader(stringIn); this.ReInit(reader); Map map; try { // Parse the expression to obtain the parse tree. // startAssignmentList() might throw TokenMgrError which is // an Error, not an Exception, so we catch Throwables here. map = startAssignmentList(); } catch (Throwable throwable) { throw new IllegalActionException(null, throwable, "Error parsing expression \"" + stringIn + "\""); } return map; } /** Return the list of classes the parser searches * when a function call is encountered. The * classes are searched in the same order that they were registered * with the parser, so the classes that are most likely to be * searched should be registered first. This method is synchronized * so that it can be called safely from multiple parsers. * @return An unmodifiable list that can be iterated over. */ public static synchronized List getRegisteredClasses() { if (_classesSearched == null) { return new ArrayList(); } return Collections.unmodifiableList(new ArrayList(_classesSearched)); } /** Add a constant to the list of constants that the parser recognizes. * It is a static method. The constants are stored in a hash table by * the Constants class. The entry for each name is a ptolemy.data.Token * of the appropriate type. The value for the constant can be given * in a ptolemy.data.Token or in one of the data wrapper classes * in java.lang. * @param name The string name that the parser will recognize. * @param value An Object constraining the value associated with * the constant. * @exception IllegalArgumentException If the constant cannot * be registered with the parser. */ public static void registerConstant(String name, Object value) throws IllegalArgumentException { if ( (value == null) || (name == null)) { throw new IllegalArgumentException("PtParser: cannot register " + "a constant if either the name or value object is null."); } ptolemy.data.Token tmp; if (value instanceof ptolemy.data.Token) { tmp = (ptolemy.data.Token)value; } else if (value instanceof Integer) { tmp = new IntToken(((Integer)value).intValue()); } else if (value instanceof Double) { tmp = new DoubleToken(((Double)value).doubleValue()); } else if (value instanceof Long) { tmp = new LongToken(((Long)value).longValue()); } else if (value instanceof String) { tmp = new StringToken((String)value); } else if (value instanceof Boolean) { tmp = new BooleanToken(((Boolean)value).booleanValue()); } else if (value instanceof Complex) { tmp = new ComplexToken((Complex)value); } else { throw new IllegalArgumentException("PtParser: cannot register " + name + " as a constant of the parser."); } Constants.add(name, tmp); return; } /** Add a class to the list of classes that the parser searches * when a function call is encountered. * It is a static method. It stores the classes in a LinkedList. The * classes are searched in the same order that they were registered * with the parser, so the classes that are most likely to be * searched should be registered first. This method is synchronized * so that it can be called safely from multiple parsers. * @param newClassName The fully qualified name of the Class to * be added to the search path for functions. * @exception IllegalArgumentException If the Class named by the * argument cannot not be found. */ public static synchronized void registerFunctionClass(String newClassName) throws IllegalArgumentException { if (_classesSearched == null) { _classesSearched = new ArrayList(); } try { Class newClass = Class.forName(newClassName); if(!_classesSearched.contains(newClass)) { _classesSearched.add(newClass); } } catch (ClassNotFoundException ex) { throw new IllegalArgumentException( "Could not find " + newClassName + "."); } CachedMethod.clear(); } /** Initialize the static variable containing the classes searched by * the parser upon encountering a function call. */ private void _initialize() { if (!_alreadyInitialized) { _alreadyInitialized = true; registerFunctionClass("java.lang.Math"); registerFunctionClass("java.lang.Double"); registerFunctionClass("java.lang.Integer"); registerFunctionClass("java.lang.Long"); registerFunctionClass("java.lang.String"); registerFunctionClass("ptolemy.data.MatrixToken"); registerFunctionClass("ptolemy.data.RecordToken"); registerFunctionClass("ptolemy.data.expr.UtilityFunctions"); registerFunctionClass("ptolemy.data.expr.FixPointFunctions"); registerFunctionClass("ptolemy.math.Complex"); registerFunctionClass("ptolemy.math.ExtendedMath"); registerFunctionClass("ptolemy.math.IntegerMatrixMath"); registerFunctionClass("ptolemy.math.DoubleMatrixMath"); registerFunctionClass("ptolemy.math.ComplexMatrixMath"); registerFunctionClass("ptolemy.math.LongMatrixMath"); registerFunctionClass("ptolemy.math.IntegerArrayMath"); registerFunctionClass("ptolemy.math.DoubleArrayStat"); registerFunctionClass("ptolemy.math.ComplexArrayMath"); registerFunctionClass("ptolemy.math.LongArrayMath"); registerFunctionClass("ptolemy.math.SignalProcessing"); registerFunctionClass("ptolemy.math.FixPoint"); } } /* Flag indicating whether the default set of classes searched * by the parser has already been loaded. */ private static boolean _alreadyInitialized = false; /* Stores the classes that are searched by the parser when a * function call is parsed. It is static, and by default only * contains the java.lang.Math class. */ private static List _classesSearched; } PARSER_END(PtParser) /* COMMENTS */ SKIP : { "//" : SingleLineCommentMode | "/*" : MultiLineCommentMode } SKIP : { : DEFAULT } SKIP : { : DEFAULT } SKIP : { < ~[] > } /* Now come to proper tokens */ SKIP : { " " | "\r" | "\t" | "\n" } /* TOKEN : { < EOL: "\n" > } */ TOKEN : /* Arithmetic operators */ { < PLUS: "+" > | < MINUS: "-" > | < MULTIPLY: "*" > | < DIVIDE: "/" > | < MODULO: "%" > | < POWER: "^" > } TOKEN : /* Assignment */ { < OPENPAREN: "(" > | < CLOSEPAREN: ")" > | < OPENBRACE: "{" > | < CLOSEBRACE: "}" > | < OPENBRACKET: "[" > | < CLOSEBRACKET: "]" > | < COMMA: "," > | < PERIOD: "." > | < COLON: ":" > | < QUESTION: "?" > } TOKEN : /* Relational operators */ { < GT: ">" > | < LT: "<" > | < GTE: ">=" > | < LTE: "<=" > | < NOTEQUALS: "!=" > | < EQUALS: "==" > } TOKEN : /* Boolean & bitwise operators */ { < COND_AND: "&&" > | < COND_OR: "||" > | < BOOL_NOT: "!" > | < BITWISE_NOT: "~" > | < AND: "&" > | < OR: "|" > | < XOR: "#" > } TOKEN : /* Shift operators */ { < SHL: "<<" > | < SHR : ">>" > | < LSHR: ">>>" > } TOKEN : /* Numeric literals */ { < INTEGER: ()? | ()? | ()? > | < #INTEGER_FORMAT_SPEC: (["l","L"]) | (["u","U"] ["b","B"]) > | < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* > | < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ > | < #OCTAL_LITERAL: "0" (["0"-"7"])* > | < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > | < DOUBLE: (["0"-"9"])+ "." (["0"-"9"])+ ()? (["f","F","d","D"])? | "." (["0"-"9"])+ ()? (["f","F","d","D"])? | (["0"-"9"])+ (["f","F","d","D"])? | (["0"-"9"])+ ()? ["f","F","d","D"] > | < COMPLEX: (["0"-"9"])+ "." (["0"-"9"])+ ()? (["i","j"])? | "." (["0"-"9"])+ ()? (["i","j"])? | (["0"-"9"])+ (["i","j"])? | (["0"-"9"])+ ()? ["i","j"] > } TOKEN : /*Boolean literals */ { } TOKEN : /* function definition */ { } < DEFAULT, StringModeIDBrace, StringModeIDParen > TOKEN : /* Function names */ { < ID: ( )+ (["0"-"9", "$", "@"] | | "::")* > | < #LETTER: ["a"-"z", "A"-"Z", "_"] > } TOKEN : /* literal strings are given using single or double quotes. */ { < STRING: ( ("\"" ("\\\"" | ~["\""])* ("\"")?) | ("'" (~["'"])* ("'")?) )> } TOKEN : /* Assignment */ { < SETEQUALS: "=" > | < SEPARATOR: ";" > } < StringMode > TOKEN : /* literal strings are any string that does not contain a lone dollar sign. */ { < SMSTRING : (("$$" | ~["$"])+)> | < SMDOLLAR : "$" > : StringModeIDNone | < SMDOLLARBRACE : "${" > : StringModeIDBrace | < SMDOLLARPAREN : "$(" > : StringModeIDParen } < StringModeIDNone > TOKEN : { // String mode identifiers with lone dollars can't contain dollars. < SMID: ( )+ (["0"-"9", "@"] | )* > :StringMode | < #SMLETTER: ["a"-"z", "A"-"Z", "_"] > } < StringModeIDBrace > TOKEN : { < SMIDBRACE: () > | < SMBRACE : > : StringMode } < StringModeIDParen > TOKEN : { < SMIDPAREN: () > | < SMPAREN : > : StringMode } TOKEN : { < ERROR: ~[] > } // A simple, optional assigment used by the expression evaluator ASTPtRootNode startSimpleAssignment() : {/*@bgen(jjtree) PtRootNode */ ASTPtRootNode jjtn000 = new ASTPtRootNode(JJTPTROOTNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/ } {/*@bgen(jjtree) PtRootNode */ try { /*@egen*/ ( LOOKAHEAD( ) assignment() | expression() ) /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; } /*@egen*/ { return jjtn000; }/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } Map startAssignmentList() : {/*@bgen(jjtree) PtRootNode */ ASTPtRootNode jjtn000 = new ASTPtRootNode(JJTPTROOTNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/ Map map = new LinkedHashMap(); } {/*@bgen(jjtree) PtRootNode */ try { /*@egen*/ assignment() { ASTPtAssignmentNode node = (ASTPtAssignmentNode) jjtree.popNode(); map.put(node.getIdentifier(), node); } ( assignment() { ASTPtAssignmentNode node2 = (ASTPtAssignmentNode) jjtree.popNode(); map.put(node2.getIdentifier(), node2); })* /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; } /*@egen*/ { return map; }/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } void assignment() : {/*@bgen(jjtree) PtAssignmentNode */ ASTPtAssignmentNode jjtn000 = new ASTPtAssignmentNode(JJTPTASSIGNMENTNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/} {/*@bgen(jjtree) PtAssignmentNode */ try { /*@egen*/ assignmentIdentifier() expression()/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } // A string mode expression, using $parameter substitution. ASTPtRootNode startString() : {/*@bgen(jjtree) PtRootNode */ ASTPtRootNode jjtn000 = new ASTPtRootNode(JJTPTROOTNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/ } {/*@bgen(jjtree) PtRootNode */ try { /*@egen*//*@bgen(jjtree) #PtSumNode(> 1) */ { ASTPtSumNode jjtn001 = new ASTPtSumNode(JJTPTSUMNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( stringModeElement() ( stringModeElement() { Token token = Token.newToken(PtParserConstants.PLUS); token.kind = PtParserConstants.PLUS; jjtn001._lexicalTokens.add(token); } )* )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; } /*@egen*/ { return jjtn000; }/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } void stringModeElement() : {} { stringModeString() | identifier() | identifier() | identifier() } void stringModeString() : {} { /*@bgen(jjtree) PtLeafNode */ { ASTPtLeafNode jjtn001 = new ASTPtLeafNode(JJTPTLEAFNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*//*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn001, true); jjtc001 = false; } /*@egen*/ { jjtn001._ptToken = new StringToken(token.image.replaceAll("\\$\\$","\\$")); jjtn001._isConstant = true; }/*@bgen(jjtree)*/ } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, true); } } /*@egen*/ } ASTPtRootNode start() : {/*@bgen(jjtree) PtRootNode */ ASTPtRootNode jjtn000 = new ASTPtRootNode(JJTPTROOTNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/} {/*@bgen(jjtree) PtRootNode */ try { /*@egen*/ expression() /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; } /*@egen*/ { return jjtn000; }/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } void expression() : {} { ( LOOKAHEAD( ) functionDefinition() | funcIf() ) } void funcIf() : {} {/*@bgen(jjtree) #PtFunctionalIfNode(> 1) */ { ASTPtFunctionalIfNode jjtn001 = new ASTPtFunctionalIfNode(JJTPTFUNCTIONALIFNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( logicalOr() ( logicalOr() logicalOr() )? )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void logicalOr() : {Token x;} {/*@bgen(jjtree) #PtLogicalNode(> 1) */ { ASTPtLogicalNode jjtn001 = new ASTPtLogicalNode(JJTPTLOGICALNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( logicalAnd() ( x = logicalAnd() { jjtn001._lexicalToken = x; } )* )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void logicalAnd() : {Token x;} {/*@bgen(jjtree) #PtLogicalNode(> 1) */ { ASTPtLogicalNode jjtn001 = new ASTPtLogicalNode(JJTPTLOGICALNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( bitwiseOr() ( x = bitwiseOr() { jjtn001._lexicalToken = x; } )* )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void bitwiseOr() : {Token x;} {/*@bgen(jjtree) #PtBitwiseNode(> 1) */ { ASTPtBitwiseNode jjtn001 = new ASTPtBitwiseNode(JJTPTBITWISENODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( bitwiseXor() ( x = bitwiseXor() { jjtn001._lexicalToken = x; } )* )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void bitwiseXor() : {Token x;} {/*@bgen(jjtree) #PtBitwiseNode(> 1) */ { ASTPtBitwiseNode jjtn001 = new ASTPtBitwiseNode(JJTPTBITWISENODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( bitwiseAnd() ( x = bitwiseAnd() { jjtn001._lexicalToken = x; } )* )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void bitwiseAnd() : {Token x;} {/*@bgen(jjtree) #PtBitwiseNode(> 1) */ { ASTPtBitwiseNode jjtn001 = new ASTPtBitwiseNode(JJTPTBITWISENODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( logicalEquals() ( x = logicalEquals() { jjtn001._lexicalToken = x; } )* )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void logicalEquals() : {Token x;} {/*@bgen(jjtree) #PtRelationalNode(> 1) */ { ASTPtRelationalNode jjtn001 = new ASTPtRelationalNode(JJTPTRELATIONALNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( relational() ( ( x = | x = ) relational() { jjtn001._lexicalToken = x; } )? )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void power() : {Token x;} {/*@bgen(jjtree) #PtPowerNode(> 1) */ { ASTPtPowerNode jjtn001 = new ASTPtPowerNode(JJTPTPOWERNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( unary() ( unary() )* )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void relational() : {Token x;} {/*@bgen(jjtree) #PtRelationalNode(> 1) */ { ASTPtRelationalNode jjtn001 = new ASTPtRelationalNode(JJTPTRELATIONALNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( shift() ( ( x = | x = | x = | x = ) shift() { jjtn001._lexicalToken = x; } )? )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void shift() : {Token x;} {/*@bgen(jjtree) #PtShiftNode(> 1) */ { ASTPtShiftNode jjtn001 = new ASTPtShiftNode(JJTPTSHIFTNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( sum() ( ( x = | x = | x = ) sum() { jjtn001._lexicalToken = x; } )? )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void sum() : {Token x;} {/*@bgen(jjtree) #PtSumNode(> 1) */ { ASTPtSumNode jjtn001 = new ASTPtSumNode(JJTPTSUMNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( term() ( ( x = | x = ) term() { jjtn001._lexicalTokens.add(x); } )* )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void term() : {Token x;} {/*@bgen(jjtree) #PtProductNode(> 1) */ { ASTPtProductNode jjtn001 = new ASTPtProductNode(JJTPTPRODUCTNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( power() ( ( x = | x = | x = ) power() { jjtn001._lexicalTokens.add(x); } )* )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1); } } /*@egen*/ } void unary() : {Token x;} {/*@bgen(jjtree) PtUnaryNode */ { ASTPtUnaryNode jjtn001 = new ASTPtUnaryNode(JJTPTUNARYNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( x = element()/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn001, true); jjtc001 = false; } /*@egen*/ { jjtn001._isMinus = true; jjtn001._lexicalToken = x; } )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, true); } } /*@egen*/ |/*@bgen(jjtree) PtUnaryNode */ { ASTPtUnaryNode jjtn002 = new ASTPtUnaryNode(JJTPTUNARYNODE); boolean jjtc002 = true; jjtree.openNodeScope(jjtn002); } try { /*@egen*/ ( x = element()/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn002, true); jjtc002 = false; } /*@egen*/ { jjtn002._isNot = true; jjtn002._lexicalToken = x; } )/*@bgen(jjtree)*/ } catch (Throwable jjte002) { if (jjtc002) { jjtree.clearNodeScope(jjtn002); jjtc002 = false; } else { jjtree.popNode(); } if (jjte002 instanceof RuntimeException) { throw (RuntimeException)jjte002; } if (jjte002 instanceof ParseException) { throw (ParseException)jjte002; } throw (Error)jjte002; } finally { if (jjtc002) { jjtree.closeNodeScope(jjtn002, true); } } /*@egen*/ |/*@bgen(jjtree) PtUnaryNode */ { ASTPtUnaryNode jjtn003 = new ASTPtUnaryNode(JJTPTUNARYNODE); boolean jjtc003 = true; jjtree.openNodeScope(jjtn003); } try { /*@egen*/ ( x = element()/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn003, true); jjtc003 = false; } /*@egen*/ { jjtn003._isBitwiseNot = true; jjtn003._lexicalToken = x; } )/*@bgen(jjtree)*/ } catch (Throwable jjte003) { if (jjtc003) { jjtree.clearNodeScope(jjtn003); jjtc003 = false; } else { jjtree.popNode(); } if (jjte003 instanceof RuntimeException) { throw (RuntimeException)jjte003; } if (jjte003 instanceof ParseException) { throw (ParseException)jjte003; } throw (Error)jjte003; } finally { if (jjtc003) { jjtree.closeNodeScope(jjtn003, true); } } /*@egen*/ | element() } /* void element() #void : { boolean isMethodCall = false; } { // Note that omitting the parens is possible for a record... ( primaryElement() [ {jjtThis._methodName = token.image; isMethodCall = true;} ( [ funcIf() ( funcIf() )* ] )? ] ) #PtMethodCallNode(isMethodCall) } */ void element() : { boolean hasName = false; boolean hasCall = false; String name = null; } {/*@bgen(jjtree) #PtFunctionApplicationNode( ! hasName && hasCall) */ { ASTPtFunctionApplicationNode jjtn002 = new ASTPtFunctionApplicationNode(JJTPTFUNCTIONAPPLICATIONNODE); boolean jjtc002 = true; jjtree.openNodeScope(jjtn002); } try { /*@egen*/ (/*@bgen(jjtree) #PtMethodCallNode( hasName) */ { ASTPtMethodCallNode jjtn001 = new ASTPtMethodCallNode(JJTPTMETHODCALLNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( primaryElement() [ { name = token.image; hasName = true; } ] [ [ expression() ( expression() )* ] { hasCall = true; } ]/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn001, hasName); jjtc001 = false; } /*@egen*/ { jjtn001._methodName = name; } )/*@bgen(jjtree)*/ } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { throw (RuntimeException)jjte001; } if (jjte001 instanceof ParseException) { throw (ParseException)jjte001; } throw (Error)jjte001; } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, hasName); } } /*@egen*/ )/*@bgen(jjtree)*/ } catch (Throwable jjte002) { if (jjtc002) { jjtree.clearNodeScope(jjtn002); jjtc002 = false; } else { jjtree.popNode(); } if (jjte002 instanceof RuntimeException) { throw (RuntimeException)jjte002; } if (jjte002 instanceof ParseException) { throw (ParseException)jjte002; } throw (Error)jjte002; } finally { if (jjtc002) { jjtree.closeNodeScope(jjtn002, ! hasName && hasCall); } } /*@egen*/ } void primaryElement() : { int len; String tidied, x; } {/*@bgen(jjtree) PtLeafNode */ { ASTPtLeafNode jjtn001 = new ASTPtLeafNode(JJTPTLEAFNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); } try { /*@egen*/ ( /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn001, true); jjtc001 = false; } /*@egen*/ { try { x = token.image.toLowerCase(); len = x.length(); Double imag = new Double(x.substring(0, len-1 )); Complex value = new Complex(0, imag.doubleValue()); jjtn001._ptToken = new ComplexToken(value); jjtn001._isConstant = true; } catch (NumberFormatException ee) { throw new ParseException( "Unable to convert token " + token.image + " to a complex number."); } } )/*@bgen(jjtree)*/ } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, true); } } /*@egen*/ |/*@bgen(jjtree) PtLeafNode */ { ASTPtLeafNode jjtn002 = new ASTPtLeafNode(JJTPTLEAFNODE); boolean jjtc002 = true; jjtree.openNodeScope(jjtn002); } try { /*@egen*/ ( /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn002, true); jjtc002 = false; } /*@egen*/ { try { x = token.image.toLowerCase(); len = x.length(); if ( x.endsWith("d") || x.endsWith("f") ) { // all floating point numbers are double Double value = new Double(x.substring(0, len-1 )); jjtn002._ptToken = new DoubleToken(value.doubleValue()); } else { Double value = new Double(x); jjtn002._ptToken = new DoubleToken(value.doubleValue()); } jjtn002._isConstant = true; } catch (NumberFormatException ee) { throw new ParseException( "Unable to convert token " + token.image + " to an float or double"); } } )/*@bgen(jjtree)*/ } finally { if (jjtc002) { jjtree.closeNodeScope(jjtn002, true); } } /*@egen*/ |/*@bgen(jjtree) PtLeafNode */ { ASTPtLeafNode jjtn003 = new ASTPtLeafNode(JJTPTLEAFNODE); boolean jjtc003 = true; jjtree.openNodeScope(jjtn003); } try { /*@egen*/ ( /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn003, true); jjtc003 = false; } /*@egen*/ { try { x = token.image.toLowerCase(); len = x.length(); int radix; boolean mustBeLong = x.endsWith("l"); boolean mustBeUnsignedByte = x.endsWith("ub"); int prefixLength; int suffixLength; if(mustBeLong) { suffixLength = 1; } else if(mustBeUnsignedByte) { suffixLength = 2; } else { suffixLength = 0; } if (x.startsWith("0x") ) { // Input is a hex number. radix = 16; prefixLength = 2; } else if(x.startsWith("0")) { // Input is an octal number. radix = 8; prefixLength = 0; } else { // Input is a decimal number. radix = 10; prefixLength = 0; } // Strip off the radix prefix and the length suffix. x = x.substring(prefixLength, len - suffixLength); if (mustBeLong) { // If the size was specified as long, then create a long. jjtn003._ptToken = new LongToken(Long.parseLong(x, radix)); } else if (mustBeUnsignedByte) { // If the size was specified as unsignedbyte, // then create an unsigned byte, truncating if necessary. jjtn003._ptToken = new UnsignedByteToken(Integer.parseInt(x, radix)); } else { // Try to infer the size. Inferred sizes are at least // integer. try { jjtn003._ptToken = new IntToken(Integer.parseInt(x, radix)); } catch (NumberFormatException nfe) { jjtn003._ptToken = new LongToken(Long.parseLong(x, radix)); } } jjtn003._isConstant = true; } catch (NumberFormatException ee) { throw new ParseException( "Unable to convert token " + token.image + " to an integer or long"); } } )/*@bgen(jjtree)*/ } finally { if (jjtc003) { jjtree.closeNodeScope(jjtn003, true); } } /*@egen*/ |/*@bgen(jjtree) PtLeafNode */ { ASTPtLeafNode jjtn004 = new ASTPtLeafNode(JJTPTLEAFNODE); boolean jjtc004 = true; jjtree.openNodeScope(jjtn004); } try { /*@egen*/ ( /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn004, true); jjtc004 = false; } /*@egen*/ { // Check to see that the start and the end are the same. String start = token.image.substring(0, 1); if(!token.image.endsWith(start)) { throw new ParseException( "Found unterminated string: " + token.image); } // Now cut the " from each end of the string. len = token.image.length(); tidied = token.image.substring(1, (len -1)); // Resolve escape sequences in the string. StringTokenizer st = new StringTokenizer(tidied, "\\", true); boolean escape = false; x = new String(); while (st.hasMoreTokens()) { String tok = st.nextToken(); if (escape) { // The previous character was a backslash that started // an escape sequence. escape = false; int trailingCharIndex = 1; switch (tok.charAt(0)) { case 'n': x += "\n"; break; case 't': x += "\t"; break; case 'b': x += "\b"; break; case 'r': x += "\r"; break; case 'f': x += "\f"; break; case '\\': x += "\\"; break; case '\'': x += "\'"; break; case '"': x += "\""; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': // The escape sequence is a character // specified in octal. int i; for (i = 1; i < tok.length(); i++) { // The octal sequence stops at the first // non-octal character. char c = tok.charAt(i); if (! (c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7')) break; } trailingCharIndex = i; int octVal = Integer.parseInt( tok.substring(0, trailingCharIndex), 8); x += (char)octVal; break; default: throw new ParseException("Unknown backslash sequence: " + "\\" + tok); } if (trailingCharIndex < tok.length()) { // Keep any remaining characters. x += tok.substring(trailingCharIndex); } } else if (tok.equals("\\")) { // Start an escape sequence. escape = true; } else { // Keep regular text. x += tok; } } if(escape) { throw new ParseException("Unterminated backslash sequence in " + "string: " + token.image); } jjtn004._ptToken = new StringToken(x); jjtn004._isConstant = true; } )/*@bgen(jjtree)*/ } finally { if (jjtc004) { jjtree.closeNodeScope(jjtn004, true); } } /*@egen*/ |/*@bgen(jjtree) PtLeafNode */ { ASTPtLeafNode jjtn005 = new ASTPtLeafNode(JJTPTLEAFNODE); boolean jjtc005 = true; jjtree.openNodeScope(jjtn005); } try { /*@egen*/ ( /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn005, true); jjtc005 = false; } /*@egen*/ { if (token.image.equalsIgnoreCase("TRUE")) { jjtn005._ptToken = BooleanToken.TRUE; } else if (token.image.equalsIgnoreCase("FALSE")) { jjtn005._ptToken = BooleanToken.FALSE; } jjtn005._isConstant = true; } )/*@bgen(jjtree)*/ } finally { if (jjtc005) { jjtree.closeNodeScope(jjtn005, true); } } /*@egen*/ | LOOKAHEAD() expression() | LOOKAHEAD() matrixConstruct() | LOOKAHEAD( ) recordConstruct() | LOOKAHEAD( ) arrayConstruct() | LOOKAHEAD( ) function() | identifier() } void functionDefinition() : {/*@bgen(jjtree) PtFunctionDefinitionNode */ ASTPtFunctionDefinitionNode jjtn000 = new ASTPtFunctionDefinitionNode(JJTPTFUNCTIONDEFINITIONNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/} {/*@bgen(jjtree) PtFunctionDefinitionNode */ try { /*@egen*/ [ { jjtn000._argList.add(token.image); } optTypeSpecifier() ( { jjtn000._argList.add(token.image); } optTypeSpecifier())* ] expression()/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; } /*@egen*/ { // A hack for type specification, since we don't have types in // the syntax. ParseTreeTypeInference inference = new ParseTreeTypeInference(); int argCount = jjtn000.getArgumentNameList().size(); jjtn000._argTypes = new ptolemy.data.type.Type[argCount]; for(int i = 0; i < argCount; i++) { ASTPtRootNode argChild = ((ASTPtRootNode)jjtn000.jjtGetChild(i)); ptolemy.data.type.Type type = inference.inferTypes(argChild); jjtn000._argTypes[i] = type; } }/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } void optTypeSpecifier() : {} { ( funcIf()) | { ASTPtLeafNode node = new ASTPtLeafNode(JJTPTLEAFNODE); node._name = "general"; node._ptToken = new GeneralToken(); node._ptType = ptolemy.data.type.BaseType.GENERAL; node._isConstant = true; jjtree.pushNode(node); } } void function() : {/*@bgen(jjtree) PtFunctionApplicationNode */ ASTPtFunctionApplicationNode jjtn000 = new ASTPtFunctionApplicationNode(JJTPTFUNCTIONAPPLICATIONNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/} {/*@bgen(jjtree) PtFunctionApplicationNode */ try { /*@egen*/ identifier() [ expression() ( expression() )* ] /*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } void assignmentIdentifier() : {/*@bgen(jjtree) PtLeafNode */ ASTPtLeafNode jjtn000 = new ASTPtLeafNode(JJTPTLEAFNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/StringBuffer name;} {/*@bgen(jjtree) PtLeafNode */ try { /*@egen*/ { // Store the name of this identifier... This will be the // name of a variable, a constant, or an undefined identifier. // Note that this name is not actually resolved into a value // until the parse tree is evaluated. name = new StringBuffer(token.image); } ( { name.append("."); name.append(token.image); })* ( { name.append("("); name.append(token.image); name.append(")"); } )?/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; } /*@egen*/ { jjtn000._name = name.toString(); }/*@bgen(jjtree)*/ } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } void identifier() : {/*@bgen(jjtree) PtLeafNode */ ASTPtLeafNode jjtn000 = new ASTPtLeafNode(JJTPTLEAFNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/} {/*@bgen(jjtree) PtLeafNode */ try { /*@egen*/ ( | | | )/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; } /*@egen*/ { // Store the name of this identifier... This will be the // name of a variable, a constant, or an undefined identifier. // Note that this name is not actually resolved into a value // until the parse tree is evaluated. // NOTE: Parser constants *are not* evaluated here. Doing // this means that they can shadow other variables in scope, // which is bad. jjtn000._name = token.image; }/*@bgen(jjtree)*/ } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } void matrixConstruct() : {/*@bgen(jjtree) PtMatrixConstructNode */ ASTPtMatrixConstructNode jjtn000 = new ASTPtMatrixConstructNode(JJTPTMATRIXCONSTRUCTNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/ int i; int nRows = 0; } {/*@bgen(jjtree) PtMatrixConstructNode */ try { /*@egen*/ { ++jjtn000._nColumns; ++nRows; } funcIf() /* first term */ ( ( ( { ++jjtn000._nColumns; } funcIf() )* /* first row */ ( { ++nRows; i = 0; } funcIf() { ++i; } ( funcIf() { ++i; } )* /* one more row */ { /* Assert that the following rows have the same number of terms as the first row. */ if ( i != jjtn000._nColumns ) { throw new ParseException("PtParser: error parsing matrix " + "construction, the row " + nRows + " does not have the same number of " + "terms as the first row."); } } )* /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; } /*@egen*/ { jjtn000._form = 1; jjtn000._nRows = nRows; } ) | ( funcIf() funcIf() ( { ++nRows; } funcIf() funcIf() funcIf() )* /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; } /*@egen*/ { jjtn000._form = 2; jjtn000._nRows = nRows; } ) )/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } void recordConstruct() : {/*@bgen(jjtree) PtRecordConstructNode */ ASTPtRecordConstructNode jjtn000 = new ASTPtRecordConstructNode(JJTPTRECORDCONSTRUCTNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/ Token x = null; } {/*@bgen(jjtree) PtRecordConstructNode */ try { /*@egen*/ x = {jjtn000._fieldNames.add(x.image);} funcIf() ( x = {jjtn000._fieldNames.add(x.image);} funcIf())* /*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ } void arrayConstruct() : {/*@bgen(jjtree) PtArrayConstructNode */ ASTPtArrayConstructNode jjtn000 = new ASTPtArrayConstructNode(JJTPTARRAYCONSTRUCTNODE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); /*@egen*/ } {/*@bgen(jjtree) PtArrayConstructNode */ try { /*@egen*/ funcIf() ( funcIf() )* /*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } /*@egen*/ }