arpaka 0.1.0

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.
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Generated by Arpaka/Lrama. Do not edit.
4
+ <% if recognizer -%>
5
+ # Recognition only: C actions and support code are omitted.
6
+ # Supply pre-tokenized input; acceptance returns true. No error recovery.
7
+ <% end -%>
8
+ class <%= class_name %>
9
+ class ParseError < StandardError
10
+ attr_reader :token, :state
11
+
12
+ def initialize(token, state)
13
+ @token = token
14
+ @state = state
15
+ super("Unexpected token #{token.inspect} in state #{state}")
16
+ end
17
+ end
18
+
19
+ TOKENS = <%= tokens.inspect %>.freeze
20
+ <% %i[yytranslate yypact yydefact yypgoto yydefgoto yytable yycheck yyr1 yyr2].each do |name| -%>
21
+ <%= name.upcase %> = <%= context.public_send(name).inspect %>.freeze
22
+ <% end -%>
23
+ YYFINAL = <%= context.yyfinal %>
24
+ YYNTOKENS = <%= context.yyntokens %>
25
+ YYPACT_NINF = <%= context.yypact_ninf %>
26
+ YYTABLE_NINF = <%= context.yytable_ninf %>
27
+
28
+ attr_accessor :lexical_context
29
+ attr_reader :parse_trace, :lookahead_token, :lookahead_value, :lookahead_state
30
+
31
+ # tokens yields [token name or numeric ID, semantic value] pairs.
32
+ # Exhaustion is EOF; [0, nil] can also terminate the stream explicitly.
33
+ def parse(tokens)
34
+ @parse_trace = []
35
+ input = tokens.to_enum
36
+ states = [0]
37
+ values = []
38
+ lookahead = nil
39
+ token = nil
40
+ value = nil
41
+ @lookahead_token = nil
42
+ @lookahead_value = nil
43
+ @lookahead_state = nil
44
+
45
+ while true
46
+ state = states.last
47
+ return <%= recognizer ? "true" : "values[-2]" %> if state == YYFINAL
48
+
49
+ action = nil
50
+ base = YYPACT[state]
51
+ unless base == YYPACT_NINF
52
+ if lookahead.nil?
53
+ pair = begin
54
+ input.next
55
+ rescue StopIteration
56
+ [0, nil]
57
+ end
58
+ unless pair.is_a?(Array) && pair.length == 2
59
+ raise ArgumentError, "Each token must be a [name or ID, value] pair"
60
+ end
61
+ token, value = pair
62
+ @parse_trace << [:read, token, state].freeze
63
+ @lookahead_token = token
64
+ @lookahead_value = value
65
+ @lookahead_state = state
66
+ id = token.is_a?(Integer) ? token : TOKENS[token.to_s]
67
+ lookahead = id && id >= 0 ? (YYTRANSLATE[id] || 2) : 2
68
+ # The reserved error symbol is internal to recovery, never lexer input.
69
+ raise ParseError.new(token, state) if lookahead == 1
70
+ end
71
+ index = base + lookahead
72
+ if index >= 0 && index < YYCHECK.length && YYCHECK[index] == lookahead
73
+ action = YYTABLE[index]
74
+ end
75
+ end
76
+
77
+ if action.nil?
78
+ rule = YYDEFACT[state]
79
+ raise ParseError.new(token, state) if rule.zero?
80
+ elsif action.positive?
81
+ @parse_trace << [:shift, token, state, action].freeze
82
+ @lexical_context&.parser_shift(token, value, state, action)
83
+ states << action
84
+ values << value
85
+ lookahead = nil
86
+ @lookahead_token = nil
87
+ @lookahead_value = nil
88
+ @lookahead_state = nil
89
+ next
90
+ elsif action.zero? || action == YYTABLE_NINF
91
+ raise ParseError.new(token, state)
92
+ else
93
+ rule = -action
94
+ end
95
+
96
+ length = YYR2[rule]
97
+ @parse_trace << [:reduce, rule, state].freeze
98
+ @lexical_context&.parser_reduce(rule, state)
99
+ result = reduce(rule, values, length)
100
+ states.pop(length)
101
+ values.pop(length)
102
+ lhs = YYR1[rule] - YYNTOKENS
103
+ index = YYPGOTO[lhs] + states.last
104
+ next_state = if index >= 0 && index < YYCHECK.length && YYCHECK[index] == states.last
105
+ YYTABLE[index]
106
+ else
107
+ YYDEFGOTO[lhs]
108
+ end
109
+ states << next_state
110
+ values << result
111
+ end
112
+ end
113
+
114
+ private
115
+
116
+ def reduce(rule, values, length)
117
+ yyval = length.zero? ? nil : values[-length]
118
+ <% unless actions.empty? -%>
119
+ case rule
120
+ <%= actions %>
121
+ else
122
+ # The default action is $$ = $1 (nil for an empty production).
123
+ end
124
+ <% end -%>
125
+ yyval
126
+ end
127
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lrama
4
+ module Ruby
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
data/lib/lrama/ruby.rb ADDED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "ruby/version"
4
+
5
+ module Lrama
6
+ module Ruby
7
+ class Error < StandardError; end
8
+
9
+ def self.generate(source, filename: "(grammar)", class_name: "Parser", mode: :parser, allow_error_rules: false)
10
+ Generator.new.generate(source, filename: filename, class_name: class_name,
11
+ mode: mode, allow_error_rules: allow_error_rules)
12
+ end
13
+
14
+ def self.compile(source, filename: "(grammar)", class_name: "Parser", mode: :parser, allow_error_rules: false)
15
+ code = generate(source, filename: filename, class_name: class_name,
16
+ mode: mode, allow_error_rules: allow_error_rules)
17
+ box = ::Ruby::Box.new
18
+ begin
19
+ box.eval(code)
20
+ rescue SyntaxError => error
21
+ raise Error, "Invalid generated Ruby for #{filename}: #{error.message}"
22
+ end
23
+ box.const_get(class_name, false)
24
+ end
25
+ end
26
+ end
27
+
28
+ require_relative "ruby/generator"
data/sig/arpaka.rbs ADDED
@@ -0,0 +1,15 @@
1
+ module Arpaka
2
+ interface _Program
3
+ def statements: () -> Array[untyped]
4
+ end
5
+
6
+ interface _Frontend
7
+ def parse: (String source, ?filename: String) -> _Program
8
+ end
9
+
10
+ def self.generate: (ruby_source: String, ?class_name: String) -> String
11
+ def self.compile: (ruby_source: String, ?class_name: String) -> _Frontend
12
+
13
+ class Error < ::Lrama::Ruby::Error
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module Lrama
2
+ module Ruby
3
+ VERSION: String
4
+
5
+ class Error < StandardError
6
+ end
7
+
8
+ def self.generate: (String source, ?filename: String, ?class_name: String, ?mode: (:parser | :recognizer), ?allow_error_rules: bool) -> String
9
+ def self.compile: (String source, ?filename: String, ?class_name: String, ?mode: (:parser | :recognizer), ?allow_error_rules: bool) -> Class
10
+
11
+ class Generator
12
+ def initialize: () -> void
13
+ def generate: (String source, ?filename: String, ?class_name: String, ?mode: (:parser | :recognizer), ?allow_error_rules: bool) -> String
14
+ end
15
+
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: arpaka
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - MATSUMOTO, Katsuyoshi
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: lrama
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 0.8.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 0.8.0
26
+ description: A Ruby parser frontend and Ruby output backend for Lrama.
27
+ email:
28
+ - github@katsyoshi.org
29
+ executables:
30
+ - arpaka
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - CHANGELOG.md
35
+ - LICENSE.txt
36
+ - README.md
37
+ - Rakefile
38
+ - assets/arpaka-logo.svg
39
+ - examples/calculator.y
40
+ - examples/calculator_ast.y
41
+ - exe/arpaka
42
+ - lib/arpaka.rb
43
+ - lib/arpaka/BSDL
44
+ - lib/arpaka/COPYING
45
+ - lib/arpaka/actions.rb
46
+ - lib/arpaka/cli.rb
47
+ - lib/arpaka/generator.rb
48
+ - lib/arpaka/ruby_grammar.rb
49
+ - lib/arpaka/runtime/ast.rb.erb
50
+ - lib/arpaka/runtime/builder.rb.erb
51
+ - lib/arpaka/runtime/frontend.rb.erb
52
+ - lib/arpaka/runtime/lexer.rb.erb
53
+ - lib/arpaka/source.json
54
+ - lib/arpaka/upstream_rules.json
55
+ - lib/lrama/ruby.rb
56
+ - lib/lrama/ruby/action_code.rb
57
+ - lib/lrama/ruby/action_scanner.rb
58
+ - lib/lrama/ruby/backend.rb
59
+ - lib/lrama/ruby/generator.rb
60
+ - lib/lrama/ruby/parser.rb.erb
61
+ - lib/lrama/ruby/version.rb
62
+ - sig/arpaka.rbs
63
+ - sig/lrama/ruby.rbs
64
+ homepage: https://github.com/katsyoshi/arpaka
65
+ licenses:
66
+ - MIT
67
+ metadata:
68
+ homepage_uri: https://github.com/katsyoshi/arpaka
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 4.0.0
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubygems_version: 4.0.20
84
+ specification_version: 4
85
+ summary: Ruby language parser frontend and Lrama output backend
86
+ test_files: []