Методические указания (1114907), страница 23
Текст из файла (страница 23)
: ('+' | '-' | '*' | '/')
;
incrementation returns [String idName]
: ID '++' {
if (!names.isExist($ID.text)) {
errors.add("line " + $ID.line + ": name " + $ID.text + " is not declarated");
}
else {
if (!names.get($ID.text).getType().equals("int")) {
errors.add("line " + $ID.line + ": name " + $ID.text + " type mismatched");
}
else {
$idName = $ID.text;
}
}
}
;
array_element returns [int instructionNumber]
: ID '[' expression ']' {
if (!names.isExist($ID.text)) {
errors.add("line " + $ID.line + ": name " + $ID.text + " is not declarated");
}
else {
if (!names.get($ID.text).getType().equals("char[]")) {
errors.add("line " + $ID.line + ": name " + $ID.text + " type mismatched");
}
}
if (!$expression.expressionType.equals("int")) {
errors.add("line " + $ID.line + ": wrong index type");
}
else {
if ($expression.expressionClass.equals("id") ||
$expression.expressionClass.equals("const_string") ||
$expression.expressionClass.equals("const_int")) {
$instructionNumber = getInstructionNumber();
if ($expression.expressionClass.equals("const_string")) {
constants.add($expression.text);
instructions.add("(" + $instructionNumber + ") " + "[]" + " " + $ID.text + " " + "D0" + constants.size());
}
else {
instructions.add("(" + $instructionNumber + ") " + "[]" + " " + $ID.text + " " + $expression.text);
}
}
else {
$instructionNumber = getInstructionNumber();
instructions.add("(" + $instructionNumber + ") " + "[]" + " " + $ID.text + " (" + $expression.instructionNumber + ")");
}
}
}
;
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.text);
}
}
;
function_call returns [String resultType, int instructionNumber]
: ID '(' parametres[$ID.line] ')' {
$instructionNumber = getInstructionNumber();
if ($ID.text.equals("strlen")) {
$resultType = "int";
instructions.add("(" + $instructionNumber + ") " + "call" + " strlen" + " 1");
}
else {
$resultType = "void";
instructions.add("(" + $instructionNumber + ") " + "call" + " " + $ID.text + " " + $parametres.parametresCount);
}
}
;
parametres [int functionLine] returns [int parametresCount]
: {
$parametresCount = 0;
}
((expressionFirst = expression) {
if ($expressionFirst.expressionType != null) {
if ($expressionFirst.expressionType.equals("void")) {
errors.add("line " + $functionLine + ": wrong parameter type of " + $expressionFirst.text);
}
else {
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("(" + getInstructionNumber() + ") " + "param" + " " + "D0" + constants.size());
}
else {
instructions.add("(" + getInstructionNumber() + ") " + "param" + " " + $expressionFirst.text);
}
$parametresCount++;
}
else {
instructions.add("(" + getInstructionNumber() + ") " + "param" + " (" + $expressionFirst.instructionNumber + ")");
$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" + " (" + $expressionNext.instructionNumber + ")");
$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" + " (" + $logical_condition.instructionNumber + ") (" + (instructionNumber + 2) + ")");
instructionNumber = getInstructionNumber();
instructions.add("(" + instructionNumber + ") " + "goto" + " " + "(" + "X" + ")");
}
operator+
'}' {
instructions.add("(" + getInstructionNumber() + ") " + "+" + " " + $incrementation.idName + " 1");
instructionNumber = getInstructionNumber();
instructions.add("(" + instructionNumber + ") " + "assign" + " " + $incrementation.idName + " (" + (instructionNumber - 1) + ")");
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 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 = "";