将语法转换为 LL(1)

发布于 2024-10-31 10:01:00 字数 2067 浏览 0 评论 0原文

我有这样的语法:

program ::= expr_list

expr_list ::= {LF} [expr {LF {LF} expr}] {LF}

lvalue ::= [expr DOT] NAME

call_param ::= [[NAME COLON] expr {COMMA [NAME COLON] expr}]

func_param ::= [NAME [COLON expr] {COMMA NAME [COLON expr]}]

expr ::= lvalue
       | lvalue ASSIGN expr
       | expr OPAREN call_param CPAREN
       | FUNC func_param LF expr_list END
       | IF expr LF expr_list {ELSEIF expr LF expr_list} [ELSE expr_list] ENDIF
       | WHILE expr LF expr_list LOOP
       | DO expr_list LOOP WHILE expr LF
       | INTEGER

我部分地编写了一个递归下降解析器:

void Parser::ntProgram()
{
    ntExprList();
}

void Parser::ntExprList()
{
    // ???
}

void Parser::ntLvalue()
{
    // ???
}

void Parser::ntCallParam()
{
    // ???
}

void Parser::ntFuncParam()
{
    if (accept(Lexer::NameTok)) {
        if (accept(Lexer::ColonTok)) {
            ntExpr();
        }
    }
    while (accept(Lexer::CommaTok)) {
        expect(Lexer::NameTok);
        if (accept(Lexer::ColonTok)) {
            ntExpr();
        }
    }
}

void Parser::ntExpr()
{
    if (accept(Lexer::FuncTok))
    {
        ntFuncParam();
        expect(Lexer::LfTok);
        ntExprList();
        expect(Lexer::EndTok);
    }
    else if (accept(Lexer::WhileTok))
    {
        ntExpr();
        expect(Lexer::LfTok);
        ntExprList();
        expect(Lexer::LoopTok);
    }
    else if (accept(Lexer::DoTok))
    {
        ntExprList();
        expect(Lexer::WhileTok);
        expect(Lexer::LoopTok);
        ntExpr();
        expect(Lexer::LfTok);
    }
    else if (accept(Lexer::IfTok))
    {
        ntExpr();
        expect(Lexer::LfTok);
        ntExprList();
        while (accept(Lexer::ElseifTok))
        {
            ntExpr();
            expect(Lexer::LfTok);
            ntExprList();
        }
        if (accept(Lexer::ElseTok))
        {
            ntExprList();
        }
        expect(Lexer::EndifTok);
    }
    else if (accept(Lexer::IntegerTok))
    {
    }
}

但我不知道在某些部分要做什么,例如 expr 可以是左值,其第一项可以是 expr。

I have this grammar:

program ::= expr_list

expr_list ::= {LF} [expr {LF {LF} expr}] {LF}

lvalue ::= [expr DOT] NAME

call_param ::= [[NAME COLON] expr {COMMA [NAME COLON] expr}]

func_param ::= [NAME [COLON expr] {COMMA NAME [COLON expr]}]

expr ::= lvalue
       | lvalue ASSIGN expr
       | expr OPAREN call_param CPAREN
       | FUNC func_param LF expr_list END
       | IF expr LF expr_list {ELSEIF expr LF expr_list} [ELSE expr_list] ENDIF
       | WHILE expr LF expr_list LOOP
       | DO expr_list LOOP WHILE expr LF
       | INTEGER

I partially wrote a recursive descent parser:

void Parser::ntProgram()
{
    ntExprList();
}

void Parser::ntExprList()
{
    // ???
}

void Parser::ntLvalue()
{
    // ???
}

void Parser::ntCallParam()
{
    // ???
}

void Parser::ntFuncParam()
{
    if (accept(Lexer::NameTok)) {
        if (accept(Lexer::ColonTok)) {
            ntExpr();
        }
    }
    while (accept(Lexer::CommaTok)) {
        expect(Lexer::NameTok);
        if (accept(Lexer::ColonTok)) {
            ntExpr();
        }
    }
}

void Parser::ntExpr()
{
    if (accept(Lexer::FuncTok))
    {
        ntFuncParam();
        expect(Lexer::LfTok);
        ntExprList();
        expect(Lexer::EndTok);
    }
    else if (accept(Lexer::WhileTok))
    {
        ntExpr();
        expect(Lexer::LfTok);
        ntExprList();
        expect(Lexer::LoopTok);
    }
    else if (accept(Lexer::DoTok))
    {
        ntExprList();
        expect(Lexer::WhileTok);
        expect(Lexer::LoopTok);
        ntExpr();
        expect(Lexer::LfTok);
    }
    else if (accept(Lexer::IfTok))
    {
        ntExpr();
        expect(Lexer::LfTok);
        ntExprList();
        while (accept(Lexer::ElseifTok))
        {
            ntExpr();
            expect(Lexer::LfTok);
            ntExprList();
        }
        if (accept(Lexer::ElseTok))
        {
            ntExprList();
        }
        expect(Lexer::EndifTok);
    }
    else if (accept(Lexer::IntegerTok))
    {
    }
}

But I don't know what to do in some parts, for example the way that an expr can be an lvalue, whose first item could be an expr.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

二智少女 2024-11-07 10:01:00

为了能够解析expr规则,你必须首先消除左递归。维基百科对此有很好的解释:

http://en.wikipedia.org/wiki/Left_recursion

In order to be able to parse the expr rule, you have to eliminate left recursion first. This is well explained on Wikipedia:

http://en.wikipedia.org/wiki/Left_recursion

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文