import java_cup.runtime.*; import java.util.*; import java.lang.*; import AST.*; import CompilerError.*; action code {: // if the compiler is parsing a class, currentClass points to it. GenericClass currentClass; ShellClass shellClass; InitMethodList initMethodList; Method currentMethod; ConstList constList; MethodList methodList; InstanceVariableList instVarList; ClassObject currentClassObject; Vector localList; boolean inInitMethod, inClassObject, isVariableNumber, isCurrentMethodAbstract; ToCreateClassList toCreateClassList; ToCreateArrayList toCreateArrayList; ClassType superclass; ParameterList methodParamList; int numDimensions; int currentMethodNumber; int currentVariableNumber; Lexer lexer; ErrorMsg errorMsg; int visibility; int currentEnumValue; ClassObjectVariableList varList; LocalVariableList localVariableList; :} parser code {: Lexer lexer; ErrorMsg errorMsg; // a constructor for class Parser. With it, we have access to the lexer public Parser( Lexer lexer, ErrorMsg errorMsg, ToCreateClassList toCreateClassList, ToCreateArrayList toCreateArrayList, ToCreateClassList newToCreateClassList, boolean isRealParamClass ) { this(lexer); this.errorMsg = errorMsg; this.lexer = lexer; this.toCreateClassList = toCreateClassList; this.toCreateArrayList = toCreateArrayList; this.newToCreateClassList = newToCreateClassList; this.isRealParamClass = isRealParamClass; currentMethodNumber = 0; currentVariableNumber = 0; } ToCreateClassList toCreateClassList, newToCreateClassList; ToCreateArrayList toCreateArrayList; boolean isRealParamClass; int currentMethodNumber, currentVariableNumber; /* this is a redefinition of a method for signalling syntax errors */ public void syntax_error( java_cup.runtime.Symbol cur_token) { errorMsg.signal("Syntax error"); } :} init with {: :} terminal ABSTRACT, AFTER, AND, ARRAY, ASSERT, ASSIGN; terminal AT, BEFORE, BEGIN, BINAND, BINNOT, BINOR; terminal BINXOR, BOOLEAN, BREAK, BYTE, CANCELA, CASE; terminal CHAR, CLASS, COLON, COMMA, CONST, DIV; terminal DO, DOUBLE, ELSE, END, ENDIF, ENUM; terminal EQ, EXCEPTION, FALSE, FOR, GE, GT; terminal String IDENT; terminal IF, INTEGER, JAVABEGIN, LE, LEFTPAR, LEFTSB, LEFTSHIFT; terminal JAVAUSE; terminal String JAVAEND; terminal LONG, LOOP, LT, MINUS, MINUSMINUS, MULT; terminal NEQ, NIL, NOT, OBJECT, OF, OR, OTHERWISE; terminal PERIOD, PLUS, PLUSPLUS, PROC, PRIVATE, PUBLIC, REAL, REFLECTIVE; terminal REMAINDER, REPEAT, RESULT, RETURN, RIGHTSB, RIGHTPAR; terminal RIGHTSHIFT, SELF, SEMICOLON, SHELL, STRING, SUBCLASS, SUBCLASSOF; terminal SUPER, THEN, THREEPERIOD, TO, TRUE, TRY, TYPE; terminal UNTIL, VAR, WHILE, XOR; terminal Integer INTEGERCONST; terminal Byte BYTECONST; terminal Long LONGCONST; terminal Float REALCONST; terminal Double DOUBLECONST; terminal Character CHARCONST; terminal UMINUS, UPLUS; terminal String LITERALSTRING; non terminal AssertClause; non terminal Expr AssertClauseO1; non terminal AssertVariableList AssertClauseL2; non terminal Expr AssertClauseO3; non terminal AssertVariable AssertVarDec; non terminal GenericClass BasicType; non terminal BlockStatement Block; non terminal LiteralBooleanConst BooleanConst; non terminal BreakStatement BreakStat; non terminal CaseStatement CaseStat; non terminal Vector CaseStatL1; non terminal OtherwiseCase CaseStatO2; non terminal ClassType Class; non terminal TypeList ClassL1; non terminal ClassDec, ClassDecL1; non terminal ClassDecO1; non terminal ClassDecO2; non terminal ClassDecO3; non terminal ClassDecO4; non terminal ClassDecO5; non terminal ClassObjDec; non terminal ClassObjDecO1; non terminal Vector ClassParamList; non terminal Vector ClassParamListL1; non terminal ClassParameter ClassParamSpecif; non terminal ClassType ClassParamSpecifO1; non terminal ConstDec; non terminal ConstDecL1; non terminal ConstExprList ConstExprList; non terminal ConstItem; non terminal Type ConstItemO1; non terminal Type ConstType; non terminal EachCase EachCase; non terminal EnumDec; non terminal EnumDecL1; non terminal Expr EnumDecL1O1; non terminal ExceptionClause; non terminal Expr Expr; non terminal LiteralIntegerConst ExprL1O1; non terminal ExprL1, ExprL1O2; non terminal ExprList ExprList, ExprO1; non terminal ExprList ExprList2; non terminal FormalParamDec; non terminal Type FormalParamDecO1; non terminal FormalParamDecList; non terminal FormalParamDecListL1; non terminal FormalIdList; non terminal ForStatement ForStat; non terminal IfStatement IfStat; non terminal StatementList IfStatO1; non terminal InitCallStatement InitCall; non terminal InitMethodDec; non terminal InstVarDec; non terminal InstVarDecList; non terminal InstVarIdList; non terminal InstVarDecListE1; non terminal Integer IntegerConstValue; non terminal JavaCodeText JavaCode, JavaCodeOp; non terminal Type JavaUseOp; non terminal LiteralConstExpr LiteralConstExpr; non terminal LocalDec; non terminal LocalVarDec; non terminal LocalVarDecIdList; non terminal LocalDecL1; non terminal LoopStatement LoopStat; non terminal MethodDec; non terminal MethodDecO1; non terminal MethodDecO2; non terminal ObjPrivatePart; non terminal ObjPublicPart; non terminal ObjVarDecList; non terminal ObjVarIdList; non terminal ObjVarDecListL1; non terminal ObjVarDec; non terminal Expr ObjVarDecL1; non terminal String Operator; non terminal String OperatorUnary; non terminal String OperatorBinary; non terminal String OperatorRelation; non terminal PrivatePart; non terminal ProcHeading; non terminal ProcHeadingO1; non terminal ProcHeadingO2; non terminal ProcHeadingO3; non terminal ProcHeadingO4; non terminal GenericClass Program; non terminal ProgramInit; non terminal Integer Relation; non terminal RepeatStatement RepeatStat; non terminal ReturnStatement ReturnStat; non terminal Expr ReturnStatO1; non terminal ShellClassDec; non terminal ShellClassDecO1; non terminal Statement Statement; non terminal StatementList StatementList; non terminal VarDecStatement StatVarDec; non terminal Expr StatVarDecO1; non terminal TryStatement TryStat; non terminal Type Type; non terminal TypeL1; non terminal TypeL1O2; non terminal Type TypeFun; non terminal Type TypeExt; non terminal TypeList TypeList; non terminal UnObjPubPri; non terminal UnObjPubPriO1; non terminal UnObjPubPriO2; non terminal UnObjPubPriO2L1; non terminal UnObjPubPriO3; non terminal UnObjPubPriO3L1; non terminal UnPubPri; non terminal UnPubPriL1; non terminal UnPubPriO2; non terminal UnPubPriO2L1; non terminal UnPubPriO3; non terminal UnPubPriO3L1; non terminal UnPubPriO4; non terminal UnPubPriO4L1; non terminal Statement UnStatBlock; non terminal WhileStatement WhileStat; precedence right ASSIGN; precedence left OR; precedence left XOR; precedence left AND; precedence nonassoc EQ, NEQ, GT, GE, LT, LE; precedence left PLUS, MINUS; precedence left MULT, DIV, REMAINDER; precedence left BINOR; precedence left BINXOR; precedence left BINAND; precedence nonassoc LEFTSHIFT, RIGHTSHIFT; precedence right NOT, UMINUS, UPLUS, BINNOT, PLUSPLUS, MINUSMINUS; precedence right CANCELA; start with Program; Expr ::= Expr:left ASSIGN Expr:right {: RESULT = new AssignmentExpr(left, right); :} | Expr:left OR Expr:right {: RESULT = new BooleanCompositeExpr(left, Sym.OR, right); :} | Expr:left XOR Expr:right {: RESULT = new BooleanCompositeExpr(left, Sym.XOR, right); :} | Expr:left AND Expr:right {: RESULT = new BooleanCompositeExpr(left, Sym.AND, right); :} | Expr:left Relation:oper Expr:right {: RESULT = new RelationExpr(left, oper.intValue(), right); :} %prec EQ | Expr:left PLUS Expr:right {: RESULT = new ArithmeticCompositeExpr(left, Sym.PLUS, right); :} | Expr:left MINUS Expr:right {: RESULT = new ArithmeticCompositeExpr(left, Sym.MINUS, right); :} | Expr:left MULT Expr:right {: RESULT = new ArithmeticCompositeExpr(left, Sym.MULT, right); :} | Expr:left DIV Expr:right {: RESULT = new ArithmeticCompositeExpr(left, Sym.DIV, right); :} | Expr:left REMAINDER Expr:right {: RESULT = new ArithmeticCompositeExpr(left, Sym.REMAINDER, right); :} | Expr:left LEFTSHIFT Expr:right {: RESULT = new ArithmeticCompositeExpr(left, Sym.LEFTSHIFT, right); :} | Expr:left RIGHTSHIFT Expr:right {: RESULT = new ArithmeticCompositeExpr(left, Sym.RIGHTSHIFT, right); :} | Expr:left BINOR Expr:right {: RESULT = new BinCompositeExpr(left, Sym.BINOR, right); :} | Expr:left BINXOR Expr:right {: RESULT = new BinCompositeExpr(left, Sym.BINXOR, right); :} | Expr:left BINAND Expr:right {: RESULT = new BinCompositeExpr(left, Sym.BINAND, right); :} | NOT Expr:right {: RESULT = new NotUnaryExpr(right); :} | MINUS Expr:right {: RESULT = new ArithmeticUnaryExpr(Sym.MINUS, right); :} %prec UMINUS | PLUS Expr:right {: RESULT = new ArithmeticUnaryExpr(Sym.PLUS, right); :} %prec UPLUS | BINNOT Expr:right {: RESULT = new BinNotUnaryExpr(right); :} | PLUSPLUS Expr:right {: RESULT = new ArithmeticUnaryExpr(Sym.PLUSPLUS, right); :} | MINUSMINUS Expr:right {: RESULT = new ArithmeticUnaryExpr(Sym.MINUSMINUS, right); :} | Expr:anArray LEFTSB Expr:index RIGHTSB {: RESULT = new ArrayIndexing(anArray, index); :} | Expr:receiver PERIOD IDENT:name ExprO1:exprList {: RESULT = new MessageSendExpr(receiver, name, exprList); :} | SUPER PERIOD IDENT:name LEFTPAR ExprList:exprList RIGHTPAR {: RESULT = new MessageSendToSuperExpr( currentClass, name, exprList ); :} LEFTPAR Expr:expr RIGHTPAR {: RESULT = new ParenthesisExpr(expr); :} | IDENT:name LEFTPAR ExprList:exprList RIGHTPAR {: // it may be a class: List(integer) RESULT = new MessageSendExpr( null, name, exprList ); :} | CANCELA LEFTPAR ConstExprList:exprList RIGHTPAR {: // array initialization RESULT = new ArrayInitExprList(exprList); :} | IDENT:name {: RESULT = new IdentExpr(name); :} | LiteralConstExpr:literalConstExpr {: RESULT = literalConstExpr; :} | LITERALSTRING:str {: RESULT = new LiteralStringExpr(str); :} | SELF {: RESULT = new SelfExpr(currentClass); :} | RESULT {: RESULT = new ResultExpr(currentMethod.getReturnType()); :} | NIL {: RESULT = Type.nilExpr; :} | BasicType:type {: RESULT = new ClassObjectExpr( type.getClassObject() ); :} | EXCEPTION PERIOD IDENT:name LEFTPAR Expr:expr RIGHTPAR {: RESULT = new ExceptionExpr(name, expr); :} | ARRAY LEFTPAR Type:type RIGHTPAR {: numDimensions = 0; :} ExprL1 {: ArrayType newArray = new ArrayType(type, numDimensions); toCreateArrayList.add(newArray); RESULT = new ClassObjectExpr(newArray.getClassObject()); :} ; ExprO1 ::= {: RESULT = null; :} | LEFTPAR ExprList:exprList RIGHTPAR {: RESULT = exprList; :} ; ExprL1 ::= ExprL1O2 | ExprL1 ExprL1O2 ; ExprL1O1 ::= {: RESULT = null; :} | IntegerConstValue:expr {: RESULT = new LiteralIntegerConst(expr.intValue()); :} ; //c it was /* ExprL1O2 ::= LEFTSB ExprL1O1:expr RIGHTSB {: arrayRangeList.add(expr); :} ; */ ExprL1O2 ::= LEFTSB RIGHTSB {: numDimensions++; :} ; ExprList ::= {: RESULT = new ExprList(); :} | ExprList2 ; ExprList2 ::= Expr:expr {: ExprList exprList = new ExprList(); exprList.add(expr); RESULT = exprList; :} | ExprList2:exprList COMMA Expr:expr {: exprList.add(expr); RESULT = exprList; :} ; AssertClause ::= ASSERT AssertClauseO1:beforeExpr AssertClauseL2:assertVariableList AssertClauseO3:afterExpr END {: currentMethod.setAssertClause( new AssertClause(beforeExpr, afterExpr, assertVariableList) ); :} ; AssertClauseO1 ::= {: RESULT = null; :} | BEFORE Expr:expr SEMICOLON {: RESULT = expr; :} ; AssertClauseL2 ::= {: RESULT = new AssertVariableList(); :} | AssertClauseL2:assertVariableList AssertVarDec:varDec SEMICOLON {: assertVariableList.add(varDec); RESULT = assertVariableList; :} ; AssertVarDec ::= VAR IDENT:name COLON Type:type ASSIGN Expr:expr {: RESULT = new AssertVariable(name, type, expr); :} ; AssertClauseO3 ::= {: RESULT = null; :} | AFTER Expr:expr SEMICOLON {: RESULT = expr; :} ; BasicType ::= BOOLEAN {: RESULT = Type.booleanType; :} | BYTE {: RESULT = Type.byteType; :} | CHAR {: RESULT = Type.charType; :} | DOUBLE {: RESULT = Type.doubleType; :} | INTEGER {: RESULT = Type.integerType; :} | LONG {: RESULT = Type.longType; :} | REAL {: RESULT = Type.realType; :} ; Block ::= BEGIN StatementList:statementList END {: RESULT = new BlockStatement(statementList); :} ; BooleanConst ::= TRUE {: RESULT = LiteralBooleanConst.booleanTrue; :} | FALSE {: RESULT = LiteralBooleanConst.booleanFalse; :} ; BreakStat ::= BREAK {: RESULT = new BreakStatement(); :} ; CaseStat ::= CASE Expr:expr OF CaseStatL1:eachCaseList CaseStatO2:otherwiseCase END {: RESULT = new CaseStatement(expr, eachCaseList, otherwiseCase); :} ; CaseStatL1 ::= EachCase:eachCase {: RESULT = new Vector(); RESULT.addElement(eachCase); :} | CaseStatL1:eachCaseList EachCase:eachCase {: eachCaseList.addElement(eachCase); RESULT = eachCaseList; :} ; CaseStatO2 ::= {: RESULT = null; :} | OTHERWISE UnStatBlock:statement {: RESULT = new OtherwiseCase(statement); :} ; Class ::= IDENT:name ClassL1:typeList {: ClassParameter classParam = currentClass.searchForClassParameter(name); if ( classParam != null ) if ( typeList != null ) { errorMsg.show("Class parameter should not have parameters"); typeList = null; } ClassType aClass; RESULT = aClass = new ClassType(name, typeList, classParam != null); if ( typeList != null ) if ( parser.isRealParamClass && toCreateClassList.get(aClass.getJavaName()) == null ) parser.newToCreateClassList.add(RESULT); else toCreateClassList.add(RESULT); :} ; ClassL1 ::= {: RESULT = null; :} | LEFTPAR TypeList:typeList RIGHTPAR {: RESULT = typeList; :} ; ClassDec ::= ShellClassDec | ClassDecL1 ClassDecO1 ClassDecO2 ClassDecO3 CLASS IDENT:name {: if ( currentClass.getName() != null && currentClass.getName().compareTo(name) != 0 ) errorMsg.show("Class object and class name are not equal"); else currentClass.setName(name); :} ClassDecO4 ClassDecO5 {: inInitMethod = true; :} UnPubPri JavaCodeOp END ; ClassDecL1 ::= {: lexer = parser.lexer; errorMsg = parser.errorMsg; toCreateClassList = parser.toCreateClassList; toCreateArrayList = parser.toCreateArrayList; currentClassObject = new ClassObject(); currentClass = new NormalClass(currentClassObject); currentClassObject.setAssociatedClass( (NormalClass ) currentClass); initMethodList = new InitMethodList(); inClassObject = false; :} ; ClassDecO1 ::= | ClassObjDec ; ClassDecO2 ::= {: currentClass.setIsAbstract(false); :} | ABSTRACT {: currentClass.setIsAbstract(true); :} ; ClassDecO3 ::= {: currentClass.setIsReflective(false); :} | REFLECTIVE {: currentClass.setIsReflective(true); :} ; ClassDecO4 ::= {: currentClass.setParamList(null); :} | ClassParamList:paramList {: if ( currentClass.getParamList() != null ) errorMsg.show("Redeclaration of class parameters"); currentClass.setParamList(paramList); :} ; ClassDecO5 ::= | SUBCLASSOF Class:aClass {: superclass = aClass; currentClass.setSuperclass(aClass); :} ; ClassObjDec ::= OBJECT {: inClassObject = true; :} IDENT:name {: currentClass.setName(name); inInitMethod = true; :} ClassObjDecO1 UnObjPubPri JavaCodeOp END {: inClassObject = false; :} ; ClassObjDecO1 ::= | ClassParamList:paramList {: currentClass.setParamList(paramList); :} ; ClassParamList ::= LEFTPAR ClassParamListL1:classParamList RIGHTPAR {: RESULT = classParamList; :} ; ClassParamListL1 ::= ClassParamSpecif:aClassParam {: RESULT = new Vector(); RESULT.addElement(aClassParam); :} | ClassParamListL1:classParamList COMMA ClassParamSpecif:aClassParam {: classParamList.addElement(aClassParam); RESULT = classParamList; :} ; ClassParamSpecif ::= IDENT:name ClassParamSpecifO1:type {: RESULT = new ClassParameter(name,type); :} ; ClassParamSpecifO1 ::= {: RESULT = null; :} | COLON Class:type {: RESULT = type; :} ; ConstDec ::= CONST ConstDecL1 SEMICOLON ; ConstDecL1 ::= ConstItem | ConstDecL1 COMMA ConstItem ; LiteralConstExpr ::= BooleanConst:value {: RESULT = value; :} | BYTECONST:value {: RESULT = new LiteralByteConst(value.byteValue()); :} | CHARCONST:value {: RESULT = new LiteralCharConst(value.charValue()); :} | DOUBLECONST:value {: RESULT = new LiteralDoubleConst(value.doubleValue()); :} | INTEGERCONST:value {: RESULT = new LiteralIntegerConst(value.intValue()); :} | LONGCONST:value {: RESULT = new LiteralLongConst(value.longValue()); :} | REALCONST:value {: RESULT = new LiteralRealConst(value.floatValue()); :} ; ConstExprList ::= Expr:expr {: ConstExprList list = new ConstExprList(); list.add(expr); RESULT = list; :} | ConstExprList:constExprList COMMA Expr:expr {: constExprList.add(expr); RESULT = constExprList; :} ; ConstItem ::= IDENT:name ConstItemO1:type ASSIGN Expr:value {: if ( type == null ) constList.add( new Constant(name, value.getType(), value) ); else constList.add( new Constant(name, type, value) ); :} ; ConstItemO1 ::= {: RESULT = null; :} | COLON ConstType:type {: RESULT = type; :} ; ConstType ::= BasicType:basicType {: RESULT = basicType; :} | STRING {: RESULT = Type.stringType; :} ; EachCase ::= ConstExprList:constExprList COLON UnStatBlock:statement {: RESULT = new EachCase(constExprList, statement); :} ; EnumDec ::= ENUM LEFTPAR EnumDecL1:enumDec RIGHTPAR {: :} ; EnumDecL1 ::= IDENT:name EnumDecL1O1:expr {: if ( expr == null ) currentEnumValue = 0; else currentEnumValue = ((Integer ) expr.getValue()).intValue(); constList.add( new Constant(name, Type.integerType, new LiteralIntegerConst(currentEnumValue++)) ); :} | EnumDecL1 COMMA IDENT:name EnumDecL1O1:expr {: if ( expr != null ) currentEnumValue = ((Integer ) expr.getValue()).intValue(); constList.add( new Constant(name, Type.integerType, new LiteralIntegerConst(currentEnumValue++)) ); :} ; EnumDecL1O1 ::= {: RESULT = null; :} | ASSIGN Expr:expr {: RESULT = expr; :} ; ExceptionClause ::= LEFTPAR EXCEPTION COLON Type:type RIGHTPAR {: currentMethod.setExceptionType(type); :} ; FormalParamDec ::= FormalIdList COLON FormalParamDecO1:type {: Enumeration e = localList.elements(); while ( e.hasMoreElements() ) ((Parameter ) e).setType(type); if ( isVariableNumber ) if ( localList.size() != 1 ) errorMsg.show("... used with more than one parameter"); else ((Parameter ) localList.elementAt(0)).setIsVariableNumber(true); :} ; FormalIdList ::= IDENT:name {: Parameter parameter = new Parameter(name); methodParamList.add(parameter); localList = new Vector(); localList.addElement(parameter); :} | FormalIdList COMMA IDENT:name {: Parameter parameter = new Parameter(name); methodParamList.add(parameter); localList.addElement(parameter); :} ; FormalParamDecO1 ::= Type:type {: isVariableNumber = false; RESULT = type; :} | THREEPERIOD Type:type {: isVariableNumber = true; RESULT = type; :} ; FormalParamDecList ::= FormalParamDec FormalParamDecListL1 ; FormalParamDecListL1 ::= | FormalParamDecListL1 SEMICOLON FormalParamDec ; ForStat ::= FOR IDENT:name ASSIGN Expr:exprFrom TO Expr:exprTo DO UnStatBlock:statement {: RESULT = new ForStatement( name, exprFrom, exprTo, statement ); :} ; IfStat ::= IF Expr:expr THEN StatementList:thenStat IfStatO1:elseStat ENDIF {: RESULT = new IfStatement(expr, thenStat, elseStat); :} ; IfStatO1 ::= {: RESULT = null; :} | ELSE StatementList:statementList {: RESULT = statementList; :} ; InitCall ::= IDENT:name CANCELA IDENT:identName LEFTPAR ExprList:exprList RIGHTPAR {: if ( identName.compareTo("ident") != 0 ) errorMsg.show("Ident expected"); RESULT = new InitCallStatement(name, exprList); :} ; InitMethodDec ::= ProcHeading ; InstVarDec ::= InstVarIdList COLON TypeExt:type SEMICOLON {: Enumeration e = localList.elements(); while ( e.hasMoreElements() ) { InstanceVariable iv = (InstanceVariable ) e.nextElement(); iv.setType(type); instVarList.add(iv); } :} ; InstVarIdList ::= IDENT:name {: localList = new Vector(); localList.addElement( new InstanceVariable(name, currentVariableNumber++) ); :} | InstVarIdList COMMA IDENT:name {: localList.addElement( new InstanceVariable(name, currentVariableNumber++) ); :} ; InstVarDecList ::= VAR InstVarDecListE1 ; InstVarDecListE1 ::= InstVarDec | InstVarDecListE1 InstVarDec ; IntegerConstValue ::= INTEGERCONST:value {: RESULT = value; :} //c it was // | IDENT:variable {: // RESULT = new VariableExpr(variable); // :} ; JavaCode ::= JavaUseOp:type JAVABEGIN JAVAEND:javaCode {: RESULT = new JavaCodeText(javaCode, type); :} ; JavaCodeOp ::= JavaCode:code {: RESULT = code; :} | {: RESULT = null; :} ; JavaUseOp ::= {: RESULT = null; :} | JAVAUSE Type:type {: RESULT = type; :} ; LocalDec ::= VAR LocalVarDec LocalDecL1 {: currentMethod.setLocalVariableList(localVariableList); :} ; LocalDecL1 ::= | LocalDecL1 LocalVarDec ; LocalVarDec ::= LocalVarDecIdList COLON TypeExt:type SEMICOLON {: Enumeration e = localList.elements(); while ( e.hasMoreElements() ) ((LocalVariable ) e).setType(type); :} ; LocalVarDecIdList ::= IDENT:name {: LocalVariable localVariable = new LocalVariable(name); localVariableList.add(localVariable); localList = new Vector(); localList.addElement(localVariable); :} | LocalVarDecIdList COMMA IDENT:name {: LocalVariable localVariable = new LocalVariable(name); localVariableList.add(localVariable); localList.addElement(localVariable); :} ; LoopStat ::= LOOP StatementList:statementList END {: RESULT = new LoopStatement(statementList); :} ; MethodDec ::= ProcHeading MethodDecO1 MethodDecO2 Block:block {: currentMethod.setBlockStatement(block); :} ; MethodDecO1 ::= | AssertClause ; MethodDecO2 ::= | LocalDec {: currentMethod.setLocalVariableList(localVariableList); :} ; ObjPrivatePart ::= ObjVarDecList | MethodDec | ConstDec | EnumDec ; ObjPublicPart ::= MethodDec | ConstDec | EnumDec ; ObjVarDecList ::= VAR ObjVarDec ObjVarDecListL1 ; ObjVarDecListL1 ::= | ObjVarDecListL1 ObjVarDec ; ObjVarDec ::= ObjVarIdList COLON Type:type ObjVarDecL1:expr SEMICOLON {: if ( expr != null ) if ( localList.size() > 1 ) errorMsg.show("Attempt to initialize more than one variable"); else ((ClassObjectVariable ) localList.elementAt(0)).setExpr(expr); Enumeration e = localList.elements(); while ( e.hasMoreElements() ) { ClassObjectVariable iv = (ClassObjectVariable ) e.nextElement(); iv.setType(type); varList.add(iv); } :} ; ObjVarIdList ::= IDENT:name {: ClassObjectVariable v = new ClassObjectVariable(name, currentVariableNumber++); localList = new Vector(); localList.addElement(v); :} | ObjVarIdList COMMA IDENT:name {: ClassObjectVariable v = new ClassObjectVariable(name, currentVariableNumber++); localList.addElement(v); :} ; ObjVarDecL1 ::= {: RESULT = null; :} | ASSIGN Expr:expr {: RESULT = expr; :} ; Operator ::= OperatorUnary | OperatorBinary | OperatorRelation ; OperatorUnary ::= PLUSPLUS {: RESULT = "++"; :} | MINUSMINUS {: RESULT = "--"; :} | BINNOT {: RESULT = "~"; :} ; OperatorBinary ::= PLUS {: RESULT = "+"; :} | MINUS {: RESULT = "-"; :} | MULT {: RESULT = "*"; :} | DIV {: RESULT = "/"; :} | REMAINDER {: RESULT = "%"; :} | BINAND {: RESULT = "&"; :} | BINOR {: RESULT = "|"; :} | BINXOR {: RESULT = "^"; :} | LEFTSHIFT {: RESULT = "<<"; :} | RIGHTSHIFT {: RESULT = ">>"; :} ; OperatorRelation ::= EQ {: RESULT = "=="; :} | LT {: RESULT = "<"; :} | GT {: RESULT = ">"; :} | LE {: RESULT = "<="; :} | GE {: RESULT = ">="; :} | NEQ {: RESULT = "<>"; :} ; PrivatePart ::= InstVarDecList | MethodDec ; ProcHeading ::= ProcHeadingO1 PROC ProcHeadingO2 ; ProcHeadingO2 ::= IDENT:name {: if ( inInitMethod ) { InitMethod m; currentMethod = m = new InitMethod(currentMethodNumber++); if ( ! inClassObject ) initMethodList.add(m); else currentClassObject.setInitMethod(m); if ( name.compareTo("init") != 0 ) errorMsg.show("Methods before the public part should be named init"); } else { currentMethod = new Method(name, isCurrentMethodAbstract, currentMethodNumber++, visibility); methodList.add(currentMethod); } methodParamList = new ParameterList(); localVariableList = new LocalVariableList(); :} LEFTPAR ProcHeadingO2 RIGHTPAR {: currentMethod.setParamList(methodParamList); :} ProcHeadingO3 ProcHeadingO4 | Operator:op {: currentMethod = new Method(op, false, currentMethodNumber++, visibility); methodList.add(currentMethod); :} LEFTPAR ProcHeadingO2 RIGHTPAR {: currentMethod.setParamList(methodParamList); :} ProcHeadingO4 ; ProcHeadingO1 ::= {: isCurrentMethodAbstract = false; :} | ABSTRACT {: isCurrentMethodAbstract = true; :} ; ProcHeadingO2 ::= | FormalParamDecList ; ProcHeadingO3 ::= | ExceptionClause ; ProcHeadingO4 ::= {: currentMethod.setReturnType(null); :} | COLON Type:type {: currentMethod.setReturnType(type); :} ; Program ::= /* ProgramInit {: lexer = parser.lexer; errorMsg = parser.errorMsg; toCreateClassList = parser.toCreateClassList; toCreateArrayList = parser.toCreateArrayList; :} */ ClassDec {: RESULT = currentClass; :} ; ProgramInit ::= ; Relation ::= EQ {: RESULT = new Integer(Sym.EQ); :} | LT {: RESULT = new Integer(Sym.LT); :} | GT {: RESULT = new Integer(Sym.GT); :} | LE {: RESULT = new Integer(Sym.LE); :} | GE {: RESULT = new Integer(Sym.GE); :} | NEQ {: RESULT = new Integer(Sym.NEQ); :} ; RepeatStat ::= REPEAT StatementList:statementList UNTIL Expr:expr {: RESULT = new RepeatStatement(statementList, expr); :} ; ReturnStat ::= RETURN ReturnStatO1:expr {: RESULT = new ReturnStatement(expr); :} ; ReturnStatO1 ::= {: RESULT = null; :} | Expr:expr {: RESULT = expr; :} ; ShellClassDec ::= SHELL CLASS IDENT:name LEFTPAR Class:type RIGHTPAR {: currentClass = new ShellClass(name, type); :} ShellClassDecO1 UnPubPri JavaCodeOp END ; ShellClassDecO1 ::= | SUBCLASSOF Class:aClass {: currentClass.setSuperclass( aClass ) ; :} ; Statement ::= Expr:s SEMICOLON {: RESULT = new ExprStatement(s); :} | InitCall:s SEMICOLON {: RESULT = s; :} | SEMICOLON {: RESULT = new NullStatement(); :} | ReturnStat:s SEMICOLON {: RESULT = s; :} | IfStat:s {: RESULT = s; :} | WhileStat:s {: RESULT = s; :} | CaseStat:s {: RESULT = s; :} | StatVarDec:s SEMICOLON {: RESULT = s; :} | ForStat:s {: RESULT = s; :} | TryStat:s {: RESULT = s; :} | RepeatStat:s SEMICOLON {: RESULT = s; :} | LoopStat:s {: RESULT = s; :} | BreakStat:s SEMICOLON {: RESULT = s; :} | JavaCode:s {: RESULT = new JavaStatement(s); :} ; StatementList ::= {: RESULT = new StatementList(); :} | StatementList:statementList Statement:statement {: statementList.add(statement); RESULT = statementList; :} ; StatVarDec ::= VAR IDENT:name COLON Type:type StatVarDecO1:expr {: RESULT = new VarDecStatement(name, type, expr); :} ; StatVarDecO1 ::= {: RESULT = null; :} | ASSIGN Expr:expr {: RESULT = expr; :} ; TryStat ::= TRY LEFTPAR Expr:expr RIGHTPAR StatementList:statementList END {: RESULT = new TryStatement(expr, statementList); :} ; Type ::= BasicType:type {: RESULT = type; :} | Class:type {: RESULT = type; :} | TypeFun:type {: RESULT = type; :} | ARRAY LEFTPAR Type:type RIGHTPAR {: numDimensions = 0; :} TypeL1 {: ArrayType anArray; RESULT = anArray = new ArrayType(type, numDimensions); toCreateArrayList.add(anArray); :} ; TypeL1 ::= TypeL1O2 | TypeL1 TypeL1O2 ; TypeL1O2 ::= LEFTSB RIGHTSB {: numDimensions++; :} ; TypeFun ::= TYPE LEFTPAR IDENT:name RIGHTPAR {: RESULT = new TypeOfVariable(name); :} ; TypeExt ::= Type:type {: RESULT = type; :} | AT Type:type {: RESULT = new AtType(type); :} ; TypeList ::= Type:type {: boolean withClassParameter = false; if ( type instanceof ClassType ) { ClassType ct = (ClassType ) type; if ( ct.getIsClassParameter() ) withClassParameter = true; } RESULT = new TypeList(withClassParameter); RESULT.add(type); :} | TypeList:typeList COMMA Type:type {: if ( type instanceof ClassType && ((ClassType ) type).getIsClassParameter() ) typeList.setWithClassParameter(true); typeList.add(type); RESULT = typeList; :} ; UnObjPubPri ::= UnObjPubPriO1 UnObjPubPriO2 UnObjPubPriO3 ; UnObjPubPriO1 ::= | InitMethodDec ; UnObjPubPriO2 ::= | PUBLIC COLON {: methodList = new MethodList(); constList = new ConstList(); visibility = Method.public_v; :} UnObjPubPriO2L1 {: currentClassObject.setPublicMethodList(methodList); currentClassObject.setPublicConstList(constList); :} ; UnObjPubPriO2L1 ::= ObjPublicPart | UnObjPubPriO2L1 ObjPublicPart ; UnObjPubPriO3 ::= | PRIVATE COLON {: methodList = new MethodList(); constList = new ConstList(); varList = new ClassObjectVariableList(); visibility = Method.private_v; :} UnObjPubPriO3L1 {: currentClassObject.setPrivateMethodList(methodList); currentClassObject.setPrivateConstList(constList); currentClassObject.setVarList(varList); :} ; UnObjPubPriO3L1 ::= ObjPrivatePart | UnObjPubPriO3L1 ObjPrivatePart ; UnPubPri ::= UnPubPriL1 {: inInitMethod = false; :} UnPubPriO2 UnPubPriO3 UnPubPriO4 ; UnPubPriL1 ::= | UnPubPriL1 InitMethodDec ; UnPubPriO2 ::= | PUBLIC COLON {: methodList = new MethodList(); visibility = Method.public_v; :} UnPubPriO2L1 {: currentClass.setPublicMethodList(methodList); :} ; UnPubPriO2L1 ::= | UnPubPriO2L1 MethodDec ; UnPubPriO3 ::= | SUBCLASS COLON {: methodList = new MethodList(); visibility = Method.subclass_v; :} UnPubPriO3L1 {: currentClass.setSubclassMethodList(methodList); :} ; UnPubPriO3L1 ::= | UnPubPriO3L1 MethodDec ; UnPubPriO4 ::= | PRIVATE COLON {: methodList = new MethodList(); instVarList = new InstanceVariableList(); visibility = Method.private_v; :} UnPubPriO4L1 {: currentClass.setInstVarList(instVarList); currentClass.setPrivateMethodList(methodList); :} ; UnPubPriO4L1 ::= | UnPubPriO4L1 PrivatePart ; UnStatBlock ::= Statement:statement SEMICOLON {: RESULT = statement; :} | BEGIN StatementList:statementList END {: RESULT = new BlockStatement(statementList); :} ; WhileStat ::= WHILE Expr:expr DO UnStatBlock:statement {: RESULT = new WhileStatement( expr, statement ); :} ;