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