final static int TT_DDOT = 47;
final static int TT_DOTASSIGN = 48;
- final static int TT_SET = 49;
+ final static int TT_ASSIGN = 49;
final static int TT_REF = 50;
final static int TT_FOREACH = 51;
final static int TT_AMPERSAND = 52;
chIndx += 2;
break;
}
- chIndx++;
+ ch = str.charAt(chIndx++);
+ if (ch == '\n') {
+ rowCount++;
+ columnCount = chIndx;
+ }
}
continue;
}
} else if (ch == '"') {
openString = false;
break;
- } else {
- if (ch == '\n') {
- rowCount++;
- columnCount = chIndx;
- }
+ } else if (ch == '\n') {
+ rowCount++;
+ columnCount = chIndx;
}
}
if (openString) {
} else if (ch == '\'') {
openString = false;
break;
- } else {
- if (ch == '\n') {
- rowCount++;
- columnCount = chIndx;
- }
+ } else if (ch == '\n') {
+ rowCount++;
+ columnCount = chIndx;
}
}
if (openString) {
break;
case '=' :
- token = TT_SET;
+ token = TT_ASSIGN;
if (str.length() > chIndx) {
ch = str.charAt(chIndx);
this.rowCount = rowCount;
this.columnCount = 0;
getNextToken();
-
- statementList();
+ if (token != TT_EOF) {
+ statementList();
+ }
if (token != TT_EOF) {
if (token == TT_ARGCLOSE) {
throwSyntaxError("too many closing ')'; end-of-file not reached");
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- throwSyntaxError("';' character after 'include' or 'include_once' expected.");
+ if (token != TT_EOF) {
+ throwSyntaxError("';' character after 'include' or 'include_once' expected.");
+ }
}
return;
} else if (token == TT_require || token == TT_require_once) {
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- throwSyntaxError("';' character after 'require' or 'require_once' expected.");
+ if (token != TT_EOF) {
+ throwSyntaxError("';' character after 'require' or 'require_once' expected.");
+ }
}
return;
} else if (token == TT_if) {
}
whileStatement();
return;
+ } else if (token == TT_do) {
+ getNextToken();
+ if (token == TT_LISTOPEN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'{' expected after 'do' keyword.");
+ }
+ if (token != TT_LISTCLOSE) {
+ statementList();
+ }
+ if (token == TT_LISTCLOSE) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'}' expected after 'do' keyword.");
+ }
+ if (token == TT_while) {
+ getNextToken();
+ if (token == TT_ARGOPEN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'while' keyword.");
+ }
+ expression();
+ if (token == TT_ARGCLOSE) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'while' condition.");
+ }
+ } else {
+ throwSyntaxError("'while' expected after 'do' keyword.");
+ }
+ if (token == TT_SEMICOLON) {
+ getNextToken();
+ } else {
+ if (token != TT_EOF) {
+ throwSyntaxError("';' expected after do-while statement.");
+ }
+ }
+ return;
} else if (token == TT_foreach) {
getNextToken();
if (token == TT_ARGOPEN) {
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
+ if (token != TT_EOF) {
+ throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
+ }
}
return;
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- throwSyntaxError("';' expected after 'echo' statement.");
+ if (token != TT_EOF) {
+ throwSyntaxError("';' expected after 'echo' statement.");
+ }
}
return;
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- throwSyntaxError("';' expected after 'print' statement.");
+ if (token != TT_EOF) {
+ throwSyntaxError("';' expected after 'print' statement.");
+ }
}
return;
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- throwSyntaxError("';' expected after 'global' or 'static' statement.");
+ if (token != TT_EOF) {
+ throwSyntaxError("';' expected after 'global' or 'static' statement.");
+ }
}
return;
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- throwSyntaxError("';' expected after 'unset' statement.");
+ if (token != TT_EOF) {
+ throwSyntaxError("';' expected after 'unset' statement.");
+ }
}
return;
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- throwSyntaxError("';' expected after 'exit' or 'die' statement.");
+ if (token != TT_EOF) {
+ throwSyntaxError("';' expected after 'exit' or 'die' statement.");
+ }
}
return;
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- throwSyntaxError("';' expected after 'define' statement.");
+ if (token != TT_EOF) {
+ throwSyntaxError("';' expected after 'define' statement.");
+ }
}
return;
} else if (token == TT_function) {
getNextToken();
functionDefinition();
return;
+ } else if (token == TT_class) {
+ getNextToken();
+ classDeclarator();
+ classBody();
+ return;
} else {
throwSyntaxError("Unexpected keyword '" + keyword + "'");
}
} else if (token == TT_LISTOPEN) {
- // compundStatement
+ // compoundStatement
getNextToken();
if (token != TT_LISTCLOSE) {
statementList();
getNextToken();
return;
} else {
- throwSyntaxError("';' expected after expression.");
+ if (token != TT_EOF) {
+ throwSyntaxError("';' expected after expression.");
+ }
}
}
}
+ public void classDeclarator() {
+ //identifier
+ //identifier 'extends' identifier
+ if (token == TT_IDENTIFIER) {
+ getNextToken();
+ if (token == TT_extends) {
+ getNextToken();
+ if (token == TT_IDENTIFIER) {
+ getNextToken();
+ } else {
+ throwSyntaxError("Class name expected after keyword 'extends'.");
+ }
+ }
+ } else {
+ throwSyntaxError("Class name expected after keyword 'class'.");
+ }
+ }
+
+ public void classBody() {
+ //'{' [class-element-list] '}'
+ if (token == TT_LISTOPEN) {
+ getNextToken();
+ if (token != TT_LISTCLOSE) {
+ classElementList();
+ }
+ if (token == TT_LISTCLOSE) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'}' expected at end of class body.");
+ }
+ } else {
+ throwSyntaxError("'{' expected at start of class body.");
+ }
+ }
+
+ public void classElementList() {
+ do {
+ classElement();
+ } while (token != TT_function || token != TT_var);
+ }
+
+ public void classElement() {
+ //class-property
+ //function-definition
+ if (token == TT_function) {
+ getNextToken();
+ functionDefinition();
+ } else if (token == TT_var) {
+ getNextToken();
+ classProperty();
+ } else {
+ throwSyntaxError("'function' or 'var' expected.");
+ }
+ }
+
+ public void classProperty() {
+ //'var' variable ';'
+ //'var' variable '=' constant ';'
+ if (token == TT_VARIABLE) {
+ getNextToken();
+ if (token == TT_ASSIGN) {
+ getNextToken();
+ constant();
+ if (token == TT_SEMICOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("';' expected after variable declaration.");
+ }
+ } else if (token == TT_SEMICOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("';' or '=' expected after variable declaration.");
+ }
+ } else {
+ throwSyntaxError("Variable expected after keyword 'var'.");
+ }
+ }
+
public void functionDefinition() {
functionDeclarator();
compoundStatement();
//variable '=' constant
if (token == TT_VARIABLE) {
getNextToken();
- if (token == TT_SET) {
+ if (token == TT_ASSIGN) {
getNextToken();
constant();
}
String ident;
boolean castFlag = false;
switch (token) {
+ case TT_new :
+ getNextToken();
+ expression();
+ break;
+ case TT_null :
+ getNextToken();
+ break;
+ case TT_false :
+ getNextToken();
+ break;
+ case TT_true :
+ getNextToken();
+ break;
case TT_STRING_CONSTANT :
getNextToken();
break;
getNextToken();
break;
case TT_REF : // ->
+ getNextToken();
switch (token) {
case TT_VARIABLE :
+ ident = identifier;
getNextToken();
+ // if (token == TT_ARGOPEN) {
+ // getNextToken();
+ // expressionList();
+ // if (token != TT_ARGCLOSE) {
+ // throwSyntaxError(") expected after variable '" + ident + "'.");
+ // }
+ // getNextToken();
+ // }
break;
case TT_IDENTIFIER :
+ ident = identifier;
getNextToken();
+ if (token == TT_ARGOPEN) {
+ getNextToken();
+ expressionList();
+ if (token != TT_ARGCLOSE) {
+ throwSyntaxError(") expected after identifier '" + ident + "'.");
+ }
+ getNextToken();
+ }
break;
case TT_LISTOPEN :
getNextToken();
default :
throwSyntaxError("Syntax error after '->' token.");
}
+ break;
case TT_INCREMENT :
getNextToken();
break;
public void assignExpression() {
castExpression();
- if (token == TT_SET) { // =
+ if (token == TT_ASSIGN) { // =
getNextToken();
logicalinclusiveorExpression();
} else if (token == TT_DOTASSIGN) { // .=
} else if (token == TT_FOREACH) { // =>
getNextToken();
logicalinclusiveorExpression();
+ } else if (token == TT_ADDTO) { // +=
+ getNextToken();
+ logicalinclusiveorExpression();
+ } else if (token == TT_SUBTRACTFROM) { // -=
+ getNextToken();
+ logicalinclusiveorExpression();
+ } else if (token == TT_TIMESBY) { // *=
+ getNextToken();
+ logicalinclusiveorExpression();
+ } else if (token == TT_DIVIDEBY) { // *=
+ getNextToken();
+ logicalinclusiveorExpression();
}
}
public void constant() {
switch (token) {
+ case TT_null :
+ getNextToken();
+ break;
+ case TT_false :
+ getNextToken();
+ break;
+ case TT_true :
+ getNextToken();
+ break;
case TT_STRING_CONSTANT :
getNextToken();
break;