aboutsummaryrefslogtreecommitdiff
path: root/demos/sample-files
diff options
context:
space:
mode:
Diffstat (limited to 'demos/sample-files')
-rw-r--r--demos/sample-files/calc-defs.c4
-rw-r--r--demos/sample-files/calc-skeleton.c6
-rw-r--r--demos/sample-files/calc.g2
-rw-r--r--demos/sample-files/gram-defs.c12
-rw-r--r--demos/sample-files/gram-skeleton.c62
-rw-r--r--demos/sample-files/lbp-code.lbp4
-rw-r--r--demos/sample-files/lbp-skeleton.c267
-rw-r--r--demos/sample-files/lbp.g46
8 files changed, 322 insertions, 81 deletions
diff --git a/demos/sample-files/calc-defs.c b/demos/sample-files/calc-defs.c
index b9d1788..9385a02 100644
--- a/demos/sample-files/calc-defs.c
+++ b/demos/sample-files/calc-defs.c
@@ -12,7 +12,7 @@
enum symbol { SYMBOLS(X_TO_ENUM) };
size_t total_symbols = SYMBOLS_END;
-extern char **symbol_to_str = (char *([])){ SYMBOLS(X_TO_STR) };
+char **symbol_to_str = (char *([])){ SYMBOLS(X_TO_STR) };
IMPLEMENT_FUNCPTR(int, symbol_is_terminal, (symbol s)) { return s < EP; }
IMPLEMENT_FUNCPTR(int, symbol_is_input_end, (symbol s)) { return s == END_INPUT; }
@@ -38,6 +38,8 @@ static struct production _grammar[] = {
struct production *grammar = _grammar;
size_t total_productions = sizeof(_grammar)/sizeof(*_grammar);
+char *stack_item_type = "int";
+
// #include "???.h"
char **semantic_action_str = (char *([])){
"v = A(0);",
diff --git a/demos/sample-files/calc-skeleton.c b/demos/sample-files/calc-skeleton.c
index ad4aba9..414293e 100644
--- a/demos/sample-files/calc-skeleton.c
+++ b/demos/sample-files/calc-skeleton.c
@@ -18,7 +18,7 @@ static struct token {
static char *next_token(char *str);
symbol token_sym(struct token *t) { return t->s; }
-intptr_t token_val(struct token *t) { return (intptr_t)t->v; }
+intptr_t token_val(struct token *t) { return (intptr_t)&t->v; }
static char *input;
@@ -40,11 +40,11 @@ int main(int argc, char **argv)
input = next_token(argv[1]);
- intptr_t value;
+ int value;
if(lr_parser(&value)) return 1;
printf("INPUT: '%s'\n", argv[1]);
- printf("OUTPUT: %jd\n", value);
+ printf("OUTPUT: %d\n", value);
return 0;
}
diff --git a/demos/sample-files/calc.g b/demos/sample-files/calc.g
index 804e072..aa5b5db 100644
--- a/demos/sample-files/calc.g
+++ b/demos/sample-files/calc.g
@@ -3,6 +3,8 @@
-nonterminal EP E.
+-stacktype { int }.
+
-left LPAREN;
-left 5;
-left TIMES;
diff --git a/demos/sample-files/gram-defs.c b/demos/sample-files/gram-defs.c
index b1ae268..97312c7 100644
--- a/demos/sample-files/gram-defs.c
+++ b/demos/sample-files/gram-defs.c
@@ -1,10 +1,10 @@
#include "util/util.h"
#define SYMBOLS(X) \
X(TERMINAL) X(NONTERM) X(LEFT) X(RIGHT) X(NOPREC) \
- X(COLON) X(PIPE) X(SEMICOL) X(DOT) \
+ X(STYPE) X(COLON) X(PIPE) X(SEMICOL) X(DOT) \
X(IDEN) X(NUM) X(ACTION) X(END_INPUT) \
\
- X(S) X(A) X(B) X(C) \
+ X(SP) X(S) X(A) X(T) X(B) X(C) \
X(Type) X(Prec) X(Prod) X(Preclist) X(Prodlist) \
X(Actionlist) X(Idenlist) X(IorNlist) \
X(SYMBOLS_END) \
@@ -22,11 +22,15 @@ IMPLEMENT_FUNCPTR(int, symbol_is_valid, (symbol s)) { return s < SYMBOLS_END; }
#include "parts/grammar.h"
#define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol)}
#define GRAMMAR_ACTION_DEF(X) \
- X(PROD(S, -->, A, B, C, END_INPUT), "") \
+ X(PROD(SP, -->, S, END_INPUT), "") \
+ X(PROD(S, -->, A, B, C), "") \
+ X(PROD(S, -->, A, T, B, C), "") \
\
X(PROD(A, -->, TERMINAL, Idenlist, \
SEMICOL, NONTERM, Idenlist, DOT), \
- "handle_type(A(1), A(4))") \
+ "handle_enum(A(1), A(4));") \
+ X(PROD(T, -->, STYPE, ACTION, DOT), \
+ "handle_stype(A(1));") \
\
X(PROD(B, -->, Preclist), "handle_prec(A(0));") \
X(PROD(B, -->, NOPREC, DOT), "handle_prec(NULL);") \
diff --git a/demos/sample-files/gram-skeleton.c b/demos/sample-files/gram-skeleton.c
index 4e40c14..9898c6b 100644
--- a/demos/sample-files/gram-skeleton.c
+++ b/demos/sample-files/gram-skeleton.c
@@ -24,10 +24,10 @@ static void *xalloc(size_t sz) {
#include "parts/precedence.h"
#include "util/list.h"
-static inline struct list_head *list_new_head(struct list_head *head, struct list_head *new)
+static inline struct list_head *list_new_head(struct list_head *list, struct list_head *newhead)
{
- if(head) list_add(new, head);
- return new;
+ newhead->next = list;
+ return newhead;
}
struct ptr_entry {
@@ -79,7 +79,7 @@ struct list_head *prod_new(char *iden, struct list_head *actionlist)
entry->ptrlist = actionlist;
})
-void handle_type(struct list_head *terminals, struct list_head *nonterminals)
+void handle_enum(struct list_head *terminals, struct list_head *nonterminals)
{
printf("#include \"parts/symbol.h\"\n");
printf("enum symbol { ");
@@ -107,6 +107,12 @@ void handle_type(struct list_head *terminals, struct list_head *nonterminals)
}
+static inline char *substring(char *str, size_t sub_end);
+void handle_stype(char *action)
+{
+ printf("char *stack_item_type = \"%s\";\n", substring(action+1, strlen(action)-2));
+}
+
void handle_prec(struct list_head *preclist)
{
printf("#include \"parts/precedence.h\"\n");
@@ -142,8 +148,7 @@ void handle_prod(struct list_head *prodlist)
printf("struct production *grammar = (struct production[]){\n");
list_for_each_entry(struct strnptr_entry, e1, list, prodlist) {
if(productions == 0)
- list_add(list_get_tail(list_entry(e1->ptrlist, struct strnptr_entry, list)->ptrlist),
- ptr_new("END_INPUT"));
+ list_get_tail(list_entry(e1->ptrlist, struct strnptr_entry, list)->ptrlist)->next = ptr_new("END_INPUT");
productions += list_len(e1->ptrlist);
list_for_each_entry(struct strnptr_entry, e2, list, e1->ptrlist) {
@@ -171,7 +176,8 @@ void handle_prod(struct list_head *prodlist)
#define action_new(idenlist, action) (intptr_t)action_new((struct list_head *)idenlist, (char *)action)
#define prod_new(iden, actionlist) (intptr_t)prod_new((char *)iden, (struct list_head *)actionlist)
-#define handle_type(terminals, nonterminals) handle_type((struct list_head *)terminals, (struct list_head *)nonterminals);
+#define handle_enum(terminals, nonterminals) handle_enum((struct list_head *)terminals, (struct list_head *)nonterminals);
+#define handle_stype(action) handle_stype((char *)action);
#define handle_prec(preclist) handle_prec((struct list_head *)preclist);
#define handle_prod(prodlist) handle_prod((struct list_head *)prodlist);
@@ -188,7 +194,7 @@ struct token {
static char *next_token(char *str);
symbol token_sym(struct token *t) { return t->s; }
-intptr_t token_val(struct token *t) { return t->v; }
+intptr_t token_val(struct token *t) { return (intptr_t)&t->v; }
static char *input;
@@ -234,10 +240,43 @@ static inline char *_strdup(char *str)
return memcpy(xalloc(strlen(str) + 1), str, strlen(str)+1);
}
+static inline size_t tillch(char *str, size_t len, char ch)
+{
+ for(size_t i = 0; i < len; i++) if(str[i] == ch) return i;
+ return len;
+}
+
+static inline char *escapeNL(char *str)
+{
+// static char new[256];
+// char *new_ptr = new;
+
+// #define addch(ch) if(new_ptr - new > sizeof(new) - 1) { \
+// fprintf(stderr, "ERROR: escapeNL cap reached"); return NULL; \
+// } else *new_ptr++ = ch;
+
+// for(size_t i = 0; i < strlen(str); i++)
+// if(str[i] == '\n') {
+// addch('\\'); addch('n');
+// continue;
+// } else addch(str[i]);
+
+// *new_ptr = '\0';
+// return new;
+
+ // temp
+ for(size_t i = 0; i < strlen(str); i++) if(str[i] == '\n') str[i] = ' ';
+ return str;
+}
+
static inline char *substring(char *str, size_t sub_end)
{
- static char sub[128];
- if(sub_end+1 > sizeof(sub)) return NULL;
+ // static char sub[256];
+ static char sub[512];
+ if(sub_end+1 > sizeof(sub)) {
+ fprintf(stderr, "ERROR: substring cap reached");
+ return NULL;
+ }
sub[sub_end] = '\0';
return memcpy(sub, str, sub_end);
@@ -282,6 +321,7 @@ static char *next_token(char *str)
else if(strcmp(s, "left") == 0) tok.s = LEFT;
else if(strcmp(s, "right") == 0) tok.s = RIGHT;
else if(strcmp(s, "noprec") == 0) tok.s = NOPREC;
+ else if(strcmp(s, "stacktype") == 0) tok.s = STYPE;
else { fprintf(stderr, "ERROR: Unknown directive '-%s'\n", s); goto fail; }
break;
case '{':
@@ -290,7 +330,7 @@ static char *next_token(char *str)
else if(str[off] == '{') c++;
else if(str[off] == '}') c--;
tok.s = ACTION;
- tok.v = (intptr_t)strdup(substring(str, off));
+ tok.v = (intptr_t)strdup(escapeNL(substring(str, off)));
break;
}
} else if(isalpha(c0)) { // iden or named symbol
diff --git a/demos/sample-files/lbp-code.lbp b/demos/sample-files/lbp-code.lbp
index df5bdcc..3750623 100644
--- a/demos/sample-files/lbp-code.lbp
+++ b/demos/sample-files/lbp-code.lbp
@@ -18,9 +18,7 @@ inbounds/int-function(low, high, val) {
(31 |_, ---).
},
-:aircraft_iden/struct {
--.
-},
+:aircraft_iden/struct { -. tova_tuk_e_sintaktichna_greshka. },
:message/struct {
DF/enum(:downlinkfmt) |5,
diff --git a/demos/sample-files/lbp-skeleton.c b/demos/sample-files/lbp-skeleton.c
index ae0a17f..bf7bdca 100644
--- a/demos/sample-files/lbp-skeleton.c
+++ b/demos/sample-files/lbp-skeleton.c
@@ -4,34 +4,84 @@
#include <stdint.h>
#include <ctype.h>
-// TODO: lr parser is bad for debugging
+// TODO: - lr parser is bad for debugging
+// - deal with errors
#define INPUT_CAP 4096
-#define ARENA_CAP 4096
+#define ARENA_CAP 8192 //4096
#define ARENA_IMPLEMENTATION
#include "util/arena.h"
static char buf[ARENA_CAP];
static struct arena_ctx global_arena;
-static void *xalloc(size_t sz) {
- void *addr = arena_allocate(&global_arena, sz);
+static void *xalloc(size_t size) {
+ void *addr = arena_allocate(&global_arena, size);
if(!addr) {
fprintf(stderr, "ERROR: Arena empty\n"); exit(1);
}
return addr;
}
+static void *xcalloc(size_t nmemb, size_t size) { return xalloc(nmemb * size); }
+static void xfree(void *ptr) { (void)ptr; return; }
+
+// macros to create the g_ variant of the function
+// where everything is cast to and from intptr_t
+// so it plays nicely with the lr parser
+// #define EMPTY()
+// #define DEFER(m) m EMPTY()
+// #define EVAL3(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__))))
+// #define EVAL2(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__))))
+// #define EVAL1(...) __VA_ARGS__
+
+// #define A1(type, name) type name
+// #define A2(type, name) intptr_t name
+// #define A3(type, name) (type)name
+
+// #define _map2() map2
+// #define map2(F, type, name, ...) F(type, name) __VA_OPT__(, DEFER(_map2)()(F, __VA_ARGS__))
+// #define map(a, ...) DEFER(_map2)()(a, EVAL1 __VA_ARGS__)
+
+// #define g(ret, name, args) EVAL3( \
+ ret name(map(A1, args)); \
+ intptr_t g_##name(map(A2, args)) \
+ { return (intptr_t)name(map(A3, args)); } \
+ ret name(map(A1, args)))
-// other things here
#include "util/list.h"
-static inline struct list_head *list_new_head(struct list_head *head, struct list_head *new)
-{
- if(head) list_add(new, head);
- return new;
-}
-#define list_new_head(head, new) (intptr_t)list_new_head((struct list_head *)head, (struct list_head *)new)
+struct ast_strlist { char *str; struct list_head list; };
+
+struct ast_expr {
+ enum { AST_NUMBER, AST_VARIABLE, AST_FIELDLIST, AST_DECLARATION, AST_DEFINITION, AST_OPERATION, AST_PARENLIST } type;
+ union {
+ int number;
+ struct ast_vrbl { int is_atom; char *iden; } variable;
+ struct ast_fiel { struct ast_vrbl variable; struct list_head *fields_strlist; } fieldlist;
+ struct ast_decl { struct ast_vrbl variable; int typed; } declaration;
+ struct ast_defn { struct ast_decl declartion; struct list_head *block_exprlist; } definition;
+ struct ast_oprn { enum { AST_OP_AND, AST_OP_OR } optype; struct list_head *left_exprlist; struct list_head *right_exprlist; } operation;
+ struct list_head *paren_exprlist;
+ };
+ struct list_head list;
+};
+
+#define NEW(t, ...) ((struct ast_##t){__VA_ARGS__})
+#define g_NEW(t, ...) ((stack_item){.t = (struct ast_##t){__VA_ARGS__}})
+
+#define LST(v) ({ typeof(v) *r = xalloc(sizeof(v)); *r = v; LIST_EMPTY(&r->list); &r->list; })
+#define g_LST(v) ((stack_item){.list = LST(v)})
+
+void ast_vrbl_print(struct ast_vrbl *vrbl);
+void ast_fiel_print(struct ast_fiel *fiel);
+void ast_decl_print(struct ast_decl *decl);
+void ast_defn_print(struct ast_defn *defn);
+void ast_oprn_print(struct ast_oprn *oprn);
+void ast_expr_print(struct ast_expr *expr);
+void ast_exprlist_print(struct list_head *list);
+
+void ast_exprlist_free(struct list_head *list);
// generated
#include "bin/lbp.h"
@@ -57,23 +107,31 @@ static uint8_t dict_lowercase_char_to_bit[256] = {
['y'] = 26, ['z'] = 27, [ 0 ] = 1, [' '] = 1
};
-
#include "parts/toklist.h"
struct token {
symbol s;
- intptr_t v;
+ stack_item v;
};
-
-#include "util/queue.h"
-QUEUE_GENERATE(tokbuf, struct token, 16)
+#define TOKEN_INIT(sym, val) (struct token){ .s = sym, .v = val }
+static void print_token(struct token *t);
symbol token_sym(struct token *t) { return t->s; }
-intptr_t token_val(struct token *t) { return t->v; }
+intptr_t token_val(struct token *t) { return (intptr_t)&t->v; }
-static void print_token(struct token *t);
+static char *input;
+static size_t line = 1;
+static size_t active_region;
static char *next_token(char *str);
-static char *input;
+static inline char *substring(char *str, size_t sub_end);
+static inline char *linestart(char *strstart, char *pos);
+static inline size_t tillch(char *str, size_t len, char ch);
+#define strdup(...) _strdup(__VA_ARGS__)
+static inline char *_strdup(char *str);
+
+
+#include "util/queue.h"
+QUEUE_GENERATE(tokbuf, struct token, 16)
struct token *toklist_eat()
{
@@ -85,7 +143,7 @@ struct token *toklist_eat()
struct token *toklist_peek() {
static struct token t;
- tokbuf_peek(&t); // err not checked
+ tokbuf_peek(&t); // err not checked
return &t;
}
@@ -94,6 +152,8 @@ struct token *toklist_peek() {
int main(void)
{
+ char *filename = "stdin";
+
static char input_buf[INPUT_CAP];
if(fread(input_buf, INPUT_CAP, 1, stdin) == INPUT_CAP) {
fprintf(stderr, "INPUT_CAP reached\n");
@@ -103,6 +163,7 @@ int main(void)
global_arena = ARENA_CTX_INIT(buf, ARENA_CAP);
types_dict = DICT_INIT(types_strings, ntypes_strings, dict_lowercase_char_to_bit);
+ // DICT_SET_ALLOCATOR(&types_dict, xcalloc, xfree);
dict_compile(&types_dict);
input = next_token(input_buf);
@@ -113,22 +174,43 @@ int main(void)
// if(token_sym(tok) == END_INPUT) break;
// } return 0;
- intptr_t value;
- if(lr_parser(&value)) {
- fprintf(stderr, input);
- return 1;
+ stack_item value;
+ struct lr_errinfo *errinfo;
+ if((errinfo = lr_parser(&value))) {
+ char *l = linestart(input_buf, input);
+
+ fprintf(stderr, "%s:%zu:%zu: ERROR: %s\n", filename, line, input - l - active_region+1, lr_err_str(errinfo));
+
+ size_t indent = fprintf(stderr, " %zu ", line);
+ fprintf(stderr, "| %s\n", substring(l, tillch(l, strlen(l), '\n')));
+
+ fprintf(stderr, "%*s| %*s", indent, "", input - l - active_region, "");
+ if(active_region == 0) active_region = 1;
+ fprintf(stderr, "^"); for(size_t i = 0; i < active_region-1; i++) fprintf(stderr, "~");
+
+ fprintf(stderr, "\n\n");
+ goto cleanup;
}
- fprintf(stderr, "OUTPUT: %jd\n", value);
+ ast_exprlist_print(value.list);
+ // ast_exprlist_free(value.list);
+cleanup:
dict_free(&types_dict);
return 0;
}
static void print_token(struct token *tok)
{
+ // TODO: unfinished function
printf("%s\n", symbol_to_str[token_sym(tok)]);
- if(token_sym(tok) == IDEN || token_sym(tok) == ATOM) printf(" %s\n", (char *)token_val(tok));
+ switch(token_sym(tok)) {
+ case IDEN:
+ case ATOM:
+ printf(" %s\n", (char *)token_val(tok));
+ break;
+ default: break;
+ }
}
// STR UTIL
@@ -150,6 +232,12 @@ static inline char *substring(char *str, size_t sub_end)
return memcpy(sub, str, sub_end);
}
+static inline char *linestart(char *strstart, char *pos)
+{
+ while(pos-- > strstart) if(*pos == '\n') return pos+1;
+ return strstart;
+}
+
static inline size_t tillch(char *str, size_t len, char ch)
{
for(size_t i = 0; i < len; i++) if(str[i] == ch) return i;
@@ -160,8 +248,10 @@ static inline size_t tillch(char *str, size_t len, char ch)
static inline int issep(char c)
{
- return isspace(c) || c == '\0' || c == '/' || c == ',' || c == ';' ||
- c == '.' || c == '(' || c == ')' || c == '{' || c == '}';
+ return isspace(c) ||
+ c == '\0' || c == '/' || c == ',' || c == ';' ||
+ c == '.' || c == '(' || c == ')' || c == '{' ||
+ c == '}';
}
static inline int tillsep(char *str)
@@ -180,10 +270,9 @@ static char *typelist_tokenize(char *str)
int s = dict_check(&types_dict, substring(str, off));
if(s < 0) {
fprintf(stderr, "ERROR: Unknown type or subtype %s\n", substring(NULL, 0));
- return NULL;
+ } else {
+ tokbuf_enqueue(&TOKEN_INIT(s, { .num = s }));
}
-
- tokbuf_enqueue(&(struct token){.s = s, .v = s});
}
str += off;
@@ -191,9 +280,12 @@ static char *typelist_tokenize(char *str)
switch(str[0]) {
case '-': return typelist_tokenize(str+1);
case '(':
+ size_t depth = 0;
while((str = next_token(str)))
- if(*(str-1)== ')') { // not really
- if(str[0] == '-') return typelist_tokenize(str+1);
+ if(str[0] == '(') depth++;
+ else if(*(str-1) == ')') {
+ if(depth > 0) depth--;
+ else if(str[0] == '-') return typelist_tokenize(str+1);
else return str;
}
return NULL;
@@ -209,8 +301,10 @@ static char *next_token(char *str)
size_t off = 0;
char c0 = str[0];
- if(c0 == '\0') tok.s = END_INPUT;
+ if(c0 == '\n') line++;
if(isspace(c0)) return next_token(str+1);
+
+ if(c0 == '\0') tok.s = END_INPUT;
else {
off = tillsep(str);
if(off == 0) { // sep
@@ -223,26 +317,28 @@ static char *next_token(char *str)
case '{': tok.s = LBRACE; break;
case '}': tok.s = RBRACE; break;
case '/':
+ char *s2 = str;
tok.s = TYPELIST_START; tokbuf_enqueue(&tok);
- if(!(str = typelist_tokenize(str+off))) goto fail;
+ if(!(s2 = typelist_tokenize(s2+off))) goto fail;
tok.s = TYPELIST_END; tokbuf_enqueue(&tok);
- return str;
- default: break;
+ active_region = s2 - str; return s2;
+ default: fprintf(stderr, "ERROR: Unknown sep '%c'\n", c0); break;
}
} else if(c0 >= '0' && c0 <= '9') { // num
tok.s = NUM;
- tok.v = (intptr_t)atoi(substring(str, off)); // not really
+ tok.v = (stack_item){ .num = atoi(substring(str, off)) }; // not really
} else { // iden or atom (possibly with fields)
+ active_region = off;
int hasfield = 0;
size_t sub_off;
do {
sub_off = tillch(str + 1, off - 1, ':') + 1;
- if(hasfield)
- tokbuf_enqueue(&(struct token){.s = COLON, .v = 0});
+ if(hasfield) tokbuf_enqueue(&TOKEN_INIT(COLON, { .num=0 }));
- tokbuf_enqueue(&(struct token){.s = (!hasfield && str[0] == ':') ? ATOM : IDEN,
- .v = (intptr_t)strdup(substring(str+hasfield, sub_off-hasfield))});
+ tokbuf_enqueue(
+ &TOKEN_INIT((!hasfield && str[0] == ':') ? ATOM : IDEN,
+ { .str = strdup(substring(str+hasfield, sub_off-hasfield))}));
} while(hasfield = 1, str += sub_off, off -= sub_off, off > 0);
return str;
@@ -250,9 +346,92 @@ static char *next_token(char *str)
}
tokbuf_enqueue(&tok);
+ active_region = off;
return str+off;
fail:
- tokbuf_enqueue(&(struct token){.s = END_INPUT});
- return NULL;
+ exit(14);
+ // tok.s = END_INPUT; tokbuf_enqueue(&tok);
+ // return NULL;
+}
+
+// ast printing
+
+void ast_vrbl_print(struct ast_vrbl *vrbl)
+{
+ printf("%s%s", vrbl->is_atom ? ":" : "", vrbl->iden);
+}
+
+void ast_fiel_print(struct ast_fiel *fiel)
+{
+ ast_vrbl_print(&fiel->variable);
+ list_for_each_entry(struct ast_strlist, entry, list, fiel->fields_strlist) {
+ printf(":%s", entry->str);
+ }
+}
+
+void ast_decl_print(struct ast_decl *decl)
+{
+ // TODO: implement
+}
+
+void ast_defn_print(struct ast_defn *defn)
+{
+ // TODO: implement
+}
+
+void ast_oprn_print(struct ast_oprn *oprn)
+{
+ ast_exprlist_print(oprn->left_exprlist);
+ if(oprn->optype == AST_OP_AND) printf(",\n"); else printf(";\n");
+ ast_exprlist_print(oprn->right_exprlist);
+}
+
+void ast_expr_print(struct ast_expr *expr) { ast_exprlist_print(&expr->list); }
+void ast_exprlist_print(struct list_head *list)
+{
+ list_for_each_entry(struct ast_expr, entry, list, list)
+ {
+ switch(entry->type) {
+ case AST_NUMBER: printf("%d", entry->number); break;
+ case AST_VARIABLE: ast_vrbl_print(&entry->variable); break;
+ case AST_FIELDLIST: ast_fiel_print(&entry->fieldlist); break;
+ case AST_DECLARATION: ast_decl_print(&entry->declaration); break;
+ case AST_OPERATION: ast_oprn_print(&entry->operation); break;
+ case AST_PARENLIST:
+ printf("(");
+ ast_exprlist_print(entry->paren_exprlist);
+ printf(")");
+ break;
+ default: fprintf(stderr, "UNKNOWN TYPE: %d\n", entry->type);
+ }
+ printf(" ");
+ }
+ printf("\n");
+}
+
+void ast_exprlist_free(struct list_head *list)
+{
+ list_for_each_safe(l, list) {
+ struct ast_expr *entry = list_entry(l, typeof(*entry), list);
+
+ switch(entry->type) {
+ case AST_NUMBER: break;
+ case AST_VARIABLE: break;
+ case AST_FIELDLIST:
+ list_for_each_safe(l, entry->fieldlist.fields_strlist)
+ free(list_entry(l, struct ast_strlist, list));
+ break;
+ case AST_DECLARATION: break;
+ case AST_DEFINITION: break;
+ case AST_OPERATION:
+ ast_exprlist_free(entry->operation.left_exprlist);
+ ast_exprlist_free(entry->operation.right_exprlist);
+ break;
+ case AST_PARENLIST: ast_exprlist_free(entry->paren_exprlist); break;
+ default: fprintf(stderr, "UNKNOWN TYPE: %d\n", entry->type);
+ }
+
+ free(entry);
+ }
}
diff --git a/demos/sample-files/lbp.g b/demos/sample-files/lbp.g
index bc82cb3..1dd176c 100644
--- a/demos/sample-files/lbp.g
+++ b/demos/sample-files/lbp.g
@@ -8,28 +8,44 @@
-nonterminal S exprlist expr sym fieldlist basetype subtypelist.
+-stacktype { union {
+ int num;
+ char *str;
+
+ struct ast_vrbl vrbl;
+ struct ast_fiel fiel;
+ struct ast_decl decl;
+ struct ast_defn defn;
+ struct ast_oprn oprn;
+
+ struct ast_expr expr;
+ struct ast_strlist strlist;
+ struct list_head *list;
+ }}.
+
-left LPAREN;
-left COMMA SEMICOL.
-S: exprlist DOT {};
+S: exprlist DOT { v = A(0); };
-exprlist: expr {}
- | exprlist expr {}
- | exprlist COMMA exprlist {}
- | exprlist SEMICOL exprlist {};
+exprlist: expr { v = g_LST(A(0).expr); }
+ | expr exprlist { v = g_LST(A(0).expr); v.list->next = A(1).list; }
+ | exprlist COMMA exprlist { v = g_LST(NEW(expr, .type = AST_OPERATION, .operation = NEW(oprn, .optype = AST_OP_AND, .left_exprlist = A(0).list, .right_exprlist = A(2).list))); }
+ | exprlist SEMICOL exprlist { v = g_LST(NEW(expr, .type = AST_OPERATION, .operation = NEW(oprn, .optype = AST_OP_OR, .left_exprlist = A(0).list, .right_exprlist = A(2).list)));};
-expr: NUM {}
- | sym {}
- | sym fieldlist {}
- | sym TYPELIST_START basetype TYPELIST_END {}
- | sym TYPELIST_START basetype subtypelist TYPELIST_END {}
- | LBRACE exprlist DOT RBRACE {}
- | LPAREN exprlist RPAREN {};
+expr: NUM { v = g_NEW(expr, .type = AST_NUMBER, .number = A(0).num); }
+ | sym { v = g_NEW(expr, .type = AST_VARIABLE, .variable = A(0).vrbl); }
+ | sym fieldlist { v = g_NEW(expr, .type = AST_FIELDLIST, .fieldlist = NEW(fiel, .variable = A(0).vrbl, .fields_strlist = A(1).list)); }
+ | sym TYPELIST_START basetype TYPELIST_END { v = g_NEW(expr, .type = AST_VARIABLE, .variable = A(0).vrbl); }
+ | sym TYPELIST_START basetype subtypelist TYPELIST_END { v = g_NEW(expr, .type = AST_VARIABLE, .variable = A(0).vrbl); }
+ | LBRACE exprlist DOT RBRACE { v = g_NEW(expr, .type = AST_PARENLIST, .paren_exprlist = A(1).list); }
+ | LPAREN exprlist RPAREN { v = g_NEW(expr, .type = AST_PARENLIST, .paren_exprlist = A(1).list); };
-sym: IDEN {} | ATOM {};
+sym: IDEN { v = g_NEW(vrbl, .is_atom = 0, .iden = A(0).str); }
+ | ATOM { v = g_NEW(vrbl, .is_atom = 1, .iden = A(0).str); };
-fieldlist: COLON IDEN {}
- | fieldlist fieldlist {};
+fieldlist: COLON IDEN { v = g_LST(NEW(strlist, .str = A(1).str)); }
+ | fieldlist fieldlist { A(0).list->next = A(1).list; v = A(0); };
basetype: T_INT {}
| T_STRUCT {} | T_STRUCT LPAREN ATOM RPAREN {}