get_production(short conflict_number, LuaToken tokens) { short entry = 0; int index, level; if (conflict_number <= TOTAL_CONFLICTS) { entry = (short)(conflict_number + (START_CONFLICT - 1)); level = 1; while (entry >= START_CONFLICT) { index = Conflict_row [entry - (START_CONFLICT - 1)]; index += tokens.peek(level); entry = Conflict [index]; ++level; } } return(entry); }
parse(ref DslAction action, ref LuaToken tokens, ref LuaError error, short start_symbol) { short rhs, lhs; short production_number, entry, symbol, token, new_token; int production_length, top, index, level; short *stack = stackalloc short[65535]; top = 65534; stack[top] = 0; if (start_symbol == 0) { start_symbol = START_SYMBOL; } if (top > 0) { stack[--top] = start_symbol; } else { error.message("LuaParse: stack overflow\n", ref tokens); return; } token = tokens.get(); new_token = token; for (symbol = (stack[top] != 0 ? stack[top++] : (short)0); symbol != 0;) { if (symbol >= START_ACTION) { action.execute(symbol - (START_ACTION - 1)); } else if (symbol >= START_SYMBOL) { entry = 0; level = 1; production_number = get_conditional_production(symbol); if (production_number != 0) { entry = get_predicted_entry(tokens, production_number, token, level, 1); } if (entry == 0) { index = Parse_row[symbol - (START_SYMBOL - 1)]; index += token; entry = Parse[index]; } while (entry >= START_CONFLICT) { index = Conflict_row[entry - (START_CONFLICT - 1)]; index += tokens.peek(level); entry = Conflict[index]; ++level; } if (entry != 0) { index = Production_row[entry]; production_length = Production[index] - 1; lhs = Production[++index]; if (lhs == symbol) { action.predict(entry); index += production_length; for (; production_length-- > 0; --index) { if (top > 0) { stack[--top] = Production[index]; } else { error.message("LuaParse: stack overflow\n", ref tokens); return; } } } else { new_token = error.no_entry(symbol, token, level - 1, ref tokens); } } else // no table entry { new_token = error.no_entry(symbol, token, level - 1, ref tokens); } } else if (symbol > 0) { if (symbol == token) { token = tokens.get(); new_token = token; } else { new_token = error.mismatch(symbol, token, ref tokens); } } else { error.message("\n parser error: symbol value 0\n", ref tokens); } if (token != new_token) { if (new_token != 0) { token = new_token; } if (token != END_OF_SLK_INPUT_) { continue; } } symbol = (stack[top] != 0 ? stack[top++] : (short)0); } if (token != END_OF_SLK_INPUT_) { error.input_left(ref tokens); } }