summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c320
1 files changed, 36 insertions, 284 deletions
diff --git a/parser.c b/parser.c
index 2c4a7d6..c577105 100644
--- a/parser.c
+++ b/parser.c
@@ -3,309 +3,61 @@
#include <stdlib.h>
#include <string.h>
+#include "lexer.h"
#include "common.h"
#include "error.h"
#include "logic.h"
#include "gate.h"
-int parse_input(char *);
-int parse_module(char *);
-int parse_expr(char *);
+static struct token *cursor;
-struct tok_lookup {
- char *str;
- int (*handler)(char*);
-};
+#ifdef emit_error
+#warning "Remember to remove the global emit_error"
+#undef emit_error
+#endif /* ifdef emit_error */
-struct op_lookup {
- char *str;
- enum BINARY (*handler)(enum BINARY, enum BINARY);
-};
+#define emit_error(...) fprintf(stderr, "Error (%zd,%zd): ", cursor->loc.line, cursor->loc.column);\
+ fprintf(stderr, __VA_ARGS__)
-static struct op_lookup uop_handlers[] = {
- {.str = "not", .handler = logic_nand},
-};
-static struct op_lookup bop_handlers[] = {
- {.str = "and", .handler = logic_and},
- {.str = "or", .handler = logic_or},
- {.str = "nand", .handler = logic_nand},
- {.str = "nor", .handler = logic_nor},
- {.str = "xor", .handler = logic_xor}
-};
+//static struct op_lookup uop_handlers[] = {
+// {.str = "not", .handler = logic_nand},
+//};
+//
+//static struct op_lookup bop_handlers[] = {
+// {.str = "and", .handler = logic_and},
+// {.str = "or", .handler = logic_or},
+// {.str = "nand", .handler = logic_nand},
+// {.str = "nor", .handler = logic_nor},
+// {.str = "xor", .handler = logic_xor}
+//};
+//
+//static struct tok_lookup tok_handlers[] = {
+// {.str = "input", .handler = parse_input},
+// {.str = "module", .handler = parse_module},
+// {.str = "expr", .handler = parse_expr}
+//};
-static struct tok_lookup tok_handlers[] = {
- {.str = "input", .handler = parse_input},
- {.str = "module", .handler = parse_module},
- {.str = "expr", .handler = parse_expr}
-};
+static int
+expect(enum TOKEN_TYPE e) {
+ char *expected_desc = "(internal error)";
+ char *observed_desc = "(internal error)";
-int
-rtrim(char *string) {
- char *old_end = string + strlen(string);
- char *w = NULL;
-
- string[strcspn(string, "\r\n")] = '\0';
-
- /* find first member of right whitespace */
- for (w = old_end; w >= string; w--) {
- if (strchr("\t ", *w) == NULL) {
- break;
- }
- *w = '\0';
- }
-
- return old_end - w;
-}
-
-char *
-eat_whitespace(char *string) {
- while (*string && isspace(*string)) {
- string++;
- }
- return string;
-}
-
-char *
-get_token_special(char *string, char **rest, char *delims) {
- size_t tok_len = 0;
- char *ret = NULL;
- string = eat_whitespace(string);
- tok_len = strcspn(string, delims);
- if (tok_len == 0) {
- emit_error("unexpected end of string");
- return NULL;
- }
- if (NULL == (ret = strndup(string, tok_len))) {
- emit_error("get_token: ");
- perror("strndup");
- return NULL;
- }
- *rest = string + tok_len;
- return ret;
-}
-
-char *
-get_token(char *string, char **rest) {
- return get_token_special(string, rest, " \t");
-}
-
-int
-expect(const char *expect, char *actual) {
- int min_len = 0;
-
- min_len = MIN(strlen(expect), strlen(actual));
-
- if (strncmp(expect, actual, min_len) != 0) {
- emit_error("Expected '%s' at start of '%s'\n", expect, actual);
+ if (cursor->type != e) {
+ expected_desc = get_token_description(e);
+ observed_desc = get_token_description(cursor->type);
+ emit_error("Expected %s, got %s\n", expected_desc, observed_desc);
return 1;
}
- return 0;
-}
-
-int parse_uop(char *str, char *name, enum BINARY (*handler)(enum BINARY, enum BINARY)) {
- char *source_name = NULL;
- char *next = NULL;
-
- if (NULL == (source_name = get_token(str, &next))) {
- return 1;
- }
-
- /* FIXME allow input from other gates, not just inputs */
- struct gate *in = gate_get_input_by_name(source_name);
- free(source_name);
- return gate_add(name, handler, in, in);
-
-
-}
-
-int parse_bop(char *str, char *name, enum BINARY (*handler)(enum BINARY, enum BINARY)) {
- char *source_name1 = NULL;
- char *source_name2 = NULL;
- char *next = NULL;
- struct gate *in1 = NULL;
- struct gate *in2 = NULL;
-
- if (NULL == (source_name1 = get_token(str, &next))) {
- return 1;
- }
-
- if (NULL == (source_name2 = get_token(next, &next))) {
- free(source_name1);
- return 1;
- }
-
- if (*next != '\0') {
- emit_error("superfluous text \"%s\"\n", next);
- free(source_name1);
- free(source_name2);
- return 1;
- }
-
- /* FIXME allow input from other gates, not just inputs */
- in1 = gate_get_input_by_name(source_name1);
- in2 = gate_get_input_by_name(source_name2);
-
- free(source_name1);
- free(source_name2);
-
- if (in1 == NULL || in2 == NULL) {
- emit_error("Undeclared identifier in source(s) for expression '%s'\n",
- name);
- return 1;
- }
-
- return gate_add(name, handler, in1, in2);
-}
-
-int
-parse_op(char *str, char *name) {
- char *tok = NULL;
- char *next = NULL;
- int match = 0;
- size_t i = 0;
-
- if (NULL == (tok = get_token(str, &next))) {
- return 1;
- }
-
- match = 0;
- for (i = 0; i < sizeof(bop_handlers)/sizeof(bop_handlers[0]); i++) {
- if (strcmp(bop_handlers[i].str, tok) == 0) {
- match = 1;
- if (parse_bop(next, name, bop_handlers[i].handler)) {
- free(tok);
- return 1;
- }
- }
- }
- for (i = 0; i < sizeof(uop_handlers)/sizeof(uop_handlers[0]); i++) {
- if (strcmp(uop_handlers[i].str, tok) == 0) {
- match = 1;
- if (parse_uop(next, name, uop_handlers[i].handler)) {
- free(tok);
- return 1;
- }
- }
- }
- if (match == 0) {
- emit_error("Invalid operator \"%s\"\n", tok);
- free(tok);
- return 1;
- }
- free(tok);
return 0;
}
-int
-parse_expr(char *str) {
- int ret = 0;
- const char *expr_sep = ": ";
- char *ident = NULL;
- char *next = NULL;
- char *op = NULL;
-
- if (NULL == (ident = get_token_special(str, &next, ": \t"))) {
- return 1;
- }
-
- if (expect(expr_sep, next)) {
- free(ident);
- return 1;
- }
-
- op = next + strlen(expr_sep);
-
- ret = parse_op(op, ident);
- free(ident);
- return ret;
-}
-
-int
-parse_input(char *str) {
- char *ident = NULL;
- char *next = NULL;
- int ret = 0;
-
- if (NULL == (ident = get_token(str, &next))) {
- return 1;
- }
-
- if (strlen(ident) == 0) {
- emit_error("input label must not be empty");
- free(ident);
- return 1;
- }
-
- if (*next != '\0') {
- emit_error("superfluous text after \"%s\" identifier: \"%s\"\n",
- ident, next);
- free(ident);
- return 1;
- }
-
- emit_info("Add input '%s'\n", ident);
- ret = gate_input_add(ident);
- free(ident);
- return ret;
-}
-
-int
-parse_module(char *str) {
- char *mod_name = NULL;
- char *next = NULL;
- if (NULL == (mod_name = get_token(str, &next))) {
- return 1;
- }
-
- if (*next != '\0') {
- emit_error("superfluous text following module name");
- free(mod_name);
- return 1;
- }
-
- printf("FIXME module name is \"%s\" but modules are not implemented\n", mod_name);
- free(mod_name);
- return 0;
-}
int
-parse_line(char *line) {
- size_t i = 0;
- char *next = NULL;
- char *tok = NULL;
- int match = 0;
-
- rtrim(line);
-
- if ( strlen(line) == 0
- || (strlen(line) == 1 && isspace(line[0]))) {
- return 0;
- }
-
- if (NULL == (tok = get_token(line, &next))) {
- return 1;
- }
-
- match = 0;
- for (i = 0; i < sizeof(tok_handlers)/sizeof(tok_handlers[0]); i++) {
- if (strcmp(tok_handlers[i].str, tok) == 0) {
- match = 1;
- if ((tok_handlers[i].handler)(next)) {
- free(tok);
- return 1;
- }
- }
- }
-
- if (match == 0) {
- emit_error("invalid token \"%s\"", tok);
- free(tok);
- return 1;
- }
- free(tok);
+parse(struct token *t) {
+ cursor = t;
+ expect(TOK_MODULE);
return 0;
}
-