diff options
author | Matthew Sotoudeh <matthew@masot.net> | 2024-02-19 02:25:28 -0800 |
---|---|---|
committer | Matthew Sotoudeh <matthew@masot.net> | 2024-02-19 02:25:28 -0800 |
commit | ffc6388571004b17e3a3dee2511ec99076ee803a (patch) | |
tree | ba14dfc0fc0b1beae949e12b8853fa690d588d2a /grammars |
initial dump
Diffstat (limited to 'grammars')
-rw-r--r-- | grammars/c/disambiguate.c | 49 | ||||
-rw-r--r-- | grammars/c/grammar.txt | 17 | ||||
-rw-r--r-- | grammars/expression/disambiguate.c | 49 | ||||
-rw-r--r-- | grammars/expression/grammar.txt | 18 |
4 files changed, 133 insertions, 0 deletions
diff --git a/grammars/c/disambiguate.c b/grammars/c/disambiguate.c new file mode 100644 index 0000000..9a8bf08 --- /dev/null +++ b/grammars/c/disambiguate.c @@ -0,0 +1,49 @@ +int disambiguator(struct state *old, struct state *new) { + // printf("Old tree: "); + // print_parse_tree2(old); + // printf("New tree: "); + // print_parse_tree2(new); + + if (old->start_idx != new->start_idx) { + // printf("\t\tIGNORING "); print_parse_tree2(old); + // printf("\t\tVS: "); print_parse_tree2(new); + return 2; + } + + // Prefer the earlier parsings in the grammar when two entirely different + // productions are taken. + if (old->production_id != new->production_id) + return old->production_id < new->production_id + ? 0 : 1; + + // If they're the same production ... + prod_id_t prod = old->production_id; + if (PRODUCTION_ID_TO_SYMBOL[prod] == SYMBOL_EXPR) { + if (PRODUCTION_ID_TO_PRODUCTION[prod][1] == SYMBOL_OP) { + struct token *old_tok = find_token(old, 1), + *new_tok = find_token(new, 1); + char *old_s = old_tok->string, *new_s = new_tok->string; + const char *precedence[] = {".", "->", "*", "/", "%", "+", "-", + "<<", ">>", "<", "<=", ">", ">=", "==", "!=", "&", "|", "&&", + "||", "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", "&=", + "^=", "|=", ",", 0}; + if (strcmp(old_s, new_s)) { + for (const char **p = precedence; *p; p++) { + if (!strcmp(old_s, *p)) { + return 1; + } else if (!strcmp(new_s, *p)) { + return 0; + } + } + // BAD! + return 2; + } else { + // Associate RIGHT + if (old_tok < new_tok) return 1; + else if (old_tok > new_tok) return 0; + } + } + } + printf("TOTALLY UNKNOWN!\n"); + return 2; +} diff --git a/grammars/c/grammar.txt b/grammars/c/grammar.txt new file mode 100644 index 0000000..486f319 --- /dev/null +++ b/grammars/c/grammar.txt @@ -0,0 +1,17 @@ +KEYWORDS list + switch volatile case while do else const for if + +IDENT regex + [a-zA-Z_][0-9a-zA-Z_]* + +INT regex + [0-9]+ + +OPS list + ( ) { } [ ] + ; , + - + ! % * & / << >> ^ | + -= += != %= *= &= /= <<= == >>= ^= |= + && || ++ -- + < <= > >= = + . -> ? : diff --git a/grammars/expression/disambiguate.c b/grammars/expression/disambiguate.c new file mode 100644 index 0000000..9a8bf08 --- /dev/null +++ b/grammars/expression/disambiguate.c @@ -0,0 +1,49 @@ +int disambiguator(struct state *old, struct state *new) { + // printf("Old tree: "); + // print_parse_tree2(old); + // printf("New tree: "); + // print_parse_tree2(new); + + if (old->start_idx != new->start_idx) { + // printf("\t\tIGNORING "); print_parse_tree2(old); + // printf("\t\tVS: "); print_parse_tree2(new); + return 2; + } + + // Prefer the earlier parsings in the grammar when two entirely different + // productions are taken. + if (old->production_id != new->production_id) + return old->production_id < new->production_id + ? 0 : 1; + + // If they're the same production ... + prod_id_t prod = old->production_id; + if (PRODUCTION_ID_TO_SYMBOL[prod] == SYMBOL_EXPR) { + if (PRODUCTION_ID_TO_PRODUCTION[prod][1] == SYMBOL_OP) { + struct token *old_tok = find_token(old, 1), + *new_tok = find_token(new, 1); + char *old_s = old_tok->string, *new_s = new_tok->string; + const char *precedence[] = {".", "->", "*", "/", "%", "+", "-", + "<<", ">>", "<", "<=", ">", ">=", "==", "!=", "&", "|", "&&", + "||", "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", "&=", + "^=", "|=", ",", 0}; + if (strcmp(old_s, new_s)) { + for (const char **p = precedence; *p; p++) { + if (!strcmp(old_s, *p)) { + return 1; + } else if (!strcmp(new_s, *p)) { + return 0; + } + } + // BAD! + return 2; + } else { + // Associate RIGHT + if (old_tok < new_tok) return 1; + else if (old_tok > new_tok) return 0; + } + } + } + printf("TOTALLY UNKNOWN!\n"); + return 2; +} diff --git a/grammars/expression/grammar.txt b/grammars/expression/grammar.txt new file mode 100644 index 0000000..a1590fa --- /dev/null +++ b/grammars/expression/grammar.txt @@ -0,0 +1,18 @@ +INT regex + [0-9]+ + +OP list + || && -- ++ = == ! + / * - + << >> % ^ + /= *= -= += <<= >>= &= |= %= ^= + -> . + < > <= >= != + ? : + ( ) { } [ ] + , ; + +EXPR nonterm .start + EXPR OP EXPR + INT + ( EXPR ) + EXPR ? EXPR : EXPR |