?? identifierchecker.java
字號:
/* File : IdentifierChecker.java
Description: This class is belongs to one of the phases of the Semantic analyzer for
JPascal, which checks that a variable,
constant or process are declared only once. That there cannot be
a constant with the same name of a process or variable, and
vice versa.
Author: Fidel Viegas (viegasfh@yahoo.com)
Date: 12/02/1999
Last Modification Date: 16/03/2000
*/
package uk.co.brainycreatures.jpascal.semantic;
import uk.co.brainycreatures.jpascal.analysis.*;
import uk.co.brainycreatures.jpascal.node.*;
import java.util.Hashtable;
import java.util.Vector;
import java.io.*;
/**
* This class is the first stage of the Semantic Analysis phase. It checks that all the identifiers are declared
* only once and that they are declared before use. It also checks that the integer, real and character literals
* are not out of range.
*/
public class IdentifierChecker extends DepthFirstAdapter {
/**
* processes the storage of identifiers of a program and/or subprograms, monitors and processes.
*/
private Hashtable global_table = new Hashtable();
/**
* stores the identifiers of a monitor.
*/
private Hashtable monitor_table = new Hashtable();
/**
* set to true when a procedure or function are given arguments
*/
private boolean throws_args = false;
/**
* used by previous_entity
*/
private final short PROGRAM = 0;
/**
* set to true when a readln statement with arguments is
* found.
*/
private boolean readln_statement = false;
/**
* used by previous_entity
*/
private final short MONITOR = 1;
/**
* program or monitor
*/
private short previous_entity = PROGRAM;
/**
* stores identifiers local to a function, procedure or process
*/
private Hashtable local_table = new Hashtable();
/**
* Reports the error messages within a program.
*/
private ErrorMessage err = new ErrorMessage();
/**
* Lets the Identifier Checker know that this is a program.
*/
private boolean program = true;
/**
* stores the procedures local to a monitor
*/
private Hashtable monitor_procs = new Hashtable();
/**
* true if the entity is a monitor
*/
private boolean monitor = false;
/**
* set to true if a monitor_call
*/
private boolean monitor_call = false;
/**
* Stores the name of the current monitor, so that when declaring
* procedures local to a monitor
* can be checked against the monitor's name.
*/
private String monitor_name;
/**
* Stores the name of the program
*/
private String program_name;
/**
* Adds a new symbol table to the linked list
* symbol_table.
*/
public void caseAPresentProgramHeading(APresentProgramHeading node) {
program_name = node.getIdentifier().getText();
}
/**
* @see IdentifierChecker.caseAPresentProgramHeading
*/
public void caseAEmptyProgramHeading(APresentProgramHeading node) {
program_name = "Noname";
}
/**
* Checks if the new constant identifier being defined already exists. If it exists, then an error message
* is reported. If it doesn't, then it is put in the symbol table of the current block(process, monitor, program,
* subprogram.
*
* @parameter node This is the node representing a constant in the AST.
*/
public void outAConstDeclaration(AConstDeclaration node){
checkNewId(node.getIdentifier());
}
/**
* Checks if the constant identifier on the right hand side of the new constant being defined is
* already defined.
* @parameter node Represents the identifier of the constant on the right hand side of a const
* constant declaration in the AST.
*/
public void outASignedidentifierConstant(ASignedidentifierConstant node) {
checkId(node.getIdentifier());
}
/**
* @see IdentifierChecker.outASignedIdentifierConstant
*/
public void outAIdentifierConstant(AIdentifierConstant node) {
checkId(node.getIdentifier());
}
/**
* If the identifier is from an export section, then put it in the export table
* else, check if the identifier was already declared and report an error if it was.
*
* @param node Represents the node of the identifier being declared.
*/
public void outASingleIdentifierList(ASingleIdentifierList node) {
TIdentifier ident = node.getIdentifier();
String key = ident.getText().toUpperCase();
if (readln_statement || throws_args) {
checkId(ident); // check if the identifier was declared
}
else {
checkNewId(ident);
}
}
/**
* @see IdentifierChecker.outASingleIdentifierList
*/
public void outASequenceIdentifierList(ASequenceIdentifierList node){
TIdentifier ident = node.getIdentifier();
String key = ident.getText().toUpperCase();
if (readln_statement || throws_args) {
checkId(ident); // check if the identifier was declared
}
else {
checkNewId(ident);
}
}
/**
* checks if the identifier is already in the table and if it isn't
* equal to a procedure, function, monitor or process if this is not
* a program declaration.
*/
public void outASimpleProcedureHeading(ASimpleProcedureHeading node) {
checkProcedure(node.getIdentifier());
if (!local_table.isEmpty()) {
local_table.clear();
}
}
/**
* {simple_throws} procedure identifier semicolon throws identifierlist
*/
public void inASimpleThrowsProcedureHeading(ASimpleThrowsProcedureHeading node) {
checkProcedure(node.getIdentifier());
if (!local_table.isEmpty()) {
local_table.clear();
}
throws_args = true;
}
/**
* out simple throws
*/
public void outASimpleThrowsProcedureHeading(ASimpleThrowsProcedureHeading node) {
throws_args = false;
}
/**
* @see IdentifierChecker.outASimpleProcedureDeclarationHeading
*/
public void inAArgumentsProcedureHeading(AArgumentsProcedureHeading node) {
checkProcedure(node.getIdentifier());
if (!local_table.isEmpty()) {
local_table.clear();
}
}
public void caseAArgumentsThrowsProcedureHeading(AArgumentsThrowsProcedureHeading node) {
checkProcedure(node.getIdentifier());
if (!local_table.isEmpty()) {
local_table.clear();
}
if (node.getParameterList() != null) {
node.getParameterList().apply(this);
}
throws_args = true;
if (node.getIdentifierList() != null) {
node.getIdentifierList().apply(this);
}
throws_args = false;
}
/**
* @see IdentifierChecker.checkSubProgramHeading
*/
public void outASimpleFunctionHeading(ASimpleFunctionHeading node) {
checkFunction(node.getIdentifier());
if (!local_table.isEmpty()) {
local_table.clear();
}
}
public void caseASimpleThrowsFunctionHeading(ASimpleThrowsFunctionHeading node) {
checkFunction(node.getIdentifier());
if (!local_table.isEmpty()) {
local_table.clear();
}
throws_args = true;
if (node.getIdentifierList() != null ) {
node.getIdentifierList().apply(this);
}
throws_args = false;
}
/**
* checks if the exceptions identifiers where previously declared
*/
public void caseAArgumentsFunctionHeading(AArgumentsFunctionHeading node) {
checkFunction(node.getIdentifier());
if (!local_table.isEmpty()) {
local_table.clear();
}
if (node.getParameterList() != null) {
node.getParameterList().apply(this);
}
}
/**
* checks if the exceptions identifiers where previously declared
*/
public void caseAArgumentsThrowsFunctionHeading(AArgumentsThrowsFunctionHeading node) {
checkFunction(node.getIdentifier());
if (!local_table.isEmpty()) {
local_table.clear();
}
if (node.getParameterList() != null) {
node.getParameterList().apply(this);
}
throws_args = true;
if (node.getIdentifierList() != null) {
node.getIdentifierList().apply(this);
}
throws_args = false;
}
/**
* checks if the identifier already exists in the global table
*/
public void outAMonitorHeading(AMonitorHeading node) {
TIdentifier ident = node.getIdentifier();
String key = ident.getText().toUpperCase();
checkMonitor(ident);
program = false;
monitor = true;
monitor_name = ident.getText();
if (!monitor_table.isEmpty()) {
monitor_table.clear();
}
monitor_procs = new Hashtable();
}
/**
* @see IdentifierChecker.outAMonitorHeading
*/
public void outAProcessHeading(AProcessHeading node) {
TIdentifier ident = node.getIdentifier();
String key = ident.getText().toUpperCase();
checkProcess(ident);
program = false;
if (!local_table.isEmpty()) {
local_table.clear();
}
}
/**
* sets inner to false if it is true or
* not_a_program to false
*/
public void outAProcedureDeclaration(AProcedureDeclaration node) {
if (previous_entity == PROGRAM) {
program = true;
}
else {
monitor = true;
}
}
/**
* sets inner to false if it is true or
* not_a_program to false
*/
public void outAFunctionDeclaration(AFunctionDeclaration node) {
program = true;
}
/**
* sets not_a_program to false
* and removes the current table from the list
*/
public void outAProcessDeclaration(AProcessDeclaration node) {
program = true;
}
/**
* checks if the identifiers in the export list exist and that
* they are not repeated in the list
*/
public void outAMonitorDeclaration(AMonitorDeclaration node) {
program = true;
monitor = false;
((Monitor) global_table.get(monitor_name.toUpperCase())).
setTable(monitor_procs);
}
/**
* checks if the identifier exists
*/
public void outAIdentifierIndex(AIdentifierIndex node) {
checkId(node.getIdentifier());
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -