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