Lrama v0.6.11

This commit is contained in:
ydah 2024-12-22 23:12:35 +09:00 committed by Yuichiro Kaneko
parent 34e6bb48af
commit d8c152eead
Notes: git 2024-12-23 06:16:50 +00:00
16 changed files with 654 additions and 564 deletions

View File

@ -1,12 +1,47 @@
# NEWS for Lrama # NEWS for Lrama
## Lrama 0.6.11 (2024-12-23)
### Add support for %type declarations using %nterm in Nonterminal Symbols
Allow to use `%nterm` in Nonterminal Symbols for `%type` declarations.
```yacc
%nterm <type> nonterminal…
```
This directive is also supported for compatibility with Bison, and only non-terminal symbols are allowed. In other words, definitions like the following will result in an error:
```yacc
%{
// Prologue
%}
%token EOI 0 "EOI"
%nterm EOI
%%
program: /* empty */
;
```
It show an error message like the following:
```command
exe/lrama nterm.y
nterm.y:6:7: symbol EOI redeclared as a nonterminal
%nterm EOI
^^^
```
## Lrama 0.6.10 (2024-09-11) ## Lrama 0.6.10 (2024-09-11)
### Aliased Named References for actions of RHS in parameterizing rules ### Aliased Named References for actions of RHS in parameterizing rules
Allow to use aliased named references for actions of RHS in parameterizing rules. Allow to use aliased named references for actions of RHS in parameterizing rules.
``` ```yacc
%rule sum(X, Y): X[summand] '+' Y[addend] { $$ = $summand + $addend } %rule sum(X, Y): X[summand] '+' Y[addend] { $$ = $summand + $addend }
; ;
``` ```
@ -18,7 +53,7 @@ https://github.com/ruby/lrama/pull/410
Allow to use named references for actions of RHS in parameterizing rules caller side. Allow to use named references for actions of RHS in parameterizing rules caller side.
``` ```yacc
opt_nl: '\n'?[nl] <str> { $$ = $nl; } opt_nl: '\n'?[nl] <str> { $$ = $nl; }
; ;
``` ```
@ -29,7 +64,7 @@ https://github.com/ruby/lrama/pull/414
Allow to define parameterizing rules in the middle of the grammar. Allow to define parameterizing rules in the middle of the grammar.
``` ```yacc
%rule defined_option(X): /* empty */ %rule defined_option(X): /* empty */
| X | X
; ;
@ -52,8 +87,8 @@ https://github.com/ruby/lrama/pull/420
Support to report unused terminal symbols. Support to report unused terminal symbols.
Run `exe/lrama --report=terms` to show unused terminal symbols. Run `exe/lrama --report=terms` to show unused terminal symbols.
``` ```console
exe/lrama --report=terms sample/calc.y $ exe/lrama --report=terms sample/calc.y
11 Unused Terms 11 Unused Terms
0 YYerror 0 YYerror
1 YYUNDEF 1 YYUNDEF
@ -74,8 +109,8 @@ https://github.com/ruby/lrama/pull/439
Support to report unused rules. Support to report unused rules.
Run `exe/lrama --report=rules` to show unused rules. Run `exe/lrama --report=rules` to show unused rules.
``` ```console
exe/lrama --report=rules sample/calc.y $ exe/lrama --report=rules sample/calc.y
3 Unused Rules 3 Unused Rules
0 unused_option 0 unused_option
1 unused_list 1 unused_list
@ -96,8 +131,8 @@ https://github.com/ruby/lrama/pull/446
Support to warning redefined parameterizing rules. Support to warning redefined parameterizing rules.
Run `exe/lrama -W` or `exe/lrama --warnings` to show redefined parameterizing rules. Run `exe/lrama -W` or `exe/lrama --warnings` to show redefined parameterizing rules.
``` ```console
exe/lrama -W sample/calc.y $ exe/lrama -W sample/calc.y
parameterizing rule redefined: redefined_method(X) parameterizing rule redefined: redefined_method(X)
parameterizing rule redefined: redefined_method(X) parameterizing rule redefined: redefined_method(X)
``` ```
@ -117,7 +152,7 @@ https://github.com/ruby/lrama/pull/457
Allow to specify tag on callee side of parameterizing rules. Allow to specify tag on callee side of parameterizing rules.
``` ```yacc
%union { %union {
int i; int i;
} }
@ -130,7 +165,7 @@ Allow to specify tag on callee side of parameterizing rules.
Allow to use named references for actions of RHS in parameterizing rules. Allow to use named references for actions of RHS in parameterizing rules.
``` ```yacc
%rule option(number): /* empty */ %rule option(number): /* empty */
| number { $$ = $number; } | number { $$ = $number; }
; ;
@ -142,7 +177,7 @@ Allow to use named references for actions of RHS in parameterizing rules.
Allow to nested parameterizing rules with tag. Allow to nested parameterizing rules with tag.
``` ```yacc
%union { %union {
int i; int i;
} }
@ -179,8 +214,8 @@ User can use `'symbol'?`, `'symbol'+` and `'symbol'*` in RHS of user defined par
Support trace actions for debugging. Support trace actions for debugging.
Run `exe/lrama --trace=actions` to show grammar rules with actions. Run `exe/lrama --trace=actions` to show grammar rules with actions.
``` ```console
exe/lrama --trace=actions sample/calc.y $ exe/lrama --trace=actions sample/calc.y
Grammar rules with actions: Grammar rules with actions:
$accept -> list, YYEOF {} $accept -> list, YYEOF {}
list -> ε {} list -> ε {}
@ -199,7 +234,7 @@ expr -> '(', expr, ')' { $$ = $2; }
Support inlining for rules. Support inlining for rules.
The `%inline` directive causes all references to symbols to be replaced with its definition. The `%inline` directive causes all references to symbols to be replaced with its definition.
``` ```yacc
%rule %inline op: PLUS { + } %rule %inline op: PLUS { + }
| TIMES { * } | TIMES { * }
; ;
@ -213,7 +248,7 @@ expr : number { $$ = $1; }
as same as as same as
``` ```yacc
expr : number { $$ = $1; } expr : number { $$ = $1; }
| expr '+' expr { $$ = $1 + $3; } | expr '+' expr { $$ = $1 + $3; }
| expr '*' expr { $$ = $1 * $3; } | expr '*' expr { $$ = $1 * $3; }
@ -226,7 +261,7 @@ expr : number { $$ = $1; }
User can specify the type of mid rule action by tag (`<bar>`) instead of specifying it with in an action. User can specify the type of mid rule action by tag (`<bar>`) instead of specifying it with in an action.
``` ```yacc
primary: k_case expr_value terms? primary: k_case expr_value terms?
{ {
$<val>$ = p->case_labels; $<val>$ = p->case_labels;
@ -241,7 +276,7 @@ primary: k_case expr_value terms?
can be written as can be written as
``` ```yacc
primary: k_case expr_value terms? primary: k_case expr_value terms?
{ {
$$ = p->case_labels; $$ = p->case_labels;
@ -266,7 +301,7 @@ Bison supports this feature from 3.1.
Support `preceded`, `terminated` and `delimited` rules. Support `preceded`, `terminated` and `delimited` rules.
``` ```text
program: preceded(opening, X) program: preceded(opening, X)
// Expanded to // Expanded to
@ -302,7 +337,7 @@ In general, these resources are freed by actions or after parsing.
However if syntax error happens in parsing, these codes may not be executed. However if syntax error happens in parsing, these codes may not be executed.
Codes associated to `%destructor` are executed when semantic value is popped from the stack by an error. Codes associated to `%destructor` are executed when semantic value is popped from the stack by an error.
``` ```yacc
%token <val1> NUM %token <val1> NUM
%type <val2> expr2 %type <val2> expr2
%type <val3> expr %type <val3> expr
@ -350,7 +385,7 @@ Lrama provides these five callbacks. Registered functions are called when each e
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. 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.
For example For example
``` ```yacc
primary: k_if expr_value then compstmt if_tail k_end primary: k_if expr_value then compstmt if_tail k_end
{ {
/*% ripper: if!($:2, $:4, $:5) %*/ /*% ripper: if!($:2, $:4, $:5) %*/
@ -375,7 +410,7 @@ https://github.com/ruby/lrama/pull/344
Allow to pass an instantiated rule to other parameterizing rules. Allow to pass an instantiated rule to other parameterizing rules.
``` ```yacc
%rule constant(X) : X %rule constant(X) : X
; ;
@ -392,7 +427,7 @@ program : option(constant(number)) // Nested rule
Allow to use nested parameterizing rules when define parameterizing rules. Allow to use nested parameterizing rules when define parameterizing rules.
``` ```yacc
%rule option(x) : /* empty */ %rule option(x) : /* empty */
| X | X
; ;
@ -419,7 +454,7 @@ https://github.com/ruby/lrama/pull/337
Allow to define parameterizing rule by `%rule` directive. Allow to define parameterizing rule by `%rule` directive.
``` ```yacc
%rule pair(X, Y): X Y { $$ = $1 + $2; } %rule pair(X, Y): X Y { $$ = $1 + $2; }
; ;
@ -442,7 +477,7 @@ https://github.com/ruby/lrama/pull/285
Allow to specify type of rules by specifying tag, `<i>` in below example. Allow to specify type of rules by specifying tag, `<i>` in below example.
Tag is post-modification style. Tag is post-modification style.
``` ```yacc
%union { %union {
int i; int i;
} }
@ -469,7 +504,7 @@ https://github.com/ruby/lrama/pull/197
Support `separated_list` and `separated_nonempty_list` parameterizing rules. Support `separated_list` and `separated_nonempty_list` parameterizing rules.
``` ```text
program: separated_list(',', number) program: separated_list(',', number)
// Expanded to // Expanded to
@ -500,7 +535,7 @@ https://github.com/ruby/lrama/pull/204
Parameterizing rules are template of rules. Parameterizing rules are template of rules.
It's very common pattern to write "list" grammar rule like: It's very common pattern to write "list" grammar rule like:
``` ```yacc
opt_args: /* none */ opt_args: /* none */
| args | args
; ;
@ -532,7 +567,7 @@ https://github.com/ruby/lrama/pull/62
### Runtime configuration for error recovery ### Runtime configuration for error recovery
Meke error recovery function configurable on runtime by two new macros. Make error recovery function configurable on runtime by two new macros.
* `YYMAXREPAIR`: Expected to return max length of repair operations. `%parse-param` is passed to this function. * `YYMAXREPAIR`: Expected to return max length of repair operations. `%parse-param` is passed to this function.
* `YYERROR_RECOVERY_ENABLED`: Expected to return bool value to determine error recovery is enabled or not. `%parse-param` is passed to this function. * `YYERROR_RECOVERY_ENABLED`: Expected to return bool value to determine error recovery is enabled or not. `%parse-param` is passed to this function.
@ -555,7 +590,7 @@ https://github.com/ruby/lrama/pull/44
Instead of positional references like `$1` or `$$`, Instead of positional references like `$1` or `$$`,
named references allow to access to symbol by name. named references allow to access to symbol by name.
``` ```yacc
primary: k_class cpath superclass bodystmt k_end primary: k_class cpath superclass bodystmt k_end
{ {
$primary = new_class($cpath, $bodystmt, $superclass); $primary = new_class($cpath, $bodystmt, $superclass);
@ -564,7 +599,7 @@ primary: k_class cpath superclass bodystmt k_end
Alias name can be declared. Alias name can be declared.
``` ```yacc
expr[result]: expr[ex-left] '+' expr[ex.right] expr[result]: expr[ex-left] '+' expr[ex.right]
{ {
$result = $[ex-left] + $[ex.right]; $result = $[ex-left] + $[ex.right];

View File

@ -13,7 +13,7 @@ module Lrama
end end
def self.to_array(int) def self.to_array(int)
a = [] a = [] #: Array[Integer]
i = 0 i = 0
while int > 0 do while int > 0 do

View File

@ -405,7 +405,7 @@ module Lrama
@check = [] @check = []
# Key is froms_and_tos, value is index position # Key is froms_and_tos, value is index position
pushed = {} pushed = {}
userd_res = {} used_res = {}
lowzero = 0 lowzero = 0
high = 0 high = 0
@ -430,7 +430,7 @@ module Lrama
end end
end end
if ok && userd_res[res] if ok && used_res[res]
ok = false ok = false
end end
@ -458,7 +458,7 @@ module Lrama
@base[state_id] = res @base[state_id] = res
pushed[froms_and_tos] = res pushed[froms_and_tos] = res
userd_res[res] = true used_res[res] = true
end end
@yylast = high @yylast = high

View File

@ -32,8 +32,10 @@ module Lrama
conflict_state.conflicts.flat_map do |conflict| conflict_state.conflicts.flat_map do |conflict|
case conflict.type case conflict.type
when :shift_reduce when :shift_reduce
# @type var conflict: State::ShiftReduceConflict
shift_reduce_example(conflict_state, conflict) shift_reduce_example(conflict_state, conflict)
when :reduce_reduce when :reduce_reduce
# @type var conflict: State::ReduceReduceConflict
reduce_reduce_examples(conflict_state, conflict) reduce_reduce_examples(conflict_state, conflict)
end end
end.compact end.compact
@ -48,7 +50,7 @@ module Lrama
@reverse_transitions = {} @reverse_transitions = {}
@states.states.each do |src_state| @states.states.each do |src_state|
trans = {} trans = {} #: Hash[Grammar::Symbol, State]
src_state.transitions.each do |shift, next_state| src_state.transitions.each do |shift, next_state|
trans[shift.next_sym] = next_state trans[shift.next_sym] = next_state
@ -66,6 +68,7 @@ module Lrama
@transitions[[src_state_item, sym]] = dest_state_item @transitions[[src_state_item, sym]] = dest_state_item
# @type var key: [StateItem, Grammar::Symbol]
key = [dest_state_item, sym] key = [dest_state_item, sym]
@reverse_transitions[key] ||= Set.new @reverse_transitions[key] ||= Set.new
@reverse_transitions[key] << src_state_item @reverse_transitions[key] << src_state_item
@ -82,7 +85,7 @@ module Lrama
@states.states.each do |state| @states.states.each do |state|
# LHS => Set(Item) # LHS => Set(Item)
h = {} h = {} #: Hash[Grammar::Symbol, Set[States::Item]]
state.closure.each do |item| state.closure.each do |item|
sym = item.lhs sym = item.lhs
@ -97,6 +100,7 @@ module Lrama
sym = item.next_sym sym = item.next_sym
state_item = StateItem.new(state, item) state_item = StateItem.new(state, item)
# @type var key: [State, Grammar::Symbol]
key = [state, sym] key = [state, sym]
@productions[state_item] = h[sym] @productions[state_item] = h[sym]
@ -109,6 +113,7 @@ module Lrama
def shift_reduce_example(conflict_state, conflict) def shift_reduce_example(conflict_state, conflict)
conflict_symbol = conflict.symbols.first conflict_symbol = conflict.symbols.first
# @type var shift_conflict_item: ::Lrama::States::Item
shift_conflict_item = conflict_state.items.find { |item| item.next_sym == conflict_symbol } shift_conflict_item = conflict_state.items.find { |item| item.next_sym == conflict_symbol }
path2 = shortest_path(conflict_state, conflict.reduce.item, conflict_symbol) path2 = shortest_path(conflict_state, conflict.reduce.item, conflict_symbol)
path1 = find_shift_conflict_shortest_path(path2, conflict_state, shift_conflict_item) path1 = find_shift_conflict_shortest_path(path2, conflict_state, shift_conflict_item)
@ -153,12 +158,14 @@ module Lrama
prev_state_item = prev_path&.to prev_state_item = prev_path&.to
if target_state_item == state_item || target_state_item.item.start_item? if target_state_item == state_item || target_state_item.item.start_item?
result.concat(reversed_reduce_path[_j..-1].map(&:to)) result.concat(
reversed_reduce_path[_j..-1] #: Array[StartPath|TransitionPath|ProductionPath]
.map(&:to))
break break
end end
if target_state_item.item.beginning_of_rule? if target_state_item.item.beginning_of_rule?
queue = [] queue = [] #: Array[Array[StateItem]]
queue << [target_state_item] queue << [target_state_item]
# Find reverse production # Find reverse production
@ -174,15 +181,17 @@ module Lrama
end end
if si.item.beginning_of_rule? if si.item.beginning_of_rule?
# @type var key: [State, Grammar::Symbol]
key = [si.state, si.item.lhs] key = [si.state, si.item.lhs]
@reverse_productions[key].each do |item| @reverse_productions[key].each do |item|
state_item = StateItem.new(si.state, item) state_item = StateItem.new(si.state, item)
queue << (sis + [state_item]) queue << (sis + [state_item])
end end
else else
# @type var key: [StateItem, Grammar::Symbol]
key = [si, si.item.previous_sym] key = [si, si.item.previous_sym]
@reverse_transitions[key].each do |prev_target_state_item| @reverse_transitions[key].each do |prev_target_state_item|
next if prev_target_state_item.state != prev_state_item.state next if prev_target_state_item.state != prev_state_item&.state
sis.shift sis.shift
result.concat(sis) result.concat(sis)
result << prev_target_state_item result << prev_target_state_item
@ -195,9 +204,10 @@ module Lrama
end end
else else
# Find reverse transition # Find reverse transition
# @type var key: [StateItem, Grammar::Symbol]
key = [target_state_item, target_state_item.item.previous_sym] key = [target_state_item, target_state_item.item.previous_sym]
@reverse_transitions[key].each do |prev_target_state_item| @reverse_transitions[key].each do |prev_target_state_item|
next if prev_target_state_item.state != prev_state_item.state next if prev_target_state_item.state != prev_state_item&.state
result << prev_target_state_item result << prev_target_state_item
target_state_item = prev_target_state_item target_state_item = prev_target_state_item
i = j i = j
@ -224,9 +234,9 @@ module Lrama
def shortest_path(conflict_state, conflict_reduce_item, conflict_term) def shortest_path(conflict_state, conflict_reduce_item, conflict_term)
# queue: is an array of [Triple, [Path]] # queue: is an array of [Triple, [Path]]
queue = [] queue = [] #: Array[[Triple, Array[StartPath|TransitionPath|ProductionPath]]]
visited = {} visited = {} #: Hash[Triple, true]
start_state = @states.states.first start_state = @states.states.first #: Lrama::State
raise "BUG: Start state should be just one kernel." if start_state.kernels.count != 1 raise "BUG: Start state should be just one kernel." if start_state.kernels.count != 1
start = Triple.new(start_state, start_state.kernels.first, Set.new([@states.eof_symbol])) start = Triple.new(start_state, start_state.kernels.first, Set.new([@states.eof_symbol]))

View File

@ -18,7 +18,7 @@ module Lrama
alias :inspect :to_s alias :inspect :to_s
def render_strings_for_report def render_strings_for_report
result = [] result = [] #: Array[String]
_render_for_report(self, 0, result, 0) _render_for_report(self, 0, result, 0)
result.map(&:rstrip) result.map(&:rstrip)
end end
@ -44,18 +44,19 @@ module Lrama
str << "#{item.next_sym.display_name}" str << "#{item.next_sym.display_name}"
length = _render_for_report(derivation.left, len, strings, index + 1) length = _render_for_report(derivation.left, len, strings, index + 1)
# I want String#ljust! # I want String#ljust!
str << " " * (length - str.length) str << " " * (length - str.length) if length > str.length
else else
str << "#{item.symbols_after_dot.map(&:display_name).join(" ")} " str << "#{item.symbols_after_dot.map(&:display_name).join(" ")} "
return str.length return str.length
end end
if derivation.right&.left if derivation.right&.left
length = _render_for_report(derivation.right.left, str.length, strings, index + 1) left = derivation.right&.left #: Derivation
str << "#{item.symbols_after_dot[1..-1].map(&:display_name).join(" ")} " length = _render_for_report(left, str.length, strings, index + 1)
str << "#{item.symbols_after_dot[1..-1].map(&:display_name).join(" ")} " # steep:ignore
str << " " * (length - str.length) if length > str.length str << " " * (length - str.length) if length > str.length
elsif item.next_next_sym elsif item.next_next_sym
str << "#{item.symbols_after_dot[1..-1].map(&:display_name).join(" ")} " str << "#{item.symbols_after_dot[1..-1].map(&:display_name).join(" ")} " # steep:ignore
end end
return str.length return str.length

View File

@ -38,9 +38,10 @@ module Lrama
private private
def _derivations(paths) def _derivations(paths)
derivation = nil derivation = nil #: Derivation
current = :production current = :production
lookahead_sym = paths.last.to.item.end_of_rule? ? @conflict_symbol : nil last_path = paths.last #: Path
lookahead_sym = last_path.to.item.end_of_rule? ? @conflict_symbol : nil
paths.reverse_each do |path| paths.reverse_each do |path|
item = path.to.item item = path.to.item
@ -57,12 +58,14 @@ module Lrama
when ProductionPath when ProductionPath
derivation = Derivation.new(item, derivation) derivation = Derivation.new(item, derivation)
current = :production current = :production
else
raise "Unexpected. #{path}"
end end
if lookahead_sym && item.next_next_sym && item.next_next_sym.first_set.include?(lookahead_sym) if lookahead_sym && item.next_next_sym && item.next_next_sym.first_set.include?(lookahead_sym)
state_item = @counterexamples.transitions[[path.to, item.next_sym]] state_item = @counterexamples.transitions[[path.to, item.next_sym]]
derivation2 = find_derivation_for_symbol(state_item, lookahead_sym) derivation2 = find_derivation_for_symbol(state_item, lookahead_sym)
derivation.right = derivation2 derivation.right = derivation2 # steep:ignore
lookahead_sym = nil lookahead_sym = nil
end end
@ -89,7 +92,7 @@ module Lrama
end end
def find_derivation_for_symbol(state_item, sym) def find_derivation_for_symbol(state_item, sym)
queue = [] queue = [] #: Array[Array[StateItem]]
queue << [state_item] queue << [state_item]
while (sis = queue.shift) while (sis = queue.shift)

View File

@ -20,6 +20,10 @@ module Lrama
"#<Path(#{type})>" "#<Path(#{type})>"
end end
alias :inspect :to_s alias :inspect :to_s
def type
raise NotImplementedError
end
end end
end end
end end

View File

@ -30,7 +30,7 @@ module Lrama
:after_shift, :before_reduce, :after_reduce, :after_shift_error_token, :after_pop_stack, :after_shift, :before_reduce, :after_reduce, :after_shift_error_token, :after_pop_stack,
:symbols_resolver, :types, :rules, :rule_builders, :sym_to_rules, :no_stdlib, :locations :symbols_resolver, :types, :rules, :rule_builders, :sym_to_rules, :no_stdlib, :locations
def_delegators "@symbols_resolver", :symbols, :nterms, :terms, :add_nterm, :add_term, def_delegators "@symbols_resolver", :symbols, :nterms, :terms, :add_nterm, :add_term, :find_term_by_s_value,
:find_symbol_by_number!, :find_symbol_by_id!, :token_to_symbol, :find_symbol_by_number!, :find_symbol_by_id!, :token_to_symbol,
:find_symbol_by_s_value!, :fill_symbol_number, :fill_nterm_type, :find_symbol_by_s_value!, :fill_symbol_number, :fill_nterm_type,
:fill_printer, :fill_destructor, :fill_error_token, :sort_by_number! :fill_printer, :fill_destructor, :fill_error_token, :sort_by_number!
@ -382,7 +382,7 @@ module Lrama
end end
def validate_rule_lhs_is_nterm! def validate_rule_lhs_is_nterm!
errors = [] errors = [] #: Array[String]
rules.each do |rule| rules.each do |rule|
next if rule.lhs.nterm? next if rule.lhs.nterm?

View File

@ -16,7 +16,7 @@ module Lrama
return unless user_code return unless user_code
resolved = Lexer::Token::UserCode.new(s_value: user_code.s_value, location: user_code.location) resolved = Lexer::Token::UserCode.new(s_value: user_code.s_value, location: user_code.location)
var_to_arg = {} var_to_arg = {} #: Hash[String, String]
symbols.each do |sym| symbols.each do |sym|
resolved_sym = bindings.resolve_symbol(sym) resolved_sym = bindings.resolve_symbol(sym)
if resolved_sym != sym if resolved_sym != sym

View File

@ -67,7 +67,7 @@ module Lrama
end end
def resolve_inline_rules def resolve_inline_rules
resolved_builders = [] resolved_builders = [] #: Array[RuleBuilder]
rhs.each_with_index do |token, i| rhs.each_with_index do |token, i|
if (inline_rule = @parameterizing_rule_resolver.find_inline(token)) if (inline_rule = @parameterizing_rule_resolver.find_inline(token))
inline_rule.rhs_list.each do |inline_rhs| inline_rule.rhs_list.each do |inline_rhs|

View File

@ -57,6 +57,10 @@ module Lrama
nterm nterm
end end
def find_term_by_s_value(s_value)
terms.find { |s| s.id.s_value == s_value }
end
def find_symbol_by_s_value(s_value) def find_symbol_by_s_value(s_value)
symbols.find { |s| s.id.s_value == s_value } symbols.find { |s| s.id.s_value == s_value }
end end

View File

@ -16,6 +16,7 @@ module Lrama
%union %union
%token %token
%type %type
%nterm
%left %left
%right %right
%nonassoc %nonassoc

View File

@ -16,7 +16,7 @@ module Lrama
def _references def _references
scanner = StringScanner.new(s_value) scanner = StringScanner.new(s_value)
references = [] references = [] #: Array[Grammar::Reference]
until scanner.eos? do until scanner.eos? do
case case

File diff suppressed because it is too large Load Diff

View File

@ -26,9 +26,8 @@ module Lrama
end end
def selected_look_ahead def selected_look_ahead
if @look_ahead if look_ahead
# @type ivar @look_ahead: Array<Grammar::Symbol> look_ahead - @not_selected_symbols
@look_ahead - @not_selected_symbols
else else
[] []
end end

View File

@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
module Lrama module Lrama
VERSION = "0.6.10".freeze VERSION = "0.6.11".freeze
end end