lrama 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yaml +10 -1
  3. data/.gitignore +1 -0
  4. data/Gemfile +1 -0
  5. data/LEGAL.md +1 -16
  6. data/README.md +11 -1
  7. data/Steepfile +2 -1
  8. data/doc/TODO.md +8 -3
  9. data/exe/lrama +1 -1
  10. data/lib/lrama/command.rb +91 -72
  11. data/lib/lrama/context.rb +11 -1
  12. data/lib/lrama/counterexamples/derivation.rb +63 -0
  13. data/lib/lrama/counterexamples/example.rb +124 -0
  14. data/lib/lrama/counterexamples/path.rb +69 -0
  15. data/lib/lrama/counterexamples/state_item.rb +6 -0
  16. data/lib/lrama/counterexamples/triple.rb +21 -0
  17. data/lib/lrama/counterexamples.rb +285 -0
  18. data/lib/lrama/digraph.rb +2 -3
  19. data/lib/lrama/grammar/auxiliary.rb +7 -0
  20. data/lib/lrama/grammar/code.rb +123 -0
  21. data/lib/lrama/grammar/error_token.rb +9 -0
  22. data/lib/lrama/grammar/precedence.rb +11 -0
  23. data/lib/lrama/grammar/printer.rb +9 -0
  24. data/lib/lrama/grammar/reference.rb +22 -0
  25. data/lib/lrama/grammar/rule.rb +39 -0
  26. data/lib/lrama/grammar/symbol.rb +87 -0
  27. data/lib/lrama/grammar/union.rb +10 -0
  28. data/lib/lrama/grammar.rb +89 -282
  29. data/lib/lrama/lexer/token/type.rb +8 -0
  30. data/lib/lrama/lexer/token.rb +77 -0
  31. data/lib/lrama/lexer.rb +4 -74
  32. data/lib/lrama/output.rb +32 -4
  33. data/lib/lrama/parser/token_scanner.rb +3 -6
  34. data/lib/lrama/parser.rb +9 -1
  35. data/lib/lrama/report/duration.rb +25 -0
  36. data/lib/lrama/report/profile.rb +25 -0
  37. data/lib/lrama/report.rb +2 -47
  38. data/lib/lrama/state/reduce_reduce_conflict.rb +9 -0
  39. data/lib/lrama/state/resolved_conflict.rb +29 -0
  40. data/lib/lrama/state/shift_reduce_conflict.rb +9 -0
  41. data/lib/lrama/state.rb +13 -30
  42. data/lib/lrama/states/item.rb +79 -0
  43. data/lib/lrama/states.rb +24 -73
  44. data/lib/lrama/states_reporter.rb +28 -3
  45. data/lib/lrama/type.rb +4 -0
  46. data/lib/lrama/version.rb +1 -1
  47. data/lib/lrama.rb +2 -0
  48. data/lrama.gemspec +1 -1
  49. data/sig/lrama/{report.rbs → report/duration.rbs} +0 -4
  50. data/sig/lrama/report/profile.rbs +7 -0
  51. data/template/bison/yacc.c +371 -0
  52. metadata +30 -5
@@ -542,6 +542,13 @@ static const <%= output.int_type_for(output.context.yytranslate) %> yytranslate[
542
542
  <%= output.yytranslate %>
543
543
  };
544
544
 
545
+ <%- if output.error_recovery -%>
546
+ /* YYTRANSLATE_INVERTED[SYMBOL-NUM] -- Token number corresponding to SYMBOL-NUM */
547
+ static const <%= output.int_type_for(output.context.yytranslate_inverted) %> yytranslate_inverted[] =
548
+ {
549
+ <%= output.yytranslate_inverted %>
550
+ };
551
+ <%- end -%>
545
552
  #if YYDEBUG
546
553
  /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
547
554
  static const <%= output.int_type_for(output.context.yyrline) %> yyrline[] =
@@ -1211,6 +1218,307 @@ yydestruct (const char *yymsg,
1211
1218
 
1212
1219
 
1213
1220
 
1221
+ <%- if output.error_recovery -%>
1222
+ #ifndef YYMAXREPAIR
1223
+ # define YYMAXREPAIR(<%= output.parse_param_name %>) (3)
1224
+ #endif
1225
+
1226
+ #ifndef YYERROR_RECOVERY_ENABLED
1227
+ # define YYERROR_RECOVERY_ENABLED(<%= output.parse_param_name %>) (1)
1228
+ #endif
1229
+
1230
+ enum yy_repair_type {
1231
+ insert,
1232
+ delete,
1233
+ shift,
1234
+ };
1235
+
1236
+ struct yy_repair {
1237
+ enum yy_repair_type type;
1238
+ yysymbol_kind_t term;
1239
+ };
1240
+ typedef struct yy_repair yy_repair;
1241
+
1242
+ struct yy_repairs {
1243
+ /* For debug */
1244
+ int id;
1245
+ /* For breadth-first traversing */
1246
+ struct yy_repairs *next;
1247
+ YYPTRDIFF_T stack_length;
1248
+ /* Bottom of states */
1249
+ yy_state_t *states;
1250
+ /* Top of states */
1251
+ yy_state_t *state;
1252
+ /* repair length */
1253
+ int repair_length;
1254
+ /* */
1255
+ struct yy_repairs *prev_repair;
1256
+ struct yy_repair repair;
1257
+ };
1258
+ typedef struct yy_repairs yy_repairs;
1259
+
1260
+ struct yy_term {
1261
+ yysymbol_kind_t kind;
1262
+ YYSTYPE value;
1263
+ YYLTYPE location;
1264
+ };
1265
+ typedef struct yy_term yy_term;
1266
+
1267
+ struct yy_repair_terms {
1268
+ int id;
1269
+ int length;
1270
+ yy_term terms[];
1271
+ };
1272
+ typedef struct yy_repair_terms yy_repair_terms;
1273
+
1274
+ static void
1275
+ yy_error_token_initialize (yysymbol_kind_t yykind, YYSTYPE * const yyvaluep, YYLTYPE * const yylocationp<%= output.user_formals %>)
1276
+ {
1277
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1278
+ switch (yykind)
1279
+ {
1280
+ <%= output.symbol_actions_for_error_token -%>
1281
+ default:
1282
+ break;
1283
+ }
1284
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
1285
+ }
1286
+
1287
+ static yy_repair_terms *
1288
+ yy_create_repair_terms(yy_repairs *reps<%= output.user_formals %>)
1289
+ {
1290
+ yy_repairs *r = reps;
1291
+ yy_repair_terms *rep_terms;
1292
+ int count = 0;
1293
+
1294
+ while (r->prev_repair)
1295
+ {
1296
+ count++;
1297
+ r = r->prev_repair;
1298
+ }
1299
+
1300
+ rep_terms = (yy_repair_terms *) YYMALLOC (sizeof (yy_repair_terms) + sizeof (yy_term) * count);
1301
+ rep_terms->id = reps->id;
1302
+ rep_terms->length = count;
1303
+
1304
+ r = reps;
1305
+ while (r->prev_repair)
1306
+ {
1307
+ rep_terms->terms[count-1].kind = r->repair.term;
1308
+ count--;
1309
+ r = r->prev_repair;
1310
+ }
1311
+
1312
+ return rep_terms;
1313
+ }
1314
+
1315
+ static void
1316
+ yy_print_repairs(yy_repairs *reps<%= output.user_formals %>)
1317
+ {
1318
+ yy_repairs *r = reps;
1319
+
1320
+ YYDPRINTF ((stderr,
1321
+ "id: %d, repair_length: %d, repair_state: %d, prev_repair_id: %d\n",
1322
+ reps->id, reps->repair_length, *reps->state, reps->prev_repair->id));
1323
+
1324
+ while (r->prev_repair)
1325
+ {
1326
+ YYDPRINTF ((stderr, "%s ", yysymbol_name (r->repair.term)));
1327
+ r = r->prev_repair;
1328
+ }
1329
+
1330
+ YYDPRINTF ((stderr, "\n"));
1331
+ }
1332
+
1333
+ static void
1334
+ yy_print_repair_terms(yy_repair_terms *rep_terms<%= output.user_formals %>)
1335
+ {
1336
+ for (int i = 0; i < rep_terms->length; i++)
1337
+ YYDPRINTF ((stderr, "%s ", yysymbol_name (rep_terms->terms[i].kind)));
1338
+
1339
+ YYDPRINTF ((stderr, "\n"));
1340
+ }
1341
+
1342
+ static void
1343
+ yy_free_repairs(yy_repairs *reps<%= output.user_formals %>)
1344
+ {
1345
+ while (reps)
1346
+ {
1347
+ yy_repairs *r = reps;
1348
+ reps = reps->next;
1349
+ YYFREE (r->states);
1350
+ YYFREE (r);
1351
+ }
1352
+ }
1353
+
1354
+ static int
1355
+ yy_process_repairs(yy_repairs *reps, yysymbol_kind_t token)
1356
+ {
1357
+ int yyn;
1358
+ int yystate = *reps->state;
1359
+ int yylen = 0;
1360
+ yysymbol_kind_t yytoken = token;
1361
+
1362
+ goto yyrecover_backup;
1363
+
1364
+ yyrecover_newstate:
1365
+ // TODO: check reps->stack_length
1366
+ reps->state += 1;
1367
+ *reps->state = (yy_state_t) yystate;
1368
+
1369
+
1370
+ yyrecover_backup:
1371
+ yyn = yypact[yystate];
1372
+ if (yypact_value_is_default (yyn))
1373
+ goto yyrecover_default;
1374
+
1375
+ /* "Reading a token" */
1376
+ if (yytoken == YYSYMBOL_YYEMPTY)
1377
+ return 1;
1378
+
1379
+ yyn += yytoken;
1380
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1381
+ goto yyrecover_default;
1382
+ yyn = yytable[yyn];
1383
+ if (yyn <= 0)
1384
+ {
1385
+ if (yytable_value_is_error (yyn))
1386
+ goto yyrecover_errlab;
1387
+ yyn = -yyn;
1388
+ goto yyrecover_reduce;
1389
+ }
1390
+
1391
+ /* shift */
1392
+ yystate = yyn;
1393
+ yytoken = YYSYMBOL_YYEMPTY;
1394
+ goto yyrecover_newstate;
1395
+
1396
+
1397
+ yyrecover_default:
1398
+ yyn = yydefact[yystate];
1399
+ if (yyn == 0)
1400
+ goto yyrecover_errlab;
1401
+ goto yyrecover_reduce;
1402
+
1403
+
1404
+ yyrecover_reduce:
1405
+ yylen = yyr2[yyn];
1406
+ /* YYPOPSTACK */
1407
+ reps->state -= yylen;
1408
+ yylen = 0;
1409
+
1410
+ {
1411
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
1412
+ const int yyi = yypgoto[yylhs] + *reps->state;
1413
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *reps->state
1414
+ ? yytable[yyi]
1415
+ : yydefgoto[yylhs]);
1416
+ }
1417
+
1418
+ goto yyrecover_newstate;
1419
+
1420
+ yyrecover_errlab:
1421
+ return 0;
1422
+ }
1423
+
1424
+ static yy_repair_terms *
1425
+ yyrecover(yy_state_t *yyss, yy_state_t *yyssp, int yychar<%= output.user_formals %>)
1426
+ {
1427
+ yysymbol_kind_t yytoken = YYTRANSLATE (yychar);
1428
+ yy_repair_terms *rep_terms = YY_NULLPTR;
1429
+ int count = 0;
1430
+
1431
+ yy_repairs *head = (yy_repairs *) YYMALLOC (sizeof (yy_repairs));
1432
+ yy_repairs *current = head;
1433
+ yy_repairs *tail = head;
1434
+ YYPTRDIFF_T stack_length = yyssp - yyss + 1;
1435
+
1436
+ head->id = count;
1437
+ head->next = 0;
1438
+ head->stack_length = stack_length;
1439
+ head->states = (yy_state_t *) YYMALLOC (sizeof (yy_state_t) * (stack_length));
1440
+ head->state = head->states + (yyssp - yyss);
1441
+ YYCOPY (head->states, yyss, stack_length);
1442
+ head->repair_length = 0;
1443
+ head->prev_repair = 0;
1444
+
1445
+ stack_length = (stack_length * 2 > 100) ? (stack_length * 2) : 100;
1446
+ count++;
1447
+
1448
+ while (current)
1449
+ {
1450
+ int yystate = *current->state;
1451
+ int yyn = yypact[yystate];
1452
+ /* See also: yypcontext_expected_tokens */
1453
+ if (!yypact_value_is_default (yyn))
1454
+ {
1455
+ int yyxbegin = yyn < 0 ? -yyn : 0;
1456
+ int yychecklim = YYLAST - yyn + 1;
1457
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1458
+ int yyx;
1459
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1460
+ {
1461
+ if (yyx != YYSYMBOL_YYerror)
1462
+ {
1463
+ if (current->repair_length + 1 > YYMAXREPAIR(<%= output.parse_param_name %>))
1464
+ continue;
1465
+
1466
+ yy_repairs *new = (yy_repairs *) YYMALLOC (sizeof (yy_repairs));
1467
+ new->id = count;
1468
+ new->next = 0;
1469
+ new->stack_length = stack_length;
1470
+ new->states = (yy_state_t *) YYMALLOC (sizeof (yy_state_t) * (stack_length));
1471
+ new->state = new->states + (current->state - current->states);
1472
+ YYCOPY (new->states, current->states, current->state - current->states + 1);
1473
+ new->repair_length = current->repair_length + 1;
1474
+ new->prev_repair = current;
1475
+ new->repair.type = insert;
1476
+ new->repair.term = (yysymbol_kind_t) yyx;
1477
+
1478
+ /* Process PDA assuming next token is yyx */
1479
+ if (! yy_process_repairs (new, yyx))
1480
+ {
1481
+ YYFREE (new);
1482
+ continue;
1483
+ }
1484
+
1485
+ tail->next = new;
1486
+ tail = new;
1487
+ count++;
1488
+
1489
+ if (yyx == yytoken)
1490
+ {
1491
+ rep_terms = yy_create_repair_terms (current<%= output.user_args %>);
1492
+ YYDPRINTF ((stderr, "repair_terms found. id: %d, length: %d\n", rep_terms->id, rep_terms->length));
1493
+ yy_print_repairs (current<%= output.user_args %>);
1494
+ yy_print_repair_terms (rep_terms<%= output.user_args %>);
1495
+
1496
+ goto done;
1497
+ }
1498
+
1499
+ YYDPRINTF ((stderr,
1500
+ "New repairs is enqueued. count: %d, yystate: %d, yyx: %d\n",
1501
+ count, yystate, yyx));
1502
+ yy_print_repairs (new<%= output.user_args %>);
1503
+ }
1504
+ }
1505
+ }
1506
+
1507
+ current = current->next;
1508
+ }
1509
+
1510
+ done:
1511
+
1512
+ yy_free_repairs(head<%= output.user_args %>);
1513
+
1514
+ if (!rep_terms)
1515
+ {
1516
+ YYDPRINTF ((stderr, "repair_terms not found\n"));
1517
+ }
1518
+
1519
+ return rep_terms;
1520
+ }
1521
+ <%- end -%>
1214
1522
 
1215
1523
 
1216
1524
 
@@ -1281,6 +1589,12 @@ YYLTYPE yylloc = yyloc_default;
1281
1589
 
1282
1590
  /* The locations where the error started and ended. */
1283
1591
  YYLTYPE yyerror_range[3];
1592
+ <%- if output.error_recovery -%>
1593
+ yy_repair_terms *rep_terms = 0;
1594
+ yy_term term_backup;
1595
+ int rep_terms_index;
1596
+ int yychar_backup;
1597
+ <%- end -%>
1284
1598
 
1285
1599
  /* Buffer for error messages, and its allocated size. */
1286
1600
  char yymsgbuf[128];
@@ -1415,6 +1729,39 @@ yybackup:
1415
1729
 
1416
1730
  /* Not known => get a lookahead token if don't already have one. */
1417
1731
 
1732
+ <%- if output.error_recovery -%>
1733
+ if (YYERROR_RECOVERY_ENABLED(<%= output.parse_param_name %>))
1734
+ {
1735
+ if (yychar == YYEMPTY && rep_terms)
1736
+ {
1737
+
1738
+ if (rep_terms_index < rep_terms->length)
1739
+ {
1740
+ YYDPRINTF ((stderr, "An error recovery token is used\n"));
1741
+ yy_term term = rep_terms->terms[rep_terms_index];
1742
+ yytoken = term.kind;
1743
+ yylval = term.value;
1744
+ yylloc = term.location;
1745
+ yychar = yytranslate_inverted[yytoken];
1746
+ YY_SYMBOL_PRINT ("Next error recovery token is", yytoken, &yylval, &yylloc<%= output.user_args %>);
1747
+ rep_terms_index++;
1748
+ }
1749
+ else
1750
+ {
1751
+ YYDPRINTF ((stderr, "Error recovery is completed\n"));
1752
+ yytoken = term_backup.kind;
1753
+ yylval = term_backup.value;
1754
+ yylloc = term_backup.location;
1755
+ yychar = yychar_backup;
1756
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc<%= output.user_args %>);
1757
+
1758
+ YYFREE (rep_terms);
1759
+ rep_terms = 0;
1760
+ yychar_backup = 0;
1761
+ }
1762
+ }
1763
+ }
1764
+ <%- end -%>
1418
1765
  /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
1419
1766
  if (yychar == YYEMPTY)
1420
1767
  {
@@ -1639,6 +1986,30 @@ yyerrorlab:
1639
1986
  | yyerrlab1 -- common code for both syntax error and YYERROR. |
1640
1987
  `-------------------------------------------------------------*/
1641
1988
  yyerrlab1:
1989
+ <%- if output.error_recovery -%>
1990
+ if (YYERROR_RECOVERY_ENABLED(<%= output.parse_param_name %>))
1991
+ {
1992
+ rep_terms = yyrecover (yyss, yyssp, yychar<%= output.user_args %>);
1993
+ if (rep_terms)
1994
+ {
1995
+ for (int i = 0; i < rep_terms->length; i++)
1996
+ {
1997
+ yy_term *term = &rep_terms->terms[i];
1998
+ yy_error_token_initialize (term->kind, &term->value, &term->location<%= output.user_args %>);
1999
+ }
2000
+
2001
+ yychar_backup = yychar;
2002
+ /* Can be packed into (the tail of) rep_terms? */
2003
+ term_backup.kind = yytoken;
2004
+ term_backup.value = yylval;
2005
+ term_backup.location = yylloc;
2006
+ rep_terms_index = 0;
2007
+ yychar = YYEMPTY;
2008
+
2009
+ goto yybackup;
2010
+ }
2011
+ }
2012
+ <%- end -%>
1642
2013
  yyerrstatus = 3; /* Each real token shifted decrements this. */
1643
2014
 
1644
2015
  /* Pop stack until we find a state that shifts the error token. */
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lrama
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuichiro Kaneko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-13 00:00:00.000000000 Z
11
+ date: 2023-08-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: LALR (1) parser generator written by Ruby
14
14
  email:
@@ -34,18 +34,42 @@ files:
34
34
  - lib/lrama/bitmap.rb
35
35
  - lib/lrama/command.rb
36
36
  - lib/lrama/context.rb
37
+ - lib/lrama/counterexamples.rb
38
+ - lib/lrama/counterexamples/derivation.rb
39
+ - lib/lrama/counterexamples/example.rb
40
+ - lib/lrama/counterexamples/path.rb
41
+ - lib/lrama/counterexamples/state_item.rb
42
+ - lib/lrama/counterexamples/triple.rb
37
43
  - lib/lrama/digraph.rb
38
44
  - lib/lrama/grammar.rb
45
+ - lib/lrama/grammar/auxiliary.rb
46
+ - lib/lrama/grammar/code.rb
47
+ - lib/lrama/grammar/error_token.rb
48
+ - lib/lrama/grammar/precedence.rb
49
+ - lib/lrama/grammar/printer.rb
50
+ - lib/lrama/grammar/reference.rb
51
+ - lib/lrama/grammar/rule.rb
52
+ - lib/lrama/grammar/symbol.rb
53
+ - lib/lrama/grammar/union.rb
39
54
  - lib/lrama/lexer.rb
55
+ - lib/lrama/lexer/token.rb
56
+ - lib/lrama/lexer/token/type.rb
40
57
  - lib/lrama/output.rb
41
58
  - lib/lrama/parser.rb
42
59
  - lib/lrama/parser/token_scanner.rb
43
60
  - lib/lrama/report.rb
61
+ - lib/lrama/report/duration.rb
62
+ - lib/lrama/report/profile.rb
44
63
  - lib/lrama/state.rb
45
64
  - lib/lrama/state/reduce.rb
65
+ - lib/lrama/state/reduce_reduce_conflict.rb
66
+ - lib/lrama/state/resolved_conflict.rb
46
67
  - lib/lrama/state/shift.rb
68
+ - lib/lrama/state/shift_reduce_conflict.rb
47
69
  - lib/lrama/states.rb
70
+ - lib/lrama/states/item.rb
48
71
  - lib/lrama/states_reporter.rb
72
+ - lib/lrama/type.rb
49
73
  - lib/lrama/version.rb
50
74
  - lib/lrama/warning.rb
51
75
  - lrama.gemspec
@@ -55,13 +79,14 @@ files:
55
79
  - sample/calc.y
56
80
  - sample/parse.y
57
81
  - sig/lrama/bitmap.rbs
58
- - sig/lrama/report.rbs
82
+ - sig/lrama/report/duration.rbs
83
+ - sig/lrama/report/profile.rbs
59
84
  - sig/lrama/warning.rbs
60
85
  - template/bison/yacc.c
61
86
  - template/bison/yacc.h
62
87
  homepage: https://github.com/ruby/lrama
63
88
  licenses:
64
- - GNU GPLv3
89
+ - GPL-3.0-or-later
65
90
  metadata: {}
66
91
  post_install_message:
67
92
  rdoc_options: []
@@ -78,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
103
  - !ruby/object:Gem::Version
79
104
  version: '0'
80
105
  requirements: []
81
- rubygems_version: 3.5.0.dev
106
+ rubygems_version: 3.4.1
82
107
  signing_key:
83
108
  specification_version: 4
84
109
  summary: LALR (1) parser generator written by Ruby