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.

  1. /* Attempt to Parse the user Input */
  2. mpc_result_t r;
  3. if (mpc_parse("<stdin>", input, Lispy, &r)) {
  4. /* On Success Print the AST */
  5. mpc_ast_print(r.output);
  6. mpc_ast_delete(r.output);
  7. } else {
  8. /* Otherwise Print the Error */
  9. mpc_err_print(r.error);
  10. mpc_err_delete(r.error);
  11. }

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.

  1. Lispy Version 0.0.0.0.2
  2. Press Ctrl+c to Exit
  3. lispy> + 5 (* 2 2)
  4. >
  5. regex
  6. operator|char:1:1 '+'
  7. expr|number|regex:1:3 '5'
  8. expr|>
  9. char:1:5 '('
  10. operator|char:1:6 '*'
  11. expr|number|regex:1:8 '2'
  12. expr|number|regex:1:10 '2'
  13. char:1:11 ')'
  14. regex
  15. lispy> hello
  16. <stdin>:1:1: error: expected whitespace, '+', '-', '*' or '/' at 'h'
  17. lispy> / 1dog
  18. <stdin>:1:4: error: expected one of '0123456789', whitespace, '-', one or more of one of '0123456789', '(' or end of input at 'd'
  19. 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.