pike.git / lib / modules / Parser.pmod / LR.pmod / module.pmod

version» Context lines:

pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:1:   /* -  * $Id: module.pmod,v 1.5 2002/05/23 15:14:48 grubba Exp $ +  * $Id: module.pmod,v 1.6 2002/05/24 12:53:15 grubba Exp $    *    * A BNF-grammar in Pike.    * Compiles to a LALR(1) state-machine.    *    * Henrik Grubbström 1996-11-24    */      #pike __REAL_VERSION__      /*! LALR(1) parser generator
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:152:    if (stringp(symbol)) {    has_tokens = 1;    break;    }    }       num_nonnullables = sizeof(r);    }   }    +  + //! Severity level + enum SeverityLevel { +  NOTICE = 0, +  WARNING, +  ERROR, + }; +  + //! Class handling reporting of errors and warnings. + class ErrorHandler + { +  //! Verbosity level +  //! +  //! @int +  //! @value -1 +  //! Just errors. +  //! @value 0 +  //! Errors and warnings. +  //! @value 1 +  //! Also notices. +  //! @endint +  optional int verbose=1; +  +  static constant severity_kind = ([ NOTICE:"Notice", +  WARNING:"Warning", +  ERROR:"Error" ]); +  +  void report(SeverityLevel level, string subsystem, string msg, +  mixed ... args) +  { +  if (level > -verbose) { +  werror("%s: %s: "+msg+"\n", +  severity_kind[level], subsystem, @args); +  } +  } + } +    //! This object implements an LALR(1) parser and compiler.   //!   //! Normal use of this object would be:   //!   //! @pre{ -  + //! set_error_handler   //! {add_rule, set_priority, set_associativity}*   //! set_symbol_to_string   //! compile   //! {parse}*   //! @}   class Parser   {    //! The grammar itself.    mapping(int : array(Rule)) grammar = ([]);   
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:179:       static multiset(mixed) nullable = (< >);      #if 0    static mapping(mixed : multiset(Rule)) derives = ([]);       /* Maps from symbol to which rules may start with that symbol */    static mapping(mixed : multiset(Rule)) begins = ([]);   #endif /* 0 */    -  +     /* Maps from symbol to the rules that use the symbol    * (used for finding nullable symbols)    */    static mapping(int : multiset(Rule)) used_by = ([]);       //! The initial LR0 state.    Kernel start_state;    -  //! Verbosity level -  //! -  //! @int -  //! @value 0 -  //! None -  //! @value 1 -  //! Some -  //! @endint -  int verbose=1; -  +     //! Error code    int lr_error=0;       /* Number of next rule (used only for conflict resolving) */    static int next_rule_number = 1;       //! LR0 states that are already known to the compiler.    mapping(string:Kernel) known_states = ([]);    -  +  //! Compile error and warning handler. +  ErrorHandler error_handler = ErrorHandler(); +  +  void report(SeverityLevel level, string subsystem, string msg, +  mixed ... args) +  { +  if (!error_handler) { +  error_handler = ErrorHandler(); +  } +  error_handler->report(level, subsystem, msg, @args); +  } +     /*    * Sub-classes    */       //!    //! An LR(0) item, a partially parsed rule.    //!    static class Item    {    //! The rule
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:350:       add_item(new_item);       if (sizeof(r->symbols) && intp(r->symbols[0]) &&    !closure_set[r->symbols[0]]) {    closure([int]r->symbols[0]);    }    }    }    } else { -  werror("Error: Definition missing for non-terminal %s\n", +  report(ERROR, "closure", +  "Definition missing for non-terminal %s",    symbol_to_string(nonterminal));    lr_error |= ERROR_MISSING_DEFINITION;    }    }       //! Make the goto-set of this state.    multiset(int|string) goto_set()    {    multiset(int|string) set = (<>);       foreach (items, Item i) {    if (i->offset != sizeof(i->r->symbols)) {    set[i->r->symbols[i->offset]] = 1;    }    }    -  if (verbose) { -  werror("goto_set()=> (< %s >)\n", +  report(NOTICE, "goto_set", "=> (< %s >)",    map(indices(set), symbol_to_string) * ", "); -  } -  +     return (set);    }       //! Generates the state reached when doing goto on the specified symbol.    //! i.e. it compiles the LR(0) state.    //!    //! @param symbol    //! Symbol to make goto on.    Kernel do_goto(int|string symbol)    {    multiset(Item) items;    -  if (verbose) { -  werror("Performing GOTO on <%s>\n", symbol_to_string(symbol)); -  } +  report(NOTICE, "do_goto", +  "Performing GOTO on <%s>", +  symbol_to_string(symbol));       items = symbol_items[symbol];    if (items) {    array(int) item_ids = [array(int)]map(sort(indices(items)->item_id),    `+, 1);    string kernel_hash = sprintf("%@4c", item_ids);       Kernel new_state = known_states[kernel_hash];       if (!new_state) {
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:421:       if ((offset != sizeof(r->symbols)) &&    intp(lookahead = r->symbols[offset]) &&    !new_state->closure_set[lookahead]) {    new_state->closure([int]lookahead);    }    }       s_q->push(new_state);    } else { -  // werror("Known state\n"); +  // report(NOTICE, "do_goto", "Known state");    }    /* DEBUG */    -  if (verbose) { -  werror("GOTO on %s generated state:\n%s\n", +  report(NOTICE, "do_goto", +  "GOTO on %s generated state:\n%s",    symbol_to_string(symbol),    state_to_string(new_state)); -  } +        /* !DEBUG */       if (items) {    foreach (indices(items), Item i) {    i->next_state = new_state;    }    }    } else { -  werror("WARNING: do_goto() on unknown symbol <%s>\n", +  report(WARNING, "do_goto", +  "do_goto() on unknown symbol <%s>",    symbol_to_string(symbol));    }    }       static string _sprintf()    {    return sprintf("%{%s\n%}", items);    }    }   
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:645:    //! Add a rule to the grammar.    //!    //! @param r    //! Rule to add.    void add_rule(Rule r)    {    array(Rule) rules;    int|string symbol;       /* DEBUG */ -  if (verbose) { -  werror("Adding rule: " + rule_to_string(r) + "\n"); -  } +  report(NOTICE, "add_rule", "Adding rule: %s", rule_to_string(r));       /* !DEBUG */       r->number = next_rule_number;    /* Reserve space for the items generatable from this rule. */    next_rule_number += sizeof(r->symbols) + 1;       /* First add the rule to the grammar */    if (grammar[r->nonterminal]) {    grammar[r->nonterminal] += ({ r });
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:689:    }    }    }       if (!(r->num_nonnullables)) {    /* This rule was nullable */    new_nullables->push(r->nonterminal);       while (new_nullables->ptr) {    symbol = [int]new_nullables->pop(); -  if (verbose) { -  werror("Nulling symbol %s\n", +  report(NOTICE, "add_rule", "Nulling symbol %s",    symbol_to_string(symbol)); -  } +     nullable[symbol] = 1;    if (used_by[symbol]) {    foreach (indices(used_by[symbol]), Rule r2) {    if (!(--r2->num_nonnullables)) {    new_nullables->push(r2->nonterminal);    }    }    used_by[symbol] = 0; /* No more need for this info */    }    }
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:850:    i2->number = 0x7fffffff;       i2->direct_lookahead = i->direct_lookahead;       cyclic = 1;    empty_cycle &= !(sizeof(i2->error_lookahead));    }    i->count = 0x7fffffff;       if (cyclic) { -  if (verbose) { -  werror("Cyclic item\n%s\n", +  report(NOTICE, "traverse_items", "Cyclic item\n%s",    item_to_string(i)); -  } +     conflict_func(empty_cycle && !(sizeof(i->error_lookahead)));    }    }    }       static void shift_conflict(int empty)    {    /* Ignored */    }   
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:932:    static int go_through(Kernel state, int item_id,    Item current_item)    {    int index;    Item i, master;       i = state->item_id_to_item[item_id];       /* What to do if not found? */    if (!i) { -  werror("go_through: item %d not found in state\n" -  "%s\n", +  report(ERROR, "go_through", +  "Item %d not found in state\n" +  "%s\n" +  "Backtrace:\n%s",    item_id, -  state_to_string(state)); -  werror("Backtrace:\n%s\n", describe_backtrace(backtrace())); +  state_to_string(state), +  describe_backtrace(backtrace()));    return 0;    }       if (i->master_item) {    master = i->master_item;    } else {    master = i;    }       if (i->offset < sizeof(i->r->symbols)) {
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:971:    /* At end of rule */    master->relation[current_item] = 1;    return (1); /* Always nullable */    }    }       static int repair(Kernel state, multiset(int|string) conflicts)    {    multiset(int|string) conflict_set = (<>);    -  if (verbose) { -  werror("Repairing conflict in state:\n%s\n" -  "Conflicts on (< %s >)\n", +  report(NOTICE, "repair", +  "Repairing conflict in state:\n%s\n" +  "Conflicts on (< %s >)",    state_to_string(state),    map(indices(conflicts), symbol_to_string) * ", "); -  } +        foreach (indices(conflicts), int|string symbol) {    int reduce_count = 0;    int shift_count = 0;    int only_operators = 1;    Priority shift_pri, reduce_pri, pri;    Rule min_rule = 0;       /* Analyse the items */    /* This loses if there are reduce-reduce conflicts,
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:1036:    } else {    pri = shift_pri;    }       foreach (state->items, Item i) {    if (i->offset == sizeof(i->r->symbols)) {    /* Reduce */    if (i->direct_lookahead[symbol]) {    Priority new_pri;    if ((new_pri = i->r->pri)->value < pri->value) { -  if (verbose) { -  werror("Ignoring reduction of item\n%s\n" -  "on lookahead %s (Priority %d < %d)\n", +  report(NOTICE, "repair", +  "Ignoring reduction of item\n%s\n" +  "on lookahead %s (Priority %d < %d)",    item_to_string(i),    symbol_to_string(symbol),    new_pri->value, pri->value); -  } +     i->direct_lookahead[symbol] = 0;    if (!sizeof(indices(i->direct_lookahead))) {    i->direct_lookahead = (<>);    }    } else if ((pri->assoc >= 0) &&    (shift_pri->value == pri->value)) { -  if (verbose) { -  werror("Ignoring reduction of item\n%s\n" -  "on lookahead %s (Right associative)\n", +  report(NOTICE, "repair", +  "Ignoring reduction of item\n%s\n" +  "on lookahead %s (Right associative)",    item_to_string(i),    symbol_to_string(symbol)); -  } +     i->direct_lookahead[symbol] = 0;    if (!sizeof(indices(i->direct_lookahead))) {    i->direct_lookahead = (<>);    }    } else { -  if (verbose) { -  werror("Kept item\n%s\n" -  "on lookahead %s\n", +  report(NOTICE, "repair", +  "Kept item\n%s\n" +  "on lookahead %s",    item_to_string(i),    symbol_to_string(symbol)); -  } +     reduce_rest++;    }    }    } else if (i->r->symbols[i->offset] == symbol) {    /* Shift */    if (shift_pri->value < pri->value) { -  if (verbose) { -  werror("Ignoring shift on item\n%s\n" -  "on lookahead %s (Priority %d < %d)\n", +  report(NOTICE, "repair", +  "Ignoring shift on item\n%s\n" +  "on lookahead %s (Priority %d < %d)",    item_to_string(i),    symbol_to_string(symbol),    i->r->pri->value, pri->value); -  } +     i->direct_lookahead = (<>);    i->next_state = 0;    } else if ((pri->assoc <= 0) &&    (reduce_pri->value == pri->value)) { -  if (verbose) { -  werror("Ignoring shift on item\n%s\n" -  "on lookahead %s (Left associative)\n", +  report(NOTICE, "repair", +  "Ignoring shift on item\n%s\n" +  "on lookahead %s (Left associative)",    item_to_string(i),    symbol_to_string(symbol)); -  } +     i->direct_lookahead = (<>);    i->next_state = 0;    } else { -  if (verbose) { -  werror("Kept item\n%s\n" -  "on lookahead %s\n", +  report(NOTICE, "repair", +  "Kept item\n%s\n" +  "on lookahead %s",    item_to_string(i),    symbol_to_string(symbol)); -  } +     shift_rest++;    }    }    }    } else {    /* Not only operators */    if (shift_count) {    /* Prefer shifts */    foreach (state->items, Item i) {    if (i->offset == sizeof(i->r->symbols)) {    /* Reduction */    if (i->direct_lookahead[symbol]) { -  if (verbose) { -  werror("Ignoring reduction on item\n%s\n" -  "on lookahead %s (can shift)\n", +  report(NOTICE, "repair", +  "Ignoring reduction on item\n%s\n" +  "on lookahead %s (can shift)",    item_to_string(i),    symbol_to_string(symbol)); -  } +     i->direct_lookahead[symbol] = 0;    if (!sizeof(indices(i->direct_lookahead))) {    i->direct_lookahead = (<>);    }    }    } else {    /* Shift */    if (i->r->symbols[i->offset] == symbol) { -  if (verbose) { -  werror("Kept item\n%s\n" -  "on lookahead (shift)%s\n", +  report(NOTICE, "repair", +  "Kept item\n%s\n" +  "on lookahead (shift)%s",    item_to_string(i),    symbol_to_string(symbol)); -  } +     shift_rest++;    }    }    }    } else {    /* Select the first reduction */    foreach (state->items, Item i) {    if (i->r == min_rule) { -  if (verbose) { -  werror("Kept item\n%s\n" -  "on lookahead %s (first rule)\n", +  report(NOTICE, "repair", +  "Kept item\n%s\n" +  "on lookahead %s (first rule)",    item_to_string(i),    symbol_to_string(symbol)); -  } +     reduce_rest++;    } else { -  if (verbose) { -  werror("Ignoring reduction on item\n%s\n" -  "on lookahead %s (not first rule)\n", +  report(NOTICE, "repair", +  "Ignoring reduction on item\n%s\n" +  "on lookahead %s (not first rule)",    item_to_string(i),    symbol_to_string(symbol)); -  } +     i->direct_lookahead[symbol] = 0;    if (!sizeof(indices(i->direct_lookahead))) {    i->direct_lookahead = (<>);    }    }    }    }    }       int conflict_free = 0;       if (reduce_rest > 1) {    if (shift_rest) { -  werror("Error: Shift-Reduce-Reduce conflict on lookahead %s\n", +  report(ERROR, "repair", +  "Shift-Reduce-Reduce conflict on lookahead %s",    symbol_to_string(symbol));    } else { -  werror("Error: Reduce-Reduce conflict on lookahead %s\n", +  report(ERROR, "repair", +  "Reduce-Reduce conflict on lookahead %s",    symbol_to_string(symbol));    }    } else if (reduce_rest) {    if (shift_rest) { -  werror("Error: Shift-Reduce conflict on lookahead %s\n", +  report(ERROR, "repair", +  "Shift-Reduce conflict on lookahead %s",    symbol_to_string(symbol));    } else {    /* REDUCE    *    * No other rule left -- conflict resolved!    */    conflict_free = 1;    }    } else {    /* SHIFT    *    * All reductions removed -- conflict resolved!    */    conflict_free = 1;    }    if (conflict_free) {    if (reduce_count > 1) {    if (shift_count) { -  if (only_operators) { -  if (verbose) { -  werror("Repaired Shift-Reduce-Reduce conflict on %s\n", +  report(only_operators?NOTICE:WARNING, "repair", +  "Repaired Shift-Reduce-Reduce conflict on %s",    symbol_to_string(symbol)); -  } +     } else { -  werror("Warning: Repaired Shift-Reduce-Reduce conflict on %s\n", +  report(only_operators?NOTICE:WARNING, "repair", +  "Repaired Reduce-Reduce conflict on %s",    symbol_to_string(symbol));    } -  } else { -  if (only_operators) { -  if (verbose) { -  werror("Repaired Reduce-Reduce conflict on %s\n", -  symbol_to_string(symbol)); -  } -  } else { -  werror("Warning: Repaired Reduce-Reduce conflict on %s\n", -  symbol_to_string(symbol)); -  } -  } +     } else if (reduce_count) {    if (shift_count) { -  if (only_operators) { -  if (verbose) { -  werror("Repaired Shift-Reduce conflict on %s\n", +  report(only_operators?NOTICE:WARNING, "repair", +  "Repaired Shift-Reduce conflict on %s",    symbol_to_string(symbol)); -  } +     } else { -  werror("Warning: Repaired Shift-Reduce conflict on %s\n", -  symbol_to_string(symbol)); -  } -  } else { +     /* No conflict */ -  if (verbose) { -  werror("No conflict on symbol %s (Plain REDUCE)\n", +  report(NOTICE, "repair", +  "No conflict on symbol %s (Plain REDUCE)",    symbol_to_string(symbol));    } -  } +     } else {    /* No conflict */ -  if (verbose) { -  werror("No conflict on symbol %s (SHIFT)\n", +  report(NOTICE, "repair", +  "No conflict on symbol %s (SHIFT)",    symbol_to_string(symbol));    } -  } +        } else {    /* Still conflicts left on this symbol */    conflict_set[symbol] = 1;    }    }       if (sizeof(indices(conflict_set))) { -  werror("Still conflicts remaining in state\n%s\n" -  "on symbols (< %s >)\n", +  report(ERROR, "repair", +  "Still conflicts remaining in state\n%s\n" +  "on symbols (< %s >)",    state_to_string(state),    map(indices(conflict_set), symbol_to_string) * ", ");    return (ERROR_CONFLICTS);    } else { -  if (verbose) { -  werror("All conflicts removed!\n"); -  } +  report(WARNING, "repair", +  "All conflicts removed!");    return (0);    }    }      #ifdef LR_PROFILE - #define LR_GAUGE(X, BLOCK) werror(X ": %f\n", gauge BLOCK) + #define LR_GAUGE(X, BLOCK) \ +  report(NOTICE, "compile", X ": %f\n", gauge BLOCK)   #else /* !LR_PROFILE */   #define LR_GAUGE(X, BLOCK) do BLOCK while(0)   #endif /* LR_PROFILE */       //! Compiles the grammar into a parser, so that parse() can be called.    int compile()    {    int lr_error = 0; /* No error yet */    int state_no = 0; /* DEBUG INFO */    Kernel state;    multiset(int|string) symbols, conflicts;       s_q = State_queue();    s_q->push(first_state());       /* First make LR(0) states */       LR_GAUGE("LR0", {    while (state = s_q->next()) {    -  if (verbose) { -  werror("Compiling state %d:\n%s", state_no++, +  report(NOTICE, "compile", "Compiling state %d:\n%s", state_no++,    state_to_string(state) + "\n"); -  } +        /* Probably better implemented as a stack */    foreach (indices(state->goto_set()), int|string symbol) {    state->do_goto(symbol);    }    }    });       /* Compute nullables */    /* Done during add_rule */ -  if (verbose) { -  werror("Nullable nonterminals: (< %s >)\n", +  report(NOTICE, "compile", "Nullable nonterminals: (< %s >)\n",    map(indices(nullable), symbol_to_string) * ", "); -  } +        LR_GAUGE("Master items", {    /* Mark Transition and Reduction master items */    for (int index = 0; index < s_q->tail; index++) {    mapping(int|string : Item) master_item =([]);       foreach (s_q->arr[index]->items, Item i) {    if (i->offset < sizeof(i->r->symbols)) {    /* This is not a reduction item, which represent themselves */    int|string symbol = i->r->symbols[i->offset];
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:1398:    if ((!transition->master_item) &&    (transition->offset != sizeof(transition->r->symbols)) &&    (intp(symbol = transition->r->symbols[transition->offset]))) {    /* Master item and    * Not a reduction item and    * next symbol is a NonTerminal    */    if (!lookup[symbol]) {    // Foo? Shouldn't these always exist since we've made    // a closure earlier? -  werror("WARNING: No item for symbol <%s>\n" +  report(WARNING, "compile", +  "No item for symbol <%s>\n"    "in state:\n" -  "%s\n", +  "%s",    symbol_to_string(symbol),    state_to_string(s_q->arr[index]));    continue;    }       /* Find items which can reduce to the nonterminal from above */    foreach (lookup[symbol], Item i) {    if (sizeof(i->r->symbols)) {    if (go_through(i->next_state, i->item_id + 1, transition)) {    /* Nullable */
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:1492:    }    }    }    }    if (sizeof(conflicts)) {    /* Repair conflicts */    // int ov = verbose;    // verbose = 1;    lr_error = repair(state, conflicts);    // verbose = ov; -  } else if (verbose) { -  werror("No conflicts in state:\n%s\n", +  } else { +  report(NOTICE, "compile", "No conflicts in state:\n%s",    state_to_string(s_q->arr[index]));    }    }    });       LR_GAUGE("Compile actions", {    /* Compile action tables */    for (int index = 0; index < s_q->tail; index++) {    Kernel state = s_q->arr[index];   
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:1521:    foreach (indices(i->direct_lookahead), int|string symbol) {    state->action[symbol] = i->r;    }    }    }    }    start_state = s_q->arr[0];    });      #ifdef LR_PROFILE -  werror("DONE\n"); +  report(NOTICE, "compile", "DONE\n");   #endif /* LR_PROFILE */       return (lr_error);    }       //! Parse the input according to the compiled grammar.    //! The last value reduced is returned.    //!    //! @note    //! The parser must have been compiled (with compile())
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:1560:    ADT.Stack state_stack = ADT.Stack(4096);    Kernel state = start_state;       string input;    mixed value;       lr_error = 0; /* No parse error yet */       if (!functionp(scanner) &&    !(objectp(scanner) && functionp(scanner->`()))) { -  werror("parser->parse(): scanner not set!\n"); +  report(ERROR, "parse", "parser->parse(): scanner not set!\n");    lr_error = ERROR_NO_SCANNER;    return(0);    }       while (1) {    mixed a;       /* Read some input */    value = scanner();   
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:1582:    input = ([array(string)]value)[0];    value = ([array(mixed)]value)[1];    } else {    input = [string]value;    }       while(1) {    while (object_program(a = state->action[input]) == Rule) {    Rule r = [object(Rule)]a;    -  if (verbose) { -  werror("Reducing according to rule\n%s\n", +  report(NOTICE, "parse", "Reducing according to rule\n%s\n",    rule_to_string(r)); -  } +        do {    if (r->action) {    /* REDUCE */    string|function func = 0;       if (stringp(func = r->action)) {    if (action_object) {    func = [string|function]action_object[r->action];    if (!functionp(func)) {    if (!func) { -  werror("Missing action \"%s\" in object\n", +  report(ERROR, "parse", +  "Missing action \"%s\" in object",    r->action);    lr_error |= ERROR_MISSING_ACTION;    } else { -  werror("Bad type (%s) for action \"%s\" in object\n", +  report(ERROR, "parse", +  "Bad type (%s) for action \"%s\" in object",    typeof(func), r->action);    lr_error |= ERROR_BAD_ACTION_TYPE;    func = 0;    }    }    } else { -  werror("Missing object for action \"%s\"\n", +  report(ERROR, "parse", "Missing object for action \"%s\"",    r->action);    lr_error |= ERROR_NO_OBJECT;    func = 0;    }    }    if (func) {    if (sizeof(r->symbols)) {    value_stack->push(([function(mixed ...:mixed)]func)    (@[array(mixed)]value_stack->    pop(sizeof(r->symbols))));
pike.git/lib/modules/Parser.pmod/LR.pmod/module.pmod:1649:    }       if (a) {    /* SHIFT or ACCEPT */    if (input == "") {    /* Only the final state is allowed to shift on ""(EOF) */    /* ACCEPT */    return(value_stack->pop());    }    /* SHIFT */ -  if (verbose) { -  werror("Shifting \"%s\", value \"%O\"\n", input, value); -  } +  report(NOTICE, "parse", +  "Shifting \"%s\", value \"%O\"", input, value);    value_stack->push(value);    state_stack->push(state);    state = [object(Kernel)]a;    } else {    /* ERROR */    if (input = "") {    /* At end of file */    lr_error |= ERROR_EOF;       if (value_stack->ptr != 1) {    if (value_stack->ptr) { -  werror("Error: Bad state at EOF -- Throwing \"%O\"\n", +  report(ERROR, "parse", "Bad state at EOF -- Throwing \"%O\"",    value_stack->pop());    state = [object(Kernel)]state_stack->pop();    continue;    } else { -  werror("Error: Empty stack at EOF!\n"); +  report(ERROR, "parse", "Empty stack at EOF!");    return (0);    }    } else { -  werror("Error: Bad state at EOF\n"); +  report(ERROR, "parse", "Bad state at EOF");    return(value_stack->pop());    }    } else {    lr_error |= ERROR_SYNTAX;    -  werror("Error: Bad input: %O(%O)\n", input, value); +  report(ERROR, "parse", "Bad input: %O(%O)", input, value);    }    }    break; /* Break out of the inner while(1) to read more input. */    }    }    }   }