Example #1
0
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;
	}
}
Example #2
0
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();
    }
}
Example #3
0
File: parser.cpp Project: wfwt/jszb
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);
}
Example #4
0
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*>();
}
Example #5
0
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;
	}
}
Example #6
0
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();
    }
}
Example #7
0
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();
    }
}
Example #8
0
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;
}
Example #9
0
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();
    }
}