parse_queue 0.1.0 → 0.2.5

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