lrama 0.6.3 → 0.6.5
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 +107 -1
- data/Steepfile +3 -0
- data/lib/lrama/grammar/code/destructor_code.rb +40 -0
- data/lib/lrama/grammar/code.rb +1 -0
- data/lib/lrama/grammar/destructor.rb +9 -0
- data/lib/lrama/grammar/rule_builder.rb +4 -3
- data/lib/lrama/grammar/stdlib.y +42 -0
- data/lib/lrama/grammar/symbol.rb +4 -2
- data/lib/lrama/grammar/symbols/resolver.rb +21 -4
- data/lib/lrama/grammar.rb +8 -1
- data/lib/lrama/lexer/token/user_code.rb +2 -0
- data/lib/lrama/lexer/token.rb +1 -1
- data/lib/lrama/lexer.rb +1 -0
- data/lib/lrama/option_parser.rb +25 -12
- data/lib/lrama/options.rb +1 -0
- data/lib/lrama/output.rb +19 -0
- data/lib/lrama/parser.rb +143 -134
- data/lib/lrama/version.rb +1 -1
- data/parser.y +9 -1
- 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 +0 -1
- data/sig/lrama/grammar/symbol.rbs +1 -0
- data/sig/lrama/lexer/token/user_code.rbs +1 -0
- data/sig/lrama/options.rbs +17 -0
- data/template/bison/yacc.c +6 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0278f10f4ec931a33647698e0b504d6f7051049b4f13429b804b30911019787e'
|
4
|
+
data.tar.gz: 51b687fabf61ac011848b17c34a151409e9bcd4cf14382ec5f9db365cb480d13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf16ab8c270f7b694798ffaa1ea6e30e09c0e7b5139866fee44e4b7e0ee1b54148c2c237b3155f31b5a599c7cd141505190de3089ae4f2521a6d0de2901a9a92
|
7
|
+
data.tar.gz: 84cca8a68fb47d48e11782c11675a7d43f18a4dec1d4472ccf764e6995e7e79ecd54b437428ba15e177d36fd9e9be76b71f0aa59fd63976f13594b68a69a353b
|
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,109 @@
|
|
1
1
|
# NEWS for Lrama
|
2
2
|
|
3
|
+
## Lrama 0.6.5 (2024-03-25)
|
4
|
+
|
5
|
+
### Typed Midrule Actions
|
6
|
+
|
7
|
+
User can specify the type of mid rule action by tag (`<bar>`) instead of specifying it with in an action.
|
8
|
+
|
9
|
+
```
|
10
|
+
primary: k_case expr_value terms?
|
11
|
+
{
|
12
|
+
$<val>$ = p->case_labels;
|
13
|
+
p->case_labels = Qnil;
|
14
|
+
}
|
15
|
+
case_body
|
16
|
+
k_end
|
17
|
+
{
|
18
|
+
...
|
19
|
+
}
|
20
|
+
```
|
21
|
+
|
22
|
+
can be written as
|
23
|
+
|
24
|
+
```
|
25
|
+
primary: k_case expr_value terms?
|
26
|
+
{
|
27
|
+
$$ = p->case_labels;
|
28
|
+
p->case_labels = Qnil;
|
29
|
+
}<val>
|
30
|
+
case_body
|
31
|
+
k_end
|
32
|
+
{
|
33
|
+
...
|
34
|
+
}
|
35
|
+
```
|
36
|
+
|
37
|
+
`%destructor` for midrule action is invoked only when tag is specified by Typed Midrule Actions.
|
38
|
+
|
39
|
+
Difference from Bison's Typed Midrule Actions is that tag is postposed in Lrama however it's preposed in Bison.
|
40
|
+
|
41
|
+
Bison supports this feature from 3.1.
|
42
|
+
|
43
|
+
## Lrama 0.6.4 (2024-03-22)
|
44
|
+
|
45
|
+
### Parameterizing rules (preceded, terminated, delimited)
|
46
|
+
|
47
|
+
Support `preceded`, `terminated` and `delimited` rules.
|
48
|
+
|
49
|
+
```
|
50
|
+
program: preceded(opening, X)
|
51
|
+
|
52
|
+
// Expanded to
|
53
|
+
|
54
|
+
program: preceded_opening_X
|
55
|
+
preceded_opening_X: opening X
|
56
|
+
```
|
57
|
+
|
58
|
+
```
|
59
|
+
program: terminated(X, closing)
|
60
|
+
|
61
|
+
// Expanded to
|
62
|
+
|
63
|
+
program: terminated_X_closing
|
64
|
+
terminated_X_closing: X closing
|
65
|
+
```
|
66
|
+
|
67
|
+
```
|
68
|
+
program: delimited(opening, X, closing)
|
69
|
+
|
70
|
+
// Expanded to
|
71
|
+
|
72
|
+
program: delimited_opening_X_closing
|
73
|
+
delimited_opening_X_closing: opening X closing
|
74
|
+
```
|
75
|
+
|
76
|
+
https://github.com/ruby/lrama/pull/382
|
77
|
+
|
78
|
+
### Support `%destructor` declaration
|
79
|
+
|
80
|
+
User can set codes for freeing semantic value resources by using `%destructor`.
|
81
|
+
In general, these resources are freed by actions or after parsing.
|
82
|
+
However if syntax error happens in parsing, these codes may not be executed.
|
83
|
+
Codes associated to `%destructor` are executed when semantic value is popped from the stack by an error.
|
84
|
+
|
85
|
+
```
|
86
|
+
%token <val1> NUM
|
87
|
+
%type <val2> expr2
|
88
|
+
%type <val3> expr
|
89
|
+
|
90
|
+
%destructor {
|
91
|
+
printf("destructor for val1: %d\n", $$);
|
92
|
+
} <val1> // printer for TAG
|
93
|
+
|
94
|
+
%destructor {
|
95
|
+
printf("destructor for val2: %d\n", $$);
|
96
|
+
} <val2>
|
97
|
+
|
98
|
+
%destructor {
|
99
|
+
printf("destructor for expr: %d\n", $$);
|
100
|
+
} expr // printer for symbol
|
101
|
+
```
|
102
|
+
|
103
|
+
Bison supports this feature from 1.75b.
|
104
|
+
|
105
|
+
https://github.com/ruby/lrama/pull/385
|
106
|
+
|
3
107
|
## Lrama 0.6.3 (2024-02-15)
|
4
108
|
|
5
109
|
### Bring Your Own Stack
|
@@ -34,6 +138,8 @@ primary: k_if expr_value then compstmt if_tail k_end
|
|
34
138
|
}
|
35
139
|
```
|
36
140
|
|
141
|
+
https://github.com/ruby/lrama/pull/367
|
142
|
+
|
37
143
|
## Lrama 0.6.2 (2024-01-27)
|
38
144
|
|
39
145
|
### %no-stdlib directive
|
@@ -51,7 +157,7 @@ Allow to pass an instantiated rule to other parameterizing rules.
|
|
51
157
|
|
52
158
|
```
|
53
159
|
%rule constant(X) : X
|
54
|
-
|
160
|
+
;
|
55
161
|
|
56
162
|
%rule option(Y) : /* empty */
|
57
163
|
| Y
|
data/Steepfile
CHANGED
@@ -5,6 +5,7 @@ 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"
|
@@ -14,6 +15,7 @@ target :lib do
|
|
14
15
|
check "lib/lrama/grammar/symbols"
|
15
16
|
check "lib/lrama/grammar/percent_code.rb"
|
16
17
|
check "lib/lrama/grammar/precedence.rb"
|
18
|
+
check "lib/lrama/grammar/destructor.rb"
|
17
19
|
check "lib/lrama/grammar/printer.rb"
|
18
20
|
check "lib/lrama/grammar/reference.rb"
|
19
21
|
check "lib/lrama/grammar/rule_builder.rb"
|
@@ -23,5 +25,6 @@ target :lib do
|
|
23
25
|
check "lib/lrama/report"
|
24
26
|
check "lib/lrama/bitmap.rb"
|
25
27
|
check "lib/lrama/digraph.rb"
|
28
|
+
check "lib/lrama/options.rb"
|
26
29
|
check "lib/lrama/warning.rb"
|
27
30
|
end
|
@@ -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
|
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
|
@@ -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
|
@@ -128,10 +128,11 @@ module Lrama
|
|
128
128
|
end
|
129
129
|
when Lrama::Lexer::Token::UserCode
|
130
130
|
prefix = token.referred ? "@" : "$@"
|
131
|
+
tag = token.tag || lhs_tag
|
131
132
|
new_token = Lrama::Lexer::Token::Ident.new(s_value: prefix + @midrule_action_counter.increment.to_s)
|
132
133
|
@replaced_rhs << new_token
|
133
134
|
|
134
|
-
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, i, lhs_tag:
|
135
|
+
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, i, lhs_tag: tag, skip_preprocess_references: true)
|
135
136
|
rule_builder.lhs = new_token
|
136
137
|
rule_builder.user_code = token
|
137
138
|
rule_builder.complete_input
|
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:, term:, alias_name: nil, number: nil, tag: nil, token_id: nil, nullable: nil, precedence: nil, printer: 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?
|
@@ -58,7 +58,7 @@ module Lrama
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def find_symbol_by_s_value!(s_value)
|
61
|
-
find_symbol_by_s_value(s_value) || (raise "Symbol not found:
|
61
|
+
find_symbol_by_s_value(s_value) || (raise "Symbol not found. value: `#{s_value}`")
|
62
62
|
end
|
63
63
|
|
64
64
|
def find_symbol_by_id(id)
|
@@ -68,7 +68,7 @@ module Lrama
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def find_symbol_by_id!(id)
|
71
|
-
find_symbol_by_id(id) || (raise "Symbol not found
|
71
|
+
find_symbol_by_id(id) || (raise "Symbol not found. #{id}")
|
72
72
|
end
|
73
73
|
|
74
74
|
def find_symbol_by_token_id(token_id)
|
@@ -78,7 +78,7 @@ module Lrama
|
|
78
78
|
def find_symbol_by_number!(number)
|
79
79
|
sym = symbols[number]
|
80
80
|
|
81
|
-
raise "Symbol not found:
|
81
|
+
raise "Symbol not found. number: `#{number}`" unless sym
|
82
82
|
raise "[BUG] Symbol number mismatch. #{number}, #{sym}" if sym.number != number
|
83
83
|
|
84
84
|
sym
|
@@ -118,6 +118,23 @@ module Lrama
|
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
|
+
def fill_destructor(destructors)
|
122
|
+
symbols.each do |sym|
|
123
|
+
destructors.each do |destructor|
|
124
|
+
destructor.ident_or_tags.each do |ident_or_tag|
|
125
|
+
case ident_or_tag
|
126
|
+
when Lrama::Lexer::Token::Ident
|
127
|
+
sym.destructor = destructor if sym.id == ident_or_tag
|
128
|
+
when Lrama::Lexer::Token::Tag
|
129
|
+
sym.destructor = destructor if sym.tag == ident_or_tag
|
130
|
+
else
|
131
|
+
raise "Unknown token type. #{destructor}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
121
138
|
def fill_error_token(error_tokens)
|
122
139
|
symbols.each do |sym|
|
123
140
|
error_tokens.each do |token|
|
@@ -154,7 +171,7 @@ module Lrama
|
|
154
171
|
def find_nterm_by_id!(id)
|
155
172
|
@nterms.find do |s|
|
156
173
|
s.id == id
|
157
|
-
end || (raise "Symbol not found
|
174
|
+
end || (raise "Symbol not found. #{id}")
|
158
175
|
end
|
159
176
|
|
160
177
|
def fill_terms_number
|
data/lib/lrama/grammar.rb
CHANGED
@@ -3,6 +3,7 @@ require "lrama/grammar/auxiliary"
|
|
3
3
|
require "lrama/grammar/binding"
|
4
4
|
require "lrama/grammar/code"
|
5
5
|
require "lrama/grammar/counter"
|
6
|
+
require "lrama/grammar/destructor"
|
6
7
|
require "lrama/grammar/error_token"
|
7
8
|
require "lrama/grammar/parameterizing_rule"
|
8
9
|
require "lrama/grammar/percent_code"
|
@@ -34,7 +35,7 @@ module Lrama
|
|
34
35
|
def_delegators "@symbols_resolver", :symbols, :nterms, :terms, :add_nterm, :add_term,
|
35
36
|
:find_symbol_by_number!, :find_symbol_by_id!, :token_to_symbol,
|
36
37
|
:find_symbol_by_s_value!, :fill_symbol_number, :fill_nterm_type,
|
37
|
-
:fill_printer, :fill_error_token, :sort_by_number!
|
38
|
+
:fill_printer, :fill_destructor, :fill_error_token, :sort_by_number!
|
38
39
|
|
39
40
|
|
40
41
|
def initialize(rule_counter)
|
@@ -43,6 +44,7 @@ module Lrama
|
|
43
44
|
# Code defined by "%code"
|
44
45
|
@percent_codes = []
|
45
46
|
@printers = []
|
47
|
+
@destructors = []
|
46
48
|
@error_tokens = []
|
47
49
|
@symbols_resolver = Grammar::Symbols::Resolver.new
|
48
50
|
@types = []
|
@@ -65,6 +67,10 @@ module Lrama
|
|
65
67
|
@percent_codes << PercentCode.new(id.s_value, code.s_value)
|
66
68
|
end
|
67
69
|
|
70
|
+
def add_destructor(ident_or_tags:, token_code:, lineno:)
|
71
|
+
@destructors << Destructor.new(ident_or_tags: ident_or_tags, token_code: token_code, lineno: lineno)
|
72
|
+
end
|
73
|
+
|
68
74
|
def add_printer(ident_or_tags:, token_code:, lineno:)
|
69
75
|
@printers << Printer.new(ident_or_tags: ident_or_tags, token_code: token_code, lineno: lineno)
|
70
76
|
end
|
@@ -345,6 +351,7 @@ module Lrama
|
|
345
351
|
fill_symbol_number
|
346
352
|
fill_nterm_type(@types)
|
347
353
|
fill_printer(@printers)
|
354
|
+
fill_destructor(@destructors)
|
348
355
|
fill_error_token(@error_tokens)
|
349
356
|
sort_by_number!
|
350
357
|
end
|
data/lib/lrama/lexer/token.rb
CHANGED
data/lib/lrama/lexer.rb
CHANGED
data/lib/lrama/option_parser.rb
CHANGED
@@ -64,9 +64,18 @@ module Lrama
|
|
64
64
|
o.on('-H', '--header=[FILE]', 'also produce a header file named FILE') {|v| @options.header = true; @options.header_file = v }
|
65
65
|
o.on('-d', 'also produce a header file') { @options.header = true }
|
66
66
|
o.on('-r', '--report=THINGS', Array, 'also produce details on the automaton') {|v| @report = v }
|
67
|
+
o.on_tail ''
|
68
|
+
o.on_tail 'Valid Reports:'
|
69
|
+
o.on_tail " #{VALID_REPORTS.join(' ')}"
|
70
|
+
|
67
71
|
o.on('--report-file=FILE', 'also produce details on the automaton output to a file named FILE') {|v| @options.report_file = v }
|
68
72
|
o.on('-o', '--output=FILE', 'leave output to FILE') {|v| @options.outfile = v }
|
73
|
+
|
69
74
|
o.on('--trace=THINGS', Array, 'also output trace logs at runtime') {|v| @trace = v }
|
75
|
+
o.on_tail ''
|
76
|
+
o.on_tail 'Valid Traces:'
|
77
|
+
o.on_tail " #{VALID_TRACES.join(' ')}"
|
78
|
+
|
70
79
|
o.on('-v', 'reserved, do nothing') { }
|
71
80
|
o.separator ''
|
72
81
|
o.separator 'Error Recovery:'
|
@@ -75,20 +84,22 @@ module Lrama
|
|
75
84
|
o.separator 'Other options:'
|
76
85
|
o.on('-V', '--version', "output version information and exit") {|v| puts "lrama #{Lrama::VERSION}"; exit 0 }
|
77
86
|
o.on('-h', '--help', "display this help and exit") {|v| puts o; exit 0 }
|
78
|
-
o.
|
87
|
+
o.on_tail
|
79
88
|
o.parse!(argv)
|
80
89
|
end
|
81
90
|
end
|
82
91
|
|
92
|
+
BISON_REPORTS = %w[states itemsets lookaheads solved counterexamples cex all none]
|
93
|
+
OTHER_REPORTS = %w[verbose]
|
94
|
+
NOT_SUPPORTED_REPORTS = %w[cex none]
|
95
|
+
VALID_REPORTS = BISON_REPORTS + OTHER_REPORTS - NOT_SUPPORTED_REPORTS
|
96
|
+
|
83
97
|
def validate_report(report)
|
84
|
-
|
85
|
-
others = %w[verbose]
|
86
|
-
list = bison_list + others
|
87
|
-
not_supported = %w[cex none]
|
98
|
+
list = VALID_REPORTS
|
88
99
|
h = { grammar: true }
|
89
100
|
|
90
101
|
report.each do |r|
|
91
|
-
if list.include?(r)
|
102
|
+
if list.include?(r)
|
92
103
|
h[r.to_sym] = true
|
93
104
|
else
|
94
105
|
raise "Invalid report option \"#{r}\"."
|
@@ -96,7 +107,7 @@ module Lrama
|
|
96
107
|
end
|
97
108
|
|
98
109
|
if h[:all]
|
99
|
-
(
|
110
|
+
(BISON_REPORTS - NOT_SUPPORTED_REPORTS).each do |r|
|
100
111
|
h[r.to_sym] = true
|
101
112
|
end
|
102
113
|
|
@@ -106,12 +117,14 @@ module Lrama
|
|
106
117
|
return h
|
107
118
|
end
|
108
119
|
|
120
|
+
VALID_TRACES = %w[
|
121
|
+
none locations scan parse automaton bitsets
|
122
|
+
closure grammar rules resource sets muscles tools
|
123
|
+
m4-early m4 skeleton time ielr cex all
|
124
|
+
]
|
125
|
+
|
109
126
|
def validate_trace(trace)
|
110
|
-
list =
|
111
|
-
none locations scan parse automaton bitsets
|
112
|
-
closure grammar rules resource sets muscles tools
|
113
|
-
m4-early m4 skeleton time ielr cex all
|
114
|
-
]
|
127
|
+
list = VALID_TRACES
|
115
128
|
h = {}
|
116
129
|
|
117
130
|
trace.each do |t|
|
data/lib/lrama/options.rb
CHANGED
data/lib/lrama/output.rb
CHANGED
@@ -150,6 +150,25 @@ module Lrama
|
|
150
150
|
str
|
151
151
|
end
|
152
152
|
|
153
|
+
def symbol_actions_for_destructor
|
154
|
+
str = ""
|
155
|
+
|
156
|
+
@grammar.symbols.each do |sym|
|
157
|
+
next unless sym.destructor
|
158
|
+
|
159
|
+
str << <<-STR
|
160
|
+
case #{sym.enum_name}: /* #{sym.comment} */
|
161
|
+
#line #{sym.destructor.lineno} "#{@grammar_file_path}"
|
162
|
+
{#{sym.destructor.translated_code(sym.tag)}}
|
163
|
+
#line [@oline@] [@ofile@]
|
164
|
+
break;
|
165
|
+
|
166
|
+
STR
|
167
|
+
end
|
168
|
+
|
169
|
+
str
|
170
|
+
end
|
171
|
+
|
153
172
|
# b4_user_initial_action
|
154
173
|
def user_initial_action(comment = "")
|
155
174
|
return "" unless @grammar.initial_action
|