orangeduck/BuildYourOwnLisp

can't understand grammar definition problem

Closed this issue · 4 comments

Hi,

I'm trying to define a grammar for an esoteric lang called Wittgen as an exercise of chapter 6 of your book, but I can't understand what is wrong with this grammar definition:


mpc_parser_t* Variable        = mpc_new("variable");
mpc_parser_t* Assign_Operator = mpc_new("assign");
mpc_parser_t* Remind_Operator = mpc_new("remind");
mpc_parser_t* Expr            = mpc_new("expr");
mpc_parser_t* Envinronment    = mpc_new("envinronment");

mpca_lang(MPCA_LANG_DEFAULT,
  " variable     : /[a-zA-Z0-9]+/ ;"                                                     
  " assign       : '+' ;"                                         
  " remind       : '@' ;"                                                                
  " expr         : <variable> | <remind> <variable> '}' | <variable> <assign> <expr>+ '}' ;"
  " envinronment : /^/<expr>+/$/ ;",
  Variable, Assign_Operator, Remind_Operator, Expr, Envinronment);

it works for the simple variable, and for the remind operator, but the assignment function "foo=foobar}" exits with this error:

WITTGEN> ale=ale} <stdin>:1:4: error: expected one of 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', one or more of one of 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', '@' or end of input at '='

Hey,

Well I don't know about Wittgen but it could be as simple as the fact that your assign rule refers to the + character. It looks like it should refer to =.

  • Dan

I'm sorry I posted a wrong test version, here's the original version:

#include "mpc.h"

int main()
{

static char input[2048];

mpc_parser_t* Variable        = mpc_new("variable");
mpc_parser_t* Assign_Operator = mpc_new("assign");
mpc_parser_t* Remind_Operator = mpc_new("remind");
mpc_parser_t* Expr            = mpc_new("expr");
mpc_parser_t* Envinronment    = mpc_new("envinronment");

mpca_lang(MPCA_LANG_DEFAULT,
  " variable     : /[a-zA-Z0-9]+/ ;"                                                     
  " assign       : '=' ;"                                         
  " remind       : '@' ;"                                                                
  " expr         : <variable> | <remind> <variable> '}' |  <variable> <assign> <expr>+ '}' ;"
  " envinronment : /^/<expr>+/$/ ;",
  Variable, Assign_Operator, Remind_Operator, Expr, Envinronment);

while(1) {

    fputs("WITTGEN> ", stdout);
    fgets(input,2048,stdin);

    mpc_result_t r;
    if (mpc_parse("<stdin>", input, Envinronment, &r)) {
        mpc_ast_print(r.output);
        mpc_ast_delete(r.output);
    }

    else {
        mpc_err_print(r.error);
        mpc_err_delete(r.error);
    }

}

mpc_cleanup(5,Variable,Assign_Operator,Remind_Operator,Expr,Envinronment);

return 0;

}

mpca_lang(MPCA_LANG_DEFAULT,
  " variable     : /[a-zA-Z0-9]+/ ;"                                                     
  " assign       : '=' ;"                                         
  " remind       : '@' ;"                                                                
  " expr         : <remind> <variable> '}' |  <variable> <assign> <expr>+ '}' | <variable>;"
  " envinronment : /^/<expr>+/$/ ;",
  Variable, Assign_Operator, Remind_Operator, Expr, Envinronment);

inserting last in the grammar definition solves the problem, why?

See: https://github.com/orangeduck/mpc#backtracking-isnt-working

It's because mpc tries each rule in order and the rule <variable> is a factor of <variable> <assign> <expr>+.