Resync Lrama v0.5.3

Previous sync included unrelated files and missed template file update.
This commit is contained in:
yui-knk 2023-08-09 11:55:19 +09:00 committed by Yuichiro Kaneko
parent fe240b672b
commit 0982c5fa00
Notes: git 2023-08-16 10:03:05 +00:00
5 changed files with 363 additions and 59 deletions

View File

@ -1,14 +0,0 @@
#!/usr/bin/env ruby
$LOAD_PATH << File.join(__dir__, "../lib")
require "lrama"
grammar_file = ARGV.shift
y = File.read(grammar_file)
warning = Lrama::Warning.new
grammar = Lrama::Parser.new(y).parse
states = Lrama::States.new(grammar, warning)
states.compute
Lrama::LexState.new(states).compute

View File

@ -1,8 +0,0 @@
require "lrama/irb/load_grammar"
# You need to explicitly require this file to add irb commands
# See: "lib/irb/extend-command.rb" in ruby/irb
module Lrama
module IRB
end
end

View File

@ -1,9 +0,0 @@
require 'irb/cmd/nop'
module Lrama
module IRB
class LoadGrammar < IRB::ExtendCommand::Nop
end
end
end

View File

@ -1,28 +0,0 @@
require 'json'
module Lrama
class JsonReporter
include Lrama::Report::Duration
def initialize(states)
@states = states
end
def report(io, **options)
report_duration(:report) do
_report(io, **options)
end
end
private
def _report(io, grammar: false, states: false, itemsets: false, lookaheads: false, solved: false, verbose: false)
# TODO: Unused terms
# TODO: Unused rules
report_conflicts(io)
report_grammar(io) if grammar
report_states(io, itemsets, lookaheads, solved, verbose)
end
end
end

View File

@ -542,6 +542,13 @@ static const <%= output.int_type_for(output.context.yytranslate) %> yytranslate[
<%= output.yytranslate %>
};
<%- if output.error_recovery -%>
/* YYTRANSLATE_INVERTED[SYMBOL-NUM] -- Token number corresponding to SYMBOL-NUM */
static const <%= output.int_type_for(output.context.yytranslate_inverted) %> yytranslate_inverted[] =
{
<%= output.yytranslate_inverted %>
};
<%- end -%>
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const <%= output.int_type_for(output.context.yyrline) %> yyrline[] =
@ -1211,6 +1218,303 @@ yydestruct (const char *yymsg,
<%- if output.error_recovery -%>
#ifndef YYMAXREPAIR
# define YYMAXREPAIR 3
#endif
enum repair_type {
insert,
delete,
shift,
};
struct repair {
enum repair_type type;
yysymbol_kind_t term;
};
typedef struct repair repair;
struct repairs {
/* For debug */
int id;
/* For breadth-first traversing */
struct repairs *next;
YYPTRDIFF_T stack_length;
/* Bottom of states */
yy_state_t *states;
/* Top of states */
yy_state_t *state;
/* repair length */
int repair_length;
/* */
struct repairs *prev_repair;
struct repair repair;
};
typedef struct repairs repairs;
struct yy_term {
yysymbol_kind_t kind;
YYSTYPE value;
YYLTYPE location;
};
typedef struct yy_term yy_term;
struct repair_terms {
int id;
int length;
yy_term terms[];
};
typedef struct repair_terms repair_terms;
static void
yy_error_token_initialize (yysymbol_kind_t yykind, YYSTYPE * const yyvaluep, YYLTYPE * const yylocationp<%= output.user_formals %>)
{
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
switch (yykind)
{
<%= output.symbol_actions_for_error_token -%>
default:
break;
}
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
static repair_terms *
yy_create_repair_terms(repairs *reps)
{
repairs *r = reps;
repair_terms *rep_terms;
int count = 0;
while (r->prev_repair)
{
count++;
r = r->prev_repair;
}
rep_terms = (repair_terms *) malloc (sizeof (repair_terms) + sizeof (yy_term) * count);
rep_terms->id = reps->id;
rep_terms->length = count;
r = reps;
while (r->prev_repair)
{
rep_terms->terms[count-1].kind = r->repair.term;
count--;
r = r->prev_repair;
}
return rep_terms;
}
static void
yy_print_repairs(repairs *reps)
{
repairs *r = reps;
fprintf (stderr,
"id: %d, repair_length: %d, repair_state: %d, prev_repair_id: %d\n",
reps->id, reps->repair_length, *reps->state, reps->prev_repair->id);
while (r->prev_repair)
{
fprintf (stderr, "%s ", yysymbol_name (r->repair.term));
r = r->prev_repair;
}
fprintf (stderr, "\n");
}
static void
yy_print_repair_terms(repair_terms *rep_terms)
{
for (int i = 0; i < rep_terms->length; i++)
fprintf (stderr, "%s ", yysymbol_name (rep_terms->terms[i].kind));
fprintf (stderr, "\n");
}
static void
yy_free_repairs(repairs *reps)
{
while (reps)
{
repairs *r = reps;
reps = reps->next;
free (r->states);
free (r);
}
}
static int
yy_process_repairs(repairs *reps, yysymbol_kind_t token)
{
int yyn;
int yystate = *reps->state;
int yylen = 0;
yysymbol_kind_t yytoken = token;
goto yyrecover_backup;
yyrecover_newstate:
// TODO: check reps->stack_length
reps->state += 1;
*reps->state = (yy_state_t) yystate;
yyrecover_backup:
yyn = yypact[yystate];
if (yypact_value_is_default (yyn))
goto yyrecover_default;
/* "Reading a token" */
if (yytoken == YYSYMBOL_YYEMPTY)
return 1;
yyn += yytoken;
if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
goto yyrecover_default;
yyn = yytable[yyn];
if (yyn <= 0)
{
if (yytable_value_is_error (yyn))
goto yyrecover_errlab;
yyn = -yyn;
goto yyrecover_reduce;
}
/* shift */
yystate = yyn;
yytoken = YYSYMBOL_YYEMPTY;
goto yyrecover_newstate;
yyrecover_default:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyrecover_errlab;
goto yyrecover_reduce;
yyrecover_reduce:
yylen = yyr2[yyn];
/* YYPOPSTACK */
reps->state -= yylen;
yylen = 0;
{
const int yylhs = yyr1[yyn] - YYNTOKENS;
const int yyi = yypgoto[yylhs] + *reps->state;
yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *reps->state
? yytable[yyi]
: yydefgoto[yylhs]);
}
goto yyrecover_newstate;
yyrecover_errlab:
return 0;
}
static repair_terms *
yyrecover(yy_state_t *yyss, yy_state_t *yyssp, int yychar)
{
yysymbol_kind_t yytoken = YYTRANSLATE (yychar);
repair_terms *rep_terms = YY_NULLPTR;
int count = 0;
repairs *head = (repairs *) malloc (sizeof (repairs));
repairs *current = head;
repairs *tail = head;
YYPTRDIFF_T stack_length = yyssp - yyss + 1;
head->id = count;
head->next = 0;
head->stack_length = stack_length;
head->states = (yy_state_t *) malloc (sizeof (yy_state_t) * (stack_length));
head->state = head->states + (yyssp - yyss);
YYCOPY (head->states, yyss, stack_length);
head->repair_length = 0;
head->prev_repair = 0;
stack_length = (stack_length * 2 > 100) ? (stack_length * 2) : 100;
count++;
while (current)
{
int yystate = *current->state;
int yyn = yypact[yystate];
/* See also: yypcontext_expected_tokens */
if (!yypact_value_is_default (yyn))
{
int yyxbegin = yyn < 0 ? -yyn : 0;
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
{
if (yyx != YYSYMBOL_YYerror)
{
if (current->repair_length + 1 > YYMAXREPAIR)
continue;
repairs *new = (repairs *) malloc (sizeof (repairs));
new->id = count;
new->next = 0;
new->stack_length = stack_length;
new->states = (yy_state_t *) malloc (sizeof (yy_state_t) * (stack_length));
new->state = new->states + (current->state - current->states);
YYCOPY (new->states, current->states, current->state - current->states + 1);
new->repair_length = current->repair_length + 1;
new->prev_repair = current;
new->repair.type = insert;
new->repair.term = (yysymbol_kind_t) yyx;
/* Process PDA assuming next token is yyx */
if (! yy_process_repairs (new, yyx))
{
free (new);
continue;
}
tail->next = new;
tail = new;
count++;
if (yyx == yytoken)
{
rep_terms = yy_create_repair_terms (current);
fprintf (stderr, "repair_terms found. id: %d, length: %d\n", rep_terms->id, rep_terms->length);
yy_print_repairs (current);
yy_print_repair_terms (rep_terms);
goto done;
}
fprintf (stderr,
"New repairs is enqueued. count: %d, yystate: %d, yyx: %d\n",
count, yystate, yyx);
yy_print_repairs (new);
}
}
}
current = current->next;
}
done:
yy_free_repairs(head);
if (!rep_terms)
{
fprintf (stderr, "repair_terms not found\n");
}
return rep_terms;
}
<%- end -%>
@ -1281,6 +1585,12 @@ YYLTYPE yylloc = yyloc_default;
/* The locations where the error started and ended. */
YYLTYPE yyerror_range[3];
<%- if output.error_recovery -%>
repair_terms *rep_terms = 0;
yy_term term_backup;
int rep_terms_index;
int yychar_backup;
<%- end -%>
/* Buffer for error messages, and its allocated size. */
char yymsgbuf[128];
@ -1415,6 +1725,36 @@ yybackup:
/* Not known => get a lookahead token if don't already have one. */
<%- if output.error_recovery -%>
if (yychar == YYEMPTY && rep_terms)
{
if (rep_terms_index < rep_terms->length)
{
YYDPRINTF ((stderr, "An error recovery token is used\n"));
yy_term term = rep_terms->terms[rep_terms_index];
yytoken = term.kind;
yylval = term.value;
yylloc = term.location;
yychar = yytranslate_inverted[yytoken];
YY_SYMBOL_PRINT ("Next error recovery token is", yytoken, &yylval, &yylloc<%= output.user_args %>);
rep_terms_index++;
}
else
{
YYDPRINTF ((stderr, "Error recovery is completed\n"));
yytoken = term_backup.kind;
yylval = term_backup.value;
yylloc = term_backup.location;
yychar = yychar_backup;
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc<%= output.user_args %>);
free (rep_terms);
rep_terms = 0;
yychar_backup = 0;
}
}
<%- end -%>
/* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
if (yychar == YYEMPTY)
{
@ -1639,6 +1979,29 @@ yyerrorlab:
| yyerrlab1 -- common code for both syntax error and YYERROR. |
`-------------------------------------------------------------*/
yyerrlab1:
<%- if output.error_recovery -%>
{
rep_terms = yyrecover (yyss, yyssp, yychar);
if (rep_terms)
{
for (int i = 0; i < rep_terms->length; i++)
{
yy_term *term = &rep_terms->terms[i];
yy_error_token_initialize (term->kind, &term->value, &term->location<%= output.user_args %>);
}
yychar_backup = yychar;
/* Can be packed into (the tail of) rep_terms? */
term_backup.kind = yytoken;
term_backup.value = yylval;
term_backup.location = yylloc;
rep_terms_index = 0;
yychar = YYEMPTY;
goto yybackup;
}
}
<%- end -%>
yyerrstatus = 3; /* Each real token shifted decrements this. */
/* Pop stack until we find a state that shifts the error token. */