parse_queue 0.1.0 → 0.2.5

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
- SHA1:
3
- metadata.gz: 2dbdae6528358e96af53ee8a1021337dd6d9c2d8
4
- data.tar.gz: 90ce08195ef61d12475c4b66e7751e248e5a5452
2
+ SHA256:
3
+ metadata.gz: e2a1861627deadb0bac32e7b807cad91fc82d90d5758c5b4969f3ede031bcbdb
4
+ data.tar.gz: 4cfd26f3b0c455a6394d10b325b12d73dce63f8b5d8e8271d3d4b73da49af594
5
5
  SHA512:
6
- metadata.gz: 2dc54cd963668ab878f3fe69f6d2ffe7731dab1e5fbc9a49af619035b9d8ebe8df4f4aa93690c98810ae97dc660455932e9f001ed7c3e8d76ac4ca8db1663d4a
7
- data.tar.gz: 749792d40d3992d2bdac14b70aecfa7021422127c71a589a2599dfa7173622136eb0f1f1e0c1d27bac5877ffc0ab13ea8631dcb205896925418788af413f2937
6
+ metadata.gz: 95750f6139a58734609f072f253bcd97eedfc7af81d5dceb6e714ee57e092bba7b71e42ce05bde2688f81a0c7636f02c612d29f4bd18673ff2171c5be10a119c
7
+ data.tar.gz: 436b508221175b802ae1dee447e1a6e76ca2e07850d1d718ffb8c9fc80a2f43fa6e2a82f79b2af893db91ff78530db190ba69a7230ddfc1d6e29adfc401642dc
data/README.md CHANGED
@@ -7,6 +7,16 @@ simple queue, it supports backing up or falling back to earlier states allowing
7
7
  the parser to try other paths in the syntax tree when one path runs into a
8
8
  dead end.
9
9
 
10
+ The parse queue was created to simplify the design of both the lexical analyzer
11
+ and the parser. Parsers often have a built-in limited "look-ahead" of tokens.
12
+ This can be seen in parser names like LL(0), LL(1), LR(1), LALR(n), etc. The
13
+ parse queue provides for a flexible look-ahead removing this burden from other
14
+ compiler components.
15
+
16
+ The operation of the parse queue is summarized in the following diagram:
17
+
18
+ ![parse queue](./images/queue.png)
19
+
10
20
  ## Installation
11
21
 
12
22
  Add this line to your application's Gemfile:
@@ -34,11 +44,21 @@ When creating a parse queue, an optional block parameter is passed in. This is
34
44
  called whenever more queue items are required. For example:
35
45
 
36
46
  ```ruby
37
- pq = ParseQueue.new { lex.next }
47
+ def open_file_tokenized(name)
48
+ txt = IO.readlines(name, nil)[0]
49
+ lex = LexicalAnalayzer.new(text: txt, rules: LEXICAL_RULES)
50
+ ParseQueue.new { lex.get }
51
+ end
38
52
  ```
39
- If this block is omitted, then items will have to added to the parse queue
40
- using the add method. The add method accepts single items, multiple items or
41
- an array of items.
53
+ This example above is a method that reads in the named file, creates an
54
+ analyzer on it (see the
55
+ [lexical_analyzer](https://rubygems.org/gems/lexical_analyzer)
56
+ gem for more details) and then uses that as the source for the parse queue.
57
+ The queue is returned for use by the compiler's parser.
58
+
59
+ Note: The constant LEXICAL_RULES is a set of rules used to define the tokens
60
+ extracted by the lexical analyzer. As such it is not discussed further here.
61
+ See that gem for more details on how rules are constructed.
42
62
 
43
63
  #### Getting a queued item:
44
64
 
@@ -50,6 +70,12 @@ Getting an item from the queue is done with the get method. For example:
50
70
  This method returns the next unread item from the queue. Note that if no items
51
71
  are available, the exception **ParseQueueNoFwd** is raised.
52
72
 
73
+ Note: The get! method is a get without backtracking. In effect it is a get
74
+ followed by a shift (see Shifting below).
75
+
76
+ ```ruby
77
+ item = pq.get!
78
+ ```
53
79
 
54
80
  #### Backtracking:
55
81
 
@@ -82,7 +108,7 @@ a value saved off at an earlier point of the processing. For example:
82
108
 
83
109
  #### Shifting
84
110
 
85
- So far, items have been retained in the queue, even when are done being
111
+ So far, items have been retained in the queue, even after they are done being
86
112
  processed. For large files, this may use a large amount of memory. To avoid
87
113
  this, used items need to be shifted out of the parse queue. This can be done as
88
114
  follows:
@@ -96,9 +122,9 @@ follows:
96
122
  }
97
123
  ```
98
124
  Note how the try! block returns a value called success. If this value is false
99
- or nil, the parse queue is rolled back to its condition at the start of the try
100
- block. Otherwise, any changes to the parse queue are retained and processed
101
- items are removed.
125
+ or nil, the parse queue is rolled back to its condition at the start of the
126
+ try! block. Otherwise, any changes to the parse queue are retained and
127
+ processed items are removed.
102
128
 
103
129
  This too can be done manually as shown below:
104
130
 
@@ -116,11 +142,21 @@ This too can be done manually as shown below:
116
142
  Note that if an attempt is made to fall back to data that has been shifted out,
117
143
  a **ParseQueueNoRev** exception is raised.
118
144
 
145
+ #### Exceptions
146
+
147
+ The parse queue uses the following exception classes:
148
+
149
+ Exception # From Ruby.
150
+ StandardError # From Ruby.
151
+ ParseQueueError # The abstract root of parse queue exceptions.
152
+ ParseQueueNoFwd # Error: Can't go forward.
153
+ ParseQueueNoRev # Error: Can't fall back.
154
+
119
155
  ## Contributing
120
156
 
121
157
  #### Plan A
122
158
 
123
- 1. Fork it ( https://github.com/PeterCamilleri/parse_queue_dup/fork )
159
+ 1. Fork it ( https://github.com/PeterCamilleri/parse_queue/fork )
124
160
  2. Create your feature branch (`git checkout -b my-new-feature`)
125
161
  3. Commit your changes (`git commit -am 'Add some feature'`)
126
162
  4. Push to the branch (`git push origin my-new-feature`)
@@ -134,10 +170,10 @@ aspect that could use some TLC or a suggestion or an idea.
134
170
  ## License
135
171
 
136
172
  The gem is available as open source under the terms of the
137
- [MIT License](http://opensource.org/licenses/MIT).
173
+ [MIT License](./LICENSE.txt).
138
174
 
139
175
  ## Code of Conduct
140
176
 
141
177
  Everyone interacting in the ParseQueue project’s codebases, issue trackers,
142
178
  chat rooms and mailing lists is expected to follow the
143
- [code of conduct](https://github.com/PeterCamilleri/parse_queue/blob/master/CODE_OF_CONDUCT.md).
179
+ [code of conduct](./CODE_OF_CONDUCT.md).
data/images/queue.png ADDED
Binary file
data/lib/parse_queue.rb CHANGED
@@ -1,54 +1,61 @@
1
- # coding: utf-8
2
-
3
1
  # The Ruby Compiler Toolkit Project - Parse Queue
4
2
  # A queue for compiler objects between parser layers.
5
3
 
6
4
  require_relative "parse_queue/exceptions"
7
5
  require_relative "parse_queue/version"
8
6
 
7
+ # The RCTP queue for parser token flow with backtracking.
9
8
  class ParseQueue
10
9
 
11
10
  # The current read point of the queue.
12
11
  attr_reader :position
13
12
 
14
- # The number of old items removed from the queue.
15
- attr_reader :offset
13
+ #The default fetch block
14
+ DFB = Proc.new { false }
16
15
 
17
16
  # Set up the parser queue.
18
17
  def initialize(&fetch)
19
- @fetch = fetch || lambda { false }
18
+ @fetch = fetch
20
19
  @buffer = []
21
20
  @offset = @position = 0
22
21
  end
23
22
 
24
23
  # How many unread items are in this parse queue?
25
- def unread
26
- @buffer.length - @position + @offset
24
+ def fwd_count
25
+ index_limit - @position
27
26
  end
28
27
 
29
- # Manually add items to the buffer
30
- def add(*items)
31
- @buffer += items.flatten
28
+ # How many already read items are still in this parse queue?
29
+ def rev_count
30
+ @position - @offset
32
31
  end
33
32
 
34
33
  # Get an item from the buffer.
35
34
  def get
36
- if @position >= (@buffer.length + @offset)
37
- item = @fetch.call
38
- fail ParseQueueNoFwd unless item
39
- @buffer << item
40
- end
35
+ @buffer << fetch_one if @position == index_limit
41
36
 
42
- result = @buffer[@position - @offset]
37
+ result = @buffer[rev_count]
43
38
  @position += 1
44
39
  result
45
40
  end
46
41
 
47
- # Get all possible items
48
- def read_all
42
+ # Get an item and shift the buffer.
43
+ def get!
44
+ result = get
45
+ shift
46
+ result
47
+ end
48
+
49
+ # Fetch all possible items.
50
+ def fetch_all
49
51
  loop do
50
52
  item = @fetch.call
51
- return unless item
53
+
54
+ unless item
55
+ @fetch = DFB
56
+ return
57
+ end
58
+
52
59
  @buffer << item
53
60
  end
54
61
  end
@@ -60,40 +67,53 @@ class ParseQueue
60
67
  end
61
68
 
62
69
  # Undo the last get.
63
- def back_up
64
- @position -= 1
70
+ def unget(count=1)
71
+ @position -= count
65
72
  validate_position
66
73
  end
67
74
 
68
75
  # Release any items before the current item.
69
76
  def shift
70
- @buffer.shift(@position - @offset)
77
+ @buffer.shift(rev_count)
71
78
  @offset = @position
72
79
  end
73
80
 
74
81
  # Try to process some items with roll back on failure.
75
82
  def try(&block)
76
83
  save = @position
77
- @position = save unless block.call
78
- validate_position
84
+ self.position = save unless (result = block.call)
85
+ result
79
86
  end
80
87
 
81
- # Try to process some items with shift of success and roll back on failure.
88
+ # Process some items with a shift on success and a roll back on failure.
82
89
  def try!(&block)
83
- save = @position
84
-
85
- if block.call
86
- shift
87
- else
88
- @position = save
89
- validate_position
90
- end
90
+ shift if (result = try(&block))
91
+ result
91
92
  end
92
93
 
94
+ private
95
+
93
96
  # Is this a valid position?
94
97
  def validate_position
95
98
  fail ParseQueueNoRev if @position < @offset
96
- fail ParseQueueNoFwd if @position >= (@buffer.length + @offset)
99
+ fail ParseQueueNoFwd if @position >= index_limit
100
+ end
101
+
102
+ # The first index past the end of the array
103
+ def index_limit
104
+ @buffer.length + @offset
105
+ end
106
+
107
+ # Fetch a single item.
108
+ def fetch_one
109
+ item = @fetch.call
110
+
111
+ unless item
112
+ @fetch = DFB
113
+ fail ParseQueueNoFwd
114
+ end
115
+
116
+ item
97
117
  end
98
118
 
99
119
  end
@@ -1,5 +1,3 @@
1
- # coding: utf-8
2
-
3
1
  # Exception types for the parse queue.
4
2
 
5
3
  # The base error class for the parse queue.
@@ -1,5 +1,3 @@
1
- # coding: utf-8
2
-
3
1
  class ParseQueue
4
- VERSION = "0.1.0"
2
+ VERSION = "0.2.5".freeze
5
3
  end
data/parse_queue.gemspec CHANGED
@@ -18,8 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test)/}) }
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.15"
22
- spec.add_development_dependency "rake", "~> 10.0"
21
+ spec.required_ruby_version = '>=2.3.0'
22
+
23
+ spec.add_development_dependency "bundler", ">= 2.1.0"
24
+ spec.add_development_dependency "rake", ">= 12.3.3"
23
25
  spec.add_development_dependency "minitest", "~> 5.0"
24
- spec.add_development_dependency 'minitest_visible', "~> 0.1"
26
+ spec.add_development_dependency 'reek', "~> 5.0.2"
25
27
  end
data/rakefile.rb CHANGED
@@ -8,3 +8,14 @@ Rake::TestTask.new(:test) do |t|
8
8
  end
9
9
 
10
10
  task :default => :test
11
+
12
+ desc "Run a scan for smelly code!"
13
+ task :reek do |t|
14
+ `reek --no-color lib > reek.txt`
15
+ end
16
+
17
+ desc "What version of parse queue is this?"
18
+ task :vers do |t|
19
+ puts
20
+ puts "parse_queue version = #{ParseQueue::VERSION}"
21
+ end
data/reek.txt ADDED
@@ -0,0 +1 @@
1
+ 0 total warnings
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parse_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - PeterCamilleri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-22 00:00:00.000000000 Z
11
+ date: 2021-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.15'
19
+ version: 2.1.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.15'
26
+ version: 2.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,19 +53,19 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: minitest_visible
56
+ name: reek
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.1'
61
+ version: 5.0.2
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.1'
68
+ version: 5.0.2
69
69
  description: The RCTP object queue for moving compiler tokens with nestable backtrack
70
70
  capability.
71
71
  email:
@@ -79,11 +79,13 @@ files:
79
79
  - Gemfile
80
80
  - LICENSE.txt
81
81
  - README.md
82
+ - images/queue.png
82
83
  - lib/parse_queue.rb
83
84
  - lib/parse_queue/exceptions.rb
84
85
  - lib/parse_queue/version.rb
85
86
  - parse_queue.gemspec
86
87
  - rakefile.rb
88
+ - reek.txt
87
89
  homepage: https://github.com/PeterCamilleri/parse_queue
88
90
  licenses:
89
91
  - MIT
@@ -96,15 +98,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
96
98
  requirements:
97
99
  - - ">="
98
100
  - !ruby/object:Gem::Version
99
- version: '0'
101
+ version: 2.3.0
100
102
  required_rubygems_version: !ruby/object:Gem::Requirement
101
103
  requirements:
102
104
  - - ">="
103
105
  - !ruby/object:Gem::Version
104
106
  version: '0'
105
107
  requirements: []
106
- rubyforge_project:
107
- rubygems_version: 2.5.2
108
+ rubygems_version: 3.2.17
108
109
  signing_key:
109
110
  specification_version: 4
110
111
  summary: The RCTP object queue for connecting parser steps.