繁体   English   中英

在手写的解析器中翻译语法文件

[英]Translating a grammar file in a hand written parser

我一直在尝试编写自己的编译器用于教育目的而且我遇到了问题。 我采用递归下降方法,先前有一些关于lex和yacc / bison的知识。

到目前为止,我只是试图处理解析方面而不考虑AST的生成或代码生成。

我正在尝试为这个特定的语法文件部分编写表达式解析

primary_expression
    : IDENTIFIER
    | CONSTANT
    | STRING_LITERAL
    | '(' expression ')'
    ;

postfix_expression
    : primary_expression
    | postfix_expression '[' expression ']'
    | postfix_expression '(' ')'
    | postfix_expression '(' argument_expression_list ')'
    | postfix_expression '.' IDENTIFIER
    | postfix_expression PTR_OP IDENTIFIER
    | postfix_expression INC_OP
    | postfix_expression DEC_OP
    ;

到目前为止,我有这个代码

void Parser::primaryExpression()
{
    if (accept(Token::eIdentifier))
    {

    }
    else if (accept(Token::eIntNumber))
    {

    }
    else if (accept('('))
    {
        expression();
        expect(')');
    }
}
void Parser::postfixExpression()
{

}

我在处理postfix_expression的递归方面遇到了一些问题,我不知道如何继续使用postfixExpression函数。

我的印象是,对于递归下降解析器,我应该以不同的方式安排我的语法。

有人能指出我正确的方向吗?

请注意, postfix_expression始终首先解析primary_expression ,因此第一个业务顺序是primaryExpression()

然后,如果下一个字符是其余七个规则中的递归postfix_expression之后的任何字符,那么您正在解析postfix_expression posfix_expression你另一个posfix_expression ,所以你再次重复。

我不会为你编写C ++代码,但是在伪代码中:

postfixExpression()
{
    primaryExpression();
    while (next character is any of the characters that follow
           postfix_expression in the remaining seven rules)
    {
         parse_the_appropriate_rule();
    }
}

在LL(递归下降)解析器中难以处理左递归 - 您需要识别并将其更改为循环而不是递归调用。 一般而言,您希望将左递归重构为

A→α|

然后你的背诵下降程序就变成了

parseA() {
    parseAlpha();
    while (lookaheadMatchesBeta())
        parseBeta();
}

请注意,这需要足够的先行来区分FIRST(β)和FOLLOW(A),以便找到所有可以匹配β的尾随事物的结尾

这与在LL语法中消除左递归的过程相同 - 您实际上正在替换上面的规则

A→αA'
A'→ε| βA'

然后用循环替换parseAPrime的tail-recursive调用并将其内联到parseA

使用您的语法并使用上面的代码使用的accept / expect技术,您会得到类似的结果:

void Parser::postfixExpression() {
    primaryExpression();
    while (true) {
        if (accept('[')) {
            expression();
            expect(']');
        } else if (accept('(')) {
            if (accept(')')) {
            } else {
                argumentExpressionList();
                expect(')'); }
        } else if (accept('.')) {

        } else if (accept(Token::DEC_OP)) {
        } else {
            break;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM