lrama 0.5.5 → 0.5.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d79363afacc07dac12ab5c1a861123e099626591104079c962e02f3df74a24f3
4
- data.tar.gz: d8ddf78087e27510ab9da808301505a10ec0151ef55d1df3a59cc80ffde81b53
3
+ metadata.gz: e54c51af6f1d3632293cbd7f68762bf7cff63758d3ce633113805a629b92072b
4
+ data.tar.gz: 5d053543f0e00c9fb20c40f5ca8236e499292f35fa8cf6fb8e85cac33b930814
5
5
  SHA512:
6
- metadata.gz: acc15bb56862ea03c6b195253ba881786acf498719f930b8a8435a60f86b44d4383778cc215e7497971833c4be596a9c41a6c5134f77703a9f5cd0a6b5714ad2
7
- data.tar.gz: d45b2ec3a22ce2e29beb6a5ec0f4d7b142cebca3b6ca76786fa19b841c257d3841d5a7a43d7d564459b8f9c5b05faa7229bd9b2e2178592ec3988b64f77b535c
6
+ metadata.gz: 87bafe9650720b154855e055e53d700cfba67d31489dbc855c716bc150dff35e92d0fc974c14cb81a07ae68febbd69118c1720a628e2819fec1ebfa304acad55
7
+ data.tar.gz: 19b0c51748cef053d205bbf13e8ff238bda2fdbb101d304f6bfe9633b4f88fe2c4a1f452627528fd2c9e78bc97955a2a5f7543212aa581c3a9f7ae96dd3d70f8
@@ -15,7 +15,7 @@ jobs:
15
15
  matrix:
16
16
  ruby: ['head', '3.2', '3.1', '3.0', '2.7', '2.6', '2.5']
17
17
  steps:
18
- - uses: actions/checkout@v3
18
+ - uses: actions/checkout@v4
19
19
  - uses: ruby/setup-ruby@v1
20
20
  with:
21
21
  ruby-version: ${{ matrix.ruby }}
@@ -29,7 +29,7 @@ jobs:
29
29
  matrix:
30
30
  ruby: ['head']
31
31
  steps:
32
- - uses: actions/checkout@v3
32
+ - uses: actions/checkout@v4
33
33
  - uses: ruby/setup-ruby@v1
34
34
  with:
35
35
  ruby-version: ${{ matrix.ruby }}
@@ -39,7 +39,7 @@ jobs:
39
39
  check-misc:
40
40
  runs-on: ubuntu-20.04
41
41
  steps:
42
- - uses: actions/checkout@v3
42
+ - uses: actions/checkout@v4
43
43
  # Copy from https://github.com/ruby/ruby/blob/089227e94823542acfdafa68541d330eee42ffea/.github/workflows/check_misc.yml#L27
44
44
  - name: Check for trailing spaces
45
45
  run: |
@@ -52,7 +52,7 @@ jobs:
52
52
  matrix:
53
53
  ruby: ['head']
54
54
  steps:
55
- - uses: actions/checkout@v3
55
+ - uses: actions/checkout@v4
56
56
  - uses: ruby/setup-ruby@v1
57
57
  with:
58
58
  ruby-version: ${{ matrix.ruby }}
@@ -71,7 +71,7 @@ jobs:
71
71
  run:
72
72
  working-directory: ../ruby/build
73
73
  steps:
74
- - uses: actions/checkout@v3
74
+ - uses: actions/checkout@v4
75
75
  - uses: ruby/setup-ruby@v1
76
76
  with:
77
77
  ruby-version: ${{ matrix.baseruby }}
data/exe/lrama CHANGED
@@ -3,4 +3,4 @@
3
3
  $LOAD_PATH << File.join(__dir__, "../lib")
4
4
  require "lrama"
5
5
 
6
- Lrama::Command.new(ARGV.dup).run
6
+ Lrama::Command.new.run(ARGV.dup)
data/lib/lrama/command.rb CHANGED
@@ -1,53 +1,34 @@
1
- require 'optparse'
2
-
3
1
  module Lrama
4
2
  class Command
5
- def initialize(argv)
6
- @argv = argv
7
-
8
- @skeleton = "bison/yacc.c"
9
- @header = false
10
- @header_file = nil
11
- @report = []
12
- @report_file = nil
13
- @outfile = "y.tab.c"
14
- @trace = []
15
- @error_recovery = false
16
- @grammar_file = nil
17
- @report_file = nil
18
- @trace_opts = nil
19
- @report_opts = nil
20
- end
3
+ def run(argv)
4
+ options = OptionParser.new.parse(argv)
21
5
 
22
- def run
23
- parse_option
24
-
25
- Report::Duration.enable if @trace_opts[:time]
6
+ Report::Duration.enable if options.trace_opts[:time]
26
7
 
27
8
  warning = Lrama::Warning.new
28
- grammar = Lrama::Parser.new(@y.read).parse
29
- @y.close if @y != STDIN
30
- states = Lrama::States.new(grammar, warning, trace_state: (@trace_opts[:automaton] || @trace_opts[:closure]))
9
+ grammar = Lrama::Parser.new(options.y.read).parse
10
+ options.y.close if options.y != STDIN
11
+ states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure]))
31
12
  states.compute
32
13
  context = Lrama::Context.new(states)
33
14
 
34
- if @report_file
15
+ if options.report_file
35
16
  reporter = Lrama::StatesReporter.new(states)
36
- File.open(@report_file, "w+") do |f|
37
- reporter.report(f, **@report_opts)
17
+ File.open(options.report_file, "w+") do |f|
18
+ reporter.report(f, **options.report_opts)
38
19
  end
39
20
  end
40
21
 
41
- File.open(@outfile, "w+") do |f|
22
+ File.open(options.outfile, "w+") do |f|
42
23
  Lrama::Output.new(
43
24
  out: f,
44
- output_file_path: @outfile,
45
- template_name: @skeleton,
46
- grammar_file_path: @grammar_file,
47
- header_file_path: @header_file,
25
+ output_file_path: options.outfile,
26
+ template_name: options.skeleton,
27
+ grammar_file_path: options.grammar_file,
28
+ header_file_path: options.header_file,
48
29
  context: context,
49
30
  grammar: grammar,
50
- error_recovery: @error_recovery,
31
+ error_recovery: options.error_recovery,
51
32
  ).render
52
33
  end
53
34
 
@@ -55,108 +36,5 @@ module Lrama
55
36
  exit 1
56
37
  end
57
38
  end
58
-
59
- private
60
-
61
- def validate_report(report)
62
- bison_list = %w[states itemsets lookaheads solved counterexamples cex all none]
63
- others = %w[verbose]
64
- list = bison_list + others
65
- not_supported = %w[cex none]
66
- h = { grammar: true }
67
-
68
- report.each do |r|
69
- if list.include?(r) && !not_supported.include?(r)
70
- h[r.to_sym] = true
71
- else
72
- raise "Invalid report option \"#{r}\"."
73
- end
74
- end
75
-
76
- if h[:all]
77
- (bison_list - not_supported).each do |r|
78
- h[r.to_sym] = true
79
- end
80
-
81
- h.delete(:all)
82
- end
83
-
84
- return h
85
- end
86
-
87
- def validate_trace(trace)
88
- list = %w[
89
- none locations scan parse automaton bitsets
90
- closure grammar resource sets muscles tools
91
- m4-early m4 skeleton time ielr cex all
92
- ]
93
- h = {}
94
-
95
- trace.each do |t|
96
- if list.include?(t)
97
- h[t.to_sym] = true
98
- else
99
- raise "Invalid trace option \"#{t}\"."
100
- end
101
- end
102
-
103
- return h
104
- end
105
-
106
- def parse_option
107
- opt = OptionParser.new
108
-
109
- # opt.on('-h') {|v| p v }
110
- opt.on('-V', '--version') {|v| puts "lrama #{Lrama::VERSION}"; exit 0 }
111
-
112
- # Tuning the Parser
113
- opt.on('-S', '--skeleton=FILE') {|v| @skeleton = v }
114
- opt.on('-t') { } # Do nothing
115
-
116
- # Output Files:
117
- opt.on('-h', '--header=[FILE]') {|v| @header = true; @header_file = v }
118
- opt.on('-d') { @header = true }
119
- opt.on('-r', '--report=THINGS', Array) {|v| @report = v }
120
- opt.on('--report-file=FILE') {|v| @report_file = v }
121
- opt.on('-v') { } # Do nothing
122
- opt.on('-o', '--output=FILE') {|v| @outfile = v }
123
-
124
- # Hidden
125
- opt.on('--trace=THINGS', Array) {|v| @trace = v }
126
-
127
- # Error Recovery
128
- opt.on('-e') {|v| @error_recovery = true }
129
-
130
- opt.parse!(@argv)
131
-
132
- @trace_opts = validate_trace(@trace)
133
- @report_opts = validate_report(@report)
134
-
135
- @grammar_file = @argv.shift
136
-
137
- if !@grammar_file
138
- abort "File should be specified\n"
139
- end
140
-
141
- if @grammar_file == '-'
142
- @grammar_file = @argv.shift or abort "File name for STDIN should be specified\n"
143
- @y = STDIN
144
- else
145
- @y = File.open(@grammar_file, 'r')
146
- end
147
-
148
- if !@report.empty? && @report_file.nil? && @grammar_file
149
- @report_file = File.dirname(@grammar_file) + "/" + File.basename(@grammar_file, ".*") + ".output"
150
- end
151
-
152
- if !@header_file && @header
153
- case
154
- when @outfile
155
- @header_file = File.dirname(@outfile) + "/" + File.basename(@outfile, ".*") + ".h"
156
- when @grammar_file
157
- @header_file = File.dirname(@grammar_file) + "/" + File.basename(@grammar_file, ".*") + ".h"
158
- end
159
- end
160
- end
161
39
  end
162
40
  end
@@ -28,7 +28,13 @@ module Lrama
28
28
  if lhs.referred_by?(ref_name)
29
29
  '$'
30
30
  else
31
- rhs.find_index {|token| token.referred_by?(ref_name) } + 1
31
+ index = rhs.find_index {|token| token.referred_by?(ref_name) }
32
+
33
+ if index
34
+ index + 1
35
+ else
36
+ raise "'#{ref_name}' is invalid name."
37
+ end
32
38
  end
33
39
  [ref[0], value, ref[2], ref[3], ref[4]]
34
40
  else
data/lib/lrama/lexer.rb CHANGED
@@ -213,19 +213,33 @@ module Lrama
213
213
  string, line = lex_string(ss, "'", line, lines)
214
214
  str << string
215
215
  next
216
+
217
+ # $ references
218
+ # It need to wrap an identifier with brackets to use ".-" for identifiers
216
219
  when ss.scan(/\$(<[a-zA-Z0-9_]+>)?\$/) # $$, $<long>$
217
220
  tag = ss[1] ? create_token(Token::Tag, ss[1], line, str.length) : nil
218
221
  references << [:dollar, "$", tag, str.length, str.length + ss[0].length - 1]
219
222
  when ss.scan(/\$(<[a-zA-Z0-9_]+>)?(\d+)/) # $1, $2, $<long>1
220
223
  tag = ss[1] ? create_token(Token::Tag, ss[1], line, str.length) : nil
221
224
  references << [:dollar, Integer(ss[2]), tag, str.length, str.length + ss[0].length - 1]
222
- when ss.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_.][-a-zA-Z0-9_.]*)/) # $foo, $expr, $<long>program
225
+ when ss.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_][a-zA-Z0-9_]*)/) # $foo, $expr, $<long>program (named reference without brackets)
226
+ tag = ss[1] ? create_token(Token::Tag, ss[1], line, str.length) : nil
227
+ references << [:dollar, ss[2], tag, str.length, str.length + ss[0].length - 1]
228
+ when ss.scan(/\$(<[a-zA-Z0-9_]+>)?\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # $expr.right, $expr-right, $<long>program (named reference with brackets)
223
229
  tag = ss[1] ? create_token(Token::Tag, ss[1], line, str.length) : nil
224
230
  references << [:dollar, ss[2], tag, str.length, str.length + ss[0].length - 1]
231
+
232
+ # @ references
233
+ # It need to wrap an identifier with brackets to use ".-" for identifiers
225
234
  when ss.scan(/@\$/) # @$
226
235
  references << [:at, "$", nil, str.length, str.length + ss[0].length - 1]
227
236
  when ss.scan(/@(\d+)/) # @1
228
237
  references << [:at, Integer(ss[1]), nil, str.length, str.length + ss[0].length - 1]
238
+ when ss.scan(/@([a-zA-Z][a-zA-Z0-9_]*)/) # @foo, @expr (named reference without brackets)
239
+ references << [:at, ss[1], nil, str.length, str.length + ss[0].length - 1]
240
+ when ss.scan(/@\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # @expr.right, @expr-right (named reference with brackets)
241
+ references << [:at, ss[1], nil, str.length, str.length + ss[0].length - 1]
242
+
229
243
  when ss.scan(/{/)
230
244
  brace_count += 1
231
245
  when ss.scan(/}/)
@@ -0,0 +1,124 @@
1
+ require 'optparse'
2
+
3
+ module Lrama
4
+ # Handle option parsing for the command line interface.
5
+ class OptionParser
6
+ def initialize
7
+ @options = Options.new
8
+ @trace = []
9
+ @report = []
10
+ end
11
+
12
+ def parse(argv)
13
+ parse_by_option_parser(argv)
14
+
15
+ @options.trace_opts = validate_trace(@trace)
16
+ @options.report_opts = validate_report(@report)
17
+ @options.grammar_file = argv.shift
18
+
19
+ if !@options.grammar_file
20
+ abort "File should be specified\n"
21
+ end
22
+
23
+ if @options.grammar_file == '-'
24
+ @options.grammar_file = argv.shift or abort "File name for STDIN should be specified\n"
25
+ else
26
+ @options.y = File.open(@options.grammar_file, 'r')
27
+ end
28
+
29
+ if !@report.empty? && @options.report_file.nil? && @options.grammar_file
30
+ @options.report_file = File.dirname(@options.grammar_file) + "/" + File.basename(@options.grammar_file, ".*") + ".output"
31
+ end
32
+
33
+ if !@options.header_file && @options.header
34
+ case
35
+ when @options.outfile
36
+ @options.header_file = File.dirname(@options.outfile) + "/" + File.basename(@options.outfile, ".*") + ".h"
37
+ when @options.grammar_file
38
+ @options.header_file = File.dirname(@options.grammar_file) + "/" + File.basename(@options.grammar_file, ".*") + ".h"
39
+ end
40
+ end
41
+
42
+ @options
43
+ end
44
+
45
+ private
46
+
47
+ def parse_by_option_parser(argv)
48
+ ::OptionParser.new do |o|
49
+ o.banner = <<~BANNER
50
+ Lrama is LALR (1) parser generator written by Ruby.
51
+
52
+ Usage: lrama [options] FILE
53
+ BANNER
54
+ o.separator ''
55
+ o.separator 'Tuning the Parser:'
56
+ o.on('-S', '--skeleton=FILE', 'specify the skeleton to use') {|v| @options.skeleton = v }
57
+ o.on('-t', 'reserved, do nothing') { }
58
+ o.separator ''
59
+ o.separator 'Output:'
60
+ o.on('-h', '--header=[FILE]', 'also produce a header file named FILE') {|v| @options.header = true; @options.header_file = v }
61
+ o.on('-d', 'also produce a header file') { @options.header = true }
62
+ o.on('-r', '--report=THINGS', Array, 'also produce details on the automaton') {|v| @report = v }
63
+ o.on('--report-file=FILE', 'also produce details on the automaton output to a file named FILE') {|v| @options.report_file = v }
64
+ o.on('-o', '--output=FILE', 'leave output to FILE') {|v| @options.outfile = v }
65
+ o.on('--trace=THINGS', Array, 'also output trace logs at runtime') {|v| @trace = v }
66
+ o.on('-v', 'reserved, do nothing') { }
67
+ o.separator ''
68
+ o.separator 'Error Recovery:'
69
+ o.on('-e', 'enable error recovery') {|v| @options.error_recovery = true }
70
+ o.separator ''
71
+ o.separator 'Other options:'
72
+ o.on('-V', '--version', "output version information and exit") {|v| puts "lrama #{Lrama::VERSION}"; exit 0 }
73
+ o.on('--help', "display this help and exit") {|v| puts o; exit 0 }
74
+ o.separator ''
75
+ o.parse!(argv)
76
+ end
77
+ end
78
+
79
+ def validate_report(report)
80
+ bison_list = %w[states itemsets lookaheads solved counterexamples cex all none]
81
+ others = %w[verbose]
82
+ list = bison_list + others
83
+ not_supported = %w[cex none]
84
+ h = { grammar: true }
85
+
86
+ report.each do |r|
87
+ if list.include?(r) && !not_supported.include?(r)
88
+ h[r.to_sym] = true
89
+ else
90
+ raise "Invalid report option \"#{r}\"."
91
+ end
92
+ end
93
+
94
+ if h[:all]
95
+ (bison_list - not_supported).each do |r|
96
+ h[r.to_sym] = true
97
+ end
98
+
99
+ h.delete(:all)
100
+ end
101
+
102
+ return h
103
+ end
104
+
105
+ def validate_trace(trace)
106
+ list = %w[
107
+ none locations scan parse automaton bitsets
108
+ closure grammar resource sets muscles tools
109
+ m4-early m4 skeleton time ielr cex all
110
+ ]
111
+ h = {}
112
+
113
+ trace.each do |t|
114
+ if list.include?(t)
115
+ h[t.to_sym] = true
116
+ else
117
+ raise "Invalid trace option \"#{t}\"."
118
+ end
119
+ end
120
+
121
+ return h
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,23 @@
1
+ module Lrama
2
+ # Command line options.
3
+ class Options
4
+ attr_accessor :skeleton, :header, :header_file,
5
+ :report_file, :outfile,
6
+ :error_recovery, :grammar_file,
7
+ :report_file, :trace_opts, :report_opts, :y
8
+
9
+ def initialize
10
+ @skeleton = "bison/yacc.c"
11
+ @header = false
12
+ @header_file = nil
13
+ @report_file = nil
14
+ @outfile = "y.tab.c"
15
+ @error_recovery = false
16
+ @grammar_file = nil
17
+ @report_file = nil
18
+ @trace_opts = nil
19
+ @report_opts = nil
20
+ @y = STDIN
21
+ end
22
+ end
23
+ end
data/lib/lrama/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Lrama
2
- VERSION = "0.5.5".freeze
2
+ VERSION = "0.5.6".freeze
3
3
  end
data/lib/lrama.rb CHANGED
@@ -5,6 +5,8 @@ require "lrama/counterexamples"
5
5
  require "lrama/digraph"
6
6
  require "lrama/grammar"
7
7
  require "lrama/lexer"
8
+ require "lrama/option_parser"
9
+ require "lrama/options"
8
10
  require "lrama/output"
9
11
  require "lrama/parser"
10
12
  require "lrama/report"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lrama
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuichiro Kaneko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-28 00:00:00.000000000 Z
11
+ date: 2023-09-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: LALR (1) parser generator written by Ruby
14
14
  email:
@@ -54,6 +54,8 @@ files:
54
54
  - lib/lrama/lexer.rb
55
55
  - lib/lrama/lexer/token.rb
56
56
  - lib/lrama/lexer/token/type.rb
57
+ - lib/lrama/option_parser.rb
58
+ - lib/lrama/options.rb
57
59
  - lib/lrama/output.rb
58
60
  - lib/lrama/parser.rb
59
61
  - lib/lrama/parser/token_scanner.rb
@@ -103,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
105
  - !ruby/object:Gem::Version
104
106
  version: '0'
105
107
  requirements: []
106
- rubygems_version: 3.4.1
108
+ rubygems_version: 3.5.0.dev
107
109
  signing_key:
108
110
  specification_version: 4
109
111
  summary: LALR (1) parser generator written by Ruby