rbscmlex 0.1.1 → 0.1.2

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: 1d945c95432fbcd698af635fd0d4a9e0f54a468270fc6f6e8c5a69df7202b1f3
4
- data.tar.gz: b359cb4c75e7082e961714d0994ed3d503a81796bbbf51c489c6e32c62dfc819
3
+ metadata.gz: ec8d6513252c0196840bfc388ab2cb429d5d1cb579e5fb23d034e6509ab24bf5
4
+ data.tar.gz: fd952eecb26646994dcfe9786fa5678b68f5ab04191009079f47acedaba1af3a
5
5
  SHA512:
6
- metadata.gz: 6f3da67c6a2479b94fb9a7fff6c6c89c03e0f386f94418a16d3ff751e505839f62deb2437127607e7259d51e1c8204c7583e3d5207c944ba0114b996f7f212bb
7
- data.tar.gz: c0a68a273da923404f3cc3051f5850250076edff9bb4637523f3b5667862d7c6b1d64b348998c0c8c2f8604f10daf364c3918928cccd0304f7ed6468585ca289
6
+ metadata.gz: 6344300170f133448eb6f6b1646ffa0e617a900c3df87b00f9a48cd6c008da73e8b9161cac4afb4d752a37c3981cd7ad1fa324c48044d484c26cd836bcfe5cc9
7
+ data.tar.gz: ecf7e267663faa64023c1f72ed82fac38b799d2fd370d7a6725e512780618ebbd70f121bf8031abb3738f9827dbd5e7c855ad700055b18dbbec2b79356d3f16b
data/CHANGELOG.md CHANGED
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
  ## [Unreleased]
8
8
  - (nothing to record here)
9
9
 
10
+ ## [0.1.2] - 2021-05-07
11
+ ### Added
12
+ - Add a mechanism to initialize a Parser instance from an array of
13
+ tokens, which already created from source of Scheme.
14
+
15
+ ### Fixed
16
+ - Fix issue #3: a wrong link in `README.md`.
17
+
10
18
  ## [0.1.1] - 2021-05-06
11
19
  ### Fixed
12
20
  - Fix issue #1: `rbscmlex` fails to read from STDIN.
data/README.md CHANGED
@@ -28,7 +28,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
28
28
 
29
29
  ## Contributing
30
30
 
31
- Bug reports and pull requests are welcome on GitHub at [https://github.com/mnbi/rus3](https://github.com/mnbi/rus3).
31
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/mnbi/rbscmlex](https://github.com/mnbi/rbscmlex).
32
32
 
33
33
 
34
34
  ## License
@@ -64,56 +64,136 @@ module Rbscmlex
64
64
 
65
65
  include Enumerable
66
66
 
67
- def initialize(src, form: TOKEN_DEFAULT_FORM)
68
- @form = form
69
- @tokens = tokenize(src)
70
- @size = @tokens.size
67
+ def initialize(obj, form: TOKEN_DEFAULT_FORM)
68
+ set_form(form)
69
+ init_pos
70
+ case obj
71
+ when String
72
+ # obj must be source program of Scheme.
73
+ @tokens = tokenize(obj)
74
+ when Array
75
+ # obj might be an array of tokens.
76
+ input_form = detect_form(obj[0])
77
+ case input_form
78
+ when :hash, :json, :token
79
+ @tokens = read_tokens(obj, form: input_form)
80
+ else
81
+ raise InvalidConversionTypeError, "cannot convert #{obj[0]} as token"
82
+ end
83
+ else
84
+ raise InvalidConversionTypeError, "cannot convert #{obj} as tokens"
85
+ end
86
+ end
71
87
 
72
- @current_pos = @next_pos = 0
88
+ def [](index)
89
+ convert(@tokens[index])
73
90
  end
74
91
 
75
92
  def each(&blk)
76
93
  if block_given?
77
- @tokens.each(&blk)
94
+ @tokens.each { |tk|
95
+ yield convert(tk)
96
+ }
78
97
  self
79
98
  else
80
- @tokens.each
99
+ to_a.to_enum
81
100
  end
82
101
  end
83
102
 
84
103
  def to_a
85
- @tokens
104
+ convert_all(@tokens)
86
105
  end
87
106
 
88
107
  def size
89
- @size
108
+ @tokens.size
90
109
  end
91
110
 
92
111
  def current_token
93
- @tokens[@current_pos]
112
+ self[@current_pos]
94
113
  end
95
114
 
96
115
  def next_token
97
116
  check_pos
98
117
  @current_pos = @next_pos
99
118
  @next_pos += 1
100
- @tokens[@current_pos]
119
+ self[@current_pos]
101
120
  end
102
121
 
103
122
  def peek_token(num = 0)
104
123
  check_pos
105
- @tokens[@next_pos + num]
124
+ self[@next_pos + num]
106
125
  end
107
126
 
108
127
  def rewind
109
- @current_pos = @next_pos = 0
128
+ init_pos
110
129
  self
111
130
  end
112
131
 
132
+ # :stopdoc:
133
+
113
134
  private
114
135
 
136
+ def set_form(form)
137
+ if TOKEN_FORMS.include?(form)
138
+ @form = form
139
+ else
140
+ raise InvalidConversionTypeError, "cannot generate #{form} as token"
141
+ end
142
+ end
143
+
144
+ def init_pos
145
+ @current_pos = @next_pos = 0
146
+ end
147
+
148
+ def read_tokens(ary, form: :token)
149
+ conv_proc ={hash: :hash2token, json: :json2token, token: nil}[form]
150
+ conv_proc ? ary.map{|e| Rbscmlex.send(conv_proc, e)} : ary.dup
151
+ end
152
+
153
+ def detect_form(obj)
154
+ case obj
155
+ when Hash
156
+ valid_token?(obj) ? :hash : nil
157
+ when Token
158
+ :token
159
+ when String
160
+ begin
161
+ JSON.parse(obj, symbolize_names: true)
162
+ rescue JSON::ParserError => _
163
+ nil
164
+ else
165
+ :json
166
+ end
167
+ else
168
+ nil
169
+ end
170
+ end
171
+
172
+ def valid_token?(obj)
173
+ case obj
174
+ when Hash
175
+ obj.key?(:type) and obj.key?(:literal)
176
+ when Token
177
+ Rbscmlex.token_type?(obj.type)
178
+ else
179
+ false
180
+ end
181
+ end
182
+
183
+ def converter
184
+ { hash: :to_h, json: :to_json, token: nil}[@form]
185
+ end
186
+
187
+ def convert(token)
188
+ converter ? token.send(converter) : token
189
+ end
190
+
191
+ def convert_all(tokens)
192
+ converter ? token.map(&converter) : tokens
193
+ end
194
+
115
195
  def check_pos
116
- raise StopIteration if @next_pos >= @size
196
+ raise StopIteration if @next_pos >= size
117
197
  end
118
198
 
119
199
  S2R_MAP = { "(" => "( ", ")" => " ) ", "'" => " ' " } # :nodoc:
@@ -124,32 +204,34 @@ module Rbscmlex
124
204
  cooked.split(" ").map { |literal|
125
205
  case literal
126
206
  when "("
127
- Rbscmlex.new_token(:lparen, literal, @form)
207
+ Rbscmlex.new_token(:lparen, literal)
128
208
  when ")"
129
- Rbscmlex.new_token(:rparen, literal, @form)
209
+ Rbscmlex.new_token(:rparen, literal)
130
210
  when "."
131
- Rbscmlex.new_token(:dot, literal, @form)
211
+ Rbscmlex.new_token(:dot, literal)
132
212
  when "'"
133
- Rbscmlex.new_token(:quotation, literal, @form)
213
+ Rbscmlex.new_token(:quotation, literal)
134
214
  when "#("
135
- Rbscmlex.new_token(:vec_lparen, literal, @form)
215
+ Rbscmlex.new_token(:vec_lparen, literal)
136
216
  when BOOLEAN
137
- Rbscmlex.new_token(:boolean, literal, @form)
217
+ Rbscmlex.new_token(:boolean, literal)
138
218
  when IDENTIFIER
139
- Rbscmlex.new_token(:identifier, literal, @form)
219
+ Rbscmlex.new_token(:identifier, literal)
140
220
  when CHAR
141
- Rbscmlex.new_token(:character, literal, @form)
221
+ Rbscmlex.new_token(:character, literal)
142
222
  when STRING
143
- Rbscmlex.new_token(:string, literal, @form)
223
+ Rbscmlex.new_token(:string, literal)
144
224
  when ARITHMETIC_OPS, COMPARISON_OPS
145
- Rbscmlex.new_token(:op_proc, literal, @form)
225
+ Rbscmlex.new_token(:op_proc, literal)
146
226
  when REAL_NUM, RATIONAL, COMPLEX, PURE_IMAG
147
- Rbscmlex.new_token(:number, literal, @form)
227
+ Rbscmlex.new_token(:number, literal)
148
228
  else
149
- Rbscmlex.new_token(:illegal, literal, @form)
229
+ Rbscmlex.new_token(:illegal, literal)
150
230
  end
151
231
  }
152
232
  end
153
233
 
234
+ # :startdoc:
235
+
154
236
  end
155
237
  end
@@ -36,26 +36,26 @@ module Rbscmlex
36
36
  # a structure to store properties of a token of Scheme program.
37
37
 
38
38
  Token = Struct.new(:type, :literal) {
39
+ # :stopdoc:
40
+ # `to_a` and `to_h` are automatically defined for a class
41
+ # generated from Struct.
42
+ # :startdoc:
43
+
39
44
  alias :to_s :literal
45
+
46
+ # Generates a new string of JSON notation, which has "type" and
47
+ # "literal" as its key.
48
+ def to_json
49
+ JSON.generate(to_h)
50
+ end
40
51
  }
41
52
 
42
53
  class << self
43
54
 
44
- # Instantiates a new token object form type and literal. The 3rd
45
- # argument specifies the form of the object. It must be one of
46
- # :token, :hash, and :json.
47
-
48
- def new_token(type, literal = nil, form = :token)
49
- case form
50
- when :token
51
- Token.new(type, literal)
52
- when :hash
53
- make_hash(type, literal)
54
- when :json
55
- JSON.generate(make_hash(type, literal))
56
- else
57
- raise InvalidConversionTypeError, "cannot generate #{type} as token"
58
- end
55
+ # Instantiates a new token object form type and literal.
56
+
57
+ def new_token(type, literal = nil)
58
+ Token.new(type, literal)
59
59
  end
60
60
 
61
61
  # Returns true when the argument is valid token type.
@@ -64,7 +64,7 @@ module Rbscmlex
64
64
  TOKEN_TYPES.include?(type)
65
65
  end
66
66
 
67
- # Returns a new Hash object with type and literal.
67
+ # Returns a new Hash object with type and literal as its keys.
68
68
 
69
69
  def make_hash(type, literal)
70
70
  {type: type, literal: literal}
@@ -75,28 +75,54 @@ module Rbscmlex
75
75
  # must be valid token type. Otherwise, raises UnknownTokenTypeError.
76
76
 
77
77
  def hash2token(hash)
78
- if h.key?("type") and h.key?("literal")
79
- type = h["type"].intern
78
+ if hash.key?(:type) and hash.key?(:literal)
79
+ type = hash[:type].intern
80
80
  raise UnknownTokenTypeError, ("got=%s" % type) unless token_type?(type)
81
- literal = h["literal"]
82
- Token.new(type.intern, literal)
81
+ literal = hash[:literal]
82
+ new_token(type, literal)
83
83
  else
84
84
  raise InvalidHashError, ("got=%s" % hash)
85
85
  end
86
86
  end
87
87
 
88
88
  # Converts a JSON notation, which hash type and literal, to a new
89
- # token object. The value associated to type of the Hash must be
89
+ # token object. The value associated to type of the JSON must be
90
90
  # valid token type. Otherwise, raises UnknownTokenTypeError.
91
91
 
92
92
  def json2token(json)
93
- h = JSON.parse(json)
93
+ h = JSON.parse(json, symbolize_names: true)
94
94
  begin
95
95
  hash2token(h)
96
96
  rescue InvalidHashError => _
97
97
  raise InvalidJsonError, ("got=%s" % json)
98
98
  end
99
99
  end
100
+
101
+ # Converts a Token object to a Hash object.
102
+
103
+ def token2hash(token)
104
+ token.to_h
105
+ end
106
+
107
+ # Converts a Token object to a string of JSON notation.
108
+
109
+ def token2json(token)
110
+ token.to_json
111
+ end
112
+
113
+ # Converts a Hash object to a string of JSON notation.
114
+
115
+ def hash2json(hash)
116
+ JSON.generate(hash)
117
+ end
118
+
119
+
120
+ # Converts a JSON notation to a new Hash object.
121
+
122
+ def json2hash(json)
123
+ JSON.parse(json)
124
+ end
125
+
100
126
  end
101
127
 
102
128
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rbscmlex
4
- VERSION = "0.1.1"
5
- RELEASE = "2021-05-06"
4
+ VERSION = "0.1.2"
5
+ RELEASE = "2021-05-07"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbscmlex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - mnbi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-06 00:00:00.000000000 Z
11
+ date: 2021-05-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A simple lexical analyzer for Scheme
14
14
  email: