(Somewhat adapted) code and solutions from the book "Build Your Own Lisp" http://www.buildyourownlisp.com
lisp
c

parsing.c 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "../mpc/mpc.h"
  4. /* If we are on Windows compile these functions */
  5. #ifdef _WIN32
  6. #include <string.h>
  7. #include <assert.h>
  8. static char buffer[2048];
  9. /* Fake readline function */
  10. char* readline(char* prompt) {
  11. fputs(prompt, stdout);
  12. fgets(buffer, 2048, stdin);
  13. char* cpy = malloc(strlen(buffer)+1);
  14. assert(cpy != NULL)
  15. strcpy(cpy, buffer);
  16. cpy[strlen(cpy)-1] = '\0';
  17. return cpy;
  18. }
  19. /* Fake add_history function */
  20. void add_history(char* unused) {}
  21. /* Otherwise include the editline headers
  22. could use __APPLE__ for detection of OSX */
  23. #else
  24. #include <editline/readline.h>
  25. #endif
  26. int main(int argc, char const *argv[])
  27. {
  28. /* Create some parsers */
  29. mpc_parser_t* Number = mpc_new("number");
  30. mpc_parser_t* Operator = mpc_new("operator");
  31. mpc_parser_t* Expr = mpc_new("expr");
  32. mpc_parser_t* Lispy = mpc_new("lispy");
  33. /* Define them with the following language */
  34. mpca_lang(MPCA_LANG_DEFAULT,
  35. " \
  36. number : /-?[0-9]([.][0-9]+)*/ ; \
  37. operator : '+' | '-' | '*' | '/' | '%' ; \
  38. expr : <number> | '(' <operator> <expr>+ ')' ; \
  39. lispy : /^/ <operator> <expr>+ /$/ ; \
  40. ",
  41. Number, Operator, Expr, Lispy);
  42. /* Print version and exit information */
  43. puts("Lispy version 0.0.0.0.2");
  44. puts("Press Ctrl+c to exit\n");
  45. /* In a never ending loop */
  46. while (1) {
  47. /* Output our prompt and get input */
  48. char* input = readline("lispy> ");
  49. /* Add input to history */
  50. add_history(input);
  51. /* Attempt to parse the user input */
  52. mpc_result_t r;
  53. if (mpc_parse("<stdin>", input, Lispy, &r)) {
  54. /* On success print the AST */
  55. mpc_ast_print(r.output);
  56. mpc_ast_delete(r.output);
  57. } else {
  58. /* Otherwise print the error */
  59. mpc_err_print(r.error);
  60. mpc_err_delete(r.error);
  61. }
  62. /* Free retrieved input */
  63. free(input);
  64. }
  65. /* Undefine and delete our parsers */
  66. mpc_cleanup(4, Number, Operator, Expr, Lispy);
  67. return 0;
  68. }