⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.java

📁 一个JAVA编写的简单编译器
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// 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 + -