Re: sexps parsing with lex/yacc

John Millaway <johnmillaway@yahoo.com>
21 Nov 2005 22:43:37 -0500

          From comp.compilers

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)
| List of all articles for this month |

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

> 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; }


%%


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.