0

C 用の MPC (Micro Parser Combinator) ライブラリを使用して逆ポーランド記法パーサーを作成しようとしています。フルAST。

文法:

mpc_parser_t* Number   = mpc_new("number");
mpc_parser_t* Exp      = mpc_new("exp");
mpc_parser_t* Exp1     = mpc_new("exp1");
mpc_parser_t* Term     = mpc_new("term");
mpc_parser_t* Term1    = mpc_new("term1");
mpc_parser_t* RPN      = mpc_new("rpn");

/* BNF for RPN */ 
mpca_lang(MPCA_LANG_DEFAULT,
    "                                                         \
        number  : /-?[0-9]+/;                                 \
        exp     : <term> <exp1>;                              \
        exp1    : '+' <term> <exp1> | '-' <term> <exp1> | ''; \
        term    : <rpn> <term1>;                              \
        term1   : '*' <rpn> <term1> | '/' <rpn> <term1> | ''; \
        rpn     : '(' <exp> ')' | <number>;                   \
    ", Number, Exp, Exp1, Term, Term1, RPN);

解析:

/* Attempt to Parse user input */
    mpc_result_t r;
    if (mpc_parse("<stdin>", input, RPN, &r)) {
        /* On success print AST */
        mpc_ast_print(r.output);
        mpc_ast_delete(r.output);
    } else {
        /* Otherwise print error */
        mpc_err_print(r.error);
        mpc_err_delete(r.error);
    }

入力:

2 2 +

出力:

number|regex:1:1 '2'

このような入力は、最初の数だけを読み取ります (たとえば、'54 8 /' は 54 のみを出力します)。何か案は?

4

1 に答える 1

1

使用している bnf が問題です:

あなたの例 (2 2 +) とエントリ ルールを見てください。

rpn     : '(' <exp> ')' | <number>;

1 - rpn の左部分が入力と一致しません: 2 != (
2 - 次に番号が一致します
3 - ルール番号の終わり、ルール rpn の終わり、解析の停止

ここで、「( 2 2 + )」と入力してみてください
。修正は、エントリ ルールの括弧をオプションにすることです。

于 2015-06-12T03:52:25.007 に答える