Parsing with MPC library in C returns only first number

282 views Asked by At

I'm attempting to write a Reverse Polish Notation parser with the MPC (Micro Parser Combinator) library for C. However, either a problem with the grammar I'm using or another problem elsewhere means that it only outputs the first number rather than the full AST.

The grammar:

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);

The parsing:

/* 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);
    }

The input:

2 2 +

The output:

number|regex:1:1 '2'

Any such input reads only the initial number (e.g. '54 8 /' outputs only 54). Any ideas?

1

There are 1 answers

0
Tezirg On BEST ANSWER

The bnf you are using is the problem :

Look at your example (2 2 +) and your entry rule:

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

1 - rpn left part is not matched by input : 2 != (
2 - then number is matched
3 - end of rule number, end of rule rpn, stop parsing

Now, I think that you could try to input "( 2 2 + )"
The fix will then be to make the parenthesis of your entry rule optional.