Методические указания (1114907), страница 20
Текст из файла (страница 20)
}
else {
instructions.add("(" + getInstructionNumber() + ") " + "param" + " " + $expressionFirst.text);
}
$parametresCount++;
}
else {
instructions.add("(" + getInstructionNumber() + ") " + "param" + " t" + $expressionFirst.tempIndex);
$parametresCount++;
}
}
}
} (',' expressionNext = expression {
if ($expressionNext.expressionType != null) {
if ($expressionNext.expressionType.equals("void")) {
errors.add("line " + $functionLine + ": wrong parameter type of " + $expressionNext.text);
}
else {
if ($expressionNext.expressionClass.equals("id") ||
$expressionNext.expressionClass.equals("const_string") ||
$expressionNext.expressionClass.equals("const_int")) {
if ($expressionNext.expressionClass.equals("const_string")) {
constants.add($expressionNext.text);
instructions.add("(" + getInstructionNumber() + ") " + "param" + " " + "D0" + constants.size());
}
else {
instructions.add("(" + getInstructionNumber() + ") " + "param" + " " + $expressionNext.text);
}
$parametresCount++;
}
else {
instructions.add("(" + getInstructionNumber() + ") " + "param" + " t" + $expressionNext.tempIndex);
$parametresCount++;
}
}
}
})*)
;
variable_declaration
: type (idParam = ID | assignParam = assign) (',' (idParamNext = ID | assignParamNext = assign))* ';' {
if (names.isExist($idParam.text)) {
errors.add("line " + $idParam.line + ": name " + $idParam.text + " duplicated");
}
else {
if ($idParam.text != null) {
names.add(names.new Name($idParam.text, $type.text, $idParam.line));
}
}
if (names.isExist($assignParam.idName)) {
errors.add("line " + $assignParam.idLine + ": name " + $assignParam.idName + " duplicated");
}
else {
if ($assignParam.idName != null) {
names.add(names.new Name($assignParam.idName, $type.text, $assignParam.idLine));
}
}
if (names.isExist($idParamNext.text)) {
errors.add("line " + $idParamNext.line + ": name " + $idParamNext.text + " duplicated");
}
else {
if ($idParamNext.text != null) {
names.add(names.new Name($idParamNext.text, $type.text, $idParamNext.line));
}
}
if (names.isExist($assignParamNext.idName)) {
errors.add("line " + $assignParamNext.idLine + ": name " + $assignParamNext.idName + " duplicated");
}
else {
if ($assignParamNext.idName != null) {
names.add(names.new Name($assignParamNext.idName, $type.text, $assignParamNext.idLine));
}
}
if ($assignParam.expressionType != null && $assignParam.idName != null && !$assignParam.expressionType.equals(names.get($assignParam.idName).getType())) {
errors.add("line " + $assignParam.idLine + ": name " + $assignParam.idName + " type is mismatched");
}
if ($assignParam.expressionType != null && $assignParamNext.idName != null && !$assignParamNext.expressionType.equals(names.get($assignParamNext.idName).getType())) {
errors.add("line " + $assignParamNext.idLine + ": name " + $assignParamNext.idName + " type is mismatched");
}
}
;
for_operator
: 'for' '(' type? assign {
if (names.isExist($assign.idName)) {
errors.add("line " + $assign.idLine + ": name " + $assign.idName + " duplicated");
}
else {
if ($assign.text != null) {
names.add(names.new Name($assign.idName, $type.text, $assign.idLine));
}
}
if (!$type.text.equals("int")) {
errors.add("line " + $assign.idLine + ": type of counter is mismatched");
}
if (!$assign.expressionType.equals(names.get($assign.idName).getType())) {
errors.add("line " + $assign.idLine + ": name " + $assign.idName + " type is mismatched");
}
}
';' logical_condition[$assign.idLine] ';' incrementation ')' '{' {
int instructionNumber = getInstructionNumber();
instructions.add("(" + instructionNumber + ") " + "if" + " t" + $logical_condition.tempVariableIndex + " (" + (instructionNumber + 2) + ")");
instructionNumber = getInstructionNumber();
instructions.add("(" + instructionNumber + ") " + "goto" + " " + "(" + "X" + ")");
}
operator+
'}' {
instructions.add("(" + getInstructionNumber() + ") " + "+" + " " + $incrementation.idName + " 1 t" + genNewTemp());
instructions.add("(" + getInstructionNumber() + ") " + "assign" + " t" + currentTempNumber + " " + "- " + $incrementation.idName);
instructionNumber = getInstructionNumber();
instructions.add("(" + instructionNumber + ") " + "goto" + " (" + ($assign.instructionNumber + 1) + ")");
for (int i = instructions.size() - 1; i > 0; i--) {
if (instructions.get(i).indexOf("X") != -1) {
String temp = instructions.get(i);
int position = temp.indexOf("X");
temp = temp.substring(0, position) + Integer.toString(instructionNumber + 1) + temp.substring(position + 1);
instructions.set(i, temp);
}
}
}
;
function_call_operator
: function_call ';'
;
logical_condition [int operatorLine] returns [int tempVariableIndex]
: expressionFirst = expression logical_link expressionSecond = expression {
if ($expressionFirst.expressionType != null) {
if (!$expressionFirst.expressionType.equals("int")) {
errors.add("line " + $operatorLine + ": wrong condition operator type of " + $expressionFirst.text);
}
else {
if ($expressionSecond.expressionType != null) {
if (!$expressionSecond.expressionType.equals("int")) {
errors.add("line " + $operatorLine + ": wrong condition operator type of " + $expressionSecond.text);
}
else {
String resultString = "";
if ($expressionFirst.expressionClass.equals("id") ||
$expressionFirst.expressionClass.equals("const_string") ||
$expressionFirst.expressionClass.equals("const_int")) {
if ($expressionFirst.expressionClass.equals("const_string")) {
constants.add($expressionFirst.text);
resultString = "(" + getInstructionNumber() + ") " + $logical_link.text + " " + "D0" + constants.size() + " ";
}
else {
resultString = "(" + getInstructionNumber() + ") " + $logical_link.text + " " + $expressionFirst.text + " ";
}
}
else {
resultString = "(" + getInstructionNumber() + ") " + $logical_link.text + " t" + $expressionFirst.tempIndex + " ";
}
if ($expressionSecond.expressionClass.equals("id") ||
$expressionSecond.expressionClass.equals("const_string") ||
$expressionSecond.expressionClass.equals("const_int")) {
$tempVariableIndex = genNewTemp();
if ($expressionSecond.expressionClass.equals("const_string")) {
constants.add($expressionSecond.text);
resultString += "D0" + constants.size() + " t" + $tempVariableIndex;
}
else {
resultString += $expressionSecond.text + " t" + $tempVariableIndex;
}
instructions.add(resultString);
}
else {
$tempVariableIndex = genNewTemp();
resultString += "t" + $expressionSecond.tempIndex + " t" + $tempVariableIndex;
instructions.add(resultString);
}
}
}
}
}
}
;
logical_link
: '==' | '!=' | '>' | '<' | '>=' | '<='
;
operator : variable_declaration | assign_operator | for_operator | function_call_operator
;
program : (operator)+
;
-
Для троек.
grammar Task5Grammar;
options {
language = Java;
}
@members {
protected NamesTable names = new NamesTable();
protected ArrayList<String> errors = new ArrayList<String>();
protected ArrayList<String> instructions = new ArrayList<String>();
protected ArrayList<String> constants = new ArrayList<String>();
protected int instructionNumber = 0;
public static void main(String[] args) throws Exception {
Task5GrammarLexer lex = new Task5GrammarLexer(new ANTLRFileStream("test.txt"));
Task5GrammarParser parser = new Task5GrammarParser(new CommonTokenStream(lex));
parser.program();
if (! parser.errors.isEmpty()) {
System.out.println("Found " + parser.errors.size() + " errors:");
for (String m : parser.errors) {
System.out.println(m);
}
}
else {
System.out.println("Compiled successfully");
System.out.println("Constants:");
int i = 1;
for (String m : parser.constants) {
System.out.println("D0" + i + " " + m);
i++;
}
System.out.println("Instructions:");
parser.instructions.add("(" + (parser.instructions.size()) + ")");
for (String m : parser.instructions) {
System.out.println(m);
}
}
}
public String getErrorHeader(RecognitionException e) {
return "line "+e.line+":";
}
public void emitErrorMessage(String msg) {
errors.add(msg);
}
public int getInstructionNumber() {
instructionNumber++;
return instructionNumber - 1;
}