package dex.compiler.parser;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;


import dex.compiler.model.base.Place;
import dex.compiler.model.expression.Call;
import dex.compiler.model.expression.DirectCall;
import dex.compiler.model.expression.Expression;
import dex.compiler.model.expression.IdentifierExpression;
import dex.compiler.model.expression.Infix;
import dex.compiler.model.statement.Assignment;
import dex.compiler.model.statement.Block;
import dex.compiler.model.statement.CallStatement;
import dex.compiler.model.statement.CatchBlock;
import dex.compiler.model.statement.Comment;
import dex.compiler.model.statement.Declaration;
import dex.compiler.model.statement.DecrementStatement;
import dex.compiler.model.statement.ForStatement;
import dex.compiler.model.statement.IfStatement;
import dex.compiler.model.statement.IncrementStatement;
import dex.compiler.model.statement.ReturnStatement;
import dex.compiler.model.statement.Statement;
import dex.compiler.model.statement.SwitchCase;
import dex.compiler.model.statement.SwitchStatement;
import dex.compiler.model.statement.ThrowStatement;
import dex.compiler.model.statement.TryStatement;
import dex.compiler.model.statement.WhileStatement;
import dex.compiler.model.type.BasicTypeNode;
import dex.compiler.model.type.TypeNode;



/**
* A parser for statement objects.
*/
class StatementParser extends ExpressionParser {



/**
* Character sequences that indicate a type tail.
*/
final private static List <String> TYPE_TAILS = Collections.unmodifiableList(Arrays.asList(
new String[] { "[]", "<(" }
));



/**
* The keywords that begin blocks in a switch statement.
*/
final private static List<String> SWITCHES = Collections.unmodifiableList(Arrays.asList(
new String[] { "case", "default" }
));


/**
* Constructs a new StatementParser.
* /


public StatementParser(ParserConfig config) {
super(config);
}



/**
* Parses a declaration.  Expects a type followed by an identifier
* and optional initializer.
* /
public Statement parseDeclaration() {
TypeNode t = parseType();
return parseDeclaration(t);
}



/**
* Parses a declaration whose type was already parsed.
*/
public Statement parseDeclaration(TypeNode t) {
String id = parseIdentifier();
Expression initializer = null;
char ch = input.skipAndPeek();
if (ch == '=') {
input.expect('=');
initializer = parseExpression();
}
return new Declaration(input.getPlace(), t, id, initializer);
}



/**
* Parses a statement
*/
public Statement parseStatement() {


// New local scope?
if (input.skipAndPeek() == '{') {
return parseBlock();
}


if (input.skipAndPeek() == '/') {
return parseComment();
}


// Check all the control flow reserved words...


if (testKeyword("while")) {
return parseWhile();
}


if (testKeyword("for")) {
return parseFor();
}


if (testKeyword("if")) {
return parseIf();
}


if (testKeyword("switch")) {
return parseSwitch();
}


/*if (testKeyword("try")) {
return parseTry();
}*/


/*if (testKeyword("return")) {
return parseReturn();
}*/


/*if (testKeyword("void")) {
return parseVoid();
}*/


/*if (testKeyword("throw")) {
return parseThrow();
}*/


char ch = input.skipAndPeek();
if (ch == '#') {
return parseDeclaration();
}


String id = parseIdentifier();


// If [] follows the id, that indicates a dynamic array type.
// If <( follows the id, that indicates a function type.
// If a type is indicated, then this statement must be a declaration.
if (input.test(TYPE_TAILS, AnyBreaks.INSTANCE) != null) {
TypeNode t = new BasicTypeNode(input.getPlace(), false, getName(id));
return parseDeclaration(parseTypeTail(t));
}


// If ( follows the id, that indicates a function call.
if (input.skipAndPeek() == '(') {
DirectCall dc = new DirectCall(input.getPlace(), id, parseExpressionList());
return new CallStatement(input.getPlace(), dc);
}


ch = input.skipAndPeek();


// An identifier followed by another identifier is a declaration
// (identifier 1 is the type, followed by the local variable name)
if (Character.isJavaIdentifierStart(ch)) {
BasicTypeNode t = new BasicTypeNode(input.getPlace(), false, getName(id));
return parseDeclaration(t);
}


Expression lvalue;


// Not a block.
// Not a control statement.
// Not a declaration.
// It must be an assignment.
lvalue = new IdentifierExpression(input.getPlace(), id);
lvalue = parseOperandTail(lvalue);


if (lvalue instanceof Call) {
Call call = (Call)lvalue;
return new CallStatement(input.getPlace(), call);
}


// Test for special case of ++
if (input.test("++", SymbolBreaks.INSTANCE)) {
input.expect("++", SymbolBreaks.INSTANCE);
return new IncrementStatement(input.getPlace(), lvalue);
}


// Also --
if (input.test("--", SymbolBreaks.INSTANCE)) {
input.expect("--", SymbolBreaks.INSTANCE);
return new DecrementStatement(input.getPlace(), lvalue);
}


Infix assignmentOp;


ch = input.skipAndPeek();
if (ch == '=') {
assignmentOp = null; // null value represents straight assignment
} else {
String symbol = pickOperator();
if (symbol == null) {
raise("Expected assignment operator.");
}
assignmentOp = Infix.get(symbol);
}



// Otherwise, whatever operator we just parsed must be follwed
// by an = sign since it's an assignment.
// Eg, if we parsed + then we expect +=
input.expect('=');


Expression rvalue = parseExpression();


return new Assignment(input.getPlace(), assignmentOp, lvalue, rvalue);
}



/**
* Parses a return statement.
*/
public ReturnStatement parseReturn() {
input.skipAndExpect("return", WordBreaks.INSTANCE);


return new ReturnStatement(input.getPlace(), parseExpression());
}



/**
* Parses a return statement that does not return a value.
*/
public ReturnStatement parseVoid() {
Place place = input.getPlace();
input.skipAndExpect("void", WordBreaks.INSTANCE);
return new ReturnStatement(place, null);
}



/**
* Parses a throw statement
*
*/
/*public ThrowStatement parseThrow() {
input.skipAndExpect("throw", WordBreaks.INSTANCE);
return new ThrowStatement(input.getPlace(), parseExpression());
}*/



/**
* Parses a block of statements.
*/
public Block parseBlock() {
input.skipAndExpect('{');
List<Statement> statements = new ArrayList<Statement>();
char ch = input.skipAndPeek();
while ((ch != 0) && (ch != '}')) {
statements.add(parseStatement());
ch = input.skipAndPeek();
}
input.expect('}');
return new Block(input.getPlace(), statements);
}



/**
* Parses a while statement.
*/
public WhileStatement parseWhile() {
input.skipAndExpect("while", WordBreaks.INSTANCE);
Expression test = parseExpression();
Statement body = parseStatement();
return new WhileStatement(input.getPlace(), test, body);
}



/**
* Parses a for statement.
*/
public ForStatement parseFor() {
input.skipAndExpect("for", WordBreaks.INSTANCE);
Statement initializer = parseStatement();
input.skipAndExpect(';');
Expression test = parseExpression();
input.skipAndExpect(';');
Statement modifier = parseStatement();
Statement body = parseStatement();
return new ForStatement(input.getPlace(), initializer, test, modifier, body);
}



/**
* Parses an if statement.
*/
public IfStatement parseIf() {
input.skipAndExpect("if", WordBreaks.INSTANCE);
Expression test = parseExpression();
Statement positive = parseStatement();
Statement negative;
if (testKeyword("else")) {
input.expect("else", WordBreaks.INSTANCE);
negative = parseStatement();
} else {
negative = null;
}
return new IfStatement(input.getPlace(), test, positive, negative);
}



/**
* Parses a switch statement.
*/
public SwitchStatement parseSwitch() {
input.skipAndExpect("switch", WordBreaks.INSTANCE);
Expression test = parseExpression();
List<SwitchCase> cases = new ArrayList<SwitchCase>();
Statement defaultStatement = null;
input.skipAndExpect('{');
while (input.skipAndTest(SWITCHES, WordBreaks.INSTANCE) != null) {
if (testKeyword("case")) {
cases.add(parseCase());
} else {
// must be default keyword
input.expect("default", WordBreaks.INSTANCE);
if (defaultStatement != null) {
raise("More than one default for switch.");
}
defaultStatement = parseStatement();
}
}
input.skipAndExpect('}');
return new SwitchStatement(input.getPlace(), test, cases, defaultStatement);
}



/**
* Parses a case of a switch statement.
*/
public SwitchCase parseCase() {
input.skipAndExpect("case", WordBreaks.INSTANCE);
List<Expression> tests = new ArrayList<Expression>();
tests.add(parseExpression());
char ch = input.skipAndPeek();
while (ch == ',') {
input.expect(',');
tests.add(parseExpression());
ch = input.skipAndPeek();
}
Statement body = parseStatement();
return new SwitchCase(input.getPlace(), tests, body);
}



/**
* Parses a try/catch/finally statement.
*/
/*public TryStatement parseTry() {
input.skipAndExpect("try", WordBreaks.INSTANCE);
Block trySection = parseBlock();
List<CatchBlock> catchSection = new ArrayList<CatchBlock()>();
Block finallySection = null;
while (testKeyword("catch")) {
input.expect("catch", WordBreaks.INSTANCE);
TypeNode type = parseType();
String id = parseIdentifier();
Block block = parseBlock();
catchSection.add(new CatchBlock(input.getPlace(), type, id, block));
}
if (testKeyword("finally")) {
input.expect("finally", WordBreaks.INSTANCE);
finallySection = parseBlock();
}
return new TryStatement(input.getPlace(), trySection, catchSection, finallySection);
}*/



/**
* Parses a comment.
*/
/*  public Comment parseComment() {
char ch = input.skipAndPeek();
if (ch != '/') {
raise("Expected comment.");
}
input.expect('/');
ch = input.peek();
String message;
if (ch == '*') {
input.expect('*');
message = input.readUntil("*/");
} else if (ch == '/') {
input.expect('/');
message = input.readUntil("\n");
} else {
raise("Expected comment.");
throw new AssertionError();
}
return new Comment(input.getPlace(), message);
}


}*/

when i compile this code, i get the following error
how i can solve them


C:\Program Files\Xinox Software\JCreator Pro\MyProjects\try\try1.java:44: <identifier> expected
final private static List <String> TYPE_TAILS = Collections.unmodifiableList(Arrays.asList(
^
C:\Program Files\Xinox Software\JCreator Pro\MyProjects\try\try1.java:52: <identifier> expected
final private static List<String> SWITCHES = Collections.unmodifiableList(Arrays.asList(
^
C:\Program Files\Xinox Software\JCreator Pro\MyProjects\try\try1.java:258: '(' or '[' expected
List<Statement> statements = new ArrayList<Statement>();
^
C:\Program Files\Xinox Software\JCreator Pro\MyProjects\try\try1.java:319: '(' or '[' expected
List<SwitchCase> cases = new ArrayList<SwitchCase>();
^
C:\Program Files\Xinox Software\JCreator Pro\MyProjects\try\try1.java:344: '(' or '[' expected
List<Expression> tests = new ArrayList<Expression>();
^
C:\Program Files\Xinox Software\JCreator Pro\MyProjects\try\try1.java:393: unclosed string literal
message = input.readUntil("*/");
^
C:\Program Files\Xinox Software\JCreator Pro\MyProjects\try\try1.java:394: <identifier> expected
} else if (ch == '/') {
^
C:\Program Files\Xinox Software\JCreator Pro\MyProjects\try\try1.java:394: 'class' or 'interface' expected
} else if (ch == '/') {
^
C:\Program Files\Xinox Software\JCreator Pro\MyProjects\try\try1.java:402: 'class' or 'interface' expected
}
^
C:\Program Files\Xinox Software\JCreator Pro\MyProjects\try\try1.java:405: 'class' or 'interface' expected
^
10 errors


Process completed.

Edited 3 Years Ago by happygeek: fixed formatting

Comments
You've been asked to use code tags many times. Also, asking others to debug code you didn't write is poor form.

Are you using JDK 1.5 or later? I'm thinking it's failing to parse the generics.

(I'm also thinking you didn't write the code either)

Are you using JDK 1.5 or later? I'm thinking it's failing to parse the generics.

(I'm also thinking you didn't write the code either)

i am use j
j2sdk1.4.2_16

well about time to load up something more up to date maybe jdk1.5.0_14 or the latest jdk1.6.0_03
Also in the future please wrap your code inside tags [ code] [ /code] or simply click on the hash sign "#" in post toolbar to get them.

This article has been dead for over six months. Start a new discussion instead.