Getting seg fault - Following your Lisp Tutorial
tiazahmd opened this issue · 3 comments
I'm on Chapter 6 of your tutorial and it's giving me a segmentation fault. Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include "mpc.h"
/* If we're compiling in windows
(which, god knows why we might do!. */
#ifdef _WIN32
#include <string.h>
static char buffer[2048];
// Fake function for windows
char* readline(char* prompt) {
fputs(prompt, stdout);
fgets(buffer, 2048, stdin)
char* cpy = malloc(strlen(buffer) + 1);
strcpy(cpy, buffer);
cpy[strlen(cpy)-1] = '\0';
return cpy;
}
void add_history(char* unused) {
}
#else
#include <editline/readline.h>
#include <editline/history.h>
#endif
int main(int argc, char** argv) {
mpc_parser_t* Number = mpc_new("number");
mpc_parser_t* Operator = mpc_new("operator");
mpc_parser_t* Expr = mpc_new("expr");
mpc_parser_t* Snoo = mpc_new("snoo");
mpca_lang(MPCA_LANG_DEFAULT,
" \
number : /-?[0-9]+/ ; \
operator : '+' | '-' | '*' | '/' ; \
expr : <number> | '(' <operator> <expr>+ ')' ; \
lispy : /^/ <operator> <expr>+ /$/ ; \
",
Number, Operator, Expr, Snoo);
puts("Snoo version 0.0.0.0.2");
puts("Press CTRL+C to quit.");
while(1) {
char *input = readline("snoo> ");
add_history(input);
mpc_result_t r;
if (mpc_parse("<stdin>", input, Snoo, &r)) {
mpc_ast_print(r.output);
mpc_ast_delete(r.output);
}
else {
mpc_err_print(r.error);
mpc_err_delete(r.error);
}
free(input);
}
mpc_cleanup(4, Number, Operator, Expr, Snoo);
return 0;
}
Here's the GDB output:
(gdb) r
Starting program: /home/imtiaz/Desktop/Github/C/snoo/snoo-repl
./snoo-repl
Program received signal SIGSEGV, Segmentation fault.
0x000055555556016d in mpca_grammar_find_parser ()
I'm submitting the issue here because I think it has something to do with MPC - and I don't have enough C knowledge to diagnose a library of MPC's caliber.
Figured out the problem. On line 34, I had the following:
mpc_parser_t* Snoo = mpc_new("snoo");
whereas it should've been
mpc_parser_t* Snoo = mpc_new("lispy");
I didn't realize the mpc_new
command needed to take lispy
as an argument.
In fact it just needs to match what is written in the grammar. I.E. in the grammar string the rule is called "lispy" so that is what you need to call the parser too. Anyway, glad you worked it out!
Got it - thanks, just updated it. for some reason, I was looking at these lines as comments:
`" \
number : /-?[0-9]+/ ; \
operator : '+' | '-' | '*' | '/' ; \
expr : <number> | '(' <operator> <expr>+ ')' ; \
lispy : /^/ <operator> <expr>+ /$/ ; \
",`
facepalm