lrama 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1d7cf0f612d3e1ac4aea0b45db6c0533beadd6412f10a85dd17aceefcfb104a9
4
+ data.tar.gz: 9e60878988696b8d300700a442cb93bb7d7919be94be80a4bd96cbfe689dad1a
5
+ SHA512:
6
+ metadata.gz: 0fa702fd65a2b84c3d426c45ea6d09a5129391409408604d50767c71f8f2d059db45bbde0b8fd96f093caf3741479add35e8cb1434bdd763c38761f70a994d93
7
+ data.tar.gz: d2d5ed81585710107200595b38316120ccc5e01718247c08b6c7de7708ae619de1ec7e37d4ce987b6c21c31d81d5f5c812ecb385d7a6d2838be26e4cf52621f1
@@ -0,0 +1,72 @@
1
+ name: test
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-20.04
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ ruby: ['head', '3.2', '3.1', '3.0']
17
+ steps:
18
+ - uses: actions/checkout@v3
19
+ - uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby }}
22
+ bundler-cache: true
23
+ - run: bundle install
24
+ - run: bundle exec rspec
25
+ test-ruby:
26
+ runs-on: ubuntu-20.04
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ baseruby: ['3.0']
31
+ ruby_branch: ['master']
32
+ defaults:
33
+ run:
34
+ working-directory: ../ruby/build
35
+ steps:
36
+ - uses: actions/checkout@v3
37
+ - uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: ${{ matrix.baseruby }}
40
+ bundler-cache: true
41
+ - run: git clone --depth=1 https://github.com/ruby/ruby.git -b ${{ matrix.ruby_branch }} ../ruby
42
+ working-directory:
43
+ - run: mkdir tool/lrama
44
+ working-directory: ../ruby
45
+ - name: Copy Lrama to ruby/tool
46
+ run: cp -r exe lib template ../ruby/tool/lrama
47
+ working-directory:
48
+ - run: tree tool/lrama
49
+ working-directory: ../ruby
50
+ # See also https://github.com/ruby/ruby/blob/master/.github/workflows/ubuntu.yml
51
+ - run: mkdir build
52
+ working-directory: ../ruby
53
+ - name: Set ENV
54
+ run: |
55
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
56
+ - name: Install libraries
57
+ run: |
58
+ set -x
59
+ arch=${arch:+:${arch/i[3-6]86/i386}}
60
+ ${arch:+sudo dpkg --add-architecture ${arch#:}}
61
+ sudo apt-get update -q || :
62
+ sudo apt-get install --no-install-recommends -q -y \
63
+ ${arch:+cross}build-essential${arch/:/-} \
64
+ libssl-dev${arch} libyaml-dev${arch} libreadline6-dev${arch} \
65
+ zlib1g-dev${arch} libncurses5-dev${arch} libffi-dev${arch} \
66
+ autoconf
67
+ sudo apt-get install -q -y pkg-config${arch} || :
68
+ - run: sudo apt-get --purge remove bison
69
+ - run: ../autogen.sh
70
+ - run: ../configure -C --disable-install-doc
71
+ - run: make YACC=$(readlink -f $(pwd)/../tool/lrama/exe/lrama)
72
+ - run: make test-all
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ /tmp
2
+ .irbrc
3
+ /Gemfile.lock
4
+ /pkg/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem "rspec"
6
+ gem "pry"
7
+ gem "stackprof"
8
+ gem "rake"
data/LEGAL.md ADDED
@@ -0,0 +1,26 @@
1
+ # LEGAL NOTICE INFORMATION
2
+
3
+ All the files in this distribution are covered under the MIT License except some files
4
+ mentioned below.
5
+
6
+ ## GNU General Public License version 3
7
+
8
+ These files are licensed under the GNU General Public License version 3. See these files for more information.
9
+
10
+ * template/bison/yacc.c
11
+ * template/bison/yacc.h
12
+
13
+ ## Same with Ruby
14
+
15
+ These files are licensed same with Ruby. See https://github.com/ruby/ruby/blob/master/COPYING for more information.
16
+
17
+ * spec/fixtures/integration/ruby_3_0_5/parse.tmp.y
18
+ * spec/fixtures/integration/ruby_3_0_5/y.tab.c
19
+ * spec/fixtures/integration/ruby_3_0_5/y.tab.h
20
+ * spec/fixtures/integration/ruby_3_1_0/parse.tmp.y
21
+ * spec/fixtures/integration/ruby_3_1_0/y.tab.c
22
+ * spec/fixtures/integration/ruby_3_1_0/y.tab.h
23
+ * spec/fixtures/integration/ruby_3_2_0/parse.tmp.y
24
+ * spec/fixtures/integration/ruby_3_2_0/y.tab.c
25
+ * spec/fixtures/integration/ruby_3_2_0/y.tab.h
26
+
data/MIT ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Yuichiro Kaneko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # Lrama
2
+
3
+ Lrama is LALR (1) parser generator written by Ruby. The first goal of this project is providing error tolerant parser for CRuby with minimal changes on CRuby parse.y file.
4
+
5
+ ## Features
6
+
7
+ * Bison style grammar file is supported with some assumptions
8
+ * b4_locations_if is always true
9
+ * b4_pure_if is always true
10
+ * b4_pull_if is always false
11
+ * b4_lac_if is always false
12
+ * Error Tolerance parser
13
+ * Subset of [Repairing Syntax Errors in LR Parsers (Corchuelo et al.)](https://idus.us.es/bitstream/handle/11441/65631/Repairing%20syntax%20errors.pdf) algorithm is supported
14
+
15
+ ## Installation
16
+
17
+ ```shell
18
+ $ bundle exec rake install
19
+ $ lrama --version
20
+ 0.1.0
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```shell
26
+ # "y.tab.c" is generated
27
+ $ lrama parse.y
28
+ ```
29
+
30
+ ## License
31
+
32
+ See LEGAL.md file.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/doc/TODO.md ADDED
@@ -0,0 +1,50 @@
1
+ # TODO
2
+
3
+ * command
4
+ * [ ] Add "--bison" option
5
+ * lexer
6
+ * [x] Basic functionalities
7
+ * parser
8
+ * [x] Basic functionalities
9
+ * [x] Precedence in grammar
10
+ * LALR
11
+ * [x] compute_nullable
12
+ * [x] compute_lr0_states
13
+ * [x] Direct Read Sets
14
+ * [x] Reads Relation
15
+ * [x] Read Sets
16
+ * [x] Includes Relation
17
+ * [x] Lookback Relation
18
+ * [x] Follow Sets
19
+ * [x] Look-Ahead Sets
20
+ * [x] Precedence support
21
+ * [x] Conflict check
22
+ * [x] Algorithm Digraph
23
+ * Rendering
24
+ * [x] Table compaction
25
+ * [x] -d option
26
+ * yacc.c
27
+ * [ ] %lex-param
28
+ * [x] %parse-param
29
+ * [x] %printer
30
+ * [x] Replace $, @ in user codes
31
+ * [x] `[@oline@]`
32
+ * [ ] b4_symbol (for eof, error and so on)
33
+ * Assumption
34
+ * b4_locations_if is true
35
+ * b4_pure_if is true
36
+ * b4_pull_if is false
37
+ * b4_lac_if is false
38
+ * Performance improvement
39
+ * [ ]
40
+ * Licenses
41
+ * [x] Write down something about licenses
42
+ * Reporting
43
+ * [ ] Bison style
44
+ * Error Tolerance
45
+ * [x] Subset of Corchuelo et al.
46
+ * Lex state
47
+ * CI
48
+ * [x] Setup CI
49
+ * [x] Add ruby 3.1 or under
50
+ * [x] Add integration tests which installs Lrama, build ruby and run `make test`
data/exe/lrama ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ $LOAD_PATH << File.join(__dir__, "../lib")
5
+ require "lrama"
6
+
7
+ Lrama::Command.new.run(ARGV.dup)
@@ -0,0 +1,129 @@
1
+ require 'optparse'
2
+
3
+ module Lrama
4
+ class Command
5
+ def run(argv)
6
+ opt = OptionParser.new
7
+
8
+ # opt.on('-h') {|v| p v }
9
+ opt.on('-V', '--version') {|v| puts Lrama::VERSION ; exit 0 }
10
+
11
+ # Tuning the Parser
12
+ skeleton = "bison/yacc.c"
13
+
14
+ opt.on('-S', '--skeleton=FILE') {|v| skeleton = v }
15
+ opt.on('-t') { } # Do nothing
16
+
17
+ # Output Files:
18
+ header = false
19
+ header_file = nil
20
+ report = []
21
+ report_file = nil
22
+ outfile = "y.tab.c"
23
+
24
+ opt.on('-h', '--header=[FILE]') {|v| header = true; header_file = v }
25
+ opt.on('-d') { header = true }
26
+ opt.on('-r', '--report=THINGS') {|v| report = v.split(',') }
27
+ opt.on('--report-file=FILE') {|v| report_file = v }
28
+ opt.on('-v') { } # Do nothing
29
+ opt.on('-o', '--output=FILE') {|v| outfile = v }
30
+
31
+ # Hidden
32
+ trace = []
33
+ opt.on('--trace=THINGS') {|v| trace = v.split(',') }
34
+
35
+ # Error Recovery
36
+ error_recovery = false
37
+ opt.on('-e') {|v| error_recovery = true }
38
+
39
+ opt.parse!(argv)
40
+
41
+ trace_opts = validate_trace(trace)
42
+ report_opts = validate_report(report)
43
+
44
+ grammar_file = argv.shift
45
+
46
+ if !report.empty? && report_file.nil? && grammar_file
47
+ report_file = File.dirname(grammar_file) + "/" + File.basename(grammar_file, ".*") + ".output"
48
+ end
49
+
50
+ if !header_file && header
51
+ case
52
+ when outfile
53
+ header_file = File.dirname(outfile) + "/" + File.basename(outfile, ".*") + ".h"
54
+ when grammar_file
55
+ header_file = File.dirname(grammar_file) + "/" + File.basename(grammar_file, ".*") + ".h"
56
+ end
57
+ end
58
+
59
+ if !grammar_file
60
+ puts "File should be specified\n"
61
+ exit 1
62
+ end
63
+
64
+ Report::Duration.enable if trace_opts[:time]
65
+
66
+ y = File.read(grammar_file)
67
+ grammar = Lrama::Parser.new(y).parse
68
+ states = Lrama::States.new(grammar, trace_state: (trace_opts[:automaton] || trace_opts[:closure]))
69
+ states.compute
70
+ context = Lrama::Context.new(states)
71
+
72
+ if report_file
73
+ reporter = Lrama::StatesReporter.new(states)
74
+ File.open(report_file, "w+") do |f|
75
+ reporter.report(f, **report_opts)
76
+ end
77
+ end
78
+
79
+ File.open(outfile, "w+") do |f|
80
+ Lrama::Output.new(
81
+ out: f,
82
+ output_file_path: outfile,
83
+ template_name: skeleton,
84
+ grammar_file_path: grammar_file,
85
+ header_file_path: header_file,
86
+ context: context,
87
+ grammar: grammar,
88
+ ).render
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def validate_report(report)
95
+ list = %w[states itemsets lookaheads solved counterexamples cex all none]
96
+ not_supported = %w[counterexamples cex all none]
97
+ h = {}
98
+
99
+ report.each do |r|
100
+ if list.include?(r) && !not_supported.include?(r)
101
+ h[r.to_sym] = true
102
+ else
103
+ raise "Invalid report option \"#{r}\"."
104
+ end
105
+ end
106
+
107
+ return h
108
+ end
109
+
110
+ def validate_trace(trace)
111
+ list = %w[
112
+ none locations scan parse automaton bitsets
113
+ closure grammar resource sets muscles tools
114
+ m4-early m4 skeleton time ielr cex all
115
+ ]
116
+ h = {}
117
+
118
+ trace.each do |t|
119
+ if list.include?(t)
120
+ h[t.to_sym] = true
121
+ else
122
+ raise "Invalid trace option \"#{t}\"."
123
+ end
124
+ end
125
+
126
+ return h
127
+ end
128
+ end
129
+ end