lrama 0.7.0 → 0.7.1

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.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/codespell.yaml +1 -1
  4. data/.github/workflows/gh-pages.yml +5 -6
  5. data/.github/workflows/test.yaml +25 -14
  6. data/Gemfile +4 -3
  7. data/NEWS.md +370 -35
  8. data/README.md +7 -88
  9. data/Rakefile +3 -2
  10. data/Steepfile +11 -5
  11. data/doc/Index.md +1 -1
  12. data/doc/development/compressed_state_table/parser.rb +2 -0
  13. data/doc/development/profiling.md +44 -0
  14. data/exe/lrama +1 -1
  15. data/lib/lrama/bitmap.rb +18 -5
  16. data/lib/lrama/command.rb +95 -43
  17. data/lib/lrama/context.rb +22 -24
  18. data/lib/lrama/counterexamples/derivation.rb +14 -4
  19. data/lib/lrama/counterexamples/example.rb +47 -22
  20. data/lib/lrama/counterexamples/node.rb +30 -0
  21. data/lib/lrama/counterexamples/path.rb +12 -14
  22. data/lib/lrama/counterexamples/state_item.rb +24 -1
  23. data/lib/lrama/counterexamples/triple.rb +27 -9
  24. data/lib/lrama/counterexamples.rb +216 -88
  25. data/lib/lrama/diagram.rb +77 -0
  26. data/lib/lrama/digraph.rb +28 -7
  27. data/lib/lrama/erb.rb +29 -0
  28. data/lib/lrama/grammar/auxiliary.rb +6 -1
  29. data/lib/lrama/grammar/binding.rb +37 -25
  30. data/lib/lrama/grammar/code/destructor_code.rb +11 -0
  31. data/lib/lrama/grammar/code/initial_action_code.rb +3 -0
  32. data/lib/lrama/grammar/code/no_reference_code.rb +3 -0
  33. data/lib/lrama/grammar/code/printer_code.rb +11 -0
  34. data/lib/lrama/grammar/code/rule_action.rb +17 -0
  35. data/lib/lrama/grammar/code.rb +16 -1
  36. data/lib/lrama/grammar/counter.rb +10 -0
  37. data/lib/lrama/grammar/destructor.rb +14 -1
  38. data/lib/lrama/grammar/error_token.rb +14 -1
  39. data/lib/lrama/grammar/inline/resolver.rb +80 -0
  40. data/lib/lrama/grammar/inline.rb +3 -0
  41. data/lib/lrama/grammar/{parameterizing_rule → parameterized}/resolver.rb +19 -8
  42. data/lib/lrama/grammar/{parameterizing_rule → parameterized}/rhs.rb +7 -2
  43. data/lib/lrama/grammar/parameterized/rule.rb +36 -0
  44. data/lib/lrama/grammar/parameterized.rb +5 -0
  45. data/lib/lrama/grammar/percent_code.rb +12 -1
  46. data/lib/lrama/grammar/precedence.rb +43 -1
  47. data/lib/lrama/grammar/printer.rb +9 -0
  48. data/lib/lrama/grammar/reference.rb +13 -0
  49. data/lib/lrama/grammar/rule.rb +61 -1
  50. data/lib/lrama/grammar/rule_builder.rb +84 -69
  51. data/lib/lrama/grammar/stdlib.y +68 -48
  52. data/lib/lrama/grammar/symbol.rb +63 -19
  53. data/lib/lrama/grammar/symbols/resolver.rb +64 -3
  54. data/lib/lrama/grammar/type.rb +13 -1
  55. data/lib/lrama/grammar/union.rb +12 -1
  56. data/lib/lrama/grammar.rb +231 -35
  57. data/lib/lrama/lexer/location.rb +25 -8
  58. data/lib/lrama/lexer/token/base.rb +73 -0
  59. data/lib/lrama/lexer/token/char.rb +15 -2
  60. data/lib/lrama/lexer/token/empty.rb +14 -0
  61. data/lib/lrama/lexer/token/ident.rb +2 -2
  62. data/lib/lrama/lexer/token/instantiate_rule.rb +4 -4
  63. data/lib/lrama/lexer/token/int.rb +14 -0
  64. data/lib/lrama/lexer/token/str.rb +11 -0
  65. data/lib/lrama/lexer/token/tag.rb +2 -2
  66. data/lib/lrama/lexer/token/token.rb +11 -0
  67. data/lib/lrama/lexer/token/user_code.rb +63 -37
  68. data/lib/lrama/lexer/token.rb +6 -56
  69. data/lib/lrama/lexer.rb +51 -23
  70. data/lib/lrama/logger.rb +12 -2
  71. data/lib/lrama/option_parser.rb +63 -9
  72. data/lib/lrama/options.rb +25 -7
  73. data/lib/lrama/output.rb +4 -11
  74. data/lib/lrama/parser.rb +854 -723
  75. data/lib/lrama/reporter/conflicts.rb +44 -0
  76. data/lib/lrama/reporter/grammar.rb +39 -0
  77. data/lib/lrama/reporter/precedences.rb +54 -0
  78. data/lib/lrama/reporter/profile/call_stack.rb +45 -0
  79. data/lib/lrama/reporter/profile/memory.rb +44 -0
  80. data/lib/lrama/reporter/profile.rb +4 -0
  81. data/lib/lrama/reporter/rules.rb +43 -0
  82. data/lib/lrama/reporter/states.rb +387 -0
  83. data/lib/lrama/reporter/terms.rb +44 -0
  84. data/lib/lrama/reporter.rb +39 -0
  85. data/lib/lrama/state/action/goto.rb +33 -0
  86. data/lib/lrama/state/action/reduce.rb +71 -0
  87. data/lib/lrama/state/action/shift.rb +39 -0
  88. data/lib/lrama/state/action.rb +5 -0
  89. data/lib/lrama/state/inadequacy_annotation.rb +140 -0
  90. data/lib/lrama/{states → state}/item.rb +33 -4
  91. data/lib/lrama/state/reduce_reduce_conflict.rb +14 -1
  92. data/lib/lrama/state/resolved_conflict.rb +38 -4
  93. data/lib/lrama/state/shift_reduce_conflict.rb +14 -1
  94. data/lib/lrama/state.rb +301 -200
  95. data/lib/lrama/states.rb +447 -175
  96. data/lib/lrama/tracer/actions.rb +22 -0
  97. data/lib/lrama/tracer/closure.rb +30 -0
  98. data/lib/lrama/tracer/duration.rb +38 -0
  99. data/lib/lrama/tracer/only_explicit_rules.rb +24 -0
  100. data/lib/lrama/tracer/rules.rb +23 -0
  101. data/lib/lrama/tracer/state.rb +33 -0
  102. data/lib/lrama/tracer.rb +51 -0
  103. data/lib/lrama/version.rb +2 -1
  104. data/lib/lrama/warnings/conflicts.rb +27 -0
  105. data/lib/lrama/warnings/implicit_empty.rb +29 -0
  106. data/lib/lrama/warnings/name_conflicts.rb +63 -0
  107. data/lib/lrama/warnings/redefined_rules.rb +23 -0
  108. data/lib/lrama/warnings/required.rb +23 -0
  109. data/lib/lrama/warnings/useless_precedence.rb +25 -0
  110. data/lib/lrama/warnings.rb +33 -0
  111. data/lib/lrama.rb +5 -5
  112. data/parser.y +495 -404
  113. data/rbs_collection.lock.yaml +27 -3
  114. data/rbs_collection.yaml +2 -0
  115. data/sig/generated/lrama/bitmap.rbs +12 -4
  116. data/sig/generated/lrama/counterexamples/derivation.rbs +36 -0
  117. data/sig/generated/lrama/counterexamples/example.rbs +58 -0
  118. data/sig/generated/lrama/counterexamples/node.rbs +18 -0
  119. data/sig/generated/lrama/counterexamples/path.rbs +23 -0
  120. data/sig/generated/lrama/counterexamples/state_item.rbs +19 -0
  121. data/sig/generated/lrama/counterexamples/triple.rbs +32 -0
  122. data/sig/generated/lrama/counterexamples.rbs +98 -0
  123. data/sig/generated/lrama/diagram.rbs +34 -0
  124. data/sig/generated/lrama/digraph.rbs +26 -6
  125. data/sig/generated/lrama/erb.rbs +14 -0
  126. data/sig/generated/lrama/grammar/auxiliary.rbs +16 -0
  127. data/sig/generated/lrama/grammar/binding.rbs +18 -12
  128. data/sig/generated/lrama/grammar/code/destructor_code.rbs +26 -0
  129. data/sig/{lrama → generated/lrama}/grammar/code/initial_action_code.rbs +6 -0
  130. data/sig/{lrama → generated/lrama}/grammar/code/no_reference_code.rbs +6 -0
  131. data/sig/generated/lrama/grammar/code/printer_code.rbs +26 -0
  132. data/sig/generated/lrama/grammar/code/rule_action.rbs +63 -0
  133. data/sig/generated/lrama/grammar/code.rbs +38 -0
  134. data/sig/{lrama → generated/lrama}/grammar/counter.rbs +4 -0
  135. data/sig/generated/lrama/grammar/destructor.rbs +19 -0
  136. data/sig/generated/lrama/grammar/error_token.rbs +19 -0
  137. data/sig/generated/lrama/grammar/inline/resolver.rbs +26 -0
  138. data/sig/generated/lrama/grammar/parameterized/resolver.rbs +42 -0
  139. data/sig/generated/lrama/grammar/parameterized/rhs.rbs +21 -0
  140. data/sig/generated/lrama/grammar/parameterized/rule.rbs +28 -0
  141. data/sig/{lrama → generated/lrama}/grammar/percent_code.rbs +8 -0
  142. data/sig/generated/lrama/grammar/precedence.rbs +45 -0
  143. data/sig/{lrama/grammar/error_token.rbs → generated/lrama/grammar/printer.rbs} +8 -3
  144. data/sig/generated/lrama/grammar/reference.rbs +31 -0
  145. data/sig/generated/lrama/grammar/rule.rbs +83 -0
  146. data/sig/generated/lrama/grammar/rule_builder.rbs +91 -0
  147. data/sig/generated/lrama/grammar/symbol.rbs +89 -0
  148. data/sig/generated/lrama/grammar/symbols/resolver.rbs +131 -0
  149. data/sig/generated/lrama/grammar/type.rbs +21 -0
  150. data/sig/generated/lrama/grammar/union.rbs +17 -0
  151. data/sig/generated/lrama/grammar.rbs +289 -0
  152. data/sig/generated/lrama/lexer/location.rbs +12 -3
  153. data/sig/generated/lrama/lexer/token/base.rbs +53 -0
  154. data/sig/generated/lrama/lexer/token/char.rbs +9 -2
  155. data/sig/generated/lrama/lexer/token/empty.rbs +11 -0
  156. data/sig/generated/lrama/lexer/token/ident.rbs +2 -2
  157. data/sig/generated/lrama/lexer/token/instantiate_rule.rbs +5 -5
  158. data/sig/generated/lrama/lexer/token/int.rbs +13 -0
  159. data/sig/generated/lrama/lexer/token/str.rbs +10 -0
  160. data/sig/generated/lrama/lexer/token/tag.rbs +2 -2
  161. data/sig/generated/lrama/lexer/token/token.rbs +10 -0
  162. data/sig/generated/lrama/lexer/token/user_code.rbs +2 -2
  163. data/sig/generated/lrama/lexer/token.rbs +1 -39
  164. data/sig/generated/lrama/lexer.rbs +54 -0
  165. data/sig/generated/lrama/logger.rbs +6 -0
  166. data/sig/generated/lrama/option_parser.rbs +52 -0
  167. data/sig/{lrama → generated/lrama}/options.rbs +27 -3
  168. data/sig/generated/lrama/reporter/conflicts.rbs +18 -0
  169. data/sig/generated/lrama/reporter/grammar.rbs +13 -0
  170. data/sig/generated/lrama/reporter/precedences.rbs +15 -0
  171. data/sig/generated/lrama/reporter/profile/call_stack.rbs +19 -0
  172. data/sig/generated/lrama/reporter/profile/memory.rbs +19 -0
  173. data/sig/generated/lrama/reporter/rules.rbs +13 -0
  174. data/sig/generated/lrama/reporter/states.rbs +69 -0
  175. data/sig/generated/lrama/reporter/terms.rbs +13 -0
  176. data/sig/generated/lrama/reporter.rbs +13 -0
  177. data/sig/generated/lrama/state/action/goto.rbs +28 -0
  178. data/sig/generated/lrama/state/action/reduce.rbs +49 -0
  179. data/sig/generated/lrama/state/action/shift.rbs +33 -0
  180. data/sig/generated/lrama/state/inadequacy_annotation.rbs +45 -0
  181. data/sig/generated/lrama/state/item.rbs +75 -0
  182. data/sig/generated/lrama/state/reduce_reduce_conflict.rbs +19 -0
  183. data/sig/generated/lrama/state/resolved_conflict.rbs +38 -0
  184. data/sig/generated/lrama/state/shift_reduce_conflict.rbs +19 -0
  185. data/sig/generated/lrama/state.rbs +231 -0
  186. data/sig/generated/lrama/states.rbs +215 -0
  187. data/sig/generated/lrama/tracer/actions.rbs +13 -0
  188. data/sig/generated/lrama/tracer/closure.rbs +13 -0
  189. data/sig/generated/lrama/tracer/duration.rbs +18 -0
  190. data/sig/generated/lrama/tracer/only_explicit_rules.rbs +13 -0
  191. data/sig/generated/lrama/tracer/rules.rbs +13 -0
  192. data/sig/generated/lrama/tracer/state.rbs +16 -0
  193. data/sig/generated/lrama/tracer.rbs +23 -0
  194. data/sig/generated/lrama/version.rbs +5 -0
  195. data/sig/generated/lrama/warnings/conflicts.rbs +13 -0
  196. data/sig/generated/lrama/warnings/implicit_empty.rbs +17 -0
  197. data/sig/generated/lrama/warnings/name_conflicts.rbs +31 -0
  198. data/sig/generated/lrama/warnings/redefined_rules.rbs +13 -0
  199. data/sig/generated/lrama/warnings/required.rbs +13 -0
  200. data/sig/generated/lrama/warnings/useless_precedence.rbs +13 -0
  201. data/sig/generated/lrama/warnings.rbs +11 -0
  202. data/sig/railroad_diagrams/railroad_diagrams.rbs +16 -0
  203. data/template/bison/_yacc.h +8 -0
  204. data/template/diagram/diagram.html +102 -0
  205. metadata +126 -66
  206. data/lib/lrama/counterexamples/production_path.rb +0 -19
  207. data/lib/lrama/counterexamples/start_path.rb +0 -23
  208. data/lib/lrama/counterexamples/transition_path.rb +0 -19
  209. data/lib/lrama/diagnostics.rb +0 -36
  210. data/lib/lrama/grammar/parameterizing_rule/rule.rb +0 -24
  211. data/lib/lrama/grammar/parameterizing_rule.rb +0 -5
  212. data/lib/lrama/grammar_validator.rb +0 -37
  213. data/lib/lrama/report/duration.rb +0 -27
  214. data/lib/lrama/report/profile.rb +0 -16
  215. data/lib/lrama/report.rb +0 -4
  216. data/lib/lrama/state/reduce.rb +0 -37
  217. data/lib/lrama/state/shift.rb +0 -15
  218. data/lib/lrama/states_reporter.rb +0 -362
  219. data/lib/lrama/trace_reporter.rb +0 -45
  220. data/sig/generated/lrama/trace_reporter.rbs +0 -25
  221. data/sig/lrama/counterexamples/derivation.rbs +0 -33
  222. data/sig/lrama/counterexamples/example.rbs +0 -45
  223. data/sig/lrama/counterexamples/path.rbs +0 -21
  224. data/sig/lrama/counterexamples/production_path.rbs +0 -11
  225. data/sig/lrama/counterexamples/start_path.rbs +0 -13
  226. data/sig/lrama/counterexamples/state_item.rbs +0 -10
  227. data/sig/lrama/counterexamples/transition_path.rbs +0 -11
  228. data/sig/lrama/counterexamples/triple.rbs +0 -20
  229. data/sig/lrama/counterexamples.rbs +0 -29
  230. data/sig/lrama/grammar/auxiliary.rbs +0 -10
  231. data/sig/lrama/grammar/code/destructor_code.rbs +0 -14
  232. data/sig/lrama/grammar/code/printer_code.rbs +0 -14
  233. data/sig/lrama/grammar/code/rule_action.rbs +0 -19
  234. data/sig/lrama/grammar/code.rbs +0 -24
  235. data/sig/lrama/grammar/destructor.rbs +0 -13
  236. data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +0 -24
  237. data/sig/lrama/grammar/parameterizing_rule/rhs.rbs +0 -14
  238. data/sig/lrama/grammar/parameterizing_rule/rule.rbs +0 -16
  239. data/sig/lrama/grammar/parameterizing_rule.rbs +0 -6
  240. data/sig/lrama/grammar/precedence.rbs +0 -13
  241. data/sig/lrama/grammar/printer.rbs +0 -13
  242. data/sig/lrama/grammar/reference.rbs +0 -22
  243. data/sig/lrama/grammar/rule.rbs +0 -45
  244. data/sig/lrama/grammar/rule_builder.rbs +0 -47
  245. data/sig/lrama/grammar/symbol.rbs +0 -38
  246. data/sig/lrama/grammar/symbols/resolver.rbs +0 -60
  247. data/sig/lrama/grammar/type.rbs +0 -11
  248. data/sig/lrama/grammar/union.rbs +0 -12
  249. data/sig/lrama/grammar.rbs +0 -108
  250. data/sig/lrama/report/duration.rbs +0 -11
  251. data/sig/lrama/report/profile.rbs +0 -7
  252. data/sig/lrama/state/reduce.rbs +0 -20
  253. data/sig/lrama/state/reduce_reduce_conflict.rbs +0 -13
  254. data/sig/lrama/state/resolved_conflict.rbs +0 -14
  255. data/sig/lrama/state/shift.rbs +0 -14
  256. data/sig/lrama/state/shift_reduce_conflict.rbs +0 -13
  257. data/sig/lrama/state.rbs +0 -79
  258. data/sig/lrama/states/item.rbs +0 -30
  259. data/sig/lrama/states.rbs +0 -101
  260. data/sig/lrama/warning.rbs +0 -16
@@ -0,0 +1,77 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Diagram
6
+ class << self
7
+ # @rbs (IO out, Grammar grammar, String template_name) -> void
8
+ def render(out:, grammar:, template_name: 'diagram/diagram.html')
9
+ return unless require_railroad_diagrams
10
+ new(out: out, grammar: grammar, template_name: template_name).render
11
+ end
12
+
13
+ # @rbs () -> bool
14
+ def require_railroad_diagrams
15
+ require "railroad_diagrams"
16
+ true
17
+ rescue LoadError
18
+ warn "railroad_diagrams is not installed. Please run `bundle install`."
19
+ false
20
+ end
21
+ end
22
+
23
+ # @rbs (IO out, Grammar grammar, String template_name) -> void
24
+ def initialize(out:, grammar:, template_name: 'diagram/diagram.html')
25
+ @grammar = grammar
26
+ @out = out
27
+ @template_name = template_name
28
+ end
29
+
30
+ # @rbs () -> void
31
+ def render
32
+ RailroadDiagrams::TextDiagram.set_formatting(RailroadDiagrams::TextDiagram::PARTS_UNICODE)
33
+ @out << ERB.render(template_file, output: self)
34
+ end
35
+
36
+ # @rbs () -> string
37
+ def default_style
38
+ RailroadDiagrams::Style::default_style
39
+ end
40
+
41
+ # @rbs () -> string
42
+ def diagrams
43
+ result = +''
44
+ @grammar.unique_rule_s_values.each do |s_value|
45
+ diagrams =
46
+ @grammar.select_rules_by_s_value(s_value).map { |r| r.to_diagrams }
47
+ add_diagram(
48
+ s_value,
49
+ RailroadDiagrams::Diagram.new(
50
+ RailroadDiagrams::Choice.new(0, *diagrams),
51
+ ),
52
+ result
53
+ )
54
+ end
55
+ result
56
+ end
57
+
58
+ private
59
+
60
+ # @rbs () -> string
61
+ def template_dir
62
+ File.expand_path('../../template', __dir__)
63
+ end
64
+
65
+ # @rbs () -> string
66
+ def template_file
67
+ File.join(template_dir, @template_name)
68
+ end
69
+
70
+ # @rbs (String name, RailroadDiagrams::Diagram diagram, String result) -> void
71
+ def add_diagram(name, diagram, result)
72
+ result << "\n<h2 class=\"diagram-header\">#{RailroadDiagrams.escape_html(name)}</h2>"
73
+ diagram.write_svg(result.method(:<<))
74
+ result << "\n"
75
+ end
76
+ end
77
+ end
data/lib/lrama/digraph.rb CHANGED
@@ -2,13 +2,34 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Lrama
5
- # Algorithm Digraph of https://dl.acm.org/doi/pdf/10.1145/69622.357187 (P. 625)
5
+ # Digraph Algorithm of https://dl.acm.org/doi/pdf/10.1145/69622.357187 (P. 625)
6
6
  #
7
- # @rbs generic X < Object -- Type of a member of `sets`
8
- # @rbs generic Y < _Or -- Type of sets assigned to a member of `sets`
7
+ # Digraph is an algorithm for graph data structure.
8
+ # The algorithm efficiently traverses SCC (Strongly Connected Component) of graph
9
+ # and merges nodes attributes within the same SCC.
10
+ #
11
+ # `compute_read_sets` and `compute_follow_sets` have the same structure.
12
+ # Graph of gotos and attributes of gotos are given then compute propagated attributes for each node.
13
+ #
14
+ # In the case of `compute_read_sets`:
15
+ #
16
+ # * Set of gotos is nodes of graph
17
+ # * `reads_relation` is edges of graph
18
+ # * `direct_read_sets` is nodes attributes
19
+ #
20
+ # In the case of `compute_follow_sets`:
21
+ #
22
+ # * Set of gotos is nodes of graph
23
+ # * `includes_relation` is edges of graph
24
+ # * `read_sets` is nodes attributes
25
+ #
26
+ #
27
+ # @rbs generic X < Object -- Type of a node
28
+ # @rbs generic Y < _Or -- Type of attribute sets assigned to a node which should support merge operation (#| method)
9
29
  class Digraph
10
- # TODO: rbs-inline 0.10.0 doesn't support instance variables.
30
+ # TODO: rbs-inline 0.11.0 doesn't support instance variables.
11
31
  # Move these type declarations above instance variable definitions, once it's supported.
32
+ # see: https://github.com/soutaro/rbs-inline/pull/149
12
33
  #
13
34
  # @rbs!
14
35
  # interface _Or
@@ -21,9 +42,9 @@ module Lrama
21
42
  # @h: Hash[X, (Integer|Float)?]
22
43
  # @result: Hash[X, Y]
23
44
 
24
- # @rbs sets: Array[X]
25
- # @rbs relation: Hash[X, Array[X]]
26
- # @rbs base_function: Hash[X, Y]
45
+ # @rbs sets: Array[X] -- Nodes of graph
46
+ # @rbs relation: Hash[X, Array[X]] -- Edges of graph
47
+ # @rbs base_function: Hash[X, Y] -- Attributes of nodes
27
48
  # @rbs return: void
28
49
  def initialize(sets, relation, base_function)
29
50
 
data/lib/lrama/erb.rb ADDED
@@ -0,0 +1,29 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ require "erb"
5
+
6
+ module Lrama
7
+ class ERB
8
+ # @rbs (String file, **untyped kwargs) -> String
9
+ def self.render(file, **kwargs)
10
+ new(file).render(**kwargs)
11
+ end
12
+
13
+ # @rbs (String file) -> void
14
+ def initialize(file)
15
+ input = File.read(file)
16
+ if ::ERB.instance_method(:initialize).parameters.last.first == :key
17
+ @erb = ::ERB.new(input, trim_mode: '-')
18
+ else
19
+ @erb = ::ERB.new(input, nil, '-') # steep:ignore UnexpectedPositionalArgument
20
+ end
21
+ @erb.filename = file
22
+ end
23
+
24
+ # @rbs (**untyped kwargs) -> String
25
+ def render(**kwargs)
26
+ @erb.result_with_hash(kwargs)
27
+ end
28
+ end
29
+ end
@@ -1,9 +1,14 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class Grammar
5
6
  # Grammar file information not used by States but by Output
6
- class Auxiliary < Struct.new(:prologue_first_lineno, :prologue, :epilogue_first_lineno, :epilogue, keyword_init: true)
7
+ class Auxiliary
8
+ attr_accessor :prologue_first_lineno #: Integer?
9
+ attr_accessor :prologue #: String?
10
+ attr_accessor :epilogue_first_lineno #: Integer?
11
+ attr_accessor :epilogue #: String?
7
12
  end
8
13
  end
9
14
  end
@@ -4,51 +4,63 @@
4
4
  module Lrama
5
5
  class Grammar
6
6
  class Binding
7
- # @rbs @actual_args: Array[Lexer::Token]
8
- # @rbs @param_to_arg: Hash[String, Lexer::Token]
7
+ # @rbs @actual_args: Array[Lexer::Token::Base]
8
+ # @rbs @param_to_arg: Hash[String, Lexer::Token::Base]
9
9
 
10
- # @rbs (Array[Lexer::Token] params, Array[Lexer::Token] actual_args) -> void
10
+ # @rbs (Array[Lexer::Token::Base] params, Array[Lexer::Token::Base] actual_args) -> void
11
11
  def initialize(params, actual_args)
12
12
  @actual_args = actual_args
13
- @param_to_arg = map_params_to_args(params, @actual_args)
13
+ @param_to_arg = build_param_to_arg(params, @actual_args)
14
14
  end
15
15
 
16
- # @rbs (Lexer::Token sym) -> Lexer::Token
16
+ # @rbs (Lexer::Token::Base sym) -> Lexer::Token::Base
17
17
  def resolve_symbol(sym)
18
- if sym.is_a?(Lexer::Token::InstantiateRule)
19
- Lrama::Lexer::Token::InstantiateRule.new(
20
- s_value: sym.s_value, location: sym.location, args: resolved_args(sym), lhs_tag: sym.lhs_tag
21
- )
22
- else
23
- param_to_arg(sym)
24
- end
18
+ return create_instantiate_rule(sym) if sym.is_a?(Lexer::Token::InstantiateRule)
19
+ find_arg_for_param(sym)
25
20
  end
26
21
 
27
22
  # @rbs (Lexer::Token::InstantiateRule token) -> String
28
23
  def concatenated_args_str(token)
29
- "#{token.rule_name}_#{token_to_args_s_values(token).join('_')}"
24
+ "#{token.rule_name}_#{format_args(token)}"
30
25
  end
31
26
 
32
27
  private
33
28
 
34
- # @rbs (Array[Lexer::Token] params, Array[Lexer::Token] actual_args) -> Hash[String, Lexer::Token]
35
- def map_params_to_args(params, actual_args)
36
- params.zip(actual_args).map do |param, arg|
37
- [param.s_value, arg]
38
- end.to_h
29
+ # @rbs (Lexer::Token::InstantiateRule sym) -> Lexer::Token::InstantiateRule
30
+ def create_instantiate_rule(sym)
31
+ Lrama::Lexer::Token::InstantiateRule.new(
32
+ s_value: sym.s_value,
33
+ location: sym.location,
34
+ args: resolve_args(sym.args),
35
+ lhs_tag: sym.lhs_tag
36
+ )
39
37
  end
40
38
 
41
- # @rbs (Lexer::Token::InstantiateRule sym) -> Array[Lexer::Token]
42
- def resolved_args(sym)
43
- sym.args.map { |arg| resolve_symbol(arg) }
39
+ # @rbs (Array[Lexer::Token::Base]) -> Array[Lexer::Token::Base]
40
+ def resolve_args(args)
41
+ args.map { |arg| resolve_symbol(arg) }
44
42
  end
45
43
 
46
- # @rbs (Lexer::Token sym) -> Lexer::Token
47
- def param_to_arg(sym)
48
- if (arg = @param_to_arg[sym.s_value].dup)
44
+ # @rbs (Lexer::Token::Base sym) -> Lexer::Token::Base
45
+ def find_arg_for_param(sym)
46
+ if (arg = @param_to_arg[sym.s_value]&.dup)
49
47
  arg.alias_name = sym.alias_name
48
+ arg
49
+ else
50
+ sym
50
51
  end
51
- arg || sym
52
+ end
53
+
54
+ # @rbs (Array[Lexer::Token::Base] params, Array[Lexer::Token::Base] actual_args) -> Hash[String, Lexer::Token::Base?]
55
+ def build_param_to_arg(params, actual_args)
56
+ params.zip(actual_args).map do |param, arg|
57
+ [param.s_value, arg]
58
+ end.to_h
59
+ end
60
+
61
+ # @rbs (Lexer::Token::InstantiateRule token) -> String
62
+ def format_args(token)
63
+ token_to_args_s_values(token).join('_')
52
64
  end
53
65
 
54
66
  # @rbs (Lexer::Token::InstantiateRule token) -> Array[String]
@@ -1,9 +1,18 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class Grammar
5
6
  class Code
6
7
  class DestructorCode < Code
8
+ # TODO: rbs-inline 0.11.0 doesn't support instance variables.
9
+ # Move these type declarations above instance variable definitions, once it's supported.
10
+ # see: https://github.com/soutaro/rbs-inline/pull/149
11
+ #
12
+ # @rbs!
13
+ # @tag: Lexer::Token::Tag
14
+
15
+ # @rbs (type: ::Symbol, token_code: Lexer::Token::UserCode, tag: Lexer::Token::Tag) -> void
7
16
  def initialize(type:, token_code:, tag:)
8
17
  super(type: type, token_code: token_code)
9
18
  @tag = tag
@@ -17,6 +26,8 @@ module Lrama
17
26
  # * ($1) error
18
27
  # * (@1) error
19
28
  # * ($:1) error
29
+ #
30
+ # @rbs (Reference ref) -> (String | bot)
20
31
  def reference_to_c(ref)
21
32
  case
22
33
  when ref.type == :dollar && ref.name == "$" # $$
@@ -1,3 +1,4 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
@@ -12,6 +13,8 @@ module Lrama
12
13
  # * ($1) error
13
14
  # * (@1) error
14
15
  # * ($:1) error
16
+ #
17
+ # @rbs (Reference ref) -> (String | bot)
15
18
  def reference_to_c(ref)
16
19
  case
17
20
  when ref.type == :dollar && ref.name == "$" # $$
@@ -1,3 +1,4 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
@@ -12,6 +13,8 @@ module Lrama
12
13
  # * ($1) error
13
14
  # * (@1) error
14
15
  # * ($:1) error
16
+ #
17
+ # @rbs (Reference ref) -> bot
15
18
  def reference_to_c(ref)
16
19
  case
17
20
  when ref.type == :dollar # $$, $n
@@ -1,9 +1,18 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class Grammar
5
6
  class Code
6
7
  class PrinterCode < Code
8
+ # TODO: rbs-inline 0.11.0 doesn't support instance variables.
9
+ # Move these type declarations above instance variable definitions, once it's supported.
10
+ # see: https://github.com/soutaro/rbs-inline/pull/149
11
+ #
12
+ # @rbs!
13
+ # @tag: Lexer::Token::Tag
14
+
15
+ # @rbs (type: ::Symbol, token_code: Lexer::Token::UserCode, tag: Lexer::Token::Tag) -> void
7
16
  def initialize(type:, token_code:, tag:)
8
17
  super(type: type, token_code: token_code)
9
18
  @tag = tag
@@ -17,6 +26,8 @@ module Lrama
17
26
  # * ($1) error
18
27
  # * (@1) error
19
28
  # * ($:1) error
29
+ #
30
+ # @rbs (Reference ref) -> (String | bot)
20
31
  def reference_to_c(ref)
21
32
  case
22
33
  when ref.type == :dollar && ref.name == "$" # $$
@@ -1,9 +1,18 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class Grammar
5
6
  class Code
6
7
  class RuleAction < Code
8
+ # TODO: rbs-inline 0.11.0 doesn't support instance variables.
9
+ # Move these type declarations above instance variable definitions, once it's supported.
10
+ # see: https://github.com/soutaro/rbs-inline/pull/149
11
+ #
12
+ # @rbs!
13
+ # @rule: Rule
14
+
15
+ # @rbs (type: ::Symbol, token_code: Lexer::Token::UserCode, rule: Rule) -> void
7
16
  def initialize(type:, token_code:, rule:)
8
17
  super(type: type, token_code: token_code)
9
18
  @rule = rule
@@ -38,6 +47,8 @@ module Lrama
38
47
  # "Position in grammar" $1
39
48
  # "Index for yyvsp" 0
40
49
  # "$:n" $:1
50
+ #
51
+ # @rbs (Reference ref) -> String
41
52
  def reference_to_c(ref)
42
53
  case
43
54
  when ref.type == :dollar && ref.name == "$" # $$
@@ -66,6 +77,7 @@ module Lrama
66
77
  end
67
78
  end
68
79
 
80
+ # @rbs () -> Integer
69
81
  def position_in_rhs
70
82
  # If rule is not derived rule, User Code is only action at
71
83
  # the end of rule RHS. In such case, the action is located on
@@ -74,15 +86,20 @@ module Lrama
74
86
  end
75
87
 
76
88
  # If this is midrule action, RHS is an RHS of the original rule.
89
+ #
90
+ # @rbs () -> Array[Grammar::Symbol]
77
91
  def rhs
78
92
  (@rule.original_rule || @rule).rhs
79
93
  end
80
94
 
81
95
  # Unlike `rhs`, LHS is always an LHS of the rule.
96
+ #
97
+ # @rbs () -> Grammar::Symbol
82
98
  def lhs
83
99
  @rule.lhs
84
100
  end
85
101
 
102
+ # @rbs (Reference ref) -> bot
86
103
  def raise_tag_not_found_error(ref)
87
104
  raise "Tag is not specified for '$#{ref.value}' in '#{@rule.display_name}'"
88
105
  end
@@ -1,3 +1,4 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require "forwardable"
@@ -10,17 +11,28 @@ require_relative "code/rule_action"
10
11
  module Lrama
11
12
  class Grammar
12
13
  class Code
14
+ # @rbs!
15
+ #
16
+ # # delegated
17
+ # def s_value: -> String
18
+ # def line: -> Integer
19
+ # def column: -> Integer
20
+ # def references: -> Array[Lrama::Grammar::Reference]
21
+
13
22
  extend Forwardable
14
23
 
15
24
  def_delegators "token_code", :s_value, :line, :column, :references
16
25
 
17
- attr_reader :type, :token_code
26
+ attr_reader :type #: ::Symbol
27
+ attr_reader :token_code #: Lexer::Token::UserCode
18
28
 
29
+ # @rbs (type: ::Symbol, token_code: Lexer::Token::UserCode) -> void
19
30
  def initialize(type:, token_code:)
20
31
  @type = type
21
32
  @token_code = token_code
22
33
  end
23
34
 
35
+ # @rbs (Code other) -> bool
24
36
  def ==(other)
25
37
  self.class == other.class &&
26
38
  self.type == other.type &&
@@ -28,6 +40,8 @@ module Lrama
28
40
  end
29
41
 
30
42
  # $$, $n, @$, @n are translated to C code
43
+ #
44
+ # @rbs () -> String
31
45
  def translated_code
32
46
  t_code = s_value.dup
33
47
 
@@ -45,6 +59,7 @@ module Lrama
45
59
 
46
60
  private
47
61
 
62
+ # @rbs (Lrama::Grammar::Reference ref) -> bot
48
63
  def reference_to_c(ref)
49
64
  raise NotImplementedError.new("#reference_to_c is not implemented")
50
65
  end
@@ -1,12 +1,22 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class Grammar
5
6
  class Counter
7
+ # TODO: rbs-inline 0.11.0 doesn't support instance variables.
8
+ # Move these type declarations above instance variable definitions, once it's supported.
9
+ # see: https://github.com/soutaro/rbs-inline/pull/149
10
+ #
11
+ # @rbs!
12
+ # @number: Integer
13
+
14
+ # @rbs (Integer number) -> void
6
15
  def initialize(number)
7
16
  @number = number
8
17
  end
9
18
 
19
+ # @rbs () -> Integer
10
20
  def increment
11
21
  n = @number
12
22
  @number += 1
@@ -1,8 +1,21 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class Grammar
5
- class Destructor < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true)
6
+ class Destructor
7
+ attr_reader :ident_or_tags #: Array[Lexer::Token::Ident|Lexer::Token::Tag]
8
+ attr_reader :token_code #: Lexer::Token::UserCode
9
+ attr_reader :lineno #: Integer
10
+
11
+ # @rbs (ident_or_tags: Array[Lexer::Token::Ident|Lexer::Token::Tag], token_code: Lexer::Token::UserCode, lineno: Integer) -> void
12
+ def initialize(ident_or_tags:, token_code:, lineno:)
13
+ @ident_or_tags = ident_or_tags
14
+ @token_code = token_code
15
+ @lineno = lineno
16
+ end
17
+
18
+ # @rbs (Lexer::Token::Tag tag) -> String
6
19
  def translated_code(tag)
7
20
  Code::DestructorCode.new(type: :destructor, token_code: token_code, tag: tag).translated_code
8
21
  end
@@ -1,8 +1,21 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class Grammar
5
- class ErrorToken < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true)
6
+ class ErrorToken
7
+ attr_reader :ident_or_tags #: Array[Lexer::Token::Ident | Lexer::Token::Tag]
8
+ attr_reader :token_code #: Lexer::Token::UserCode
9
+ attr_reader :lineno #: Integer
10
+
11
+ # @rbs (ident_or_tags: Array[Lexer::Token::Ident|Lexer::Token::Tag], token_code: Lexer::Token::UserCode, lineno: Integer) -> void
12
+ def initialize(ident_or_tags:, token_code:, lineno:)
13
+ @ident_or_tags = ident_or_tags
14
+ @token_code = token_code
15
+ @lineno = lineno
16
+ end
17
+
18
+ # @rbs (Lexer::Token::Tag tag) -> String
6
19
  def translated_code(tag)
7
20
  Code::PrinterCode.new(type: :error_token, token_code: token_code, tag: tag).translated_code
8
21
  end
@@ -0,0 +1,80 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Grammar
6
+ class Inline
7
+ class Resolver
8
+ # @rbs (Lrama::Grammar::RuleBuilder rule_builder) -> void
9
+ def initialize(rule_builder)
10
+ @rule_builder = rule_builder
11
+ end
12
+
13
+ # @rbs () -> Array[Lrama::Grammar::RuleBuilder]
14
+ def resolve
15
+ resolved_builders = [] #: Array[Lrama::Grammar::RuleBuilder]
16
+ @rule_builder.rhs.each_with_index do |token, i|
17
+ if (rule = @rule_builder.parameterized_resolver.find_inline(token))
18
+ rule.rhs.each do |rhs|
19
+ builder = build_rule(rhs, token, i, rule)
20
+ resolved_builders << builder
21
+ end
22
+ break
23
+ end
24
+ end
25
+ resolved_builders
26
+ end
27
+
28
+ private
29
+
30
+ # @rbs (Lrama::Grammar::Parameterized::Rhs rhs, Lrama::Lexer::Token token, Integer index, Lrama::Grammar::Parameterized::Rule rule) -> Lrama::Grammar::RuleBuilder
31
+ def build_rule(rhs, token, index, rule)
32
+ builder = RuleBuilder.new(
33
+ @rule_builder.rule_counter,
34
+ @rule_builder.midrule_action_counter,
35
+ @rule_builder.parameterized_resolver,
36
+ lhs_tag: @rule_builder.lhs_tag
37
+ )
38
+ resolve_rhs(builder, rhs, index, token, rule)
39
+ builder.lhs = @rule_builder.lhs
40
+ builder.line = @rule_builder.line
41
+ builder.precedence_sym = @rule_builder.precedence_sym
42
+ builder.user_code = replace_user_code(rhs, index)
43
+ builder
44
+ end
45
+
46
+ # @rbs (Lrama::Grammar::RuleBuilder builder, Lrama::Grammar::Parameterized::Rhs rhs, Integer index, Lrama::Lexer::Token token, Lrama::Grammar::Parameterized::Rule rule) -> void
47
+ def resolve_rhs(builder, rhs, index, token, rule)
48
+ @rule_builder.rhs.each_with_index do |tok, i|
49
+ if i == index
50
+ rhs.symbols.each do |sym|
51
+ if token.is_a?(Lexer::Token::InstantiateRule)
52
+ bindings = Binding.new(rule.parameters, token.args)
53
+ builder.add_rhs(bindings.resolve_symbol(sym))
54
+ else
55
+ builder.add_rhs(sym)
56
+ end
57
+ end
58
+ else
59
+ builder.add_rhs(tok)
60
+ end
61
+ end
62
+ end
63
+
64
+ # @rbs (Lrama::Grammar::Parameterized::Rhs rhs, Integer index) -> Lrama::Lexer::Token::UserCode
65
+ def replace_user_code(rhs, index)
66
+ user_code = @rule_builder.user_code
67
+ return user_code if rhs.user_code.nil? || user_code.nil?
68
+
69
+ code = user_code.s_value.gsub(/\$#{index + 1}/, rhs.user_code.s_value)
70
+ user_code.references.each do |ref|
71
+ next if ref.index.nil? || ref.index <= index # nil は $$ の場合
72
+ code = code.gsub(/\$#{ref.index}/, "$#{ref.index + (rhs.symbols.count - 1)}")
73
+ code = code.gsub(/@#{ref.index}/, "@#{ref.index + (rhs.symbols.count - 1)}")
74
+ end
75
+ Lrama::Lexer::Token::UserCode.new(s_value: code, location: user_code.location)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'inline/resolver'