Mercurial > lbo > hg > ylisp
changeset 50:fd6eb7b5966c
gen/parser: Properly handle distinction between atoms, ids, quoting
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Fri, 23 Aug 2019 10:57:57 +0200 |
parents | 0d6b50b31ce3 |
children | a3bbf2a1a353 |
files | gen/y.lex gen/y.yy src/expr.h |
diffstat | 3 files changed, 73 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/gen/y.lex Thu Aug 22 11:07:52 2019 +0200 +++ b/gen/y.lex Fri Aug 23 10:57:57 2019 +0200 @@ -20,8 +20,8 @@ LEFTP "(" RIGHTP ")" NUMBER -?[1-9][0-9]* -ATOM '[a-z+*/-][a-z0-9]* -ID [a-z+*/-][a-z0-9]* +ATOM [a-z+*/-][a-z0-9]* +QUOTE ' STRING_LIT \"[[:alnum:][:blank:][:punct:]]*\" %% @@ -31,7 +31,7 @@ {RIGHTP} { return TOK_RIGHTP; } {NUMBER} { yylval->number = atoll(yytext); return TOK_NUMBER_LITERAL; } {ATOM} { yylval->atom = strdup(yytext); return TOK_ATOM; } -{ID} { yylval->ref = yref_new_c(yytext); return TOK_ID; } +{QUOTE} { return TOK_QUOTE; } {STRING_LIT} { yylval->string = strdup(yytext); return TOK_STRING_LITERAL; } %%
--- a/gen/y.yy Thu Aug 22 11:07:52 2019 +0200 +++ b/gen/y.yy Fri Aug 23 10:57:57 2019 +0200 @@ -40,12 +40,17 @@ %define lr.type ielr %union yvalue { +// Parsed values ('semantic values'): + // More yexprs. yvec_t exprs; // One yexpr. yexpr_t expr; // A reference. yref_t ref; + +// Lexed values: + // A number literal (todo: floats) long long number; // A string literal. @@ -59,14 +64,17 @@ %token <number> TOK_NUMBER_LITERAL %token <string> TOK_STRING_LITERAL %token <atom> TOK_ATOM -%token <ref> TOK_ID +%token TOK_QUOTE %token TOK_LEFTP %token TOK_RIGHTP %type <exprs> many_sexpr %type <expr> sexpr +%type <expr> literal %type <expr> inner_sexpr +%type <expr> inner_quoted_sexpr %type <expr> value +%type <expr> quoted_value %% @@ -91,9 +99,32 @@ $$ = v; }; -sexpr: TOK_LEFTP inner_sexpr TOK_RIGHTP { +sexpr: TOK_QUOTE TOK_LEFTP inner_quoted_sexpr TOK_RIGHTP { + printf("found quoted sexpr\n"); + $$ = $3; + } + | TOK_LEFTP inner_sexpr TOK_RIGHTP { printf("found sexpr\n"); $$ = $2; + }; + +inner_quoted_sexpr: inner_quoted_sexpr quoted_value { + yexpr_init_or_extend(&$1, $2); + $$ = $1; + } + // A quoted sexpr can contain more sexprs, but they are quoted too. + | inner_quoted_sexpr TOK_LEFTP inner_quoted_sexpr TOK_RIGHTP { + yexpr_init_or_extend(&$1, $3); + $$ = $1; + } + | %empty { + printf("finished quoted sexpr\n"); + yexpr_t e; + yexpr_init(&e); + yvec_t v; + YVEC_INIT(&v, 0, yexpr_t); + yexpr_set_list(&e, v); + $$ = e; }; inner_sexpr: inner_sexpr value { @@ -101,7 +132,6 @@ $$ = $1; } | inner_sexpr sexpr { - printf("found sexpr\n"); yexpr_init_or_extend(&$1, $2); $$ = $1; } @@ -109,42 +139,55 @@ printf("finished sexpr\n"); yexpr_t e; yexpr_init(&e); + yvec_t v; + YVEC_INIT(&v, 0, yexpr_t); + yexpr_set_list(&e, v); $$ = e; }; -value: TOK_ATOM { - printf("found atom %s\n", $1); - yexpr_t atom; - yexpr_set_atom_name(&atom, strdup($1)); - $$ = atom; +value: TOK_QUOTE quoted_value { + printf("found quoted value\n"); + $$ = $2; + } + | TOK_ATOM { + printf("found ID %s\n", $1); + yref_t ref = yref_new_c($1); + yexpr_t expr; + yexpr_set_ref(&expr, ref); + $$ = expr; } - | TOK_ID { - ystr_t debug = yref_debug(&$1); - printf("found ID %s\n", ystr_str(&debug)); - ystr_destroy(&debug); + | literal; - yexpr_t ref; - yexpr_set_ref(&ref, $1); - $$ = ref; - } - | TOK_NUMBER_LITERAL { +quoted_value: TOK_ATOM { + printf("found atom %s\n", $1); + yexpr_t expr; + yexpr_set_atom_name(&expr, $1); + $$ = expr; + } | literal; + +literal: TOK_NUMBER_LITERAL { printf("found number %d\n", $1); - yexpr_t num; - yexpr_set_number(&num, $1); - $$ = num; + yexpr_t expr; + yexpr_set_number(&expr, $1); + $$ = expr; } | TOK_STRING_LITERAL { printf("found string %s\n", $1); - yexpr_t strexpr; + yexpr_t expr; ystr_t str = ystr_new($1); - yexpr_set_str(&strexpr, str); - $$ = strexpr; - } + yexpr_set_str(&expr, str); + $$ = expr; + }; + %% int parse(FILE* in, yvec_t* out_exprs) { void* scanner; - assert(0 == yylex_init(&scanner)); + int r; + if (0 != (r = yylex_init(&scanner))) { + error(r, 0, "couldn't initialize scanner!"); + exit(1); + } #ifndef DEBUG FILE* out = fopen("/dev/null", "w"); #else
--- a/src/expr.h Thu Aug 22 11:07:52 2019 +0200 +++ b/src/expr.h Fri Aug 23 10:57:57 2019 +0200 @@ -141,7 +141,8 @@ void yexpr_set_ref(yexpr_t* v, yref_t ref); /** - * Set the value of `v` to the list/vector `vec`. Ownership of `vec` is transferred to `v`; do not destroy `vec`. + * Set the value of `v` to the list/vector `vec`. Ownership of `vec` is + * transferred to `v`; do not destroy `vec`. */ void yexpr_set_list(yexpr_t* v, yvec_t vec);