?? typechecker.java
字號:
/**
* 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 + -