📄 parser.java
字号:
// Recursive Descent
package syntax;
/**
* The Parser for JSub. To organize the Syntax tree
*/
public class Parser {
private int sy; // current Token for Analysis
// Errorhandling
void error (String text) {
util.Error.e1 (text + " line " + scanner.getyylineno() + " sy '" + CKeyWords.getText (sy) + "'");
}
void error (String text, int expectedSymbol){
util.Error.e1 (text + " '" +
CKeyWords.getText(expectedSymbol) + "' sy was: '" +
CKeyWords.getText (sy) + "' line " + scanner.getyylineno ());
}
private syntax.Scanner scanner; // Scanner
/**
*The SymbolTable
*
*/
private ast.SymbolTable symboltable;
/**
* The Stack for contain Syntax tree
*
*/
private java.util.Stack stack; // Stack for nodes
public void dump () {
symboltable.dump ();
for (int i = stack.size()-1; i >= 0; i--) {
ast.IJSubNode n = (ast.IJSubNode)stack.elementAt(i);
n.dump ("");
}
}
public void codegen () {
codegen.WriteCode.genHeader (nameOfClass);
symboltable.codegen ();
codegen.WriteCode.genDefaultConstructor ();
}
public void genXML (java.io.PrintStream p) {
this.symboltable.genXML (p);
}
public Parser (String name) {
scanner = new syntax.Scanner ();
symboltable = new ast.SymbolTable ();
stack = new java.util.Stack ();
scanner.open (name);
sy = scanner.yylex ();
}
// Test scan
private void ts (int expectedSymbol) {
util.Trace.symbol (sy);
if (sy == expectedSymbol)
sy = scanner.yylex ();
else
error ("Symbol expected", expectedSymbol);
}
// Data Flow inherited attributes
// store in global Variable
// Modifier
private String nameOfClass = null;
private boolean isStatic = false, isPublic = false;
// Type
private int syType = ast.declaration.JSubObject.TVOID;
// Identifier
private String syIdentifier = null;
private static final int localDeclaration = 0, staticDeclaration = 1;
private ast.declaration.StaticMethod currentMethod = null;
// Method Parsers
public void parseClass() {
util.Trace.begin ("Class");
ts (CKeyWords.SY_PUBLIC); // public
ts (CKeyWords.SY_CLASS); // class
codegen.WriteCode.setClassName (nameOfClass = scanner.getText ());
symboltable.setName (nameOfClass);
ts (CKeyWords.SY_IDENTIFIER); // Identifier
ts (CKeyWords.SY_LB1); // {
while ( sy == CKeyWords.SY_PUBLIC /* public */
|| sy == CKeyWords.SY_STATIC /* static */
|| sy == CKeyWords.SY_INT /* int */
|| sy == CKeyWords.SY_VOID) /* void */ {
parseDeclaration (null);
}
ts (CKeyWords.SY_RB1); // }
util.Trace.end ("Class");
} // end of parseClass
void parseDeclaration(ast.IJSubNode node) {
util.Trace.begin ("Declaration");
while ( sy == CKeyWords.SY_PUBLIC /* public */
|| sy == CKeyWords.SY_STATIC /* static */) {
parseModifier ();
}
parseType ();
util.Trace.decl (scanner.getText ()); // Trace
syIdentifier = scanner.getText ();
ts (CKeyWords.SY_IDENTIFIER); // Identifier
switch (sy) {
case CKeyWords.SY_SEMICOLON : // parseAttributeDecl
case CKeyWords.SY_COMMA : // parseAttributeDecl
case CKeyWords.SY_ASS : // parseAttributeDecl
//AttributeDecl
parseAttributeDecl (node);
break;
case CKeyWords.SY_LB2 : // parseMethodDecl
parseMethodDecl ();
break;
default : error ("Unexpected Token");
}
util.Trace.end ("Declaration");
} // end of parseDeclaration
void parseModifier() {
util.Trace.begin ("Modifier");
isStatic = isPublic = false;
switch (sy) {
case CKeyWords.SY_STATIC : // static
isStatic = true;
ts (CKeyWords.SY_STATIC); // static
break;
case CKeyWords.SY_PUBLIC : // public
isPublic = true;
ts (CKeyWords.SY_PUBLIC); // public
break;
default : error ("Unexpected Token");
}
util.Trace.end ("Modifier");
} // end of parseModifier
void parseAttributeDecl(ast.IJSubNode node) {
util.Trace.begin ("AttributeDecl");
ast.declaration.JSubObject decl = null;
symboltable.addObject (decl = new ast.declaration.StaticVariable (syIdentifier, isPublic));
if (sy == CKeyWords.SY_ASS /* = */) {
parseInitializer (node, decl);
}
parseAttributeDeclList (node, staticDeclaration);
ts (CKeyWords.SY_SEMICOLON); // ;
util.Trace.end ("AttributeDecl");
} // end of parseAttributeDecl
void parseAttributeDeclList(ast.IJSubNode node, int context) {
util.Trace.begin ("AttributeDeclList");
ast.declaration.JSubObject decl = null;
while (sy == CKeyWords.SY_COMMA /* , */) {
ts (CKeyWords.SY_COMMA); // ,
util.Trace.decl (scanner.getText ()); // Trace
if (context == staticDeclaration)
symboltable.addObject (decl = new ast.declaration.StaticVariable (scanner.getText (), isPublic));
else
symboltable.addObject (decl = new ast.declaration.LocalVariable (scanner.getText (), false));
ts (CKeyWords.SY_IDENTIFIER); // Identifier
if (sy == CKeyWords.SY_ASS /* = */) {
parseInitializer (node, decl);
}
}
util.Trace.end ("AttributeDeclList");
} // end of parseAttributeDeclList
void parseInitializer(ast.IJSubNode node, ast.declaration.JSubObject decl) {
util.Trace.begin ("Initializer");
ts (CKeyWords.SY_ASS); // =
parseExpr ();
ast.IJSubNode newnode = new ast.binaryExpr.AssNode (new ast.Leaf (decl));
newnode.addChild ((ast.IJSubNode)stack.pop());
// static initialize
if (node != null)
node.addChild (newnode);
util.Trace.end ("Initializer");
} // end of parseInitializer
void parseMethodDecl() {
util.Trace.begin ("MethodDecl");
ast.declaration.StaticMethod method = (currentMethod = new ast.declaration.StaticMethod (syIdentifier, isPublic, syType));
symboltable.addObject (method);
ast.NameSpace newNameSpace = symboltable.push ();
method.setNameSpace (newNameSpace);
ast.declaration.LocalVariable.reset ();
ts (CKeyWords.SY_LB2); // (
if ( sy == CKeyWords.SY_IDENTIFIER /* Identifier */
|| sy == CKeyWords.SY_INT /* int */) {
parseParameterList ();
}
ts (CKeyWords.SY_RB2); // )
parseBlockStatement ();
symboltable.pop ();
method.setStatements ((ast.IJSubNode)stack.pop());
util.Trace.end ("MethodDecl");
} // end of parseMethodDecl
void parseBlockStatement() {
util.Trace.begin ("BlockStatement");
ast.statement.BlockNode node = new ast.statement.BlockNode ();
ts (CKeyWords.SY_LB1); // {
while ( sy == CKeyWords.SY_INT /* int */
|| sy == CKeyWords.SY_IDENTIFIER /* Identifier */
|| sy == CKeyWords.SY_LB1 /* { */
|| sy == CKeyWords.SY_SEMICOLON /* ; */
|| sy == CKeyWords.SY_LB2 /* ( */
|| sy == CKeyWords.SY_IF /* if */
|| sy == CKeyWords.SY_WHILE /* while */
|| sy == CKeyWords.SY_RETURN /* return */
|| sy == CKeyWords.SY_MINUS /* - */
|| sy == CKeyWords.SY_BOOL_NOT /* ! */
|| sy == CKeyWords.SY_NUMBERLITERAL /* Literal */) {
switch (sy) {
case CKeyWords.SY_INT : // parseVariableDecl
parseVariableDecl (node);
break;
case CKeyWords.SY_IDENTIFIER : // parseStatement
case CKeyWords.SY_LB1 : // parseStatement
case CKeyWords.SY_SEMICOLON : // parseStatement
case CKeyWords.SY_LB2 : // parseStatement
case CKeyWords.SY_IF : // parseStatement
case CKeyWords.SY_WHILE : // parseStatement
case CKeyWords.SY_RETURN : // parseStatement
case CKeyWords.SY_MINUS : // parseStatement
case CKeyWords.SY_BOOL_NOT : // parseStatement
case CKeyWords.SY_NUMBERLITERAL : // parseStatement
parseStatement ();
node.addChild ((ast.IJSubNode)stack.pop());
break;
default : error ("Unexpected Token");
}
}
stack.push (node);
ts (CKeyWords.SY_RB1); // }
util.Trace.end ("BlockStatement");
} // end of parseBlockStatement
void parseParameterList() {
util.Trace.begin ("ParameterList");
parseParameter ();
while ( sy == CKeyWords.SY_COMMA /* , */) {
ts (CKeyWords.SY_COMMA); // ,
parseParameter ();
}
util.Trace.end ("ParameterList");
} // end of parseParameterList
void parseParameter() {
util.Trace.begin ("Parameter");
switch (sy) {
case CKeyWords.SY_INT : // int
ts (CKeyWords.SY_INT); // int
symboltable.addObject (new ast.declaration.LocalVariable (scanner.getText (), true));
ts (CKeyWords.SY_IDENTIFIER); // Identifier
break;
case CKeyWords.SY_IDENTIFIER : // Identifier
ts (CKeyWords.SY_IDENTIFIER); // Identifier
ts (CKeyWords.SY_IDENTIFIER); // Identifier
ts (CKeyWords.SY_LB3); // [
ts (CKeyWords.SY_RB3); // ]
break;
default : error ("Unexpected Token");
}
util.Trace.end ("Parameter");
} // end of parseParameter
void parseVariableDecl(ast.IJSubNode node) {
util.Trace.begin ("VariableDecl");
ast.declaration.BaliObject decl = null;
ts (CKeyWords.SY_INT); // int
symboltable.addObject (decl = new ast.declaration.LocalVariable (scanner.getText (), false));
ts (CKeyWords.SY_IDENTIFIER); // Identifier
if ( sy == CKeyWords.SY_ASS /* = */) {
parseInitializer (node, decl);
}
parseAttributeDeclList (node, localDeclaration);
ts (CKeyWords.SY_SEMICOLON); // ;
util.Trace.end ("VariableDecl");
} // end of parseVariableDecl
void parseStatement() {
util.Trace.begin ("Statement");
switch (sy) {
case CKeyWords.SY_LB1 : // parseBlockStatement
parseBlockStatement ();
break;
case CKeyWords.SY_IF : // parseifStatement
parseifStatement ();
break;
case CKeyWords.SY_WHILE : // parsewhileStatement
parsewhileStatement ();
break;
case CKeyWords.SY_RETURN : // parsereturnStatement
parsereturnStatement ();
break;
case CKeyWords.SY_SEMICOLON : // parsenothingStatement
parsenothingStatement ();
break;
case CKeyWords.SY_IDENTIFIER : // parseExpr
case CKeyWords.SY_LB2 : // parseExpr
case CKeyWords.SY_MINUS : // parseExpr
case CKeyWords.SY_BOOL_NOT : // parseExpr
case CKeyWords.SY_NUMBERLITERAL : // parseExpr
parseExpr ();
stack.push (new ast.statement.ExprNode ((ast.JSubNode)stack.pop()));
ts (CKeyWords.SY_SEMICOLON); // ;
break;
default : error ("Unexpected Token");
}
util.Trace.end ("Statement");
} // end of parseStatement
void parseifStatement() {
util.Trace.begin ("ifStatement");
ast.IJSubNode expr = null;
ast.statement.IfNode ifstat = null;
ast.IJSubNode tstat = null;
ast.IJSubNode fstat = null;
ts (CKeyWords.SY_IF); // if
ts (CKeyWords.SY_LB2); // (
parseExpr ();
expr = (ast.IJSubNode)stack.pop ();
if (! (expr instanceof ast.booleanExpr.JSubBooleanNode))
util.Error.e1 ("Boolean expression of if expected");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -