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