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?
The bnf you are using is the problem :
Look at your example (2 2 +) and your entry rule:
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.