Skip to content

Instantly share code, notes, and snippets.

@gatlin
Last active December 20, 2015 07:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gatlin/6096021 to your computer and use it in GitHub Desktop.
Save gatlin/6096021 to your computer and use it in GitHub Desktop.
I think I'm doing this correctly so far
all: sexp
sexp: sexp.y sexp.l
yacc -d sexp.y
lex sexp.l
gcc -o sexp lex.yy.c y.tab.c -ly -ll
clean:
rm -rf *.{c,o,h}
rm sexp
%{
#include "y.tab.h"
#include <math.h>
extern int yyleng;
extern int lines;
extern int indent;
%}
%option noyywrap
%%
([0-9]+) {
yylval.intval = atoi(yytext); return INTEGER; }
([0-9]+|([0-9]*(\.[0-9]+)?)([eE][-+]?[0-9]+)?) {
yylval.floatval = atof(yytext); return FLOAT; }
True { yylval.boolval = 1; return BOOLEAN; }
False { yylval.boolval = 0; return BOOLEAN; }
(lambda|\\) { yylval.symval = yytext; return SYMBOL; }
(let) { yylval.symval = yytext; return SYMBOL; }
'(.)' { yylval.charval = yytext[1]; return CHARACTER; }
[a-zA-Z_:#\*+=][a-zA-Z0-9_!:#\*'+-\/=]* {
/* this will interpret `'#'a` as
* a character '#' and then a symbol a
*/
yylval.symval = yytext; return SYMBOL; }
\( { indent++; return LPAREN; }
\) { indent--; return RPAREN; }
\[ { indent++; return LBRACE; }
\] { indent--; return RBRACE; }
' return QUOTE;
\n { lines++; }
[ \t]+ /* ignore whitespace */;
%%
%{
#include <stdio.h> /* avoid the implicit redeclaration warning */
int lines = 1;
int indent = 0;
void printFloat(double x);
void printInt(int x);
void printSym(char* x);
void printBool(int x);
void printChar(char x);
void printList();
void printQuote();
%}
%union {
double floatval;
int intval;
char* symval;
int boolval;
char charval;
}
%token <floatval> FLOAT
%token <symval> SYMBOL
%token <intval> INTEGER
%token <boolval> BOOLEAN
%token <charval> CHARACTER
%token LPAREN RPAREN QUOTE LBRACE RBRACE LAMBDA LET
%start members
%%
sexpr
: atom
| list
;
list
: LPAREN members RPAREN
| LBRACE members RBRACE
| LPAREN RPAREN
| LBRACE RBRACE
| QUOTE list
;
members
: sexpr
| sexpr members
;
atom
: FLOAT { printFloat($1); }
| SYMBOL { printSym($1); }
| QUOTE SYMBOL { printSym($2); }
| INTEGER { printInt($1); }
| BOOLEAN { printBool($1); }
| CHARACTER { printChar($1); }
;
%%
/*
* Print indentation using global variable
*/
void printIndentation() {
int i = 0;
for (; i < indent; i++) {
printf(" ");
}
}
/*
* Print functions which use indentation
*/
void printFloat(double x) {
printIndentation();
printf("%f :: FLOAT\n",x);
}
void printInt(int x) {
printIndentation();
printf("%d :: INTEGER\n",x);
}
void printSym(char* x) {
printIndentation();
printf("%s :: SYMBOL\n",x);
}
void printBool(int x) {
printIndentation();
printf("%s :: BOOLEAN\n",(x)?"True":"False");
}
void printChar(char x) {
printIndentation();
printf("%c :: CHARACTER\n",x);
}
void printQuote() {
printf("QUOTE ");
}
/*
* override the default error handler to at least use line numbers
*/
yyerror(char *errmsg) {
fprintf(stderr,"%s at line %d\n",errmsg,lines);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment