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

📄 javasourcegenerator.java

📁 java实现的一个pascal编译器
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
package uk.co.brainycreatures.jpascal.code;

import uk.co.brainycreatures.jpascal.analysis.*;
import uk.co.brainycreatures.jpascal.node.*;

import java.util.*;
import java.io.*;

public class JavaSourceGenerator extends DepthFirstAdapter {
  /**
   * used by previous_entity
   */
  private final short PROGRAM = 0;

  private final short MONITOR = 1;

  /**
   * name of main class
   */
  private String class_name;

  /**
   * set to true when an expression is being assigned to a function;
   */
  private boolean function_assign = false;

  /**
   * true if writeln or write statement
   */
  private boolean write_stmt = false;

  /**
   * value of constant assigned to a new constant being defined
   */
  private String const_value;

  /**
   * name of the source file
   */
  private String source_name;

  /**
   * stores the monitors procedures
   */
  private Hashtable monitor_procs = new Hashtable();

  /**
   * stores information about the identifiers of a program
   */
  private Hashtable global_table = new Hashtable();

  /**
   * stores information about the identifiers of a monitor
   */
  private Hashtable monitor_table = new Hashtable();

  /**
   * stores information about the identifiers of a procedure,
   * function or process.
   */
  private Hashtable local_table = new Hashtable();

  /**
   * index of an array
   */
  private String index;

  /**
   * true if a send statement is present
   */
  private boolean send_stmt;

  /**
   * used to generate the output file
   */
  private PrintWriter out;

  /**
   * program or monitor
   */
  private short previous_entity;

  /**
   * set to true if the declarations or statements are 
   * inside the main program block. Initially it is true, because
   * the first declarations belong to a program
   */
  private boolean program = true; 

  /**
   * size of a string
   */
  private String string_size;

  /**
   * value to be sent to a channel
   */
   private String value;

  /**
   * set to true if the declarations or statements are 
   * being processed in a monitor block
   */
  private boolean monitor = false;

  /**
   * set to true if the declarations are in a process
   */
  private boolean process = false;

  /**
   * list of identifiers
   */
  private Vector idlist = new Vector();

  /**
   * holds the name of the current monitor
   */
  private String monitor_name;

  /**
   * set to true if a private procedure
   */
  private boolean private_proc = false;

  /**
   * set to true if a monitor call statement is being processed
   */
  private boolean monitor_call = false;

  /**
   * type of variable, function or constant
   */
   private String type;

  /**
   * Default constructor
   */
  public JavaSourceGenerator(String source) {
    source_name = source;
    class_name = source.substring(0, source.length() - 4);
    try {
      out = new PrintWriter(new BufferedWriter(
                               new FileWriter(class_name + ".java")));
    }
    catch (Exception e) {
      System.out.println(e);
    }
    out.println("// file generated from " + source_name);
    out.println("// by JPascal's compiler ");
    out.println("// author: Fidel Viegas (viegasfh@hotmail.com)");
    out.println();
    out.println("public class " + class_name + " {");
  }

  /**
   * main_body =
   *  begin
   *    main_statement_part
   *  end;
   */
  public void inAMainBody(AMainBody node) {
    out.println("  public static void main(String[] args) {");
  }

  public void outAMainBody(AMainBody node) {
    out.println("  }");
    out.print("}");
  }

  // declarations

  /**
   * private_mod =
   * {non_empty} private |
   * generates the private modifier of a monitor procedure
   */
  public void outANonEmptyPrivateMod(ANonEmptyPrivateMod node) {
    out.print("    private ");
    private_proc = true;
  }

  /**
   * const_declaration =
   * identifier equal constant semicolon ;
   */
  public void outAConstDeclaration(AConstDeclaration node) {
    String const_name = node.getIdentifier().getText();
    if (program) {
      out.println("  static final " + type + " " + const_name + " = " + const_value + ";");
      global_table.put(const_name.toUpperCase(),
		new Constant(const_name, type));
    }
    else if (monitor) {
      out.println("    final " + type + " " + const_name + " = " + const_value + ";");
      monitor_table.put(const_name.toUpperCase(),
                        new Constant(const_name, type));
    }
    else {
      out.println("    final " + type + " " + const_name + " = " + const_value + ";");
      local_table.put(const_name.toUpperCase(),
                      new Constant(const_name, type));
    }
  }

  /**
   * constant =
   *  {identifier} identifier |
   * puts an identifier in the identifiers list of 
   * a variables declaration
   */
  public void outAIdentifierConstant(AIdentifierConstant node) {
    String key = node.getIdentifier().getText().toUpperCase();
    Object entity;

    // if this is a program
    if (program) {
      // get the attributes from the global table
      entity =  global_table.get(key);	
    }
    else if (monitor) { // else if this is a monitor
      // get the attributes from the monitor table
      entity = monitor_table.get(key);
    }
    else { // else if process, function or procedure
        // get the attributes from the local table
        entity = local_table.get(key);
    }
    if (entity instanceof Constant) {
      const_value = ((Constant)entity).getImage();
      type = ((Constant)entity).getType();
    }
    else { // for channel variable
      const_value = ((Variable) entity).getImage();
    }
  }

  /**
   * {signedidentifier} sign identifier |
   */
  public void outASignedidentifierConstant(ASignedidentifierConstant node) {
    String key = node.getIdentifier().getText().toUpperCase();
    Constant constant; 
    if (program) { // oh! this is a program.
      // then get the constant's attributes from the global table
      constant = (Constant) global_table.get(key); 
    }
    else if (monitor) { // alright! this is a monitor declaration
      // then check if the identifier is in the monitor table
      if (monitor_table.containsKey(key)) {
        constant = (Constant) monitor_table.get(key);
      }
      else { // Oh! it is in the globals declaration part
        constant = (Constant) global_table.get(key);
      }
    }
    else { // alright! this is either a procedure, process or 
      // function.
      // then check the locals table
      if (local_table.containsKey(key)) {
        constant = (Constant) local_table.get(key);
      }
      else { // oh! I see, it is in the global table
        constant = (Constant) global_table.get(key);
      }
    } 
    const_value = constant.getImage();
    type = constant.getType();
  }

  /**
   * {signedinteger} sign integer_literal |
   */
  public void outASignedintegerConstant(ASignedintegerConstant node) {
      type = "int";
      if (node.getSign() instanceof APlusSign) {
        const_value = "+" + node.getIntegerLiteral().getText();
      }
      else {
        const_value = "-" + node.getIntegerLiteral().getText();
      }
  }

  /**
   * {unsignedinteger} integer_literal |
   */
  public void outAUnsignedintegerConstant(AUnsignedintegerConstant node) {
      type = "int";
      const_value = node.getIntegerLiteral().getText();
  }

  /**
   * {signedreal} sign real_literal |
   */
  public void outASignedrealConstant(ASignedrealConstant node) {
      type = "double";
      if (node.getSign() instanceof APlusSign) {
        const_value = "+" + node.getRealLiteral().getText();
      }
      else {
        const_value = "-" + node.getRealLiteral().getText();
      }
  }

  /**
   * {unsignedreal} real_literal |
   */
  public void outAUnsignedrealConstant(AUnsignedrealConstant node) {
      type = "double";
      const_value = node.getRealLiteral().getText();
  }

  /**
   * {string} character_literal ;
   */
  public void outAStringConstant(AStringConstant node) {
      String char_lit = node.getCharacterLiteral().getText();
      if (node.getCharacterLiteral().getText().length() <= 3) {
        type = "char";
        const_value = "\"" + char_lit.substring(1, char_lit.length() - 1) + "\"";
      }
      else {
        type = "java.lang.String";
        const_value = "\"" + char_lit.substring(1, char_lit.length() - 1) +
          "\"";
      }
  }

  /**
   * var_declaration =
   *   var var_decl+ ;
   */
  public void inAVarDecl(AVarDecl node) {
    if (!idlist.isEmpty()) {
      idlist.removeAllElements();
    }
  }

  /**
   * var_decl =
   *   identifier_list colon P.type semicolon ;
   */
  public void outAVarDecl(AVarDecl node) {
    String var_name;
    for(Enumeration e = idlist.elements(); e.hasMoreElements();) {
      var_name = (String) e.nextElement();
      if (program) { // is this a program?
        global_table.put(var_name.toUpperCase(),
                        new Variable(var_name, type));
   
        // then indent once
        if (type.substring(type.length() - 2, type.length()).equals("[]")) {
          out.println("  static " + type + " " + var_name + " = new " +
            type.substring(0, type.length() -2) + "[" + index + "];");
        }
        else if (type.equals("exception")) {
          out.println("  static class " + var_name + " extends " +
            "java.lang.Exception {");
          out.println("  }");
        }
        else if (type.equals("uk.edu.sbu.seeie.jpascal.type.ChannelOfInteger")
              || type.equals("uk.edu.sbu.seeie.jpascal.type.ChannelOfReal")
              || type.equals("uk.edu.sbu.seeie.jpascal.type.ChannelOfChar")
              || type.equals("uk.edu.sbu.seeie.jpascal.type.ChannelOfBoolean")
              || type.equals("uk.edu.sbu.seeie.jpascal.type.ChannelOfString")) {
          out.println("  static " + type + " " + var_name + " = " +
              "new " + type + "();");
        }
        else if (type.equals("uk.edu.sbu.seeie.jpascal.type.Semaphore")) {
          out.println("  static " + type + " " + var_name + " = " +
             "new " + type + "(" + index + ");");
        }
        else {
          out.println("  static " + type + " " + var_name + ";");
        }
      }
      else { // No! this is a monitor, process, program, function or 
             // procedure
        if (type.substring(type.length() - 2, type.length()).equals("[]")) {
          out.println("    " + type + " " + var_name + " = new " +
             type.substring(0, type.length() - 2) + "[" + index + "];");
        }
        else if (type.equals("uk.edu.sbu.seeie.jpascal.type.Condition")) {
          out.println("    " + type + " " + var_name + " = " +
             "new " + type + "();");
        }
        else {
          out.println("    " + type + " " + var_name + ";");
        }
        // is this a monitor?
        // then put the identifier on the monitor table
        if (monitor) {
          monitor_table.put(var_name.toUpperCase(),
                          new Variable(var_name, type));
        }
        else { // oops! put it in the local table
          local_table.put(var_name.toUpperCase(), 
                        new Variable(var_name, type));
        }
      }
    }
  }

  /**
   * identifier_list =
   *   {single} identifier |
   */
  public void outASingleIdentifierList(ASingleIdentifierList node) {
      String name = node.getIdentifier().getText();
      idlist.addElement(name);
  }

  /**
   * {sequence} identifier_list comma identifier ;
   */
  public void outASequenceIdentifierList(ASequenceIdentifierList node) {
      String name = node.getIdentifier().getText();
      idlist.addElement(name);
  }

  /**
   * procedure_heading =
   *  {simple} procedure identifier semicolon |
   * generate the procedure heading
   */
  public void inASimpleProcedureHeading(ASimpleProcedureHeading node) {
    String name = node.getIdentifier().getText();
    // is this a program?
    // then store it in the global table
    if (program) {
      global_table.put(name.toUpperCase(), new Procedure(name));
      out.println("  static void " + node.getIdentifier().getText() + "() {");
      previous_entity = PROGRAM;
      program = false;
    }
    else if (monitor) { // this must be a monitor
      if (private_proc) {
        out.println("void " + node.getIdentifier().getText() + "() {");
	private_proc = false;
      }
      else {
        out.println("    public synchronized void " + node.getIdentifier().getText() + "() {");
      }
      monitor_table.put(name.toUpperCase(), new Procedure(name));
      monitor_procs.put(name.toUpperCase(), new Procedure(name));
      previous_entity = MONITOR;
      monitor = false;
    }
  }

  /**
   * {simple_throws} procedure identifier [s1]:semicolon throws
   *     identifier_list semicolon;
   */
  public void inASimpleThrowsProcedureHeading(ASimpleThrowsProcedureHeading node) {
    String name = node.getIdentifier().getText();
    // is this a program?
    // then store it in the global table
    if (program) {
      global_table.put(name.toUpperCase(), new Procedure(name));
      out.print("  static void " + node.getIdentifier().getText());
      previous_entity = PROGRAM;
      program = false;
    }
    else if (monitor) { // this must be a monitor
      if (private_proc) {
	private_proc = false;
      }
      else {
        out.print("    public synchronized void" + node.getIdentifier().getText());
      }
      monitor_table.put(name.toUpperCase(), new Procedure(name));
      monitor_procs.put(name.toUpperCase(), new Procedure(name));
      previous_entity = MONITOR;
      monitor = false;
    }
    if (!idlist.isEmpty()) {
      idlist.removeAllElements();
    }
  }

  /**
   * generates the throws part
   */
  public void outASimpleThrowsProcedureHeading(ASimpleThrowsProcedureHeading node) {
    out.print("() throws ");
    Enumeration e = idlist.elements();
    String key = ((String) e.nextElement()).toUpperCase();
    String id = ((Variable) global_table.get(key)).getImage();
    out.print(id);
    for (; e.hasMoreElements();) {
      key = ((String) e.nextElement()).toUpperCase();
      id = ((Variable) global_table.get(key)).getImage();
      out.print(", " + id);
    }
    out.println(" {");
  }

  /**
   * This method generates the heading for a procedure with arguments
   */
  public void inAArgumentsProcedureHeading(AArgumentsProcedureHeading node) {
    String name = node.getIdentifier().getText();
     // is this a program?
     if (program) {
       out.print("  static void " + name + "(");
       global_table.put(name.toUpperCase(), new Procedure(name));
       previous_entity = PROGRAM;
       program = false;
     }
     else { // indent twice
       out.print("    public synchronized void " + name + "(");
       monitor_table.put(name.toUpperCase(), new Procedure(name));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -