lrama 0.5.5 → 0.5.6

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