lrama 0.6.2 → 0.6.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.
- checksums.yaml +4 -4
- data/.github/workflows/test.yaml +2 -3
- data/Gemfile +1 -1
- data/NEWS.md +101 -1
- data/README.md +23 -0
- data/Steepfile +5 -0
- data/lib/lrama/context.rb +4 -4
- data/lib/lrama/grammar/code/destructor_code.rb +40 -0
- data/lib/lrama/grammar/code/initial_action_code.rb +6 -0
- data/lib/lrama/grammar/code/no_reference_code.rb +4 -0
- data/lib/lrama/grammar/code/printer_code.rb +6 -0
- data/lib/lrama/grammar/code/rule_action.rb +11 -1
- data/lib/lrama/grammar/code.rb +1 -0
- data/lib/lrama/grammar/destructor.rb +9 -0
- data/lib/lrama/grammar/reference.rb +4 -3
- data/lib/lrama/grammar/rule_builder.rb +10 -3
- data/lib/lrama/grammar/stdlib.y +42 -0
- data/lib/lrama/grammar/symbol.rb +4 -2
- data/lib/lrama/grammar/symbols/resolver.rb +293 -0
- data/lib/lrama/grammar/symbols.rb +1 -0
- data/lib/lrama/grammar.rb +32 -244
- data/lib/lrama/lexer/token/user_code.rb +13 -2
- data/lib/lrama/lexer/token.rb +1 -1
- data/lib/lrama/lexer.rb +7 -0
- data/lib/lrama/option_parser.rb +25 -12
- data/lib/lrama/options.rb +1 -0
- data/lib/lrama/output.rb +75 -2
- data/lib/lrama/parser.rb +537 -464
- data/lib/lrama/state.rb +4 -4
- data/lib/lrama/states/item.rb +6 -8
- data/lib/lrama/states_reporter.rb +2 -2
- data/lib/lrama/version.rb +1 -1
- data/lrama.gemspec +7 -0
- data/parser.y +27 -0
- data/sig/lrama/grammar/binding.rbs +0 -1
- data/sig/lrama/grammar/code/destructor_code.rbs +15 -0
- data/sig/lrama/grammar/destructor.rbs +11 -0
- data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +0 -1
- data/sig/lrama/grammar/reference.rbs +2 -2
- data/sig/lrama/grammar/symbol.rbs +5 -4
- data/sig/lrama/grammar/symbols/resolver.rbs +41 -0
- data/sig/lrama/grammar/type.rbs +11 -0
- data/sig/lrama/options.rbs +17 -0
- data/template/bison/yacc.c +12 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce98751a4b4d20c20addf8eebf2a4eb22150b401abbb994941d73f2b2ef81a09
|
4
|
+
data.tar.gz: 94b83050b10ec5d01d61093cd2af595e52b3761cc8e86423fa8f30110e44e330
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9e194703ec0b1657389f289b7c4d9cfd13326b1efe25e656080e5260ef2b7f3d4e93fd3d5d49e0934cfb394bc46b994c167a74c3dd2fb2ed3f3ebaaaf31647d
|
7
|
+
data.tar.gz: 59e1ed986bbea4ea4a56295d799f6ef5afee24e128fec66bc7ea8184f9bd849aa0807b5995b201e3dda274f6f0f023899a8c287e9a25818dae75c05e5c45cf6a
|
data/.github/workflows/test.yaml
CHANGED
@@ -124,9 +124,8 @@ jobs:
|
|
124
124
|
strategy:
|
125
125
|
fail-fast: false
|
126
126
|
matrix:
|
127
|
-
# '3.0' is the oldest living ruby version
|
128
|
-
|
129
|
-
baseruby: ['head', '3.0', '2.7']
|
127
|
+
# '3.0' is the oldest living ruby version and minimal BASERUBY version
|
128
|
+
baseruby: ['head', '3.0']
|
130
129
|
ruby_branch: ['master']
|
131
130
|
defaults:
|
132
131
|
run:
|
data/Gemfile
CHANGED
@@ -12,6 +12,6 @@ gem "stackprof", platforms: [:ruby] # stackprof doesn't support Windows
|
|
12
12
|
# Recent steep requires Ruby >= 3.0.0.
|
13
13
|
# Then skip install on some CI jobs.
|
14
14
|
if !ENV['GITHUB_ACTION'] || ENV['INSTALL_STEEP'] == 'true'
|
15
|
-
gem "rbs", "3.4.
|
15
|
+
gem "rbs", "3.4.4", require: false
|
16
16
|
gem "steep", "1.6.0", require: false
|
17
17
|
end
|
data/NEWS.md
CHANGED
@@ -1,5 +1,105 @@
|
|
1
1
|
# NEWS for Lrama
|
2
2
|
|
3
|
+
## Lrama 0.6.4 (2024-03-22)
|
4
|
+
|
5
|
+
### Parameterizing rules (preceded, terminated, delimited)
|
6
|
+
|
7
|
+
Support `preceded`, `terminated` and `delimited` rules.
|
8
|
+
|
9
|
+
```
|
10
|
+
program: preceded(opening, X)
|
11
|
+
|
12
|
+
// Expanded to
|
13
|
+
|
14
|
+
program: preceded_opening_X
|
15
|
+
preceded_opening_X: opening X
|
16
|
+
```
|
17
|
+
|
18
|
+
```
|
19
|
+
program: terminated(X, closing)
|
20
|
+
|
21
|
+
// Expanded to
|
22
|
+
|
23
|
+
program: terminated_X_closing
|
24
|
+
terminated_X_closing: X closing
|
25
|
+
```
|
26
|
+
|
27
|
+
```
|
28
|
+
program: delimited(opening, X, closing)
|
29
|
+
|
30
|
+
// Expanded to
|
31
|
+
|
32
|
+
program: delimited_opening_X_closing
|
33
|
+
delimited_opening_X_closing: opening X closing
|
34
|
+
```
|
35
|
+
|
36
|
+
https://github.com/ruby/lrama/pull/382
|
37
|
+
|
38
|
+
### Support `%destructor` declaration
|
39
|
+
|
40
|
+
User can set codes for freeing semantic value resources by using `%destructor`.
|
41
|
+
In general, these resources are freed by actions or after parsing.
|
42
|
+
However if syntax error happens in parsing, these codes may not be executed.
|
43
|
+
Codes associated to `%destructor` are executed when semantic value is popped from the stack by an error.
|
44
|
+
|
45
|
+
```
|
46
|
+
%token <val1> NUM
|
47
|
+
%type <val2> expr2
|
48
|
+
%type <val3> expr
|
49
|
+
|
50
|
+
%destructor {
|
51
|
+
printf("destructor for val1: %d\n", $$);
|
52
|
+
} <val1> // printer for TAG
|
53
|
+
|
54
|
+
%destructor {
|
55
|
+
printf("destructor for val2: %d\n", $$);
|
56
|
+
} <val2>
|
57
|
+
|
58
|
+
%destructor {
|
59
|
+
printf("destructor for expr: %d\n", $$);
|
60
|
+
} expr // printer for symbol
|
61
|
+
```
|
62
|
+
|
63
|
+
Bison supports this feature from 1.75b.
|
64
|
+
|
65
|
+
https://github.com/ruby/lrama/pull/385
|
66
|
+
|
67
|
+
## Lrama 0.6.3 (2024-02-15)
|
68
|
+
|
69
|
+
### Bring Your Own Stack
|
70
|
+
|
71
|
+
Provide functionalities for Bring Your Own Stack.
|
72
|
+
|
73
|
+
Ruby’s Ripper library requires their own semantic value stack to manage Ruby Objects returned by user defined callback method. Currently Ripper uses semantic value stack (`yyvsa`) which is used by parser to manage Node. This hack introduces some limitation on Ripper. For example, Ripper can not execute semantic analysis depending on Node structure.
|
74
|
+
|
75
|
+
Lrama introduces two features to support another semantic value stack by parser generator users.
|
76
|
+
|
77
|
+
1. Callback entry points
|
78
|
+
|
79
|
+
User can emulate semantic value stack by these callbacks.
|
80
|
+
Lrama provides these five callbacks. Registered functions are called when each event happen. For example %after-shift function is called when shift happens on original semantic value stack.
|
81
|
+
|
82
|
+
* `%after-shift` function_name
|
83
|
+
* `%before-reduce` function_name
|
84
|
+
* `%after-reduce` function_name
|
85
|
+
* `%after-shift-error-token` function_name
|
86
|
+
* `%after-pop-stack` function_name
|
87
|
+
|
88
|
+
2. `$:n` variable to access index of each grammar symbols
|
89
|
+
|
90
|
+
User also needs to access semantic value of their stack in grammar action. `$:n` provides the way to access to it. `$:n` is translated to the minus index from the top of the stack.
|
91
|
+
For example
|
92
|
+
|
93
|
+
```
|
94
|
+
primary: k_if expr_value then compstmt if_tail k_end
|
95
|
+
{
|
96
|
+
/*% ripper: if!($:2, $:4, $:5) %*/
|
97
|
+
/* $:2 = -5, $:4 = -3, $:5 = -2. */
|
98
|
+
}
|
99
|
+
```
|
100
|
+
|
101
|
+
https://github.com/ruby/lrama/pull/367
|
102
|
+
|
3
103
|
## Lrama 0.6.2 (2024-01-27)
|
4
104
|
|
5
105
|
### %no-stdlib directive
|
@@ -17,7 +117,7 @@ Allow to pass an instantiated rule to other parameterizing rules.
|
|
17
117
|
|
18
118
|
```
|
19
119
|
%rule constant(X) : X
|
20
|
-
|
120
|
+
;
|
21
121
|
|
22
122
|
%rule option(Y) : /* empty */
|
23
123
|
| Y
|
data/README.md
CHANGED
@@ -1,7 +1,23 @@
|
|
1
1
|
# Lrama
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/lrama)
|
4
|
+
[](https://github.com/ruby/lrama/actions/workflows/test.yaml)
|
5
|
+
|
3
6
|
Lrama is LALR (1) parser generator written by Ruby. The first goal of this project is providing error tolerant parser for CRuby with minimal changes on CRuby parse.y file.
|
4
7
|
|
8
|
+
* [Features](#features)
|
9
|
+
* [Installation](#installation)
|
10
|
+
* [Usage](#usage)
|
11
|
+
* [Versions and Branches](#versions-and-branches)
|
12
|
+
* [Supported Ruby version](#supported-ruby-version)
|
13
|
+
* [Development](#development)
|
14
|
+
* [How to generate parser.rb](#how-to-generate-parserrb)
|
15
|
+
* [Test](#test)
|
16
|
+
* [Profiling Lrama](#profiling-lrama)
|
17
|
+
* [Build Ruby](#build-ruby)
|
18
|
+
* [Release flow](#release-flow)
|
19
|
+
* [License](#license)
|
20
|
+
|
5
21
|
## Features
|
6
22
|
|
7
23
|
* Bison style grammar file is supported with some assumptions
|
@@ -11,6 +27,9 @@ Lrama is LALR (1) parser generator written by Ruby. The first goal of this proje
|
|
11
27
|
* b4_lac_if is always false
|
12
28
|
* Error Tolerance parser
|
13
29
|
* Subset of [Repairing Syntax Errors in LR Parsers (Corchuelo et al.)](https://idus.us.es/bitstream/handle/11441/65631/Repairing%20syntax%20errors.pdf) algorithm is supported
|
30
|
+
* Parameterizing rules
|
31
|
+
* The definition of a non-terminal symbol can be parameterized with other (terminal or non-terminal) symbols.
|
32
|
+
* Providing a generic definition of parameterizing rules as a [standard library](lib/lrama/grammar/stdlib.y).
|
14
33
|
|
15
34
|
## Installation
|
16
35
|
|
@@ -85,6 +104,8 @@ Running tests:
|
|
85
104
|
```shell
|
86
105
|
$ bundle install
|
87
106
|
$ bundle exec rspec
|
107
|
+
# or
|
108
|
+
$ bundle exec rake spec
|
88
109
|
```
|
89
110
|
|
90
111
|
Running type check:
|
@@ -93,6 +114,8 @@ Running type check:
|
|
93
114
|
$ bundle install
|
94
115
|
$ bundle exec rbs collection install
|
95
116
|
$ bundle exec steep check
|
117
|
+
# or
|
118
|
+
$ bundle exec rake steep
|
96
119
|
```
|
97
120
|
|
98
121
|
Running both of them:
|
data/Steepfile
CHANGED
@@ -5,21 +5,26 @@ target :lib do
|
|
5
5
|
signature "sig"
|
6
6
|
|
7
7
|
check "lib/lrama/grammar/binding.rb"
|
8
|
+
check "lib/lrama/grammar/code/destructor_code.rb"
|
8
9
|
check "lib/lrama/grammar/code/printer_code.rb"
|
9
10
|
check "lib/lrama/grammar/code.rb"
|
10
11
|
check "lib/lrama/grammar/counter.rb"
|
11
12
|
check "lib/lrama/grammar/error_token.rb"
|
12
13
|
check "lib/lrama/grammar/parameterizing_rule"
|
13
14
|
check "lib/lrama/grammar/parameterizing_rules"
|
15
|
+
check "lib/lrama/grammar/symbols"
|
14
16
|
check "lib/lrama/grammar/percent_code.rb"
|
15
17
|
check "lib/lrama/grammar/precedence.rb"
|
18
|
+
check "lib/lrama/grammar/destructor.rb"
|
16
19
|
check "lib/lrama/grammar/printer.rb"
|
17
20
|
check "lib/lrama/grammar/reference.rb"
|
18
21
|
check "lib/lrama/grammar/rule_builder.rb"
|
19
22
|
check "lib/lrama/grammar/symbol.rb"
|
23
|
+
check "lib/lrama/grammar/type.rb"
|
20
24
|
check "lib/lrama/lexer"
|
21
25
|
check "lib/lrama/report"
|
22
26
|
check "lib/lrama/bitmap.rb"
|
23
27
|
check "lib/lrama/digraph.rb"
|
28
|
+
check "lib/lrama/options.rb"
|
24
29
|
check "lib/lrama/warning.rb"
|
25
30
|
end
|
data/lib/lrama/context.rb
CHANGED
@@ -265,9 +265,9 @@ module Lrama
|
|
265
265
|
|
266
266
|
s = actions.each_with_index.map do |n, i|
|
267
267
|
[i, n]
|
268
|
-
end.
|
268
|
+
end.reject do |i, n|
|
269
269
|
# Remove default_reduction_rule entries
|
270
|
-
n
|
270
|
+
n == 0
|
271
271
|
end
|
272
272
|
|
273
273
|
if s.count != 0
|
@@ -462,7 +462,7 @@ module Lrama
|
|
462
462
|
@yylast = high
|
463
463
|
|
464
464
|
# replace_ninf
|
465
|
-
@yypact_ninf = (@base.
|
465
|
+
@yypact_ninf = (@base.reject {|i| i == BaseMin } + [0]).min - 1
|
466
466
|
@base.map! do |i|
|
467
467
|
case i
|
468
468
|
when BaseMin
|
@@ -472,7 +472,7 @@ module Lrama
|
|
472
472
|
end
|
473
473
|
end
|
474
474
|
|
475
|
-
@yytable_ninf = (@table.compact.
|
475
|
+
@yytable_ninf = (@table.compact.reject {|i| i == ErrorActionNumber } + [0]).min - 1
|
476
476
|
@table.map! do |i|
|
477
477
|
case i
|
478
478
|
when nil
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Lrama
|
2
|
+
class Grammar
|
3
|
+
class Code
|
4
|
+
class DestructorCode < Code
|
5
|
+
def initialize(type:, token_code:, tag:)
|
6
|
+
super(type: type, token_code: token_code)
|
7
|
+
@tag = tag
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# * ($$) *yyvaluep
|
13
|
+
# * (@$) *yylocationp
|
14
|
+
# * ($:$) error
|
15
|
+
# * ($1) error
|
16
|
+
# * (@1) error
|
17
|
+
# * ($:1) error
|
18
|
+
def reference_to_c(ref)
|
19
|
+
case
|
20
|
+
when ref.type == :dollar && ref.name == "$" # $$
|
21
|
+
member = @tag.member
|
22
|
+
"((*yyvaluep).#{member})"
|
23
|
+
when ref.type == :at && ref.name == "$" # @$
|
24
|
+
"(*yylocationp)"
|
25
|
+
when ref.type == :index && ref.name == "$" # $:$
|
26
|
+
raise "$:#{ref.value} can not be used in #{type}."
|
27
|
+
when ref.type == :dollar # $n
|
28
|
+
raise "$#{ref.value} can not be used in #{type}."
|
29
|
+
when ref.type == :at # @n
|
30
|
+
raise "@#{ref.value} can not be used in #{type}."
|
31
|
+
when ref.type == :index # $:n
|
32
|
+
raise "$:#{ref.value} can not be used in #{type}."
|
33
|
+
else
|
34
|
+
raise "Unexpected. #{self}, #{ref}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -6,18 +6,24 @@ module Lrama
|
|
6
6
|
|
7
7
|
# * ($$) yylval
|
8
8
|
# * (@$) yylloc
|
9
|
+
# * ($:$) error
|
9
10
|
# * ($1) error
|
10
11
|
# * (@1) error
|
12
|
+
# * ($:1) error
|
11
13
|
def reference_to_c(ref)
|
12
14
|
case
|
13
15
|
when ref.type == :dollar && ref.name == "$" # $$
|
14
16
|
"yylval"
|
15
17
|
when ref.type == :at && ref.name == "$" # @$
|
16
18
|
"yylloc"
|
19
|
+
when ref.type == :index && ref.name == "$" # $:$
|
20
|
+
raise "$:#{ref.value} can not be used in initial_action."
|
17
21
|
when ref.type == :dollar # $n
|
18
22
|
raise "$#{ref.value} can not be used in initial_action."
|
19
23
|
when ref.type == :at # @n
|
20
24
|
raise "@#{ref.value} can not be used in initial_action."
|
25
|
+
when ref.type == :index # $:n
|
26
|
+
raise "$:#{ref.value} can not be used in initial_action."
|
21
27
|
else
|
22
28
|
raise "Unexpected. #{self}, #{ref}"
|
23
29
|
end
|
@@ -6,14 +6,18 @@ module Lrama
|
|
6
6
|
|
7
7
|
# * ($$) error
|
8
8
|
# * (@$) error
|
9
|
+
# * ($:$) error
|
9
10
|
# * ($1) error
|
10
11
|
# * (@1) error
|
12
|
+
# * ($:1) error
|
11
13
|
def reference_to_c(ref)
|
12
14
|
case
|
13
15
|
when ref.type == :dollar # $$, $n
|
14
16
|
raise "$#{ref.value} can not be used in #{type}."
|
15
17
|
when ref.type == :at # @$, @n
|
16
18
|
raise "@#{ref.value} can not be used in #{type}."
|
19
|
+
when ref.type == :index # $:$, $:n
|
20
|
+
raise "$:#{ref.value} can not be used in #{type}."
|
17
21
|
else
|
18
22
|
raise "Unexpected. #{self}, #{ref}"
|
19
23
|
end
|
@@ -11,8 +11,10 @@ module Lrama
|
|
11
11
|
|
12
12
|
# * ($$) *yyvaluep
|
13
13
|
# * (@$) *yylocationp
|
14
|
+
# * ($:$) error
|
14
15
|
# * ($1) error
|
15
16
|
# * (@1) error
|
17
|
+
# * ($:1) error
|
16
18
|
def reference_to_c(ref)
|
17
19
|
case
|
18
20
|
when ref.type == :dollar && ref.name == "$" # $$
|
@@ -20,10 +22,14 @@ module Lrama
|
|
20
22
|
"((*yyvaluep).#{member})"
|
21
23
|
when ref.type == :at && ref.name == "$" # @$
|
22
24
|
"(*yylocationp)"
|
25
|
+
when ref.type == :index && ref.name == "$" # $:$
|
26
|
+
raise "$:#{ref.value} can not be used in #{type}."
|
23
27
|
when ref.type == :dollar # $n
|
24
28
|
raise "$#{ref.value} can not be used in #{type}."
|
25
29
|
when ref.type == :at # @n
|
26
30
|
raise "@#{ref.value} can not be used in #{type}."
|
31
|
+
when ref.type == :index # $:n
|
32
|
+
raise "$:#{ref.value} can not be used in #{type}."
|
27
33
|
else
|
28
34
|
raise "Unexpected. #{self}, #{ref}"
|
29
35
|
end
|
@@ -11,8 +11,10 @@ module Lrama
|
|
11
11
|
|
12
12
|
# * ($$) yyval
|
13
13
|
# * (@$) yyloc
|
14
|
+
# * ($:$) error
|
14
15
|
# * ($1) yyvsp[i]
|
15
16
|
# * (@1) yylsp[i]
|
17
|
+
# * ($:1) i - 1
|
16
18
|
#
|
17
19
|
#
|
18
20
|
# Consider a rule like
|
@@ -24,6 +26,8 @@ module Lrama
|
|
24
26
|
# "Rule" class: keyword_class { $1 } tSTRING { $2 + $3 } keyword_end { $class = $1 + $keyword_end }
|
25
27
|
# "Position in grammar" $1 $2 $3 $4 $5
|
26
28
|
# "Index for yyvsp" -4 -3 -2 -1 0
|
29
|
+
# "$:n" $:1 $:2 $:3 $:4 $:5
|
30
|
+
# "index of $:n" -5 -4 -3 -2 -1
|
27
31
|
#
|
28
32
|
#
|
29
33
|
# For the first midrule action:
|
@@ -31,6 +35,7 @@ module Lrama
|
|
31
35
|
# "Rule" class: keyword_class { $1 } tSTRING { $2 + $3 } keyword_end { $class = $1 + $keyword_end }
|
32
36
|
# "Position in grammar" $1
|
33
37
|
# "Index for yyvsp" 0
|
38
|
+
# "$:n" $:1
|
34
39
|
def reference_to_c(ref)
|
35
40
|
case
|
36
41
|
when ref.type == :dollar && ref.name == "$" # $$
|
@@ -39,6 +44,8 @@ module Lrama
|
|
39
44
|
"(yyval.#{tag.member})"
|
40
45
|
when ref.type == :at && ref.name == "$" # @$
|
41
46
|
"(yyloc)"
|
47
|
+
when ref.type == :index && ref.name == "$" # $:$
|
48
|
+
raise "$:$ is not supported"
|
42
49
|
when ref.type == :dollar # $n
|
43
50
|
i = -position_in_rhs + ref.index
|
44
51
|
tag = ref.ex_tag || rhs[ref.index - 1].tag
|
@@ -47,6 +54,9 @@ module Lrama
|
|
47
54
|
when ref.type == :at # @n
|
48
55
|
i = -position_in_rhs + ref.index
|
49
56
|
"(yylsp[#{i}])"
|
57
|
+
when ref.type == :index # $:n
|
58
|
+
i = -position_in_rhs + ref.index
|
59
|
+
"(#{i} - 1)"
|
50
60
|
else
|
51
61
|
raise "Unexpected. #{self}, #{ref}"
|
52
62
|
end
|
@@ -70,7 +80,7 @@ module Lrama
|
|
70
80
|
end
|
71
81
|
|
72
82
|
def raise_tag_not_found_error(ref)
|
73
|
-
raise "Tag is not specified for '$#{ref.value}' in '#{@rule
|
83
|
+
raise "Tag is not specified for '$#{ref.value}' in '#{@rule}'"
|
74
84
|
end
|
75
85
|
end
|
76
86
|
end
|
data/lib/lrama/grammar/code.rb
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
module Lrama
|
2
|
+
class Grammar
|
3
|
+
class Destructor < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true)
|
4
|
+
def translated_code(tag)
|
5
|
+
Code::DestructorCode.new(type: :destructor, token_code: token_code, tag: tag).translated_code
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -2,11 +2,12 @@ module Lrama
|
|
2
2
|
class Grammar
|
3
3
|
# type: :dollar or :at
|
4
4
|
# name: String (e.g. $$, $foo, $expr.right)
|
5
|
-
#
|
5
|
+
# number: Integer (e.g. $1)
|
6
|
+
# index: Integer
|
6
7
|
# ex_tag: "$<tag>1" (Optional)
|
7
|
-
class Reference < Struct.new(:type, :name, :index, :ex_tag, :first_column, :last_column, keyword_init: true)
|
8
|
+
class Reference < Struct.new(:type, :name, :number, :index, :ex_tag, :first_column, :last_column, keyword_init: true)
|
8
9
|
def value
|
9
|
-
name ||
|
10
|
+
name || number
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
@@ -115,12 +115,12 @@ module Lrama
|
|
115
115
|
@replaced_rhs << lhs_token
|
116
116
|
parameterizing_rule_resolver.created_lhs_list << lhs_token
|
117
117
|
parameterizing_rule.rhs_list.each do |r|
|
118
|
-
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter,
|
118
|
+
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: token.lhs_tag, skip_preprocess_references: true)
|
119
119
|
rule_builder.lhs = lhs_token
|
120
120
|
r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) }
|
121
121
|
rule_builder.line = line
|
122
|
-
rule_builder.user_code = r.user_code
|
123
122
|
rule_builder.precedence_sym = r.precedence_sym
|
123
|
+
rule_builder.user_code = r.user_code
|
124
124
|
rule_builder.complete_input
|
125
125
|
rule_builder.setup_rules(parameterizing_rule_resolver)
|
126
126
|
@rule_builders_for_parameterizing_rules << rule_builder
|
@@ -181,11 +181,18 @@ module Lrama
|
|
181
181
|
if referring_symbol[1] == 0 # Refers to LHS
|
182
182
|
ref.name = '$'
|
183
183
|
else
|
184
|
-
ref.
|
184
|
+
ref.number = referring_symbol[1]
|
185
185
|
end
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
189
|
+
if ref.number
|
190
|
+
# TODO: When Inlining is implemented, for example, if `$1` is expanded to multiple RHS tokens,
|
191
|
+
# `$2` needs to access `$2 + n` to actually access it. So, after the Inlining implementation,
|
192
|
+
# it needs resolves from number to index.
|
193
|
+
ref.index = ref.number
|
194
|
+
end
|
195
|
+
|
189
196
|
# TODO: Need to check index of @ too?
|
190
197
|
next if ref.type == :at
|
191
198
|
|
data/lib/lrama/grammar/stdlib.y
CHANGED
@@ -8,6 +8,9 @@
|
|
8
8
|
|
9
9
|
**********************************************************************/
|
10
10
|
|
11
|
+
// -------------------------------------------------------------------
|
12
|
+
// Options
|
13
|
+
|
11
14
|
/*
|
12
15
|
* program: option(number)
|
13
16
|
*
|
@@ -21,6 +24,45 @@
|
|
21
24
|
| X
|
22
25
|
;
|
23
26
|
|
27
|
+
// -------------------------------------------------------------------
|
28
|
+
// Sequences
|
29
|
+
|
30
|
+
/*
|
31
|
+
* program: preceded(opening, X)
|
32
|
+
*
|
33
|
+
* =>
|
34
|
+
*
|
35
|
+
* program: preceded_opening_X
|
36
|
+
* preceded_opening_X: opening X
|
37
|
+
*/
|
38
|
+
%rule preceded(opening, X): opening X { $$ = $2; }
|
39
|
+
;
|
40
|
+
|
41
|
+
/*
|
42
|
+
* program: terminated(X, closing)
|
43
|
+
*
|
44
|
+
* =>
|
45
|
+
*
|
46
|
+
* program: terminated_X_closing
|
47
|
+
* terminated_X_closing: X closing
|
48
|
+
*/
|
49
|
+
%rule terminated(X, closing): X closing { $$ = $1; }
|
50
|
+
;
|
51
|
+
|
52
|
+
/*
|
53
|
+
* program: delimited(opening, X, closing)
|
54
|
+
*
|
55
|
+
* =>
|
56
|
+
*
|
57
|
+
* program: delimited_opening_X_closing
|
58
|
+
* delimited_opening_X_closing: opening X closing
|
59
|
+
*/
|
60
|
+
%rule delimited(opening, X, closing): opening X closing { $$ = $2; }
|
61
|
+
;
|
62
|
+
|
63
|
+
// -------------------------------------------------------------------
|
64
|
+
// Lists
|
65
|
+
|
24
66
|
/*
|
25
67
|
* program: list(number)
|
26
68
|
*
|
data/lib/lrama/grammar/symbol.rb
CHANGED
@@ -7,11 +7,12 @@
|
|
7
7
|
module Lrama
|
8
8
|
class Grammar
|
9
9
|
class Symbol
|
10
|
-
attr_accessor :id, :alias_name, :tag, :number, :token_id, :nullable, :precedence,
|
10
|
+
attr_accessor :id, :alias_name, :tag, :number, :token_id, :nullable, :precedence,
|
11
|
+
:printer, :destructor, :error_token, :first_set, :first_set_bitmap
|
11
12
|
attr_reader :term
|
12
13
|
attr_writer :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol
|
13
14
|
|
14
|
-
def initialize(id:, alias_name: nil, number: nil, tag: nil,
|
15
|
+
def initialize(id:, term:, alias_name: nil, number: nil, tag: nil, token_id: nil, nullable: nil, precedence: nil, printer: nil, destructor: nil)
|
15
16
|
@id = id
|
16
17
|
@alias_name = alias_name
|
17
18
|
@number = number
|
@@ -21,6 +22,7 @@ module Lrama
|
|
21
22
|
@nullable = nullable
|
22
23
|
@precedence = precedence
|
23
24
|
@printer = printer
|
25
|
+
@destructor = destructor
|
24
26
|
end
|
25
27
|
|
26
28
|
def term?
|