簡體   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