lrama 0.5.2 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
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