Create a gist now

Instantly share code, notes, and snippets.

A lispy arithmetic REPL
%{
#include <stdio.h> // include print functions
#include <math.h> // include `pow' function
#include <ctype.h> // include `isdigit' function
int yylex (void); // declare lexing function
void yyerror (char const *); // declare yyerror function
%}
%define api.value.type {double} // delcare all tokens and non-terminals to have type `double'
%token NUM // declare NUM as a terminal
%%
input:
%empty
| input line
;
line:
'\n'
| expression '\n' { printf ("%.10g\n", $1); }
;
expression:
NUM
| '(' '+' expression expression ')' { $$ = $3 + $4; }
| '(' '-' expression expression ')' { $$ = $3 - $4; }
| '(' '*' expression expression ')' { $$ = $3 * $4; }
| '(' '/' expression expression ')' { $$ = $3 / $4; }
;
%%
int yylex (void)
{
int c;
while ((c = getchar ()) == ' ' || c == '\t')
continue;
if (c == '.' || isdigit (c))
{
ungetc (c, stdin);
scanf ("%lf", &yylval);
return NUM;
}
if (c == EOF)
return 0;
return c;
}
int main (void)
{ return yyparse(); }
void yyerror (char const *s)
{
fprintf (stderr, "%s\n", s);
yyparse();
}
all:
/usr/local/Cellar/bison/3.0.4/bin/bison lispcalc.y && gcc -lm -o lispcalc lispcalc.tab.c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment