void Parser::ParseDeclaration() { SymType* type = ParseTypeSpecifier(); Symbol* symbol = NULL; if (*lexer.Peek() == SEMICOLON) { lexer.Get(); return; } else { symbol = ParseDeclarator(type); } while (true) { if (!parseFunc.empty()) { symStack.Add(symbol, 0); } else { symStack.Add(symbol); } if (*lexer.Peek() == ASSIGN) { BaseToken* oper = lexer.Get(); SyntaxNode* left = new NodeVar(counter++, symbol); symStack.SetUsed(left->token->GetText()); SyntaxNode* right = ParseExpression(precedences[COMMA]+1); NodeBinaryOp* node = new NodeBinaryOp(counter++, left, oper, right); stmtStack.push_back(new StmtExpr(node)); node->GetType(); } if (*lexer.Peek() == SEMICOLON || *lexer.Peek() == FIGURE_RIGHT_BRACKET) { lexer.Get(); break; } Expected(lexer.Peek()->GetSubType(), COMMA); lexer.Get(); symbol = ParseDeclarator(type); } }
void Parser::ParseStructDeclaration() { if (*lexer.Peek() == FIGURE_RIGHT_BRACKET) { lexer.Get(); return; } SymType* type = ParseTypeSpecifier(); Symbol* declarator = ParseDeclarator(type); while (true) { symStack.Add(declarator, 2); Expected(*lexer.Peek() != ASSIGN, "data member initializer is not allowed"); if (*lexer.Peek() == COMMA) { lexer.Get(); declarator = ParseDeclarator(type); } else if (*lexer.Peek() == SEMICOLON) { lexer.Get(); if (*lexer.Peek() == FIGURE_RIGHT_BRACKET) { lexer.Get(); break; } type = ParseTypeSpecifier(); declarator = ParseDeclarator(type); } else { Error("expected `,` or `;`"); } } }
void Parser::ParseParameterList() { while (*lexer.Peek() != ROUND_RIGHT_BRACKET) { SymType* type = ParseTypeSpecifier(); Symbol* param = ParseDeclarator(type, true); Expected(*lexer.Peek() != EOF_, "expected a `)`"); if (*lexer.Peek() == COMMA) { lexer.Get(); } dynamic_cast<SymVar*>(param)->local = true; symStack.Add(param, 1); } lexer.Get(); }
/* Parses the parameter declaration grammar * * Its syntax is: * * parameter-declaration: * declaration-specifiers declarator * declaration-specifiers opt pointer * * @param desc description for the parameter declaration * */ static void ParseParamDecl(char *desc) { char type_qual[kMaxToken]; char type_spec[kMaxToken]; char var_name[kMaxToken]; memset(type_qual, 0, kMaxToken); memset(type_spec, 0, kMaxToken); memset(var_name, 0, kMaxToken); ParseDeclarationSpec(type_qual, type_spec); ParseDeclarator(var_name, desc); if (*type_qual != '\0') { strcat(desc, " "); strcat(desc, type_qual); } strcat(desc, " "); strcat(desc, type_spec); }
SymVar* Parser::ParseDeclarator(SymType* type, bool parseParams) { SymVar* result = NULL; //pointer while (*lexer.Peek() == MULTIPLICATION) { type = new SymTypePointer(type); lexer.Get(); } //direct-declarator if (*lexer.Peek() == ROUND_LEFT_BRACKET) { lexer.Get(); result = ParseDeclarator(type); Expected(lexer.Get()->GetSubType(), ROUND_RIGHT_BRACKET); return result; } Expected(parseParams || *lexer.Peek() == IDENTIFIER, "exepcted an identifier"); if (parseParams && *lexer.Peek() != IDENTIFIER) { string n = to_string((long double)counter++); BaseToken* dummy = new BaseToken("abstract-"+n, 0, 0, IDENTIFIER, IDENTIFIER); result = new SymVar(dummy, type); } else { string msg = "redefinition: " + lexer.Peek()->GetText(); Expected(!symStack.Top()->Find(lexer.Peek()->GetText()), &msg[0]); result = new SymVar(lexer.Get(), type); } BaseToken* token = lexer.Peek(); if (*token == SQUARE_LEFT_BRACKET) { lexer.Get(); Expected(*lexer.Peek() != SQUARE_RIGHT_BRACKET, "unknown size"); SyntaxNode* index = ParseExpression(); Expected(*index->token != IDENTIFIER, "expression must have a constant value"); SymType* indexType = index->GetType(); Expected(indexType == intType && indexType->CanConvertTo(intType), "expression must be an integral constant expression"); Expected(lexer.Get()->GetSubType(), SQUARE_RIGHT_BRACKET); int size = dynamic_cast<TokenVal <int> *>(index->token)->GetValue(); result->SetType(new SymTypeArray(size, type)); } else if (*token == ROUND_LEFT_BRACKET) { lexer.Get(); SymTypeFunc* t = new SymTypeFunc(type); t->params->offset = 4; symStack.Push(t->params); ParseParameterList(); symStack.Pop(); if (*lexer.Peek() == FIGURE_LEFT_BRACKET) { parseFunc.push_back(t); t->body = ParseBlock(); parseFunc.pop_back(); } result->SetType(t); } return result; }