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

C++ 在手写解析器中翻译语法文件,c++,parsing,bison,yacc,C++,Parsing,Bison,Yacc,出于教育目的,我一直在尝试编写自己的编译器,但我遇到了一个问题。我已经采用了递归下降方法,并了解了一些关于lex和yacc/bison的知识 到目前为止,我只是尝试处理解析方面,而不考虑AST的生成或代码生成 我正在尝试为这个特定的语法文件部分编写表达式解析 primary_expression : IDENTIFIER | CONSTANT | STRING_LITERAL | '(' expression ')' ; postfix_expressi

出于教育目的,我一直在尝试编写自己的编译器,但我遇到了一个问题。我已经采用了递归下降方法,并了解了一些关于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\u表达式的递归性时遇到了一些问题,我不知道如何继续使用
postfix表达式
函数

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


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

请注意,
postfix\u表达式
总是首先解析
primary\u表达式
,因此第一个业务顺序是
primaryExpression()

然后,如果下一个字符是其余七条规则中递归
postfix\u表达式
后面的任何字符,则您正在解析
postfix\u表达式
。这将获得另一个
posfix\u表达式
,因此您可以再次重复

<>我不会为你编写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(递归下降)解析器中很难处理——您需要识别at并将其更改为循环,而不是递归调用。一般来说,您希望将左递归重构为

A→ α| Aβ

然后你的反复下降程序就变成了

parseA() {
    parseAlpha();
    while (lookaheadMatchesBeta())
        parseBeta();
}
注意,这需要足够的前瞻性来区分第一个(β)和后续(A),以便找到所有可以匹配β的后续内容的结尾

这与在LL语法中消除左递归的过程相同——您实际上是在用

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

然后用循环替换
parseAPrime
中的尾部递归调用,并将其内联到
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;
        }
    }
}