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(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment