Parsing User Input
Our new code creates a mpc
parser for our Polish Notation language, but we still need to actually use it on the user input supplied each time from the prompt. We need to edit our while
loop so that rather than just echoing user input back, it actually attempts to parse the input using our parser. We can do this by replacing the call to printf
with the following mpc
code, that makes use of our program parser Lispy
.
/* Attempt to Parse the user Input */
mpc_result_t r;
if (mpc_parse("<stdin>", input, Lispy, &r)) {
/* On Success Print the AST */
mpc_ast_print(r.output);
mpc_ast_delete(r.output);
} else {
/* Otherwise Print the Error */
mpc_err_print(r.error);
mpc_err_delete(r.error);
}
This code calls the mpc_parse
function with our parser Lispy
, and the input string input
. It copies the result of the parse into r
and returns 1
on success and 0
on failure. We use the address of operator &
on r
when we pass it to the function. This operator will be explained in more detail in later chapters.
On success an internal structure is copied into r
, in the field output
. We can print out this structure using mpc_ast_print
and delete it using mpc_ast_delete
.
Otherwise there has been an error, which is copied into r
in the field error
. We can print it out using mpc_err_print
and delete it using mpc_err_delete
.
Compile these updates, and take this program for a spin. Try out different inputs and see how the system reacts. Correct behaviour should look like the following.
Lispy Version 0.0.0.0.2
Press Ctrl+c to Exit
lispy> + 5 (* 2 2)
>
regex
operator|char:1:1 '+'
expr|number|regex:1:3 '5'
expr|>
char:1:5 '('
operator|char:1:6 '*'
expr|number|regex:1:8 '2'
expr|number|regex:1:10 '2'
char:1:11 ')'
regex
lispy> hello
<stdin>:1:1: error: expected whitespace, '+', '-', '*' or '/' at 'h'
lispy> / 1dog
<stdin>:1:4: error: expected one of '0123456789', whitespace, '-', one or more of one of '0123456789', '(' or end of input at 'd'
lispy>
I’m getting an error <stdin>:1:1: error: Parser Undefined!
.
This error is due to the syntax for your grammar supplied to mpca_lang
being incorrect. See if you can work out what part of the grammar is incorrect. You can use the reference code for this chapter to help you find this, and verify how the grammar should look.