Stmt* Parser::parseStmt() { if ( check( IDENT_T ) ) { Token ID = match( IDENT_T ); Stmt* node = parseStmtID( ID.lexeme, ID.line, ID.column ); match( SEMICOLON_T ); return node; } else if ( check( BEGIN_T ) ) { Token begin = match( BEGIN_T ); list<Stmt*> body = parseStmts(); match( END_T ); match( SEMICOLON_T ); Sequence* node = new Sequence( body, begin.line, begin.column ); return node; } else if ( check( IF_T ) ) { Token ifToken = match( IF_T ); Expr* test = parseExpr(); match( THEN_T ); Stmt* trueClause = parseStmt(); Stmt* node = parseStmtIf( test, trueClause, ifToken.line, ifToken.column ); return node; } else if ( check( WHILE_T ) ) { Token whileToken = match( WHILE_T ); Expr* test = parseExpr(); match( DO_T ); Stmt* body = parseStmt(); While* node = new While( test, body, whileToken.line, whileToken.column ); return node; } else if ( check( PROMPT_T ) ) { Token prompt = match( PROMPT_T ); Token message = match( STRINGCONST_T ); Stmt* node = parseStmtPrompt( message.lexeme, prompt.line, prompt.column ); match( SEMICOLON_T ); return node; } else { Token print = match( PRINT_ST ); list<Item*> items = parseItems(); match( SEMICOLON_T ); Print* node = new Print( items, print.line, print.column ); return node; } }
bool Parser::parseElseBranch( AstBlkStmtNode*& blk ) { #ifdef DEBUG_PARSER fprintf( stderr, "parseElseBranch\n" ); #endif /* DEBUG_PARSER */ switch( peek() ) { case LEXTOK_KW_ELSE: blk = new AstBlkStmtNode(); return match( LEXTOK_KW_ELSE ) && parseStmt( blk ); case LEXTOK_SCOL: case LEXTOK_KW_END: blk = NULL; return true; default: return error(); } }
static Formula *parseFormula(Parser *p) { Stmt *stmt; Array stmts; arrayInit(&stmts, sizeof(Stmt *), 8); do { p->tok = lexerGetToken(p->lex, &p->tokval, &p->toklen); if (p->tok == TK_ID) { stmt = parseStmt(p); if (stmt) { Stmt **p = (Stmt **)arrayAdd(&stmts); *p = stmt; } else if (p->isquit){ goto end; } } else if (p->tok == TK_EOF) { break; } else { if (handleParserError(p, 1, "解析formula,不识别符号")) { break; } } } while (1); end: #ifdef LOG_PARSE info("解析得到formula\n"); #endif return formulaNew(&stmts); }
list<Stmt*> Parser::parseStmts() { if ( check( IDENT_T ) || check( BEGIN_T ) || check( IF_T ) || check( WHILE_T ) || check( PROMPT_T ) || check( PRINT_ST ) ) { Stmt* stmt = parseStmt(); list<Stmt*> stmts = parseStmts(); stmts.push_front( stmt ); return stmts; } else return list<Stmt*>(); }
Stmt* Parser::parseStmtIf( Expr* t, Stmt* tr, int lin, int col ) { if ( check( ELSE_T ) ) { match( ELSE_T ); Stmt* falseClause = parseStmt(); IfThenElse* node = new IfThenElse( t, tr, falseClause, lin, col ); return node; } else { IfThen* node = new IfThen( t, tr, lin, col ); return node; } }
bool Parser::parseBlockRest( AstBlkStmtNode* blk ) { #ifdef DEBUG_PARSER fprintf( stderr, "parseBlockRest\n" ); #endif /* DEBUG_PARSER */ switch( peek() ) { case LEXTOK_SCOL: return match( LEXTOK_SCOL ) && parseStmt( blk ) && parseBlockRest( blk ); case LEXTOK_KW_END: return true; default: return error(); } }
bool Parser::parseBlock( AstBlkStmtNode* blk ) { #ifdef DEBUG_PARSER fprintf( stderr, "parseBlock\n" ); #endif /* DEBUG_PARSER */ switch( peek() ) { case LEXTOK_KW_CONST: case LEXTOK_KW_VAR: case LEXTOK_KW_BEGIN: return parseDeclsLoc( blk ) && match( LEXTOK_KW_BEGIN ) && parseStmt( blk ) && parseBlockRest( blk ) && match( LEXTOK_KW_END ); default: return error(); } }
static int parse(ej_t *ep, int state, int flags) { a_assert(ep); switch (state) { /* * Any statement, function arguments or conditional expressions */ case STATE_STMT: if ((state = parseStmt(ep, state, flags)) != STATE_STMT_DONE && state != STATE_EOF && state != STATE_STMT_BLOCK_DONE && state != STATE_RET) { state = STATE_ERR; } break; case STATE_DEC: if ((state = parseStmt(ep, state, flags)) != STATE_DEC_DONE && state != STATE_EOF) { state = STATE_ERR; } break; case STATE_EXPR: if ((state = parseStmt(ep, state, flags)) != STATE_EXPR_DONE && state != STATE_EOF) { state = STATE_ERR; } break; /* * Variable declaration list */ case STATE_DEC_LIST: state = parseDeclaration(ep, state, flags); break; /* * Function argument string */ case STATE_ARG_LIST: state = parseArgs(ep, state, flags); break; /* * Logical condition list (relational operations separated by &&, ||) */ case STATE_COND: state = parseCond(ep, state, flags); break; /* * Expression list */ case STATE_RELEXP: state = parseExpr(ep, state, flags); break; } if (state == STATE_ERR && ep->error == NULL) { ejError(ep, T("Syntax error")); } return state; }
bool Parser::parseStmt( AstBlkStmtNode* blk ) { bool inc; std::string str; AstExprNode *expr1, *expr2; AstBlkStmtNode *bodyBlk, *elseBlk; #ifdef DEBUG_PARSER fprintf( stderr, "parseStmt\n" ); #endif /* DEBUG_PARSER */ switch( peek() ) { case LEXTOK_IDENT: str = peekStr(); return match( LEXTOK_IDENT ) && parseStmtIdent( str, blk ); case LEXTOK_KW_IF: bodyBlk = new AstBlkStmtNode(); elseBlk = NULL; if( !match( LEXTOK_KW_IF ) || !parseExpr0( expr1 ) || !match( LEXTOK_KW_THEN ) || !parseStmt( bodyBlk ) || !parseElseBranch( elseBlk ) ) return false; blk->addStmt( new AstIfStmtNode( expr1, bodyBlk, elseBlk ) ); return true; case LEXTOK_KW_WHILE: if( !match( LEXTOK_KW_WHILE ) || !parseExpr0( expr1 ) || !match( LEXTOK_KW_DO ) ) return false; bodyBlk = new AstBlkStmtNode(); bodyBlk->addStmt( new AstBreakStmtNode( new AstUnopExprNode( LEXTOK_NOT, expr1 ) ) ); if( !parseStmt( bodyBlk ) ) return false; blk->addStmt( new AstLoopStmtNode( bodyBlk ) ); return true; case LEXTOK_KW_FOR: if( !match( LEXTOK_KW_FOR ) ) return false; str = peekStr(); if( !match( LEXTOK_IDENT ) || !match( LEXTOK_ASSGN ) || !parseExpr0( expr1 ) || !parseForDirection( inc ) || !parseExpr0( expr2 ) || !match( LEXTOK_KW_DO ) ) return false; bodyBlk = new AstBlkStmtNode(); bodyBlk->addStmt( new AstBreakStmtNode( new AstBinopExprNode( (inc ? LEXTOK_GT : LEXTOK_LT), new AstVarExprNode( str.c_str() ), expr2 ) ) ); if( !parseStmt( bodyBlk ) ) return false; bodyBlk->addStmt( new AstBinopStmtNode( (inc ? LEXTOK_KW_INC : LEXTOK_KW_DEC), new AstVarExprNode( str.c_str() ), new AstIntExprNode( 1 ) ) ); blk->addStmt( new AstBinopStmtNode( LEXTOK_ASSGN, new AstVarExprNode( str.c_str() ), expr1 ) ); blk->addStmt( new AstLoopStmtNode( bodyBlk ) ); return true; case LEXTOK_KW_EXIT: blk->addStmt( new AstExitStmtNode() ); return match( LEXTOK_KW_EXIT ); case LEXTOK_KW_CONST: case LEXTOK_KW_VAR: case LEXTOK_KW_BEGIN: return parseBlock( blk ); case LEXTOK_KW_INC: if( !match( LEXTOK_KW_INC ) || !match( LEXTOK_LPAR ) ) return false; str = peekStr(); if( !match( LEXTOK_IDENT ) || !parseStmtLvalIdent( str, expr1 ) || !match( LEXTOK_RPAR ) ) return false; blk->addStmt( new AstBinopStmtNode( LEXTOK_KW_INC, expr1, new AstIntExprNode( 1 ) ) ); return true; case LEXTOK_KW_DEC: if( !match( LEXTOK_KW_DEC ) || !match( LEXTOK_LPAR ) ) return false; str = peekStr(); if( !match( LEXTOK_IDENT ) || !parseStmtLvalIdent( str, expr1 ) || !match( LEXTOK_RPAR ) ) return false; blk->addStmt( new AstBinopStmtNode( LEXTOK_KW_DEC, expr1, new AstIntExprNode( 1 ) ) ); return true; case LEXTOK_KW_READLN: if( !match( LEXTOK_KW_READLN ) || !match( LEXTOK_LPAR ) ) return false; str = peekStr(); if( !match( LEXTOK_IDENT ) || !parseStmtLvalIdent( str, expr1 ) || !match( LEXTOK_RPAR ) ) return false; blk->addStmt( new AstReadStmtNode( "%d", expr1 ) ); return true; case LEXTOK_KW_WRITE: if( !match( LEXTOK_KW_WRITE ) || !match( LEXTOK_LPAR ) ) return false; str = peekStr(); if( !match( LEXTOK_STRING ) || !match( LEXTOK_RPAR ) ) return false; blk->addStmt( new AstWriteStmtNode( "%s", new AstStrExprNode( str.c_str() ) ) ); return true; case LEXTOK_KW_WRITELN: if( !match( LEXTOK_KW_WRITELN ) || !match( LEXTOK_LPAR ) || !parseExpr0( expr1 ) || !match( LEXTOK_RPAR ) ) return false; blk->addStmt( new AstWriteStmtNode( "%d\n", expr1 ) ); return true; case LEXTOK_SCOL: case LEXTOK_KW_END: return true; default: return error(); } }