grammar MFJGrammar; @header { package structure.antlrGenerated; import structure.astNode.*; import structure.resource.*; import structure.integrity.*; import structure.program.*; import static structure.astNode.Ast.*; import static tools.DataStructures.*; import tools.Assertions; } @lexer::header { package structure.antlrGenerated; } @members{ /* Old???-? protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException{ super.mismatch(input,ttype,follow); throw new MismatchedTokenException(ttype,input); }*/ protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow)throws RecognitionException{ MismatchedTokenException result = new MismatchedTokenException(ttype,input); IntegrityChecker.printHintOverError(result); super.recoverFromMismatchedToken(input,ttype,follow); throw result; } public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException{ IntegrityChecker.printHintOverError(e); super.recoverFromMismatchedSet(input,e,follow); throw e; } void check(RecognitionException re,Object o)throws RecognitionException{ // reportError(re); // throw re; } void check(Object o)throws RecognitionException{ // if(o==null || state.failed)throw new RecognitionException(); } //recoverFromMismatchedToken BaseReconizer //public ArrayList eList=new ArrayList(); //@Override //public void displayRecognitionError(String[] tokenNames,RecognitionException e) { // eList.add(e); // super.displayRecognitionError(tokenNames,e); // } //public ClassTable parseProgram()throws RecognitionException{ // ClassTable result= this.classTable(); // if(eList.isEmpty())return result; // throw eList.get(0); // } } @rulecatch{ catch (RecognitionException e){ throw e; } } /*@lexer::rulecatch{ catch (RecognitionException e){ throw e; } }*/ literal returns[Value value ] @after{check($value);}: INT{$value =new IntValue(Integer.parseInt($INT.text));} // | // '$$'v1=userClassName{$value =new ClassNameValue($v1.value.value);} | '$'v2=memberName{$value =new MemberNameValue($v2.value.value);} | s=STRING{$value =new StringValue($s.text);} | TRUE {$value =new BoolValue(true);} | FALSE{$value =new BoolValue(false);} | v3=bc{$value=$v3.value;} ; pList returns[ParamsUse value]@after{check($value);}: kwORound (v=expressionList)? kwCRound{$value =new ParamsUse(($v.value==null)?(new ArrayList()):($v.value));} ; //optPlist returns[ParamsUse value] /*@after{check($value);}*/ : // ((kwORound)=>v=pList{$value=$v.value;})| // ; initListArray returns[ParamsUse value] @after{check($value);} : kwOCurly kwCCurly{$value =new ParamsUse(new ArrayList());} | kwOCurly v=expressionList kwCCurly{$value =new ParamsUse($v.value);} ; expressionList returns[ArrayList value] @after{check($value);} : v1=e{$value=AL($v1.value);}(kwComma vn=e{$value.add($vn.value);})* ; paramDecList returns[ParamsDec value] @after{check($value);} : kwORound kwCRound{ $value=new ParamsDec(new ArrayList(),new ArrayList()); } | kwORound v=typeIdList kwCRound{$value=new ParamsDec($v.value._1,$v.value._2);} ; typeIdList returns [Tuple2,ArrayList>value] @after{check($value);} :( type1=className name1=variableName{ $value=T( AL($type1.value), AL($name1.value) ); } (kwComma typeN=className nameN=variableName{ $value._1.add($typeN.value); $value._2.add($nameN.value); })* ){ IntegrityChecker.checkDuplication($value._2); } ; //baseE : '('e')'|literal | baseE'.'ID| baseE'.'ID'('eList')'| 'new' ID'('eList')' | ID | ID'('eList')'; newC returns[Expression value] @after{check($value);} : kwNew type=instantiableClassName p=pList{$value=new New($type.value,$p.value);} ; newA returns[Expression value] @after{check($value);} : kwNew type=className kwOSquare kwCSquare p=initListArray {$value=new NewArray($type.value,$p.value);} ; nudeAtomE: atomE EOF; atomE returns[Expression value] @after{check($value);} : kwORound v1=e kwCRound{$value=$v1.value;} | v3=newC{$value=$v3.value;} | v4=newA{$value=$v4.value;} | v6=memberName p=pList{ $value=new InternalMethodCall($v6.value,$p.value); } | v5=variableAccess {$value=$v5.value;} | v2=literal{$value=$v2.value;} ; baseE returns[Expression value] @after{check($value);} : v=atomE{$value=$v.value;} (d=dot{ if($d.value._2==null)$value=new ClientFieldAccess($value,$d.value._1); else $value=new ClientMethodCall($value,$d.value._1,$d.value._2); } )* ; nudeDot : dot EOF; dot returns[Tuple2 value] @after{check($value);} : kwDot ( name=memberName (p=pList)? { $value=T($name.value,$p.value); } ) ; /*dotMeth returns[Tuple2 value] @after{check($value);} : kwDot name=memberName p=pList{ $value=T($name.value,$p.value); } ; dotField returns[Tuple2 value] @after{check($value);} : kwDot name=memberName{ $value=T($name.value,(ParamsUse)null); } ; */ postUnE returns[Expression value] @after{check($value);} : be=baseE{$value=$be.value;} (p=postUnOp{ if($p.value._1==0)$value=new RestrictExp($value,$p.value._2); else if($p.value._1==1)$value=new AliasExp($value,$p.value._2,$p.value._3); else if($p.value._1==2)$value=new RedirectExp($value,$p.value._2,$p.value._3); else if($p.value._1==3)$value=new GetMembers($value); else if($p.value._1==4)$value=new AccessArray($value,$p.value._2); else throw Assertions.codeNotReachable(); })* ; unE returns[Expression value] @after{check($value);} : p=unOpSeq pe=postUnE{ $value=$pe.value; if($p.value!=null) for(int i=$p.value.size()-1;i>=0;i--){ $value=new UnOpExp($p.value.get(i),$value); } } ; unOpSeq returns [ArrayList value] @after{check($value);} :{ $value=new ArrayList(); }(p=uNOP{ $value.add($p.value); })* ; binE0 returns[Expression value] @after{check($value);} : left=unE{$value=$left.value;} (bop=bOp0 right=unE{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE1 returns[Expression value] @after{check($value);} : left=binE0{$value=$left.value;} (bop=bOp1 right=binE0{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE2 returns[Expression value] @after{check($value);} : left=binE1{$value=$left.value;} (bop=bOp2 right=binE1{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE3 returns[Expression value] @after{check($value);} : left=binE2{$value=$left.value;} (bop=bOp3 right=binE2{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE4 returns[Expression value] @after{check($value);} : left=binE3{$value=$left.value;} (bop=bOp4 right=binE3{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE5 returns[Expression value] @after{check($value);} : left=binE4{$value=$left.value;} (bop=bOp5 right=binE4{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE6 returns[Expression value] @after{check($value);} : left=binE5{$value=$left.value;} (bop=bOp6 right=binE5{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE7 returns[Expression value] @after{check($value);} : left=binE6{$value=$left.value;} (bop=bOp7 right=binE6{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE8 returns[Expression value] @after{check($value);} : left=binE7{$value=$left.value;} (bop=bOp8 right=binE7{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE9 returns[Expression value] @after{check($value);} : left=binE8{$value=$left.value;} (bop=bOp9 right=binE8{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE10 returns[Expression value] @after{check($value);} : left=binE9{$value=$left.value;} (bop=bOp10 right=binE9{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE11 returns[Expression value] @after{check($value);} : left=binE10{$value=$left.value;}(bop=bOp11 right=binE10{$value=new BinOpExp($value,$bop.value,$right.value);})*; binE12 returns[Expression value] @after{check($value);} : left=binE11{$value=$left.value;}(bop=bOp12 right=binE11{$value=new BinOpExp($value,$bop.value,$right.value);})*; e returns[Expression value] @after{check($value);} : v=binE12{$value=$v.value;}; nudeStm: stm EOF; stm returns[Statement value] @after{check($value);} : (className id)=> v1=stmDec{$value=$v1.value;} | (kwIf)=> v2=stmIf{$value=$v2.value;} | (kwWhile)=> v3=stmWhile{$value=$v3.value;} | (kwOCurly)=> v4=stmBlock{$value=$v4.value;} | (kwReturn)=> v5=stmReturn{$value=$v5.value;} | (kwPrint)=> v6=stmPrint{$value=$v6.value;} | (id kwEqual)=> v7=stmVarAssign{$value=$v7.value;} | (kwTry)=> v8=stmTryCatch{$value=$v8.value;} | (kwThrow)=> v9=stmThrow{$value=$v9.value;} | (kwFor)=> v10=stmForeach{$value=$v10.value;} | v11=stmExp{$value=$v11.value;} ; stmThrow returns[Throw value] @after{check($value);} : kwThrow v=e kwSc{ $value=new Throw($v.value); } ; stmExp returns[StmExp value] @after{check($value);} : v=e kwSc { if(!($v.value instanceof ValidStmExp)) //throw new ParsingError( // "Syntax error, insert \"AssignmentOperator Expression\" to complete Expression" // ); throw new ClassNotWellFormed.ExpressionNotStatement("Syntax error, insert \"AssignmentOperator Expression\" to complete Expression"); $value=new StmExp($v.value); } ; stmVarAssign returns[VariableAssignament value] @after{check($value);} : name=variableName kwEqual v=e kwSc{ $value=new VariableAssignament($name.value,$v.value); } ; stmTryCatch returns[Try value] @after{check($value);} : kwTry b=stmBlock c=stmAuxCatchList { $value=new Try($b.value,$c.value._1,$c.value._2,$c.value._3); } ; stmForeach returns[Foreach value] @after{check($value);} : kwFor kwORound type=className name=variableName kwColon v=e kwCRound s=stm{ $value=new Foreach($type.value,$name.value,$v.value,$s.value); } ; stmAuxCatchList returns[Tuple3,ArrayList,ArrayList> value] @after{check($value);} :{ $value=T(new ArrayList(),new ArrayList(),new ArrayList()); } (kwCatch kwORound type=className name=variableName kwCRound b2=stmBlock { $value._1.add($type.value); $value._2.add($name.value); $value._3.add($b2.value); })+ ; stmDec returns[VariableDeclaration value] @after{check($value);} : type=className name=variableName kwEqual v=e kwSc{ $value=new VariableDeclaration($type.value,$name.value,$v.value); } ; stmIf returns[If value] @after{check($value);} : kwIf kwORound ve=e kwCRound vThen=stm ((kwElse)=>(kwElse vElse=stm)|){ if($vElse.value==null)$value=new If($ve.value,$vThen.value,new Block(new ArrayList())); else $value=new If($ve.value,$vThen.value,$vElse.value); } ; stmWhile returns[While value] @after{check($value);} : kwWhile kwORound ve=e kwCRound v=stm{ $value=new While($ve.value,$v.value); } ; stmBlock returns[Block value] @after{check($value);} : kwOCurly v=stmList kwCCurly{ $value=new Block($v.value); } ; stmList returns[ArrayList value] @after{check($value);} :{ $value=new ArrayList(); }(v=stm { $value.add($v.value); })* ; stmReturn returns[Statement value] @after{check($value);} : kwReturn v=e kwSc{$value=new Return($v.value);} ; stmPrint returns[Statement value] @after{check($value);} : kwPrint kwORound v=e kwCRound kwSc{$value=new Print($v.value);} ; bc returns[BaseClassValue value] @after{check($value);} : vi=impl kwOCurly vm=memList kwCCurly { $value=IntegrityChecker.checkBaseClass($vi.value,$vm.value); } ; impl returns[ArrayList value] @after{check($value);} : { $value=new ArrayList(); }| kwImplements v=instantiableClassName{ $value=AL($v.value); } (kwComma vn=instantiableClassName{ $value.add($vn.value); })* ; memList returns[ArrayList value] @after{check($value);} :{ $value=new ArrayList(); }(v=mem{$value.add($v.value);})* ; mem returns[Ast value] @after{check($value);} : v1=field{$value=$v1.value;} | v2=abstractField{$value=$v2.value;} | v3=method{$value=$v3.value;} | v4=abstractMethod{$value=$v4.value;} | v5=constructor{$value=$v5.value;} ; field returns[Member value] @after{check($value);} : type=className name=memberName kwSc{ $value=new Field($type.value,$name.value); } ; abstractField returns[Member value] @after{check($value);} : kwAbstract type=className name=memberName kwSc{ $value=new AbstractField($type.value,$name.value); } ; method returns[Member value] @after{check($value);} : type=className name=memberName p=paramDecList s=stmBlock{ $value=new Method($type.value,$name.value,$p.value,$s.value); } ; abstractMethod returns[Member value] @after{check($value);} : kwAbstract type=className name=memberName p=paramDecList kwSc{ $value=new AbstractMethod($type.value,$name.value,$p.value); } ; constructor returns[Constructor value] @after{check($value);} : kwConstructor p=paramDecList kwOCurly fil=fieldInitList kwCCurly{ $value=new Constructor($p.value,$fil.value._1,$fil.value._2); } ; fieldInitList returns[Tuple2,ArrayList> value] @after{check($value);} :{ $value=T(new ArrayList(),new ArrayList()); }(name=memberName kwEqual v=e kwSc{ $value._1.add($name.value); $value._2.add($v.value); })* ; resource returns [Resource value] @after{check($value);} : Class name=className kwEqual v=e //kwSc { $value=new Resource($name.value,$v.value); } ; classTable returns[ClassTable value] @after{check($value);} :{ $value=new ClassTable(); } (r=resource{ if($value.keySet().contains($r.value.getName())) throw new ClassNotWellFormed.DuplicatedClassDeclaration($r.value.getName().value); $value.put($r.value.getName(),$r.value); })* kwMain kwEqual v=stm{$value.mainExpression=$v.value;} { IntegrityChecker.checkWellFormedClassTable($value); } ; postUnOp returns[Tuple3 value] @after{check($value);} : kwOSquare kwRestrict v=e kwCSquare{ $value=T(0,$v.value,(Expression)null); } | kwOSquare kwAlias v1=e kwTo v2=e kwCSquare{ $value=T(1,$v1.value,$v2.value); } | kwOSquare kwRedirect v1=e kwTo v2=e kwCSquare{ $value=T(2,$v1.value,$v2.value); } | kwOSquare kwMembers kwCSquare{ $value=T(3,(Expression)null,(Expression)null); } | kwOSquare v=e kwCSquare{ $value=T(4,$v.value,(Expression)null); } /* kwOSquare v1=e ( kwAlias v2=e kwCSquare{ $value=T(1,$v1.value,$v2.value); } | kwRedirect v3=e kwCSquare{ $value=T(2,$v1.value,$v3.value); } | kwCSquare{ $value=T(4,$v1.value,(Expression)null); } ) | kwOSquare kwMembers kwCSquare{ $value=T(3,(Expression)null,(Expression)null); }*/ ; userClassName returns [ClassName value] @after{check($value);} : name=id{ IntegrityChecker.checkForbidden($name.text); assert !IntegrityChecker.predefinedTypesString.contains($name.text); $value=new ClassName($name.text); } ; instantiableClassName returns [ClassName value] @after{check($value);} : name2=predefinedClass{ $value=new ClassName($name2.text); } | name3=predefinedType{ $value=new ClassName($name3.text); } | name=userClassName{ $value=$name.value; } ; className returns [ClassName value] @after{check($value);} : v=instantiableClassName{$value=$v.value;} (kwOSquare kwCSquare{$value=new ClassName($value.value+"[]");})* ; variableAccess returns [VariableAccess value] @after{check($value);} : name=variableNameOrThis{$value=new VariableAccess($name.value);} ; variableName returns [VariableName value] @after{check($value);} : name=id{ IntegrityChecker.checkForbidden($name.text); $value=new VariableName($name.text); } ; variableNameOrThis returns [VariableName value] @after{check($value);} : v=variableName{ $value=$v.value; } | kwThis{ $value=new VariableName("this"); } ; memberName returns [MemberName value] @after{check($value);} : name=id{ IntegrityChecker.checkForbidden($name.text); $value=new MemberName($name.text); } ; uNOP returns[UnOp value] @after{check($value);} : v='!'{$value=UnOp.fromRepr($v.text);} ; //BINOP // 0 1 2 3 4 5 6 7 8 9 10 11 12 bOp12 returns[BinOp value] @after{check($value);} : v='&&'{$value=BinOp.fromRepr($v.text);}; bOp11 returns[BinOp value] @after{check($value);} : v='||'{$value=BinOp.fromRepr($v.text);}; bOp10 returns[BinOp value] @after{check($value);} : v='=='{$value=BinOp.fromRepr($v.text);}; bOp9 returns[BinOp value] @after{check($value);} : v='<'{$value=BinOp.fromRepr($v.text);}; bOp8 returns[BinOp value] @after{check($value);} : v='<='{$value=BinOp.fromRepr($v.text);}; bOp7 returns[BinOp value] @after{check($value);} : v='>'{$value=BinOp.fromRepr($v.text);}; bOp6 returns[BinOp value] @after{check($value);} : v='>='{$value=BinOp.fromRepr($v.text);}; bOp5 returns[BinOp value] @after{check($value);} : v='[+]'{$value=BinOp.fromRepr($v.text);}; bOp4 returns[BinOp value] @after{check($value);} : v='+'{$value=BinOp.fromRepr($v.text);}; bOp3 returns[BinOp value] @after{check($value);} : v='-'{$value=BinOp.fromRepr($v.text);}; bOp2 returns[BinOp value] @after{check($value);} : v='*'{$value=BinOp.fromRepr($v.text);}; bOp1 returns[BinOp value] @after{check($value);} : v='/'{$value=BinOp.fromRepr($v.text);}; bOp0 returns[BinOp value] @after{check($value);} : v='%'{$value=BinOp.fromRepr($v.text);}; predefinedType : Class | 'name' |'int' | 'boolean' |'void' ; predefinedClass : 'String'|'Object'|'RuntimeException' ; forbiddenId : 'abstract'|'continue'|'for'|'new'|'switch'|'assert'| 'default'|'goto'|'package'|'synchronized'|'do'|'if'|'private'| 'this'|'break'|'double'|'implements'|'protected'|'throw'|'byte'| 'else'|'import'|'public'|'throws'|'case'|'enum'|'instanceof'| 'return'|'transient'|'catch'|'extends'|'short'|'try'|'char'|'final'| 'interface'|'static'|'finally'|'long'|'strictfp'|'volatile'|'const'| 'float'|'native'|'super'|'while'|'print'; kwIf returns[Object value] @after{check($value);}:v='if' {$value=$v.text;}; kwWhile returns[Object value] @after{check($value);}:v='while' {$value=$v.text;}; kwFor returns[Object value] @after{check($value);}:v='for' {$value=$v.text;}; kwSc returns[Object value] @after{check($value);}:v=';' {$value=$v.text;}; kwImplements returns[Object value] @after{check($value);}:v='implements' {$value=$v.text;}; kwReturn returns[Object value] @after{check($value);}:v='return' {$value=$v.text;}; kwElse returns[Object value] @after{check($value);}:v='else' {$value=$v.text;}; kwTry returns[Object value] @after{check($value);}:v='try' {$value=$v.text;}; kwCatch returns[Object value] @after{check($value);}:v='catch' {$value=$v.text;}; kwNew returns[Object value] @after{check($value);}:v='new' {$value=$v.text;}; kwThrow returns[Object value] @after{check($value);}:v='throw' {$value=$v.text;}; kwORound returns[Object value] @after{check($value);}:v='(' {$value=$v.text;}; kwCRound returns[Object value] @after{check($value);}:v=')' {$value=$v.text;}; kwOCurly returns[Object value] @after{check($value);}:v='{' {$value=$v.text;}; kwCCurly returns[Object value] @after{check($value);}:v='}' {$value=$v.text;}; kwOSquare returns[Object value] @after{check($value);}:v='[' {$value=$v.text;}; kwCSquare returns[Object value] @after{check($value);}:v=']' {$value=$v.text;}; kwComma returns[Object value] @after{check($value);}:v=',' {$value=$v.text;}; kwDot returns[Object value] @after{check($value);}:v='.' {$value=$v.text;}; kwEqual returns[Object value] @after{check($value);}:v='=' {$value=$v.text;}; kwPrint returns[Object value] @after{check($value);}:v='print' {$value=$v.text;}; kwColon returns[Object value] @after{check($value);}:v=':' {$value=$v.text;}; kwMain returns[Object value] @after{check($value);}:v='main' {$value=$v.text;}; kwAbstract returns[Object value] @after{check($value);}:v='abstract' {$value=$v.text;}; kwConstructor returns[Object value] @after{check($value);}:v='constructor' {$value=$v.text;}; kwThis returns[Object value] @after{check($value);}:v='this' {$value=$v.text;}; kwAlias returns[Object value] @after{check($value);}:v='alias' {$value=$v.text;}; kwRedirect returns[Object value] @after{check($value);}:v='redirect' {$value=$v.text;}; kwRename returns[Object value] @after{check($value);}:v='rename' {$value=$v.text;}; kwMembers returns[Object value] @after{check($value);}:v='members' {$value=$v.text;}; kwRestrict returns[Object value] @after{check($value);}:v='restrict' {$value=$v.text;}; kwTo returns[Object value] @after{check($value);}:v='to' {$value=$v.text;}; Class : 'class'; TRUE : 'true'; FALSE : 'false'; id : IDD|'main'; IDD : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* ; INT : '0'|(('1'..'9')('0'..'9')*) ; COMMENT : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} | '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} ; WS : ( ' ' | '\t' | '\r' | '\n' ) {$channel=HIDDEN;} ; STRING : '"' ( ESC_SEQ | ~('\\'|'"') )* '"' ; fragment HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; fragment ESC_SEQ : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') | UNICODE_ESC | OCTAL_ESC ; fragment OCTAL_ESC : '\\' ('0'..'3') ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ; fragment UNICODE_ESC : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT ;