stream_parser 0.1
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 +7 -0
- data/README.md +59 -0
- data/lib/stream_parser.rb +106 -0
- data/lib/stream_parser/version.rb +3 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0e47f922c40712cf85591d6fe3f5e39b8fd974964a9c8604bc1d91dcaebedd36
|
4
|
+
data.tar.gz: fed08e64284d9b798822d620d06d7618932ff3ac3546e5033186aba807befc54
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d25b559fb053168d5637ad0f774eb291b98ee34cd7baf30858699b1584e533f8322fdcd677685f4647bc101df997251cea1cb843b9d3d5d511fbd234b75e1ce7
|
7
|
+
data.tar.gz: e2fa502f87ed3285044086780c0e615641edccdb1e3680418a004e247f19dbd389a2f6465068bfb1081b44a2599e159ede05101f5f1e691d1f6f89802d967b4c
|
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# StreamParser
|
2
|
+
|
3
|
+
StreamParser is a Ruby Module to help build fast and efficent parsers.
|
4
|
+
|
5
|
+
Installation
|
6
|
+
------------
|
7
|
+
|
8
|
+
Add `gem 'stream_parser'` to your Gemfile or install via RubyGems (`gem install stream_parser`)
|
9
|
+
|
10
|
+
Usage Example:
|
11
|
+
--------------
|
12
|
+
|
13
|
+
Below is an example to extract all quoted strings from a string:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class QuotedStringFinder
|
17
|
+
include StreamParser
|
18
|
+
|
19
|
+
def parse
|
20
|
+
@stack = []
|
21
|
+
@results = []
|
22
|
+
|
23
|
+
while !eos?
|
24
|
+
case @stack.last
|
25
|
+
when :double_quoted_string
|
26
|
+
if scan_until('"') # Can only use pre_match is there is a match
|
27
|
+
@results << pre_match
|
28
|
+
@stack.pop
|
29
|
+
end
|
30
|
+
when :single_quoted_string
|
31
|
+
if scan_until("'") # Can only use pre_match is there is a match
|
32
|
+
@results << pre_match
|
33
|
+
@stack.pop
|
34
|
+
end
|
35
|
+
else
|
36
|
+
scan_until(/['"]/)
|
37
|
+
if match == '"'
|
38
|
+
@stack << :double_quoted_string
|
39
|
+
elsif match == "'"
|
40
|
+
@stack << :single_quoted_string
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
raise SyntaxError.new("Unbalanced Quotes in string") if !@stack.empty?
|
46
|
+
|
47
|
+
@results
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
QuotedStringFinder.parse(%q{Here "are" a few 'examples' for "you"})
|
52
|
+
# => ["are", "examples", "you"]
|
53
|
+
|
54
|
+
QuotedStringFinder.parse(%q{Here "ar})
|
55
|
+
# => SyntaxError "Unbalanced Quotes in string"
|
56
|
+
```
|
57
|
+
|
58
|
+
|
59
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module StreamParser
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
def parse(source, *args, **nparams, &block)
|
10
|
+
self.new(source).parse(*args, **nparams, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :match
|
16
|
+
|
17
|
+
def initialize(source)
|
18
|
+
@source = source
|
19
|
+
seek(0)
|
20
|
+
end
|
21
|
+
|
22
|
+
# def parse
|
23
|
+
# # implmentation
|
24
|
+
# end
|
25
|
+
|
26
|
+
def eos?
|
27
|
+
@index >= (@source.size - 1)
|
28
|
+
end
|
29
|
+
|
30
|
+
def scan_until(r)
|
31
|
+
r = Regexp.new(Regexp.escape(r)) if r.is_a?(String)
|
32
|
+
index = @source.index(r, @index)
|
33
|
+
match = @source.match(r, @index)
|
34
|
+
|
35
|
+
if match
|
36
|
+
@match = match.to_s
|
37
|
+
@old_index = @index
|
38
|
+
@index = index + @match.size
|
39
|
+
else
|
40
|
+
@match = nil
|
41
|
+
@old_index = @index
|
42
|
+
@index = @source.size - 1
|
43
|
+
end
|
44
|
+
match
|
45
|
+
end
|
46
|
+
|
47
|
+
def pre_match
|
48
|
+
@source[@old_index...(@index-@match.size)]
|
49
|
+
end
|
50
|
+
|
51
|
+
def rewind(by=1)
|
52
|
+
@index -= by
|
53
|
+
end
|
54
|
+
|
55
|
+
def forward(by=1)
|
56
|
+
@index += by
|
57
|
+
end
|
58
|
+
|
59
|
+
def seek(pos)
|
60
|
+
@old_index = nil
|
61
|
+
@match = nil
|
62
|
+
@index = pos
|
63
|
+
end
|
64
|
+
|
65
|
+
def next_char
|
66
|
+
@source[@index+1]
|
67
|
+
end
|
68
|
+
|
69
|
+
def prev_char
|
70
|
+
@source[@index-1]
|
71
|
+
end
|
72
|
+
|
73
|
+
def next_word
|
74
|
+
nw = @source.match(/\s*(\S+)/, @index)
|
75
|
+
nw.nil? ? nil : nw[1]
|
76
|
+
end
|
77
|
+
|
78
|
+
def current_line
|
79
|
+
start = @source.rindex(/(\n|\A)/, @index-(@match&.length||0)) || 0
|
80
|
+
start += 1 if @source[start] == "\n"
|
81
|
+
|
82
|
+
uptop = @source.index(/(\n|\z)/, @index)
|
83
|
+
uptop -= 1 if @source[uptop] == "\n"
|
84
|
+
|
85
|
+
@source[start..uptop]
|
86
|
+
end
|
87
|
+
|
88
|
+
def cursor
|
89
|
+
start = @source.rindex(/(\n|\A)/, @index-(@match&.length||0)) || 0
|
90
|
+
start += 1 if @source[start] == "\n"
|
91
|
+
|
92
|
+
uptop = @source.index(/(\n|\z)/, @index)
|
93
|
+
uptop -= 1 if @source[uptop] == "\n"
|
94
|
+
|
95
|
+
lineno = @source[0..start].count("\n") + 1
|
96
|
+
|
97
|
+
output = "#{lineno.to_s.rjust(4)}: #{@source[start..uptop]}\n "
|
98
|
+
output << if @match
|
99
|
+
" #{'-'* (@index-(@match.length)-start)}#{'^'*(@match.length)}"
|
100
|
+
else
|
101
|
+
"^"
|
102
|
+
end
|
103
|
+
output
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stream_parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jon Bracy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-05-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-reporters
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mocha
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
- jonbracy@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files:
|
103
|
+
- README.md
|
104
|
+
files:
|
105
|
+
- README.md
|
106
|
+
- lib/stream_parser.rb
|
107
|
+
- lib/stream_parser/version.rb
|
108
|
+
homepage: https://github.com/malomalo/stream_parser
|
109
|
+
licenses:
|
110
|
+
- MIT
|
111
|
+
metadata: {}
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options:
|
114
|
+
- "--main"
|
115
|
+
- README.md
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 3.0.0
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubygems_version: 3.2.3
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: SAX/Stream style parse helpers
|
133
|
+
test_files: []
|