Методические указания (1114907), страница 18
Текст из файла (страница 18)
$instructionNumber = getInstructionNumber();
instructions.add("(" + $instructionNumber + ") " + "[]" + " " + "(" + ($instructionNumber - 1) + ") " + " " + "(" + $expression.instructionNumber + ")" );
check();
}
else {
instructions.add("(" + $instructionNumber + ") " + "ID" + " " + $ID.text);
check();
$instructionNumber = getInstructionNumber();
instructions.add("(" + $instructionNumber + ") " + "[]" + " " + "(" + ($instructionNumber - 1) + ")" + " " + "(" + $expression.instructionNumber + ")");
check();
}
}
else {
instructions.add("(" + $instructionNumber + ") " + "ID" + " " + $ID.text);
check();
$instructionNumber = getInstructionNumber();
instructions.add("(" + $instructionNumber + ") " + "[]" + " " + "(" + ($instructionNumber - 1) + ")" + " (" + $expression.instructionNumber + ")");
check();
}
}
}
;
getting_address returns[int instructionNumber]
: '&' ID {
if (!names.isExist($ID.text)) {
errors.add("line " + $ID.line + ": name " + $ID.text + " is not declarated");
}
else {
$instructionNumber = getInstructionNumber();
instructions.add("(" + $instructionNumber + ") " + "ID" + " " + $ID.text);
check();
$instructionNumber = getInstructionNumber();
instructions.add("(" + $instructionNumber + ") " + "&" + " " + "(" + ($instructionNumber - 1) + ")");
check();
}
}
;
function_call[boolean flag] returns [String resultType, int instructionNumber]
: ID '(' parametres[$ID.line]? ')' {
$instructionNumber = getInstructionNumber();
if ($flag) {
$instructionNumber = getInstructionNumber();
}
String resultString = "(" + $instructionNumber + ") " + $ID.text + " ";
for (int number : $parametres.instructionsList) {
resultString += "(" + number + ") ";
}
if ($ID.text.equals("strlen")) {
$resultType = "int";
}
else {
$resultType = "void";
}
instructions.add(resultString);
check();
}
;
parametres [int functionLine] returns [ArrayList<Integer> instructionsList]
: {
$instructionsList = new ArrayList<Integer>();
}
((expressionFirst = expression) {
if ($expressionFirst.expressionType != null) {
if ($expressionFirst.expressionType.equals("void")) {
errors.add("line " + $functionLine + ": wrong parameter type of " + $expressionFirst.text);
}
else {
int instructionNumber = getInstructionNumber();
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);
instructions.add("(" + instructionNumber + ") " + "param" + " " + "(" + $expressionFirst.instructionNumber + ")");
check();
}
else {
instructions.add("(" + instructionNumber + ") " + "param" + " " + "(" + $expressionFirst.instructionNumber + ")");
check();
}
$instructionsList.add(instructionNumber);
}
else {
instructions.add("(" + instructionNumber + ") " + "param" + " (" + $expressionFirst.instructionNumber + ")");
check();
$instructionsList.add(instructionNumber);
}
}
}
} (',' expressionNext = expression {
if ($expressionNext.expressionType != null) {
if ($expressionNext.expressionType.equals("void")) {
errors.add("line " + $functionLine + ": wrong parameter type of " + $expressionNext.text);
}
else {
instructionNumber = getInstructionNumber();
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("(" + instructionNumber + ") " + "param" + " " + "(" + $expressionNext.instructionNumber + ")" );
check();
}
else {
instructions.add("(" + instructionNumber + ") " + "param" + " " + "(" + $expressionNext.instructionNumber + ")");
check();
}
$instructionsList.add(instructionNumber);
}
else {
instructions.add("(" + instructionNumber + ") " + "param" + " (" + $expressionNext.instructionNumber + ")");
check();
$instructionsList.add(instructionNumber);
}
}
}
})*)
;
variable_declaration returns [int instructionNumber]
: type (idParam = ID | assignParam = 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));
$instructionNumber = $assignParam.instructionNumber;
}
}
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");
}
}
;
for_operator returns [int instructionNumber]
: {
ArrayList<Integer> forInstructions = new ArrayList<Integer>();
}
'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 ')' '{' {
$instructionNumber = getInstructionNumber();
String resultString = "(" + instructionNumber + ") " + "for" + " (" + $assign.instructionNumber + ")" + " (" + $logical_condition.instructionNumber + ") " + "(" + $incrementation.instructionNumber + ") ";
instructions.add(resultString);
check();
}
(operator {
forInstructions.add($operator.instructionNumber);
})+ '}' {
for (int i = instructions.size() - 1; i > 0; i--) {
if (instructions.get(i).indexOf("for") != -1) {
for (int number : forInstructions) {
String temp = instructions.get(i);
temp += "(" + number + ") ";
instructions.set(i, temp);
}
}
}
}
;
function_call_operator returns[int instructionNumber]
: function_call[true] ';' {
$instructionNumber = $function_call.instructionNumber;
}
;
logical_condition [int operatorLine] returns [int instructionNumber]
: 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 = "";
$instructionNumber = getInstructionNumber();
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 = "(" + $instructionNumber + ") " + $logical_link.text + " " + "D0" + (constants.indexOf($expressionFirst.text) + 1) + " ";
}
else {
resultString = "(" + $instructionNumber + ") " + $logical_link.text + " " + $expressionFirst.text + " ";
}
}
else {
resultString = "(" + $instructionNumber + ") " + $logical_link.text + " (" + $expressionFirst.instructionNumber + ") ";
}
if ($expressionSecond.expressionClass.equals("id") ||
$expressionSecond.expressionClass.equals("const_string") ||
$expressionSecond.expressionClass.equals("const_int")) {
$instructionNumber = getInstructionNumber();
if ($expressionSecond.expressionClass.equals("const_string")) {
//constants.add($expressionSecond.text);
resultString += "D0" + (constants.indexOf($expressionSecond.text) + 1);
}
else {
resultString += $expressionSecond.text;
}