Пример #1
0
bool
Parser::parseFunDeclArgsRest(
    AstFunDeclNode* fun
    )
{
    std::string name;
    AstTypeNode* type;

#ifdef DEBUG_PARSER
    fprintf( stderr, "parseFunDeclArgsRest\n" );
#endif /* DEBUG_PARSER */

    switch( peek() )
    {
    case LEXTOK_SCOL:
        if( !match( LEXTOK_SCOL ) )
            return false;

        name = peekStr();
        if( !match( LEXTOK_IDENT ) ||
            !match( LEXTOK_COL ) ||
            !parseTypeIdent( type ) )
            return false;

        fun->addArg( name.c_str(), type );
        return parseFunDeclArgsRest( fun );

    case LEXTOK_RPAR:
        return true;

    default:
        return error();
    }
}
Пример #2
0
bool
Parser::parseIdentListRest(
    std::vector< std::string >& idents
    )
{
#ifdef DEBUG_PARSER
    fprintf( stderr, "parseIdentListRest\n" );
#endif /* DEBUG_PARSER */

    switch( peek() )
    {
    case LEXTOK_COMMA:
        if( !match( LEXTOK_COMMA ) )
            return false;

        idents.push_back( peekStr() );

        return match( LEXTOK_IDENT )
            && parseIdentListRest( idents );

    case LEXTOK_EQ:
    case LEXTOK_COL:
        return true;

    default:
        return error();
    }
}
Пример #3
0
bool
Parser::parseExpr5(
    AstExprNode*& expr
    )
{
    std::string name;

#ifdef DEBUG_PARSER
    fprintf( stderr, "parseExpr5\n" );
#endif /* DEBUG_PARSER */

    switch( peek() )
    {
        // Expr5:
    case LEXTOK_IDENT:
        name = peekStr();

        return match( LEXTOK_IDENT )
            && parseExpr5Ident( name, expr );

    case LEXTOK_NUMBER:
        expr = new AstIntExprNode( peekInt() );

        return match( LEXTOK_NUMBER );

    case LEXTOK_LPAR:
        return match( LEXTOK_LPAR )
            && parseExpr0( expr )
            && match( LEXTOK_RPAR );

    default:
        return error();
    }
}
Пример #4
0
/// Try and match a given string in the input
/// The string is consumed if matched
bool Input::matchStr(const std::string& str)
{
    if (peekStr(str))
    {
        for (size_t i = 0; i < str.length(); ++i)
            readCh();

        return true;
    }

    return false;
}
Пример #5
0
bool
Parser::parseVarDeclRest(
    AstBlkStmtNode* blk
    )
{
    AstTypeNode* type;
    std::vector< std::string > idents;
    std::vector< std::string >::const_iterator cur, end;

#ifdef DEBUG_PARSER
    fprintf( stderr, "parseVarDeclRest\n" );
#endif /* DEBUG_PARSER */

    switch( peek() )
    {
    case LEXTOK_IDENT:
        idents.push_back( peekStr() );

        if( !match( LEXTOK_IDENT ) ||
            !parseIdentListRest( idents ) ||
            !match( LEXTOK_COL ) ||
            !parseTypeIdent( type ) ||
            !match( LEXTOK_SCOL ) )
            return false;

        cur = idents.begin();
        end = idents.end();

        blk->addDecl(
            new AstVarDeclNode(
                (cur++)->c_str(), type ) );

        for(; cur != end; ++cur )
            blk->addDecl(
                new AstVarDeclNode(
                    cur->c_str(),
                    type->clone() ) );

        return parseVarDeclRest( blk );

    case LEXTOK_KW_CONST:
    case LEXTOK_KW_VAR:
    case LEXTOK_KW_BEGIN:
        return true;

    default:
        return error();
    }
}
Пример #6
0
bool
Parser::parseProgram(
    AstProgDeclNode*& prog
    )
{
    AstFunDeclNode* fun;
    AstBlkStmtNode* blk;

#ifdef DEBUG_PARSER
    fprintf( stderr, "parseProgram\n" );
#endif /* DEBUG_PARSER */

    switch( peek() )
    {
    case LEXTOK_KW_PROG:
        if( !match( LEXTOK_KW_PROG ) )
            return false;

        prog = new AstProgDeclNode(
            peekStr().c_str() );
        blk = new AstBlkStmtNode();

        if( !match( LEXTOK_IDENT ) ||
            !match( LEXTOK_SCOL ) ||
            !parseDeclsGlob( prog ) ||
            !parseBlock( blk ) ||
            !match( LEXTOK_DOT ) ||
            !match( LEXTOK_EOI ) )
            return false;

        fun = new AstFunDeclNode( "main" );
        fun->setResType( new AstIntTypeNode() );
        fun->setBody( blk );

        prog->addFun( fun );
        return true;

    default:
        return error();
    }
}
Пример #7
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();
    }
}
Пример #8
0
bool
Parser::parseDeclsGlob(
    AstProgDeclNode* prog
    )
{
    AstFunDeclNode* fun;
    AstTypeNode* resType;

#ifdef DEBUG_PARSER
    fprintf( stderr, "parseDeclsGlob\n" );
#endif /* DEBUG_PARSER */

    switch( peek() )
    {
    case LEXTOK_KW_FUNC:
        if( !match( LEXTOK_KW_FUNC ) )
            return false;

        fun = new AstFunDeclNode(
            peekStr().c_str() );

        if( !match( LEXTOK_IDENT ) ||
            !match( LEXTOK_LPAR ) ||
            !parseFunDeclArgs( fun ) ||
            !match( LEXTOK_RPAR ) ||
            !match( LEXTOK_COL ) ||
            !parseTypeIdent( resType ) ||
            !match( LEXTOK_SCOL ) ||
            !parseFunDeclBody( fun ) ||
            !match( LEXTOK_SCOL ) )
            return false;

        fun->setResType( resType );
        prog->addFun( fun );

        return parseDeclsGlob( prog );

    case LEXTOK_KW_PROC:
        if( !match( LEXTOK_KW_PROC ) )
            return false;

        fun = new AstFunDeclNode(
            peekStr().c_str() );

        if( !match( LEXTOK_IDENT ) ||
            !match( LEXTOK_LPAR ) ||
            !parseFunDeclArgs( fun ) ||
            !match( LEXTOK_RPAR ) ||
            !match( LEXTOK_SCOL ) ||
            !parseFunDeclBody( fun ) ||
            !match( LEXTOK_SCOL ) )
            return false;

        fun->setResType( NULL );
        prog->addFun( fun );

        return parseDeclsGlob( prog );

    case LEXTOK_KW_CONST:
    case LEXTOK_KW_VAR:
    case LEXTOK_KW_BEGIN:
        return true;

    default:
        return error();
    }
}