asCScriptNode *asCParser::ParseCondition() { asCScriptNode *node = new asCScriptNode(snCondition); node->AddChildLast(ParseExpression()); if( isSyntaxError ) return node; sToken t; GetToken(&t); if( t.type == ttQuestion ) { node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t); if( t.type != ttColon ) { Error(ExpectedToken(":").AddressOf(), &t); return node; } node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; } else RewindTo(&t); return node; }
asCScriptNode *asCParser::ParseWhile() { asCScriptNode *node = new asCScriptNode(snWhile); sToken t; GetToken(&t); if( t.type != ttWhile ) { Error(ExpectedToken("while").AddressOf(), &t); return node; } node->UpdateSourcePos(t.pos, t.length); GetToken(&t); if( t.type != ttOpenParanthesis ) { Error(ExpectedToken("(").AddressOf(), &t); return node; } node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t); if( t.type != ttCloseParanthesis ) { Error(ExpectedToken(")").AddressOf(), &t); return node; } node->AddChildLast(ParseStatement()); return node; }
asCScriptNode *asCParser::ParseGlobalVar() { asCScriptNode *node = new asCScriptNode(snGlobalVar); // Parse data type node->AddChildLast(ParseType(true)); if( isSyntaxError ) return node; sToken t; for(;;) { // Parse identifier node->AddChildLast(ParseIdentifier()); if( isSyntaxError ) return node; // If next token is assignment, parse expression GetToken(&t); if( t.type == ttAssignment ) { GetToken(&t); RewindTo(&t); if( t.type == ttStartStatementBlock ) { node->AddChildLast(ParseInitList()); if( isSyntaxError ) return node; } else { node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; } } else if( t.type == ttOpenParanthesis ) { RewindTo(&t); node->AddChildLast(ParseArgList()); if( isSyntaxError ) return node; } else RewindTo(&t); // continue if list separator, else terminate with end statement GetToken(&t); if( t.type == ttListSeparator ) continue; else if( t.type == ttEndStatement ) { node->UpdateSourcePos(t.pos, t.length); return node; } else { Error(ExpectedTokens(",", ";").AddressOf(), &t); return node; } } return 0; }
ParsingResult Parser::ParseInstruction(InstructionBlock& body, TokIterator& it) { ParsingResult io_res = ParseIOInstr(body, it); if(io_res != NOT_MATCHED) { return io_res; } ParsingResult contr_flow_res = ParseControlFlowInstr(body, it); if(contr_flow_res != NOT_MATCHED) { return contr_flow_res; } ParsingResult assign_res = ParseAssignment(body, it); if(assign_res != NOT_MATCHED) { return assign_res; } FuncCallCreator func_call_creator; ParsingResult func_res = ParseFuncCallHeader(func_call_creator, it); if(func_res != NOT_MATCHED) { if(func_res == INCORRECT) { return INCORRECT; } body.AddInstruction(PtrVisitable(new FuncCall(func_call_creator.Create()))); return CORRECT; } ParsingResult return_expr_res = ParseReturnExpr(body, it); if(return_expr_res != NOT_MATCHED) { return return_expr_res; } return NOT_MATCHED; }
asCScriptNode *asCParser::ParseExpressionStatement() { asCScriptNode *node = new asCScriptNode(snExpressionStatement); sToken t; GetToken(&t); if( t.type == ttEndStatement ) { node->UpdateSourcePos(t.pos, t.length); return node; } RewindTo(&t); node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t); if( t.type != ttEndStatement ) { Error(ExpectedToken(";").AddressOf(), &t); return node; } node->UpdateSourcePos(t.pos, t.length); return node; }
void TParser::ParseStatement(void) { InsertLineMarker(); //--Call the appropriate parsing function based on //--the statement's first token. switch (token) { case tcIdentifier: { //--Search for the identifier and enter it if //--necessary. Append the symbol table node handle //--to the icode. TSymtabNode *pNode = Find(pToken->String()); icode.Put(pNode); //--Based on how the identifier is defined, //--parse an assignment statement or a procedure call. if (pNode->defn.how == dcUndefined) { pNode->defn.how = dcVariable; SetType(pNode->pType, pDummyType); ParseAssignment(pNode); } else if (pNode->defn.how == dcProcedure) { ParseSubroutineCall(pNode, true); } else ParseAssignment(pNode); break; } case tcREPEAT: ParseREPEAT(); break; case tcWHILE: ParseWHILE(); break; case tcIF: ParseIF(); break; case tcFOR: ParseFOR(); break; case tcCASE: ParseCASE(); break; case tcBEGIN: ParseCompound(); break; } //--Resynchronize at a proper statement ending. if (token != tcEndOfFile) { Resync(tlStatementFollow, tlStatementStart); } }
asCScriptNode *asCParser::ParseCast() { asCScriptNode *node = new asCScriptNode(snCast); sToken t1; GetToken(&t1); if( t1.type != ttCast ) { Error(ExpectedToken("cast").AddressOf(), &t1); return node; } node->UpdateSourcePos(t1.pos, t1.length); GetToken(&t1); if( t1.type != ttLessThan ) { Error(ExpectedToken("<").AddressOf(), &t1); return node; } // Parse the data type node->AddChildLast(ParseType(true)); if( isSyntaxError ) return node; node->AddChildLast(ParseTypeMod(false)); if( isSyntaxError ) return node; GetToken(&t1); if( t1.type != ttGreaterThan ) { Error(ExpectedToken(">").AddressOf(), &t1); return node; } GetToken(&t1); if( t1.type != ttOpenParanthesis ) { Error(ExpectedToken("(").AddressOf(), &t1); return node; } node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t1); if( t1.type != ttCloseParanthesis ) { Error(ExpectedToken(")").AddressOf(), &t1); return node; } node->UpdateSourcePos(t1.pos, t1.length); return node; }
NodeStatement* Parser::ParseElement() { if (t.GetValue() == "begin") return ParseBlock(); if (t.GetValue() == "if") return ParseIf(); if (t.GetValue() == "while") return ParseWhile(); if (t.GetValue() == "repeat") return ParseRepeat(); if (t.GetValue() == "for") return ParseFor(); if (t.GetValue() == "write") return ParseWrite(true, false); if (t.GetValue() == "writeln") return ParseWrite(true, true); if (t.GetValue() == "exit") { t = sc.GetNextToken(); return new StatementExit(true); } if (t.GetType() == identifier) { bool found = false; _Table::iterator it = TableStack.Find(t.GetValue(), found); if (found) { if (it->second->IsProc() || it->second->IsFunc()) { t = sc.GetNextToken(); return ParseSub((SymProc*)it->second); } } return ParseAssignment(); } if (t.GetValue() == "(") { return ParseAssignment(); } throw Error("Statement error", t); }
AST* ParseOperator(ParserState* parser) { AST* ast; switch(parser->currentToken.type) { case TOKEN_BEGIN: return ParseBlock(parser); case TOKEN_ID: ast = parser->nextToken.type == TOKEN_LEFTBRACKET ? ParseFunctionCall(parser) : ParseAssignment(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_LOCAL: ast = ParseAssignment(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_WHILE: return ParseWhileCycle(parser); case TOKEN_IF: return ParseIfStatement(parser); case TOKEN_FUNCTION: return ParseFunctionDefinition(parser); case TOKEN_RETURN: ast = ParseReturn(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_PRINT: ast = ParsePrint(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_INCLUDE: return ParseInclude(parser); case TOKEN_LOAD: ast = ParseLoad(parser); Match(parser, TOKEN_SEMICOLON); return ast; /** TODO: Factor common parts out of switch */ } FailWithUnexpectedToken(parser, parser->currentToken.type, TOKEN_ID); return NULL; }
asCScriptNode *asCParser::ParseArgList() { asCScriptNode *node = new asCScriptNode(snArgList); sToken t1; GetToken(&t1); if( t1.type != ttOpenParanthesis ) { Error(ExpectedToken("(").AddressOf(), &t1); return node; } node->UpdateSourcePos(t1.pos, t1.length); GetToken(&t1); if( t1.type == ttCloseParanthesis ) { node->UpdateSourcePos(t1.pos, t1.length); // Statement block is finished return node; } else { RewindTo(&t1); for(;;) { node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; // Check if list continues GetToken(&t1); if( t1.type == ttCloseParanthesis ) { node->UpdateSourcePos(t1.pos, t1.length); return node; } else if( t1.type == ttListSeparator ) continue; else { Error(ExpectedTokens(")", ",").AddressOf(), &t1); return node; } } } return 0; }
asCScriptNode *asCParser::ParseFor() { asCScriptNode *node = new asCScriptNode(snFor); sToken t; GetToken(&t); if( t.type != ttFor ) { Error(ExpectedToken("for").AddressOf(), &t); return node; } node->UpdateSourcePos(t.pos, t.length); GetToken(&t); if( t.type != ttOpenParanthesis ) { Error(ExpectedToken("(").AddressOf(), &t); return node; } if( IsVarDecl() ) node->AddChildLast(ParseDeclaration()); else node->AddChildLast(ParseExpressionStatement()); if( isSyntaxError ) return node; node->AddChildLast(ParseExpressionStatement()); if( isSyntaxError ) return node; GetToken(&t); if( t.type != ttCloseParanthesis ) { RewindTo(&t); node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t); if( t.type != ttCloseParanthesis ) { Error(ExpectedToken(")").AddressOf(), &t); return node; } } node->AddChildLast(ParseStatement()); return node; }
asCScriptNode *asCParser::ParseIf() { asCScriptNode *node = new asCScriptNode(snIf); sToken t; GetToken(&t); if( t.type != ttIf ) { Error(ExpectedToken("if").AddressOf(), &t); return node; } node->UpdateSourcePos(t.pos, t.length); GetToken(&t); if( t.type != ttOpenParanthesis ) { Error(ExpectedToken("(").AddressOf(), &t); return node; } node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t); if( t.type != ttCloseParanthesis ) { Error(ExpectedToken(")").AddressOf(), &t); return node; } node->AddChildLast(ParseStatement()); if( isSyntaxError ) return node; GetToken(&t); if( t.type != ttElse ) { // No else statement return already RewindTo(&t); return node; } node->AddChildLast(ParseStatement()); return node; }
asCScriptNode *asCParser::ParseExprPostOp() { asCScriptNode *node = new asCScriptNode(snExprPostOp); sToken t; GetToken(&t); if( !IsPostOperator(t.type) ) { Error(TXT_EXPECTED_POST_OPERATOR, &t); return node; } node->SetToken(&t); node->UpdateSourcePos(t.pos, t.length); if( t.type == ttDot ) { sToken t1, t2; GetToken(&t1); GetToken(&t2); RewindTo(&t1); if( t2.type == ttOpenParanthesis ) node->AddChildLast(ParseFunctionCall()); else node->AddChildLast(ParseIdentifier()); } else if( t.type == ttOpenBracket ) { node->AddChildLast(ParseAssignment()); GetToken(&t); if( t.type != ttCloseBracket ) { ExpectedToken("]"); return node; } node->UpdateSourcePos(t.pos, t.length); } return node; }
bool GCFS_Utils::ParseConfigString(char * string, GCFS_Utils::keyValueArray_t& vValues) { // replace $(process) with @(process) to get rid of '$' character. It is delimiter as well ReplaceToken(string, "$(process)", "@(process)"); // Parse all the commands/assignments char * pPos = NULL; // TODO: Write own tokenizer to allow escaping and quotes to avoid splitting char * pToken = strtok_r(string, GCFS_CONFIG_DELIMITERS, &pPos); while(pToken != NULL) { ReplaceToken(pToken, "@(process)", "$(process)"); vValues.push_back(ParseAssignment(pToken)); pToken = strtok_r(NULL, GCFS_CONFIG_DELIMITERS, &pPos); } return true; }
asCScriptNode *asCParser::ParseAssignment() { asCScriptNode *node = new asCScriptNode(snAssignment); node->AddChildLast(ParseCondition()); if( isSyntaxError ) return node; sToken t; GetToken(&t); RewindTo(&t); if( IsAssignOperator(t.type) ) { node->AddChildLast(ParseAssignOperator()); if( isSyntaxError ) return node; node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; } return node; }
asCScriptNode *asCParser::ParseExprValue() { asCScriptNode *node = new asCScriptNode(snExprValue); sToken t1; GetToken(&t1); RewindTo(&t1); if( t1.type == ttIdentifier || IsRealType(t1.type) ) { if( IsFunctionCall() ) node->AddChildLast(ParseFunctionCall()); else node->AddChildLast(ParseIdentifier()); } else if( t1.type == ttCast ) node->AddChildLast(ParseCast()); else if( IsConstant(t1.type) ) node->AddChildLast(ParseConstant()); else if( t1.type == ttOpenParanthesis ) { GetToken(&t1); node->UpdateSourcePos(t1.pos, t1.length); node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t1); if( t1.type != ttCloseParanthesis ) Error(ExpectedToken(")").AddressOf(), &t1); node->UpdateSourcePos(t1.pos, t1.length); } else Error(TXT_EXPECTED_EXPRESSION_VALUE, &t1); return node; }
StatementFor* Parser::ParseFor() { NodeExpression* expr; NodeStatement* body; StatementAssign* assign; bool isDownto = false; t = sc.GetNextToken(); assign = ParseAssignment(); if (!assign->GetType()->IsInt()) throw Error("Ordinal expression expected", t); if (t.GetValue() == "downto") isDownto = true; else if (t.GetValue() != "to") throw Error("\"to\" or \"downto\" expected", t); t = sc.GetNextToken(); expr = ParseComparision(); if (!expr->GetType()->IsInt()) throw Error("ordinal expression expected", t); t = RequireToken("do", "\"do\" expected"); body = ParseElement(); return new StatementFor(expr, body, assign, isDownto); }
bool LinkPartition::ParseOverlays(LinkManager *manager, CmdFiles &files, LinkTokenizer &spec) { if (!spec.MustMatch(LinkTokenizer::eBegin)) return false; bool done = false; while (!done) { if (spec.Matches(LinkTokenizer::eSymbol)) { if (!ParseAssignment(spec)) return false; if (!spec.MustMatch(LinkTokenizer::eSemi)) return false; } else if (spec.Matches(LinkTokenizer::eRegion)) { spec.NextToken(); if (!CreateSeparateRegions(manager, files, spec)) return false; } else if (!spec.MustMatch(LinkTokenizer::eOverlay)) { done = true; } else { LinkOverlay *newOverlay = new LinkOverlay(this); overlays.push_back(new LinkOverlaySpecifier(newOverlay)); if (!newOverlay->ParseOverlaySpec(manager, files, spec)) return false; if (!spec.MustMatch(LinkTokenizer::eSemi)) return false; } } return spec.MustMatch(LinkTokenizer::eEnd); }
asCScriptNode *asCParser::ParseSwitch() { asCScriptNode *node = new asCScriptNode(snSwitch); sToken t; GetToken(&t); if( t.type != ttSwitch ) { Error(ExpectedToken("switch").AddressOf(), &t); return node; } node->UpdateSourcePos(t.pos, t.length); GetToken(&t); if( t.type != ttOpenParanthesis ) { Error(ExpectedToken("(").AddressOf(), &t); return node; } node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t); if( t.type != ttCloseParanthesis ) { Error(ExpectedToken(")").AddressOf(), &t); return node; } GetToken(&t); if( t.type != ttStartStatementBlock ) { Error(ExpectedToken("{").AddressOf(), &t); return node; } while( !isSyntaxError ) { GetToken(&t); if( t.type == ttEndStatementBlock || t.type == ttDefault) break; RewindTo(&t); if( t.type != ttCase ) { Error(ExpectedToken("case").AddressOf(), &t); return node; } node->AddChildLast(ParseCase()); if( isSyntaxError ) return node; } if( t.type == ttDefault) { RewindTo(&t); node->AddChildLast(ParseCase()); if( isSyntaxError ) return node; GetToken(&t); } if( t.type != ttEndStatementBlock ) { Error(ExpectedToken("}").AddressOf(), &t); return node; } return node; }
asCScriptNode *asCParser::ParseInitList() { asCScriptNode *node = new asCScriptNode(snInitList); sToken t1; GetToken(&t1); if( t1.type != ttStartStatementBlock ) { Error(ExpectedToken("{").AddressOf(), &t1); return node; } node->UpdateSourcePos(t1.pos, t1.length); GetToken(&t1); if( t1.type == ttEndStatementBlock ) { node->UpdateSourcePos(t1.pos, t1.length); // Statement block is finished return node; } else { RewindTo(&t1); for(;;) { GetToken(&t1); if( t1.type == ttListSeparator ) { // No expression node->AddChildLast(new asCScriptNode(snUndefined)); GetToken(&t1); if( t1.type == ttEndStatementBlock ) { // No expression node->AddChildLast(new asCScriptNode(snUndefined)); node->UpdateSourcePos(t1.pos, t1.length); return node; } RewindTo(&t1); } else if( t1.type == ttEndStatementBlock ) { // No expression node->AddChildLast(new asCScriptNode(snUndefined)); node->UpdateSourcePos(t1.pos, t1.length); // Statement block is finished return node; } else if( t1.type == ttStartStatementBlock ) { RewindTo(&t1); node->AddChildLast(ParseInitList()); if( isSyntaxError ) return node; GetToken(&t1); if( t1.type == ttListSeparator ) continue; else if( t1.type == ttEndStatementBlock ) { node->UpdateSourcePos(t1.pos, t1.length); // Statement block is finished return node; } else { Error(ExpectedTokens("}", ",").AddressOf(), &t1); return node; } } else { RewindTo(&t1); node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t1); if( t1.type == ttListSeparator ) continue; else if( t1.type == ttEndStatementBlock ) { node->UpdateSourcePos(t1.pos, t1.length); // Statement block is finished return node; } else { Error(ExpectedTokens("}", ",").AddressOf(), &t1); return node; } } } } return 0; }