Related articles |
---|
sexps parsing with lex/yacc animesh@neolinuxsolutions.com (2005-11-12) |
Re: sexps parsing with lex/yacc jburgy@gmail.com (2005-11-19) |
Re: sexps parsing with lex/yacc johnmillaway@yahoo.com (John Millaway) (2005-11-21) |
From: | John Millaway <johnmillaway@yahoo.com> |
Newsgroups: | comp.compilers |
Date: | 21 Nov 2005 22:43:37 -0500 |
Organization: | Compilers Central |
References: | 05-11-095 |
Keywords: | parse, Lisp |
Posted-Date: | 21 Nov 2005 22:43:37 EST |
> I need to parse sexps,
Hi,
Below is the flex scanner and bison parser for my lisp dialect. Notice that
most of the work is done in the scanner. The parser is trivial. Also, a
simple, but important optimization step is to recognize certain built-in
symbols at scan time (if that suits your dialect). I hope this helps.
-Millaway
/* -------- Bison Parser ---------- */
%debug
%defines
%token tCELL
%token tQUOTE
%token tQQUOTE
%token tCOMMA
%token tCOMMAAT
%token tERR
%%
snippet:
exprs { result = $1; }
;
exprs:
expr { $$ = PAIR($1,NIL); }
| exprs expr { $$ = APPEND_D ($1, $2); }
;
expr:
tCELL { $$ = $1; }
| '(' exprs ')' { $$ = $2; }
| tQUOTE expr { $$ = PAIR(cQUOTE, PAIR($2,NIL)); }
| tQQUOTE expr { $$ = PAIR(cQUASIQUOTE, PAIR($2,NIL)); }
| tCOMMA expr { $$ = PAIR(cUNQUOTE, PAIR($2,NIL)); }
| tCOMMAAT expr { $$ = PAIR(cUNQUOTE_SPLICING, PAIR($2,NIL)); }
| tERR { yyerror("..."); }
;
%%
/* -------- Flex Scanner ---------- */
%option yylineno ecs meta-ecs nodefault noyywrap nounput
INTrx [+-]?[[:digit:]]+
REALrx [+-]?[[:digit:]]+("."[[:digit:]]+)?
WS [[:space:]]+
IDENTrx [^',`{}(),[:space:]\[\]][^{}(),[:space:]\[\]]*
%%
"(" { lv = NULL; return '('; }
")" { lv = NULL; return ')'; }
",@" { lv = NULL; return tCOMMAAT; }
"," { lv = NULL; return tCOMMA; }
"'" { lv = NULL; return tQUOTE; }
"`" { lv = NULL; return tQQUOTE; }
"#\\space" { lv = cell_mk_char (m, ' '); return tCELL; }
"#\\newline" { lv = cell_mk_char (m, '\n'); return tCELL; }
"#\\tab" { lv = cell_mk_char (m, '\t'); return tCELL; }
"#\\". { lv = cell_mk_char (m, yytext[2]); return tCELL; }
"#t" { lv = m->cTRUE; return tCELL;}
"true" { lv = m->cTRUE; return tCELL;}
"#f" { lv = m->cFALSE; return tCELL;}
"false" { lv = m->cFALSE; return tCELL;}
quote { lv = m->cQUOTE; return tCELL;}
quasiquote { lv = m->cQUASIQUOTE; return tCELL;}
unquote { lv = m->cUNQUOTE; return tCELL;}
unquote-splicing { lv=m->cUNQUOTE_SPLICING; return tCELL;}
"..." { lv = m->cELLIPSES; return tCELL;}
let { lv = m->cLET; return tCELL;}
letrec { lv = m->cLETREC; return tCELL;}
"let*" { lv = m->cLETSTAR; return tCELL;}
and { lv = m->cAND; return tCELL;}
begin { lv = m->cBEGIN; return tCELL;}
cond { lv = m->cCOND; return tCELL;}
def { lv = m->cDEF; return tCELL;}
do { lv = m->cDO; return tCELL;}
if { lv = m->cIF; return tCELL;}
lambda { lv = m->cLAMBDA; return tCELL;}
macro-lambda { lv = m->cMACRO; return tCELL;}
or { lv = m->cOR; return tCELL;}
set"!" { lv = m->cSET; return tCELL;}
[Nn][Ii][Ll] { lv = m->cNIL; return tCELL; }
"\""([^#\"]|(#[^\\])|(#\\.))*"\"" {
lv = cell_string_unescape_d (m,
cell_alloc_strn (m, yytext+1, yyleng-2));
return tCELL;
}
"("[[:space:]]*")" { lv=m->cNIL; return tCELL; }
"+" { lv = m->cPLUS; return tCELL;}
"-" { lv = m->cMINUS; return tCELL;}
{INTrx} { lv = cell_mk_i32 (m, strtol(yytext,NULL,0)); return tCELL; }
{REALrx} { lv = cell_mk_real (m, strtod(yytext,NULL)); return tCELL; }
{IDENTrx} {
/* Intern the string and lookup the symbol. */
Cell* cs;
cs = cell_string_intern_for_symnam (m, yytext, yyleng);
lv = cell_alloc_sym (m, cs, NULL);
return tCELL;
}
{WS} { /* skip */; }
";"[^\n]*\n { /* comment */; if (0){ yy_flex_realloc (NULL,0); goto
find_rule;} }
. { return tERR; }
%%
Return to the
comp.compilers page.
Search the
comp.compilers archives again.