void alert_parse(struct state *state) { } int disambiguator(struct state *old, struct state *new) { // fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); // print_parse_tree(old, 0, stderr); // print_parse_tree(new, 0, stderr); // fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); if (old->n_poisoned < new->n_poisoned) return 0; if (new->n_poisoned < old->n_poisoned) return 1; // 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] == START_SYMBOL && PRODUCTION_ID_TO_PRODUCTION[prod][1] != DONE_SYMBOL) { struct token *old_tok = find_token(old, 1), *new_tok = find_token(new, 1); if (old_tok < new_tok) return 0; else if (old_tok > new_tok) return 1; } if (PRODUCTION_ID_TO_PRODUCTION[prod][0] == SYMBOL_ERROR && PRODUCTION_ID_TO_PRODUCTION[prod][1] != DONE_SYMBOL) { struct token *old_tok = find_token(old, 1), *new_tok = find_token(new, 1); if (old_tok < new_tok) return 0; else if (old_tok > new_tok) return 1; } else if (PRODUCTION_ID_TO_PRODUCTION[prod][1] == SYMBOL_ERROR) { struct token *old_tok = find_token(old, 1), *new_tok = find_token(new, 1); if (old_tok < new_tok) return 1; else if (old_tok > new_tok) return 0; } else 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; } } fprintf(stderr, "ERROR: didn't find operator '%s'\n", old_s); exit(1); } else { if (old_tok < new_tok) return 1; else if (old_tok > new_tok) return 0; } } } // Generally speaking, we want left associativity to avoid long chains of // completions. struct token *old_tok = find_token(old, 1), *new_tok = find_token(new, 1); if (old_tok < new_tok) return 1; else if (old_tok > new_tok) return 0; fprintf(stderr, "TOTALLY UNKNOWN!\n"); fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~\n"); pprint_state(old); // print_parse_tree(old, 0, stderr); fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~\n"); pprint_state(new); // print_parse_tree(new, 0, stderr); fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~\n"); exit(1); return 2; }