?? javasourcegenerator.java
字號(hào):
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));
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -