/*
* JParser.java
*
* Created on December 28, 2004, 6:19 PM
*/
package compiler;
import compiler.JLex;
import compiler.Token;
import java.io.IOException;
/**
*
* @author Sarangan Rajamanickam
*/
public class JParser implements compiler.TokenConstants{
private JLex jlex;
private Token token;
/** Creates a new instance of JParser */
public JParser(String filename) {
jlex=new JLex(filename);
}
private void error(String errormessage){
System.out.println("Error!Error!Error!");
System.out.println(errormessage);
System.out.println("Error at location:
"+(token.position/1000)+"-"+(token.position%1000));
System.exit(1);
}
/**
* Actual Function that starts the parsing
*/
public AST parse()throws IOException{
AST tree = null ;
token=jlex.getToken();
tree = compilationunit();
if(token.kind != EOF){
error("Problem
Exists");
}
return tree ;
}
/**
* Rule 1: <compilationunit> ::= <classdeclaration>
| e
*/
private CompilationUnit compilationunit()throws
IOException{
CompilationUnit cu = null ;
ClassDeclaration cd = null ;
if(token.kind!=EOF){
cd = classdeclaration();
}
else{
return
null ;
}
cu = new CompilationUnit(cd);
System.out.println("The File is
parsed.");
return cu ;
}
/**
* Rule 2: <classdeclaration> ::= <public>
class identifier <classbody>
*/
private ClassDeclaration classdeclaration()throws IOException{
ClassDeclaration cd = null ;
Terminal pd = null ;
Terminal cn = null ;
ClassBody cb = null ;
pd = publicdec();
if(token.kind==CLASS){
token=jlex.getToken();
if(token.kind==IDENTIFIER){
cn = new Terminal(token.word) ;
token=jlex.getToken();
cb = classbody();
}else{
error("Mistake in the Name of the Class");
}
}else{
error("No
Class in the Program");
}
cd = new ClassDeclaration(pd,cn,cb);
return cd ;
}
/**
* Rule 3: <public> ::= public | e
*/
private Terminal publicdec()throws IOException{
Terminal pd = null ;
if(token.kind == PUBLIC){
pd = new
Terminal("public");
token=jlex.getToken();
}
return pd ;
}
/**
* Rule 4: <classbody> ::= { <classbodydeclaration>*
}
*/
private ClassBody classbody()throws IOException{
ClassBody cb = null ;
Declarations ds1 = null ;
Declarations ds2 = null ;
if(token.kind==LEFTSETBRACKET){
token=jlex.getToken();
while(token.kind==PUBLIC
|| token.kind==PRIVATE || token.kind==PROTECTED){
ds2 = classbodydeclaration();
if(ds1 == null){
ds1 = ds2 ;
}else{
Declarations temp = ds1 ;
ds1 = new SequenceDeclarations(temp,ds2) ;
}
}
if(token.kind==RIGHTSETBRACKET){
token=jlex.getToken();
}else{
error("No '}' End of the Class Body");
}
}else{
error("No
'{' Start of the Class Body");
}
cb = new ClassBody(ds1);
return cb;
}
/**
* Rule 5: <classbodydeclaration> ::= <modifier>
<static> <final> <type> identifier ;
| <modifier> <static> <final> <type> identifier
( <formalparamaterlist> ) <block>
| <modifier> identifier ( <formalparamaterlist> ) <block>
*/
private Declarations classbodydeclaration() throws IOException{
Static st = null ;
Type tp = null ;
Terminal vn = null ;
Declarations fv = null ;
Block blk = null ;
Modifier md = modifier();
VariableDeclarations ds = null
;
FunctionDeclarations fd = null
;
if(token.kind!=IDENTIFIER){
st = staticdec();
//fn =
finaldec();
tp = type();
if(token.kind==IDENTIFIER){
vn = new Terminal(token.word);
token=jlex.getToken();
if(token.kind==SEMICOLON){
ds = new VariableDeclarations(md,st,tp,vn);
token=jlex.getToken();
return ds;
}
if(token.kind==LEFTBRACES){
token=jlex.getToken();
fv = formalparameterlist();
if(token.kind==RIGHTBRACES){
token=jlex.getToken();
blk = block();
fd = new FunctionDeclarations(md,st,tp,vn,fv,blk,"simplefunction") ;
return fd;
}else{
error("No ')' Closing Right Braces");
}
}else{
error("No '(' Opening Left Braces");
}
}else{
error("Requires Identifier as Variable Name");
}
}
//This piece is for the 3rd part
of the rule.
if(token.kind==IDENTIFIER){
vn = new
Terminal(token.word);
token=jlex.getToken();
if(token.kind==LEFTBRACES){
token=jlex.getToken();
fv=formalparameterlist();
if(token.kind==RIGHTBRACES){
token=jlex.getToken();
blk = block();
fd = new FunctionDeclarations(md,null,null,vn,fv,blk,"constructor");
return fd;
}else{
error("No ')' Closing Right Braces");
}
}else{
error("No '(' Opening Left Braces");
}
}
//It does not match any of the
rule.Automatically call error();
error("Error After Modifier");
Declarations temp = null ;
return temp ;
}
/**
* Rule 6: <modifier> ::=
public | private | protected
*/
private Modifier modifier()throws IOException{
Modifier md = null ;
if(token.kind==PUBLIC || token.kind==PRIVATE
|| token.kind==PROTECTED){
md = new
Modifier(token.word);
token=jlex.getToken();
}else{
error("Unrecogonised
Modifier");
}
return md ;
}
/**
* Rule 7: <static> ::= static | e
*/
private Static staticdec()throws IOException{
Static st = null ;
if(token.kind==STATIC){
st = new
Static(token.word);
token=jlex.getToken();
}
return st ;
}
/**
* Rule 8: <final> ::= final | e
*/
/*private void finaldec()throws IOException{
if(token.kind==FINAL){
token=jlex.getToken();
return;
}else{
return;
}
}*/
/**
* Rule 9: <formalparameterlist> ::=
<vardecs> | e
*/
private Declarations formalparameterlist()throws IOException{
Declarations vd = null ;
if(token.kind==RIGHTBRACES){//that
means there is no formalparameters
return
vd ;
}
vd = vardecs();
return vd ;
}
/**
* Rule 10: <vardecs> ::=
<vardec> (, <vardec> )*
*/
private Declarations vardecs()throws IOException{
Declarations vd1 = null ;
Declarations vd2 = null ;
vd1 = vardec();
while(token.kind==COMMA){
token=jlex.getToken();
vd2 =
vardec();
Declarations
temp = vd1 ;
vd1 =
new SequenceDeclarations(temp,vd2);
}
return vd1;
}
/**
* Rule 11: <vardec> ::=
<type> identifier
*/
private VariableDeclarations vardec()throws IOException{
VariableDeclarations vd = null
;
Type tp = null ;
Terminal vn = null ;
tp = type();
if(token.kind==IDENTIFIER){
vn = new
Terminal(token.word);
vd = new
VariableDeclarations(tp,vn);
token=jlex.getToken();
}else{
error("No
Legal Name for the Identifier");
}
return vd;
}
/**
* Rule 12: <block> ::=
{ (<vardec> ; )* <statement> * } //TO BE NOTED
*/
private Block block()throws IOException{
Block blk = null ;
Declarations vd1 = null ;
Declarations vd2 = null ;
Command cmd1 = null ;
Command cmd2 = null ;
if(token.kind==LEFTSETBRACKET){
token=jlex.getToken();
while(token.kind==INT
|| token.kind==BOOLEAN || token.kind==VOID || token.kind==LEFTBRACES){
vd2 = vardec();
if(token.kind==SEMICOLON){
token=jlex.getToken();
}else{
error("No Semicolon for the Declaration Termination");
}
if(vd1 == null){
vd1 = vd2 ;
}else{
Declarations temp=vd1;
vd1 = new SequenceDeclarations(temp,vd2);
}
}
while(token.kind==IF
|| token.kind==WHILE || token.kind==THIS || token.kind==RETURN || token.kind==IDENTIFIER){
cmd2 = statement();
if(cmd1 == null ){
cmd1 = cmd2;
}else{
Command tempC=cmd1;
cmd1=new SequenceCommand(tempC,cmd2);
}
}
if(token.kind==RIGHTSETBRACKET){
token=jlex.getToken();
}else{
error("No '}' Closing Bracket for the Block");
}
}else{
error("No
'{' Opening Bracket for the Block");
}
blk = new Block(vd1,cmd1);
return blk ;
}
/**
* Rule 13: <statement> ::=
if ( <expression> ) { <statement> * }
*
| if ( <expression> ) { <statement>* } else { <statement>*
}
*
| while ( <expression> ) { <statement> * }
*
| <statementwithouttrailingsubstatement>
*/
private Command statement()throws IOException{
Command cmd1 = null ;
Command cmd2 = null ;
Expression exp = null ;
Command cmd3 = null ;
Command cmd4 = null ;
//This piece of code is for first
2 parts of the rule.
if(token.kind == IF){
token=jlex.getToken();
if(token.kind
== LEFTBRACES){
token=jlex.getToken();
exp = expression();
if(token.kind == RIGHTBRACES){
token=jlex.getToken();
if(token.kind == LEFTSETBRACKET){
token=jlex.getToken();
while(token.kind==IF || token.kind==WHILE || token.kind==IDENTIFIER || token.kind==THIS
|| token.kind==RETURN){
cmd2 = statement();
if(cmd1 == null){
cmd1=cmd2;
}else{
Command tempC=cmd1;
cmd1=new SequenceCommand(tempC,cmd2);
}
}
if(token.kind == RIGHTSETBRACKET){
token=jlex.getToken();
if(token.kind != ELSE){
IfElseCommand ifelsecommand = new IfElseCommand(exp,cmd1);
return ifelsecommand;
}
else{
token=jlex.getToken();
if(token.kind == LEFTSETBRACKET){
token=jlex.getToken();
while(token.kind==IF || token.kind==WHILE || token.kind==IDENTIFIER || token.kind==THIS
|| token.kind==RETURN){
cmd4=statement();
if(cmd3==null){
cmd3=cmd4;
}else{
Command tempCo=cmd3;
cmd3=new SequenceCommand(tempCo,cmd4);
}
}
if(token.kind == RIGHTSETBRACKET){
IfElseCommand ifelsecommand2=new IfElseCommand(exp,cmd1,cmd3);
token=jlex.getToken();
return ifelsecommand2;
}else{
error("No '}' Closing Bracket for the Else part of the loop");
}
}else{
error("No '{' Opening Bracket for the Else part of the loop");
}
}
}else{
error("No '}' closing Bracket");
}
}else{
error("No '{' opening Bracket for the Body of the loop");
}
}else{
error("No ')' closing braces for the expression");
}
}else{
error("No '(' opening braces for the expression");
}
}
if(token.kind == WHILE){
token=jlex.getToken();
if(token.kind
== LEFTBRACES){
token=jlex.getToken();
exp=expression();
if(token.kind == RIGHTBRACES){
token=jlex.getToken();
if(token.kind == LEFTSETBRACKET){
token=jlex.getToken();
while(token.kind==IF || token.kind==WHILE || token.kind==IDENTIFIER || token.kind==THIS
|| token.kind==RETURN){
cmd2=statement();
if(cmd1==null){
cmd1=cmd2;
}else{
Command tempCo2=cmd1;
cmd1=new SequenceCommand(tempCo2,cmd2);
}
}
if(token.kind == RIGHTSETBRACKET){
WhileCommand whilecommand=new WhileCommand(exp,cmd1);
token=jlex.getToken();
return whilecommand;
}else{
error("No '}' right bracket for the loop");
}
}else{
error("No '{' left bracket for the loop");
}
}else{
error("No ')' braces for the expression");
}
}else{
error("No '(' braces for the expression");
}
}
/* With the above we complete
the third rule also. Now we just call the remaining fourth option.
* If there is an error,
say anyother token at this position (say 'public') it will be found at
* later functions called
by statementwithouttrailingsubstatement()
*/
cmd1 = statementwithouttrailingsubstatement();
return cmd1 ;
}
/**
* Rule 14: <statementwithouttrailingsubstatement>
::= <expressionstatement>
*
| <returnstatement>
*/
private Command statementwithouttrailingsubstatement()throws
IOException{
Command cmd = null ;
if(token.kind == RETURN){
cmd =
returnstatement();
return
cmd ;
}
cmd = expressionstatement();
return cmd ;
}
/**
* Rule 15: <returnstatement>
::= return <returntail> ;
*/
private ReturnCommand returnstatement()throws IOException{
ReturnCommand rc = null ;
Expression exp = null ;
if(token.kind==RETURN){
token=jlex.getToken();
if(token.kind!=SEMICOLON){//This
piece of code is added because if there is not semicolon it must be an expression
or error. It helps us to simplify the code in returntail().
exp = returntail();
}
if(token.kind
== SEMICOLON){
rc = new ReturnCommand(exp);
token=jlex.getToken();
}else{
error("No semicolon in the return statement");
}
}else{
error("No
return keyword");
}
return rc;
}
/**
* Rule 16: <returntail> ::= <expression>
| e
*/
private Expression returntail()throws IOException{
/* Important: This section is
executed only if there is an expression. Or else it will
* not be executed. So it
is enough to go directly for expression. It is not necessary
* to check for 'e'
*/
Expression exp = expression();
return exp ;
}
/**
* Rule 17: <expressionstatement>
::= <statementexpression> ;
*/
private Command expressionstatement()throws IOException{
Command cmd = null ;
cmd = statementexpression();
if(token.kind == SEMICOLON){
token=jlex.getToken();
}else{
error("No
semicolon at the end of the statement");
}
return cmd ;
}
/**
* Rule 18: <statementexpression>
::= <statementexpr-prefix> <statementexpr-suffix>
*/
private Command statementexpression()throws IOException{
Command cmd = null ;
String type = null ;
ThisAndName tan = statementexpressionprefix();
if(token.kind == EQUALS){
type =
"assign" ;
}else{
type="method"
;
}
Expression exp = statementexpressionsuffix();
if(type.equals("assign")){
cmd =
new AssignmentCommand(tan,exp);
}else{
cmd =
new MethodCallCommand(tan,exp) ;
}
return cmd;
}
/**
* Rule 19: <statementexpr-prefix> ::= <this-and-name>
*/
private ThisAndName statementexpressionprefix()throws
IOException{
return thisandname();
}
/**
* Rule 20: <statementexpr-suffix>
::= <assignment-suffix>
*
| <methodinvocation-suffix>
*/
private Expression statementexpressionsuffix()throws IOException{
Expression exp = null ;
if(token.kind == LEFTBRACES){
exp =
methodinvocationsuffix();
return
exp;
}
exp = assignmentsuffix();
return exp;
}
/**
* Rule 21: <methodinvocation-suffix>
::= ( <argumentList> )
*/
private Expression methodinvocationsuffix()throws IOException{
Expression exp = null ;
if(token.kind == LEFTBRACES){
token=jlex.getToken();
if(token.kind
!= RIGHTBRACES){
exp = argumentlist();
}
if(token.kind
== RIGHTBRACES){
token=jlex.getToken();
}else{
error("No ')' at methodinvocation");
}
}else{
error("No
'(' at methodinvocation");
}
return exp ;
}
/**
* Rule 22: <assignment-suffix>
::= = <expression>
*/
private Expression assignmentsuffix()throws IOException{
Expression exp = null;
if(token.kind == EQUALS){
token=jlex.getToken();
exp =
expression();
}else{
error("Missing
'='");
}
return exp;
}
/**
* Rule 23: <argumentlist> ::=
<expression> ( , <expression> ) * | e
*/
private Expression argumentlist()throws IOException{
// Not necessary to check for
'e'. It is already checked at the calling side.
Expression exp1 = null;
Expression exp2 = null;
exp1=expression();
while(token.kind==COMMA){
token=jlex.getToken();
exp2 =
expression();
Expression
tempE=exp1;
exp1=new
SequenceExpression(tempE,exp2);
}
return exp1;
}
/**
* Rule 24: <name> ::= identifier
( . identifier ) *
*/
private Name name()throws IOException{
Name nm = null ;
String temp_ident = null ;
if(token.kind == IDENTIFIER){
temp_ident
= token.word ;
token=jlex.getToken();
while(token.kind
== DOT){
token=jlex.getToken();
if(token.kind == IDENTIFIER){
temp_ident=temp_ident+"."+token.word;
token=jlex.getToken();
}
else{
error("Need legal identifier");
}
}
}else{
error("Need
legal identifier");
}
nm = new Name(temp_ident);
return nm ;
}
/**
* Rule 25: <this-and-name>
::= <name> | this.<name>
*/
private ThisAndName thisandname()throws IOException{
ThisAndName tan = null ;
Name nm = null ;
boolean thisavailability = false
;
if(token.kind == THIS){
thisavailability
= true ;
token=jlex.getToken();
if(token.kind
== DOT){
token=jlex.getToken();
nm = name();
tan = new ThisAndName(nm,true);
return tan;
}else{
error("Need '.' after 'this'");
}
}
nm = name();
tan = new ThisAndName(nm,false);
return tan;
}
/**
* Rule 26: <expression> ::= <cond-or-expr>
<cond-or-expr-tail>
*/
private Expression expression()throws IOException{
Expression exp1 = null ;
exp1 = conditionalorexpression();
return conditionalorexpressiontail(exp1);
}
/**
* Rule 27: <cond-or-expr-tail> ::=
|| <cond-or-expr> <cond-or-expr-tail> | e
*/
private Expression conditionalorexpressiontail(Expression
exp1)throws IOException{
if(token.kind == OR){
token=jlex.getToken();
Expression
exp2 = conditionalorexpression();
BinaryOpExpression
b = new BinaryOpExpression(exp1,new Terminal("||"),exp2);
Expression
ret = conditionalorexpressiontail(b);
return
ret;
}else{
return
exp1;
}
}
/**
* Rule 28: <cond-or-expr> ::=
<cond-and-expr> <cond-and-expr-tail>
*/
private Expression conditionalorexpression()throws IOException{
Expression exp1 = conditionalandexpression();
return conditionalandexpressiontail(exp1);
}
/**
* Rule 29: <cond-and-expr-tail> ::= &&
<cond-and-expr> <cond-and-expr-tail> | e
*/
private Expression conditionalandexpressiontail(Expression
exp1)throws IOException{
if(token.kind == AND){
token=jlex.getToken();
Expression
exp2 = conditionalandexpression();
BinaryOpExpression
b = new BinaryOpExpression(exp1,new Terminal("&&"),exp2);
Expression
ret = conditionalandexpressiontail(b);
return
ret;
}else{
return
exp1;
}
}
/**
* Rule 30: <cond-and-expr> ::=
<equal-op> <equal-op-tail>
*/
private Expression conditionalandexpression()throws IOException{
Expression exp1 = equalop();
return equaloptail(exp1);
}
/**
* Rule 31: <equal-op-tail> ::=
<equalityoperator> <equal-op> <equal-op-tail> | e
*/
private Expression equaloptail(Expression exp1)throws
IOException{
if(token.kind == EQUIVALENT ||
token.kind == NOTEQUIVALENT){
Terminal
op = equalityoperator();
Expression
exp2 = equalop();
BinaryOpExpression
b = new BinaryOpExpression(exp1,op,exp2);
Expression
ret = equaloptail(b);
return
ret;
}else{
return
exp1;
}
}
/**
* Rule 32: <equalityoperator> ::=
== | !=
*/
private Terminal equalityoperator()throws IOException{
Terminal ter = null;
if(token.kind == EQUIVALENT ||
token.kind == NOTEQUIVALENT){
if(token.kind
== EQUIVALENT)
ter=new Terminal("==");
else
ter=new Terminal("!=");
token=jlex.getToken();
}else{
error("Not
a valid equality operator");
}
return ter;
}
/**
* Rule 33: <equal-op> ::= <rel-op>
<rel-op-tail>
*/
private Expression equalop()throws IOException{
Expression exp1 = relop();
return reloptail(exp1);
}
/**
* Rule 34: <rel-op-tail> ::= <relationaloperator>
<rel-op> <rel-op-tail> | e
*/
private Expression reloptail(Expression exp1)throws IOException{
if(token.kind == LESSTHAN || token.kind
== GREATERTHAN || token.kind == LESSEQUALS || token.kind == GREATEREQUALS){
Terminal
op = relationaloperator() ;
Expression
exp2 = relop() ;
BinaryOpExpression
b = new BinaryOpExpression(exp1,op,exp2);
Expression
ret = reloptail(b);
return
ret;
}else{
return
exp1;
}
}
/**
* Rule 35: <relationaloperaor> : = <
| > | >= | <=
*/
private Terminal relationaloperator()throws IOException{
Terminal ter = null ;
if(token.kind == LESSTHAN || token.kind
== GREATERTHAN || token.kind == LESSEQUALS || token.kind == GREATEREQUALS){
if(token.kind
== LESSTHAN)
ter = new Terminal("<");
if(token.kind
== GREATERTHAN)
ter = new Terminal(">");
if(token.kind
== LESSEQUALS)
ter = new Terminal("<=");
if(token.kind
== GREATEREQUALS)
ter = new Terminal(">=");
token=jlex.getToken();
}else{
error("Not
a valid relational operator");
}
return ter ;
}
/**
* Rule 36: <rel-op> ::=
<add-op> <add-op-tail>
*/
private Expression relop()throws IOException{
Expression exp1 = addop();
return addoptail(exp1);
}
/**
* Rule 37: <add-op-tail> ::= <additionoperator>
<add-op> <add-op-tail> | e
*/
private Expression addoptail(Expression exp1)throws IOException{
if(token.kind == PLUS || token.kind
== MINUS){
Terminal
op = additionoperator() ;
Expression
exp2 = addop() ;
BinaryOpExpression
b = new BinaryOpExpression(exp1,op,exp2) ;
Expression
ret = addoptail(b) ;
return
ret ;
}else{
return
exp1 ;
}
}
/**
* Rule 38: <additionoperator> :=
+ | -
*/
private Terminal additionoperator()throws IOException{
Terminal ter = null ;
if(token.kind == PLUS || token.kind
== MINUS){
if(token.kind
== PLUS)
ter = new Terminal("+");
else
ter = new Terminal("-");
token=jlex.getToken();
}else{
error("Not
a valid addition operator");
}
return ter ;
}
/**
* Rule 39: <add-op> ::=
<mult-op> <mult-op-tail>
*/
private Expression addop()throws IOException{
Expression exp1 = multop();
return multoptail(exp1);
}
/**
* Rule 40: <mult-op-tail> ::= <multiplicationoperator>
<mult-op> <mult-op-tail> | e
*/
private Expression multoptail(Expression exp1)throws IOException{
if(token.kind == ASTRIEK || token.kind
== DIVIDES || token.kind== MODULO){
Terminal
op = multiplicationoperator();
Expression
exp2 = multop();
BinaryOpExpression
b = new BinaryOpExpression(exp1,op,exp2);
Expression
ret = multoptail(b);
return
ret;
}else{
return
exp1;
}
}
/**
* Rule 41: <multiplicationoperator> ::=
* | / | %
*/
private Terminal multiplicationoperator()throws IOException{
Terminal ter = null ;
if(token.kind == ASTRIEK || token.kind
== DIVIDES || token.kind== MODULO){
if(token.kind
== ASTRIEK)
ter = new Terminal("*");
if(token.kind
== DIVIDES)
ter = new Terminal("/");
if(token.kind
== MODULO)
ter = new Terminal("%");
token=jlex.getToken();
}else{
error("Not
a valid multiplication operator");
}
return ter;
}
/**
* Rule 42: <mult-op> ::=
+ <mult-op>
*
| -<mult-op>
*
| !<mult-op>
*
| <primary>
*/
private Expression multop()throws IOException{
if(token.kind == PLUS || token.kind
== MINUS || token.kind == NOT){
Terminal
op = null ;
if(token.kind
== PLUS)
op = new Terminal("+");
if(token.kind
== MINUS)
op = new Terminal("-");
if(token.kind
== NOT)
op = new Terminal("!");
token=jlex.getToken();
Expression
exp1 = multop();
UnaryOpExpression
U = new UnaryOpExpression(op,exp1);
return
U;
}
return primary();
}
/**
* Rule 43: <primary>
::= <primarywithliteral>
*
| <primarywithoutliteral>
*/
private Expression primary()throws IOException{
Expression exp = null ;
if(token.kind == INTEGERLITERAL
|| token.kind == BOOLEANLITERAL || token.kind == NULLLITERAL){
exp =
primarywithliteral();
return
exp;
}else{
exp =
primarywithoutliteral();
return
exp;
}
}
/**
* Rule 44: <primarywithliteral>
:= intliteral
*
| boolliteral
*
| nullliteral
*/
private Expression primarywithliteral()throws IOException{
Expression exp = null ;
if(token.kind == INTEGERLITERAL
|| token.kind == BOOLEANLITERAL || token.kind == NULLLITERAL){
if(token.kind
== INTEGERLITERAL){
exp = new IntegerLiteralExpression(new Integer(token.val).toString());
}
if(token.kind
== BOOLEANLITERAL){
exp = new BooleanLiteralExpression(token.word);
}
if(token.kind
== NULLLITERAL){
exp = new NullLiteralExpression(token.word);
}
token=jlex.getToken();
}else{
error("Not
a valid literal");
}
return exp ;
}
/**
* Rule 45: <primarywithoutliteral>
:= ( <expression> )
*
| <classinstancecreationexpression>
*
| <this-and-name>
*
| <this-and-name> ( <argumentList>
)
*
| this
*/
private Expression primarywithoutliteral()throws IOException{
Expression temp = null ;
//This piece is for the first
part of the rule.
if(token.kind == LEFTBRACES){
token=jlex.getToken();
Expression
exp1 = expression();
if(token.kind
== RIGHTBRACES){
SimplePWLExpression SPE = new SimplePWLExpression(exp1);
token=jlex.getToken();
return SPE;
}else{
error("No ')' closing braces");
}
}
//This piece is for second part
of the rule.
if(token.kind == NEW){
ClassInstanceCreationExpression
exp1 = classinstancecreationexpression();
return
exp1;
}
if(token.kind == THIS){
token=jlex.getToken();
if(token.kind
== DOT){
token=jlex.getToken();
Name nm = name();
ThisAndName tan = new ThisAndName(nm,true);
if(token.kind != LEFTBRACES){
ThisAndNameExpression exp2 = new ThisAndNameExpression(tan);
return exp2 ;
}
if(token.kind == LEFTBRACES){
token=jlex.getToken();
Expression exp3 = null ;
if(token.kind != RIGHTBRACES){
exp3 = argumentlist();
}
if(token.kind == RIGHTBRACES){
MethodCallExpression exp4 = new MethodCallExpression(tan,exp3);
token=jlex.getToken();
return exp4;//For the fourth part of the rule.
}else{
error("No ')' braces");
}
}
}else{
return new JustThis("this");//For the last part of the rule.
}
}
if(token.kind == IDENTIFIER){
ThisAndName
th = thisandname();
if(token.kind==LEFTBRACES){
token=jlex.getToken();
Expression exp = null;
if(token.kind != RIGHTBRACES)
exp = argumentlist();
if(token.kind == RIGHTBRACES){
MethodCallExpression CT = new MethodCallExpression(th,exp);
token=jlex.getToken();
return CT;
}else{
error("No ')' right braces");
}
}else{
ThisAndNameExpression STA = new ThisAndNameExpression(th);
return STA;//For the third part of the rule.
}
}
//If the token does not match
any it is automatically an error.
error("Illegal start of the code");
return temp ;
}
/**
* Rule 46: <classInstancecreationexpression>
::= new <name> ( <argumentlist> )
*/
private ClassInstanceCreationExpression classinstancecreationexpression()throws
IOException{
Name nm = null ;
Expression exp = null ;
if(token.kind == NEW){
token=jlex.getToken();
nm = name();
if(token.kind
== LEFTBRACES){
token=jlex.getToken();
if(token.kind != RIGHTBRACES){
exp = argumentlist();
}
if(token.kind == RIGHTBRACES){
token=jlex.getToken();
}else{
error("No matching ')' braces");
}
}else{
error("No starting '(' braces");
}
}else{
error("Requires
'new' keyword");
}
return new ClassInstanceCreationExpression(nm,exp);
}
/**
* Rule 47: <type>
::= <primitivetype>
*
| ( <referencetype> )
*/
private Type type()throws IOException{
Type tp = null ;
if(token.kind == INT || token.kind
== BOOLEAN || token.kind ==VOID){
tp = primitivetype();
}else{
if(token.kind
== LEFTBRACES){
token=jlex.getToken();
tp = referencetype();
if(token.kind == RIGHTBRACES){
token=jlex.getToken();
}else{
error("No matching ')' braces");
}
}else{
error("No '(' left braces");
}
}
return tp ;
}
/**
* Rule 48: <primitivetype>
::= int
*
| boolean
*
| void
*/
private PrimitiveType primitivetype()throws IOException{
PrimitiveType PT = null ;
Terminal tp = null ;
if(token.kind == INT || token.kind
== BOOLEAN || token.kind == VOID){
tp = new
Terminal(token.word);
token=jlex.getToken();
}else{
error("Illegal
start of the code");
}
PT = new PrimitiveType(tp);
return PT ;
}
/**
* Rule 49: <referencetype>
::= <name>
*/
private ReferenceType referencetype()throws IOException{
ReferenceType RT = null ;
Name nm = null ;
nm = name();
RT = new ReferenceType(nm);
return RT;
}
}