rbscmlex 0.1.1 → 0.1.2

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: 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: