📄 decafcparser.y
字号:
{ yyclearin; yyerrok; yyless(0); /* unread "identifier" */ ReportError(ERROR_UNBALANCED_BRACKETS, NULL, currentLineNumber, currentColumnNumber); nodePtr = CreateNode(NODE_TYPE_ERROR, 0); $$.nodePtr = CreateNode(NODE_TYPE_INT_ARRAY_DEC, 2, $1.nodePtr, nodePtr); } ;OtherArrayDeclaration : StartArray TOKEN_OP_RIGHT_SQUARE_BRACKET { nodePtr = CreateNode(NODE_TYPE_DIM, 0); $$.nodePtr = CreateNode(NODE_TYPE_OTHER_ARRAY_DEC, 2, $1.nodePtr, nodePtr); } | OtherArrayDeclaration TOKEN_OP_LEFT_SQUARE_BRACKET TOKEN_OP_RIGHT_SQUARE_BRACKET { nodePtr = CreateNode(NODE_TYPE_DIM, 0); $$.nodePtr = CreateNode(NODE_TYPE_OTHER_ARRAY_DEC, 2, $1.nodePtr, nodePtr); } ;StartArray : TOKEN_IDENTIFIER TOKEN_OP_LEFT_SQUARE_BRACKET { $$.nodePtr = $1.nodePtr; } | error TOKEN_OP_LEFT_SQUARE_BRACKET { yyclearin; yyerrok; ReportError(ERROR_MISSING_ARRAY_NAME, NULL, currentLineNumber, currentColumnNumber); $$.nodePtr = CreateNode(NODE_TYPE_ERROR, 0); } ;ConstructorDeclaration : TOKEN_IDENTIFIER TOKEN_OP_LEFT_PARENTHESIS ParameterList TOKEN_OP_RIGHT_PARENTHESIS Block { $$.nodePtr = CreateNode(NODE_TYPE_CONSTRUCTOR_DEC, 3, $1.nodePtr, $3.nodePtr, $5.nodePtr); #ifdef DEBUG printf("\nSymbol table for constructor %s:\n", $1.nodePtr->info.lexeme); DisplaySymbolTable(currentBlockSymbolTable); #endif $$.nodePtr->info.symbolTablePtr = currentBlockSymbolTable; FreeSymbolTable(currentParameterSymbolTable); currentParameterSymbolTable = NewSymbolTable(SYMBOL_TABLE_SIZE); currentBlockSymbolTable = NewSymbolTable(SYMBOL_TABLE_SIZE); inMethod = FALSE; } ;MethodDeclarationList : MethodDeclaration { $$.nodePtr = CreateNode(NODE_TYPE_METHOD_DEC_LIST, 1, $1.nodePtr); } | MethodDeclarationList MethodDeclaration { $$.nodePtr = MergeSubTrees(NODE_TYPE_METHOD_DEC_LIST, 2, $1.nodePtr, $2.nodePtr); } ;MethodDeclaration : Type TOKEN_IDENTIFIER TOKEN_OP_LEFT_PARENTHESIS ParameterList TOKEN_OP_RIGHT_PARENTHESIS Block { $$.nodePtr = CreateNode(NODE_TYPE_METHOD_DEC, 4, $1.nodePtr, $2.nodePtr, $4.nodePtr, $6.nodePtr); parameterVarID = 0; localVarID = 0; methodName = (String)malloc( strlen($2.nodePtr->info.lexeme) + 1 + 1); strcpy(methodName, $2.nodePtr->info.lexeme); strcat(methodName, STRING_LEFT_PARENTHESIS); elementPtr = Lookup(currentClassSymbolTable, // $2.nodePtr->info.lexeme); methodName); /* if ((elementPtr != NULL) && (elementPtr->typePtr == voidTypePtr)) { */ if (elementPtr != NULL) { ReportError(ERROR_METHOD_REDECLARATION, $2.nodePtr->info.lexeme, $2.nodePtr->lineNumber, $2.nodePtr->columnNumber); } else { Insert(currentClassSymbolTable, // $2.nodePtr->info.lexeme, methodName, 0, voidTypePtr); if (strcmp($2.nodePtr->info.lexeme, STRING_MAIN) == 0) { if (hasMainMethod == TRUE) { ReportError(ERROR_MAIN_METHOD_REDECLARATION, $2.nodePtr->info.lexeme, $2.nodePtr->lineNumber, $2.nodePtr->columnNumber); } else { hasMainMethod = TRUE; mainMethodDecNodePtr = $$.nodePtr; if ($4.nodePtr->numberOfChildren > 1) { ReportError(ERROR_MAIN_METHOD_PARA_LIST, $2.nodePtr->info.lexeme, $4.nodePtr->lineNumber, $4.nodePtr->columnNumber); } } } } free(methodName); #ifdef DEBUG printf("\nSymbol table for method %s:\n", $2.nodePtr->info.lexeme); DisplaySymbolTable($6.nodePtr->info.symbolTablePtr); #endif $$.nodePtr->info.symbolTablePtr = $6.nodePtr->info.symbolTablePtr; FreeSymbolTable(currentParameterSymbolTable); currentParameterSymbolTable = NewSymbolTable(SYMBOL_TABLE_SIZE); currentBlockSymbolTable = NewSymbolTable(SYMBOL_TABLE_SIZE); inMethod = FALSE; firstBlock = TRUE; } | TOKEN_KW_VOID TOKEN_IDENTIFIER TOKEN_OP_LEFT_PARENTHESIS ParameterList TOKEN_OP_RIGHT_PARENTHESIS Block { ReplaceNode(NODE_TYPE_TYPE, $1.nodePtr); $$.nodePtr = CreateNode(NODE_TYPE_METHOD_DEC, 4, $1.nodePtr, $2.nodePtr, $4.nodePtr, $6.nodePtr); parameterVarID = 0; localVarID = 0; methodName = (String)malloc( strlen($2.nodePtr->info.lexeme) + 1 + 1); strcpy(methodName, $2.nodePtr->info.lexeme); strcat(methodName, STRING_LEFT_PARENTHESIS); elementPtr = Lookup(currentClassSymbolTable, // $2.nodePtr->info.lexeme); methodName); /* if ((elementPtr != NULL) && (elementPtr->typePtr == voidTypePtr)) { */ if (elementPtr != NULL) { ReportError(ERROR_METHOD_REDECLARATION, $2.nodePtr->info.lexeme, $2.nodePtr->lineNumber, $2.nodePtr->columnNumber); } else { Insert(currentClassSymbolTable, // $2.nodePtr->info.lexeme, methodName, 0, NULL); if (strcmp($2.nodePtr->info.lexeme, STRING_MAIN) == 0) { if (hasMainMethod == TRUE) { ReportError(ERROR_MAIN_METHOD_REDECLARATION, $2.nodePtr->info.lexeme, $2.nodePtr->lineNumber, $2.nodePtr->columnNumber); } else { hasMainMethod = TRUE; mainMethodDecNodePtr = $$.nodePtr; if ($4.nodePtr->numberOfChildren > 1) { ReportError(ERROR_MAIN_METHOD_PARA_LIST, $2.nodePtr->info.lexeme, $4.nodePtr->lineNumber, $4.nodePtr->columnNumber); } } } } free(methodName); #ifdef DEBUG printf("\nSymbol table for method %s:\n", $2.nodePtr->info.lexeme); DisplaySymbolTable($6.nodePtr->info.symbolTablePtr); #endif $$.nodePtr->info.symbolTablePtr = $6.nodePtr->info.symbolTablePtr; /* currentBlockSymbolTable; */ FreeSymbolTable(currentParameterSymbolTable); currentParameterSymbolTable = NewSymbolTable(SYMBOL_TABLE_SIZE); currentBlockSymbolTable = NewSymbolTable(SYMBOL_TABLE_SIZE); inMethod = FALSE; } ;ParameterList : /* empty production */ { $$.nodePtr = CreateNode(NODE_TYPE_PARA_LIST, 1, NULL); currentBlockSymbolTable = DupSymbolTable(currentParameterSymbolTable); #ifdef DEBUG printf("Duplicate parameter symbol table:\n"); DisplaySymbolTable(currentBlockSymbolTable); #endif inMethod = TRUE; firstBlock = TRUE; // printf("Set firstBlock to 1\n"); } | Parameter RemainingParameterList { ReplaceNode(NODE_TYPE_PARA_LIST, $2.nodePtr); $$.nodePtr = MergeSubTrees(NODE_TYPE_PARA_LIST, 2, $1.nodePtr, $2.nodePtr); currentBlockSymbolTable = DupSymbolTable(currentParameterSymbolTable); #ifdef DEBUG printf("Duplicate parameter symbol table:\n"); DisplaySymbolTable(currentBlockSymbolTable); #endif inMethod = TRUE; firstBlock = TRUE; // printf("Set firstBlock to 1\n"); } ;Parameter : Type TOKEN_IDENTIFIER { $$.nodePtr = CreateNode(NODE_TYPE_PARAMETER, 2, $1.nodePtr, $2.nodePtr); if (Lookup(currentParameterSymbolTable, $2.nodePtr->info.lexeme) == NULL) { Insert(currentParameterSymbolTable, $2.nodePtr->info.lexeme, parameterVarID + FIRST_LOCAL_VAR_OFFSET, $1.nodePtr->typePtr); parameterVarID ++; // printf("parameterVarID is %d\n", parameterVarID); } else { ReportError(ERROR_PARA_REDECLARATION, NULL, currentLineNumber, currentColumnNumber); } } ;RemainingParameterList : /* empty production */ { $$.nodePtr = CreateNode(NODE_TYPE_R_PARA_LIST, 1, NULL); } | TOKEN_OP_COMMA Parameter RemainingParameterList { $$.nodePtr = MergeSubTrees(NODE_TYPE_R_PARA_LIST, 2, $2.nodePtr, $3.nodePtr); } ;Block : TOKEN_OP_LEFT_CURLY_BRACKET LocalVarDeclarationList StatementList TOKEN_OP_RIGHT_CURLY_BRACKET { $$.nodePtr = CreateNode(NODE_TYPE_BLOCK, 2, $2.nodePtr, $3.nodePtr); // localVarID = beginLocalVarID; #ifdef DEBUG printf("\nCurrent block symbol table:\n"); DisplaySymbolTable(currentBlockSymbolTable); #endif $$.nodePtr->info.symbolTablePtr = currentBlockSymbolTable; // currentBlockSymbolTable = Pop(symbolTableStackPtr); Pop(symbolTableStackPtr, ¤tBlockSymbolTable, &localVarID); // printf("pop begin localVarID %d\n", localVarID); localVarID ++; #ifdef DEBUG printf("Pop symbol table:\n"); DisplaySymbolTable(currentBlockSymbolTable); #endif } ;LocalVarDeclarationList : /* empty production */ { $$.nodePtr = CreateNode(NODE_TYPE_L_VAR_DEC_LIST, 1, NULL); } | LocalVarDeclarationList LocalVarDeclaration { $$.nodePtr = MergeSubTrees(NODE_TYPE_L_VAR_DEC_LIST, 2, $1.nodePtr, $2.nodePtr); } ;LocalVarDeclaration : Type TOKEN_IDENTIFIER TOKEN_OP_SEMICOLON { $$.nodePtr = CreateNode(NODE_TYPE_L_VAR_DEC, 2, $1.nodePtr, $2.nodePtr); #ifdef DEBUG printf("Before inserting %s\n", $2.nodePtr->info.lexeme); DisplaySymbolTable(currentBlockSymbolTable); #endif // if ($1.nodePtr->numberOfChildren > 0) { // CreateNewArrayType($1.nodePtr); // } if (Lookup(currentBlockSymbolTable, $2.nodePtr->info.lexeme) == NULL) { elementPtr = Insert(currentBlockSymbolTable, $2.nodePtr->info.lexeme, localVarID + FIRST_LOCAL_VAR_OFFSET, $1.nodePtr->typePtr); elementPtr->typePtr = $1.nodePtr->typePtr; localVarID ++; } else { ReportError(ERROR_VAR_REDECLARATION, NULL, currentLineNumber, currentColumnNumber); } } | Type TOKEN_IDENTIFIER error { yyclearin; yyerrok; ReportError(ERROR_MISSING_SEMICOLON, NULL, currentLineNumber, currentColumnNumber); $$.nodePtr = CreateNode(NODE_TYPE_L_VAR_DEC, 2, $1.nodePtr, $2.nodePtr); // if ($1.nodePtr->numberOfChildren > 0) { // CreateNewArrayType($1.nodePtr); // } if (Lookup(currentBlockSymbolTable, $2.nodePtr->info.lexeme) == NULL) { Insert(currentBlockSymbolTable, $2.nodePtr->info.lexeme, localVarID + FIRST_LOCAL_VAR_OFFSET, $1.nodePtr->typePtr); localVarID ++; } else { ReportError(ERROR_VAR_REDECLARATION, NULL, currentLineNumber, currentColumnNumber); } } | Type error TOKEN_OP_SEMICOLON { yyclearin; yyerrok; ReportError(ERROR_INVALID_VAR_DECLARATION, NULL, currentLineNumber, currentColumnNumber); nodePtr = CreateNode(NODE_TYPE_ERROR, 0); $$.nodePtr = CreateNode(NODE_TYPE_L_VAR_DEC, 2, $1.nodePtr, nodePtr); } ;StatementList : Statement { $$.nodePtr = CreateNode(NODE_TYPE_STMT_LIST, 1, $1.nodePtr); } | StatementList Statement { $$.nodePtr = MergeSubTrees(NODE_TYPE_STMT_LIST, 2, $1.nodePtr, $2.nodePtr); } ;Statement: TOKEN_OP_SEMICOLON { $$.nodePtr = CreateNode(NODE_TYPE_EMPTY_STMT, 0); } | Name TOKEN_OP_ASSIGN Expression TOKEN_OP_SEMICOLON { $$.nodePtr = CreateNode(NODE_TYPE_ASGN_STMT, 2, $1.nodePtr, $3.nodePtr); } | Name TOKEN_OP_LEFT_PARENTHESIS ArgList TOKEN_OP_RIGHT_PARENTHESIS TOKEN_OP_SEMICOLON { $$.nodePtr = CreateNode(NODE_TYPE_FUNC_STMT, 2, $1.nodePtr, $3.nodePtr); } | TOKEN_KW_PRINT TOKEN_OP_LEFT_PARENTHESIS ArgList TOKEN_OP_RIGHT_PARENTHESIS TOKEN_OP_SEMICOLON { $$.nodePtr = CreateNode(NODE_TYPE_PRINT_STMT, 1, $3.nodePtr); } | ConditionalStatement { $$.nodePtr = $1.nodePtr; } | TOKEN_KW_WHILE TOKEN_OP_LEFT_PARENTHESIS Expression TOKEN_OP_RIGHT_PARENTHESIS Statement { $$.nodePtr = CreateNode(NODE_TYPE_WHILE_STMT, 2, $3.nodePtr, $5.nodePtr); } | TOKEN_KW_RETURN OptionalExpression TOKEN_OP_SEMICOLON { $$.nodePtr = CreateNode(NODE_TYPE_RETURN_STMT, 1, $2.nodePtr); } | Block { ReplaceNode(NODE_TYPE_BLOCK_STMT, $1.nodePtr); } | error TOKEN_OP_SEMICOLON { yyclearin; yyerrok; ReportError(ERROR_INVALID_STATEMENT, NULL, currentLineNumber, currentColumnNumber); $$.nodePtr = CreateNode(NODE_TYPE_ERROR, 0); } | error TOKEN_OP_RIGHT_CURLY_BRACKET { yyclearin; yyerrok;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -