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

📄 typechecker.java

📁 java实现的一个pascal编译器
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/**
 * File : TypeChecker.java
 * Description : This class is used in the semantic analysis phase
 * of the compiler for JPascal. It certifies that the operators are
 * applied to the correct type, that the variables are of the same
 * type, and it also checks if the literals are not out of range.
 */
package uk.co.brainycreatures.jpascal.semantic;

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

public class TypeChecker extends DepthFirstAdapter implements Types {
  /**
   * used by previous_entity.
   */
  private final short PROGRAM = 0;
  
  /**
   * same as above.
   */
  private final short MONITOR = 1;

  /**
   * used to distinguish between a program's procedure and a 
   * monitor's procedure.
   */
  private short previous_entity = PROGRAM;

  /**
   * true when a procedure call.
   */
  private boolean procedure_call = false;

  /**
   * used to hold the type of a variable(s) or the type of
   * returned by a function
   */
  private Type type;

  /**
   * true when a channel operation is requested.
   */
  private boolean channel_operations = false;

  /**
   * stores all the procedures and functions that raise
   * exceptions.
   */
  private Hashtable throws_table = new Hashtable();

  /**
   * used when a try statement is accessed
   */
  private boolean try_statement = false;

  /**
   * true when the declarations or statements are
   * in a program
   */
  private boolean program = true; 

  /**
   * true when the declarations are local to a monitor
   */
  private boolean monitor = false;

  /**
   * used when statements meant to be used inside
   * a process are present
   */
  private boolean process = false;

  /**
   * true when a function
   */
  private boolean function = false;

  /**
   * true when a monitor call is processed.
   */
  private boolean monitor_call = false;

  /**
   * name of the current function
   */
  private String current_function;

  /**
   * used to hold the identifiers of a global 
   * declaration part
   */
  private Hashtable global_table = new Hashtable();

  /**
   * Used to hold identifiers local to a 
   * monitor
   */
  private Hashtable monitor_table = new Hashtable();

  /**
   * stores the list of identifiers in a procedure or
   * function throws heading.
   */
  private Hashtable throws_list = new Hashtable();

  /**
   * used to hold identifiers local to a procedure
   * function or process.
   */
  private Hashtable local_table = new Hashtable();

  /**
   * used to hold the type of each argument and the 
   * number of arguments expected (size of vector)
   */
   private Vector arguments = new Vector();

  /**
   * stores identifiers found in a variables
   * declaration part and functions or procedures
   * parameters.
   */
  private Vector idlist = new Vector();

  /** 
   * stores the type of each expression passed as an argument
   * to a function or procedure.
   */
  private Vector exp_list = new Vector();

  /**
   * true if the procedure local to a monitor is
   * private
   */
  private boolean private_modifier = false;

  /**
   * reports error messages
   */
  ErrorMessage err = new ErrorMessage();

  /**
   * private_mod =
   *   {non_empty} private |
   *   {empty} ;
   *
   * if the private keyword is present, then alternative
   * {non_empty} will set private_modifier to true
   */
  public void outANonEmptyPrivateMod(ANonEmptyPrivateMod node) {
    private_modifier = true;
  }

  /**
   * const_declaration =
   *   identifier equal constant semicolon
   * puts the identifier in the corresponding symbol table
   */
  public void outAConstDeclaration(AConstDeclaration node) {
    TIdentifier ident = node.getIdentifier();
    String key = ident.getText().toUpperCase();

    // is this a program
    if (program) { // put it in the global table
      global_table.put(key, new Constant(type));
    }
    else if (monitor) { //oh! this is a monitor
      // put it in the monitor table
      monitor_table.put(key, new Constant(type));
    } 
    else { // it must be a process, function or procedure
      // put it in the local table
      local_table.put(key, new Constant(type));
    }
  }

  /**
   * constant =
   *   {identifier} identifier |
   *
   * sets type to constant's type and checks if it is 
   * a constant in a process, monitor, function or procedure
   * declaration section
   */
  public void outAIdentifierConstant(AIdentifierConstant node) {
    TIdentifier ident = node.getIdentifier();
    String key = ident.getText().toUpperCase();
    Object entity = null;

    if (program) {
      entity = global_table.get(key);
      if ((entity instanceof Variable) && channel_operations) {
        type = ((Variable) entity).getType();
      }
      else {
        type = ((Constant) entity).getType();
      } 
    }
    else if (monitor) {
      if (monitor_table.containsKey(key)) {
        entity = monitor_table.get(key);
        if ((entity instanceof Variable) && channel_operations) {
          type = ((Variable) entity).getType();
        }
        else {
          type = ((Constant) entity).getType();
        }
      }
      else {
        entity = global_table.get(key);
        if ((entity instanceof Variable) && channel_operations) {
          type = ((Variable) entity).getType();
        }
        else if (entity instanceof Constant) {
          type = ((Constant) entity).getType();
        }
        else {
          err.report(3, ident.getLine(), ident.getPos());
        }
      }
    }
    else { 
      if (local_table.containsKey(key)) {
        entity = local_table.get(key);
        if ((entity instanceof Variable) && channel_operations) {
          type = ((Variable) entity).getType();
        }
        else {
          type = ((Constant) entity).getType();
        }
      }
      else {
        entity = global_table.get(key);
        if ((entity instanceof Variable) && channel_operations) {
          type = ((Variable) entity).getType();
        }
        else if (entity instanceof Constant) {
          type = ((Constant) entity).getType();
        }
        else {
          err.report(3, ident.getLine(), ident.getPos());
        }
      }
    }
  }

  /**
   * constant =
   *  .......... |
   *  {signedidentifier} sign identifier |
   *  .......... |
   *  .......... ;
   * @see TypeChecker.outAIdentifierConstant
   */
  public void outASignedidentifierConstant(ASignedidentifierConstant node) {
    TIdentifier ident = node.getIdentifier();
    String key = ident.getText().toUpperCase();
    Object entity = null;

    if (program) {
      entity = global_table.get(key);
      if ((entity instanceof Variable) && channel_operations) {
        type = ((Variable) entity).getType();
      }
      else {
        type = ((Constant) entity).getType();
      }
    }
    else if (monitor) {
      if (monitor_table.containsKey(key)) {
        entity = monitor_table.get(key);
        if ((entity instanceof Variable) && channel_operations) {
          type = ((Variable) entity).getType();
        }
        else {
          type = ((Constant) entity).getType();
        }
      }
      else {
        entity = global_table.get(key);
        if ((entity instanceof Variable) && channel_operations) {
          type = ((Variable) entity).getType();
        }
        else if (entity instanceof Constant) {
          type = ((Constant) entity).getType();
        }
        else {
          err.report(3, ident.getLine(), ident.getPos());
        }
      }
    }
    else { 
      if (local_table.containsKey(key)) {
        entity = global_table.get(key);
        if ((entity instanceof Variable) && channel_operations) {
          type = ((Variable) entity).getType();
        }
        else {
          type = ((Constant) entity).getType();
        }
      }
      else {
        entity = global_table.get(key);
        if ((entity instanceof Variable) && channel_operations) {
          type = ((Variable) entity).getType();
        }
        else if (entity instanceof Constant) {
          type = ((Constant) entity).getType();
        }
        else {
          err.report(3, ident.getLine(), ident.getPos());
        }
      }
    }
  }

  /**
   * constant =
   *   ............ |
   *   {signedinteger} sign integer_literal |
   *   ............ |
   *   ............ ;
   * reports an error if the identifier is out of range
   */
  public void outASignedintegerConstant(ASignedintegerConstant node) {
    TIntegerLiteral int_lit= node.getIntegerLiteral();
    PSign sign = node.getSign();
    String image = int_lit.getText();

    type = INTEGER;

    if (sign instanceof APlusSign) {
      image = "+" + image;
    }
    else {
      image = "-" + image;
    }

    try {
      int value = Integer.parseInt(image);

      if ((value < Integer.MIN_VALUE) || (value > Integer.MAX_VALUE)) {
        err.report(6, int_lit.getLine(), int_lit.getPos());
      }
    }
    catch (NumberFormatException ex) {
      err.report(6, int_lit.getLine(), int_lit.getPos());
    }
  }

  /**
   * constant =
   *    ........ |
   *    {unsignedinteger} integer_literal |
   *    ........ | 
   *    ........ ;
   * @see TypeChecker.outASignedIntegerConstant
   */
  public void outAUnsignedintegerConstant(AUnsignedintegerConstant node) {
    TIntegerLiteral int_lit= node.getIntegerLiteral();
    String image = int_lit.getText();

    type = INTEGER;

    try {
      int value = Integer.parseInt(image);
      if (value > Integer.MAX_VALUE) {
        err.report(6, int_lit.getLine(), int_lit.getPos());
      }
    }
    catch (NumberFormatException ex) {
      err.report(6, int_lit.getLine(), int_lit.getPos());
    }
  }

  /**
   * constant =
   *    ............ |
   *    {signedreal} sign real_literal |
   *    .............. ;
   * reports an error if the real_literal is 
   * out of range.
   */
  public void outASignedrealConstant(ASignedrealConstant node) {
    TRealLiteral real_lit = node.getRealLiteral();
    String image = real_lit.getText();
    PSign sign = node.getSign();
  
    type = REAL;

    if (sign instanceof APlusSign) {
      image = "+" + image;
    }
    else {
      image = "-" + image;
    }

    try {
      float value = Float.valueOf(image).floatValue();
      if ((value < (float) (-3.4028235e38)) || (value > Float.MAX_VALUE)) {
        err.report(17, real_lit.getLine(), real_lit.getPos());
      }
    } 
    catch (NumberFormatException ex) {
      err.report(17, real_lit.getLine(), real_lit.getPos());
    }
  }
  
  /**
   * constant =
   *   ........... |
   *   {unsignedreal} real_literal |
   *   ........... ;
   */
  public void outAUnsignedrealConstant(AUnsignedrealConstant node) {
    TRealLiteral real_lit = node.getRealLiteral();
    String image = real_lit.getText();

    type = REAL;
    try {
      float value = Float.valueOf(image).floatValue();
      if (value > Float.MAX_VALUE) {
        err.report(17, real_lit.getLine(), real_lit.getPos());
      }
    } 
    catch (NumberFormatException ex) {
      err.report(17, real_lit.getLine(), real_lit.getPos());

⌨️ 快捷键说明

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