sportdb-parser 0.7.1 → 0.8.0
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 +4 -4
- data/CHANGELOG.md +1 -1
- data/Manifest.txt +25 -7
- data/Rakefile +23 -0
- data/lib/sportdb/parser/debuggable.rb +53 -0
- data/lib/sportdb/parser/lexer-logger.rb +20 -0
- data/lib/sportdb/parser/lexer-on_goal.rb +167 -0
- data/lib/sportdb/parser/lexer-on_group_def.rb +31 -0
- data/lib/sportdb/parser/lexer-on_prop_lineup.rb +79 -0
- data/lib/sportdb/parser/lexer-on_prop_misc.rb +123 -0
- data/lib/sportdb/parser/lexer-on_prop_penalties.rb +40 -0
- data/lib/sportdb/parser/lexer-on_round_def.rb +37 -0
- data/lib/sportdb/parser/lexer-on_top.rb +133 -0
- data/lib/sportdb/parser/lexer-prep_doc.rb +131 -0
- data/lib/sportdb/parser/lexer-prep_line.rb +63 -0
- data/lib/sportdb/parser/lexer-tokenize.rb +468 -0
- data/lib/sportdb/parser/lexer.rb +122 -1376
- data/lib/sportdb/parser/lexer_buffer.rb +8 -37
- data/lib/sportdb/parser/lexer_token.rb +126 -0
- data/lib/sportdb/parser/parse_tree--core.rb +29 -0
- data/lib/sportdb/parser/parse_tree-match.rb +309 -0
- data/lib/sportdb/parser/parse_tree-props.rb +233 -0
- data/lib/sportdb/parser/parse_tree.rb +202 -0
- data/lib/sportdb/parser/parser-top.rb +102 -0
- data/lib/sportdb/parser/parser.rb +1253 -1392
- data/lib/sportdb/parser/token-date--helpers.rb +130 -0
- data/lib/sportdb/parser/token-date--names.rb +108 -0
- data/lib/sportdb/parser/token-date.rb +20 -192
- data/lib/sportdb/parser/token-date_duration.rb +8 -27
- data/lib/sportdb/parser/token-geo.rb +16 -16
- data/lib/sportdb/parser/token-goals--helpers.rb +114 -0
- data/lib/sportdb/parser/token-goals.rb +101 -255
- data/lib/sportdb/parser/token-group.rb +8 -22
- data/lib/sportdb/parser/token-prop.rb +178 -124
- data/lib/sportdb/parser/token-prop_name.rb +48 -39
- data/lib/sportdb/parser/token-round.rb +21 -35
- data/lib/sportdb/parser/token-score--helpers.rb +189 -0
- data/lib/sportdb/parser/token-score.rb +9 -393
- data/lib/sportdb/parser/token-score_full.rb +331 -0
- data/lib/sportdb/parser/token-status.rb +44 -46
- data/lib/sportdb/parser/token-status_inline.rb +112 -0
- data/lib/sportdb/parser/token-text.rb +41 -31
- data/lib/sportdb/parser/token-time.rb +29 -26
- data/lib/sportdb/parser/token.rb +90 -158
- data/lib/sportdb/parser/version.rb +2 -2
- data/lib/sportdb/parser.rb +88 -62
- metadata +27 -9
- data/lib/sportdb/parser/blocktxt.rb +0 -99
- data/lib/sportdb/parser/lexer_tty.rb +0 -111
- data/lib/sportdb/parser/racc_parser.rb +0 -88
- data/lib/sportdb/parser/racc_tree.rb +0 -557
- data/lib/sportdb/parser/token-table.rb +0 -149
- data/lib/sportdb/parser/token_helpers.rb +0 -92
- /data/lib/sportdb/parser/{parser_runtime.rb → parser-runtime.rb} +0 -0
|
@@ -2,7 +2,7 @@ module SportDb
|
|
|
2
2
|
class Lexer
|
|
3
3
|
|
|
4
4
|
####
|
|
5
|
-
#
|
|
5
|
+
#
|
|
6
6
|
## note - use \A (instead of ^) - \A strictly matches the start of the string.
|
|
7
7
|
##
|
|
8
8
|
## todo - add support for trailing markers e.g.
|
|
@@ -17,45 +17,45 @@ ROUND_OUTLINE_I_RE = %r{ \A
|
|
|
17
17
|
[ ]* ## ignore leading spaces (if any)
|
|
18
18
|
(?<round_marker>
|
|
19
19
|
[▪]{1,3} ## BLACK SMALL SQUARE e.g. ▪,▪▪,▪▪▪
|
|
20
|
-
)
|
|
20
|
+
)
|
|
21
21
|
[ ]+
|
|
22
22
|
(?<round_outline>
|
|
23
23
|
## must start with letter - why? why not?
|
|
24
24
|
### 1st round
|
|
25
|
-
## allow numbers e.g. Group A - 1
|
|
26
|
-
##
|
|
25
|
+
## allow numbers e.g. Group A - 1
|
|
26
|
+
##
|
|
27
27
|
## note - CANNOT incl. :| !!!
|
|
28
28
|
## used for markers for defs/definitions
|
|
29
|
-
[^:|]+? ## use non-greedy
|
|
29
|
+
[^:|]+? ## use non-greedy
|
|
30
30
|
)
|
|
31
31
|
(?:
|
|
32
|
-
[ ]+
|
|
32
|
+
[ ]+
|
|
33
33
|
[▪]+
|
|
34
34
|
)?
|
|
35
|
-
[ ]* ## ignore trailing spaces (if any)
|
|
35
|
+
[ ]* ## ignore trailing spaces (if any)
|
|
36
36
|
\z
|
|
37
37
|
}xi
|
|
38
38
|
|
|
39
39
|
ROUND_OUTLINE_II_RE = %r{ \A
|
|
40
40
|
[ ]* ## ignore leading spaces (if any)
|
|
41
41
|
(?<round_marker>
|
|
42
|
-
::{1,3} ## e.g. ::,:::,::::
|
|
43
|
-
)
|
|
42
|
+
::{1,3} ## e.g. ::,:::,::::
|
|
43
|
+
)
|
|
44
44
|
[ ]+
|
|
45
45
|
(?<round_outline>
|
|
46
46
|
## must start with letter - why? why not?
|
|
47
47
|
### 1st round
|
|
48
|
-
## allow numbers e.g. Group A - 1
|
|
49
|
-
##
|
|
48
|
+
## allow numbers e.g. Group A - 1
|
|
49
|
+
##
|
|
50
50
|
## note - CANNOT incl. :| !!!
|
|
51
51
|
## used for markers for defs/definitions
|
|
52
|
-
[^:|]+? ## use non-greedy
|
|
52
|
+
[^:|]+? ## use non-greedy
|
|
53
53
|
)
|
|
54
54
|
(?:
|
|
55
|
-
[ ]+
|
|
55
|
+
[ ]+
|
|
56
56
|
::+
|
|
57
57
|
)?
|
|
58
|
-
[ ]* ## ignore trailing spaces (if any)
|
|
58
|
+
[ ]* ## ignore trailing spaces (if any)
|
|
59
59
|
\z
|
|
60
60
|
}xi
|
|
61
61
|
|
|
@@ -65,38 +65,24 @@ ROUND_OUTLINE_RE = Regexp.union( ROUND_OUTLINE_I_RE,
|
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
###
|
|
68
|
-
# note - for def(initions) only one level support
|
|
68
|
+
# note - for def(initions) only one level support
|
|
69
69
|
# that is, no round outline additions possible (e.g ▪▪ 1st leg etc.)
|
|
70
70
|
ROUND_DEF_OUTLINE_RE = %r{ \A
|
|
71
71
|
[ ]* ## ignore leading spaces (if any)
|
|
72
72
|
(?: [▪] ## BLACK SMALL SQUARE
|
|
73
73
|
|
|
|
74
|
-
:: )
|
|
74
|
+
:: )
|
|
75
75
|
[ ]+
|
|
76
76
|
(?<round_outline>
|
|
77
|
-
[^:|]+? ## use non-greedy
|
|
77
|
+
[^:|]+? ## use non-greedy
|
|
78
78
|
)
|
|
79
|
-
[ ]* ## ignore trailing spaces (if any)
|
|
80
|
-
### possitive lookahead MUST be : OR |
|
|
81
|
-
(?= [:|]
|
|
82
|
-
[ ]) ## note: requires space for now after [:|] - keep - why? why not?
|
|
79
|
+
[ ]* ## ignore trailing spaces (if any)
|
|
80
|
+
### possitive lookahead MUST be : OR |
|
|
81
|
+
(?= [:|]
|
|
82
|
+
[ ]) ## note: requires space for now after [:|] - keep - why? why not?
|
|
83
83
|
}ix
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
ROUND_DEF_BASICS_RE = %r{
|
|
87
|
-
(?<spaces> [ ]{2,}) |
|
|
88
|
-
(?<space> [ ])
|
|
89
|
-
|
|
|
90
|
-
(?<sym> [:|,] ) ### note - add comma (,) as optional separator
|
|
91
|
-
}ix
|
|
92
|
-
|
|
93
|
-
ROUND_DEF_RE = Regexp.union( ROUND_DEF_BASICS_RE,
|
|
94
|
-
DURATION_RE, # note - duration MUST match before date
|
|
95
|
-
DATE_RE, ## note - date must go before time (e.g. 12.12. vs 12.12)
|
|
96
|
-
ANY_RE,
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
|
|
100
86
|
|
|
101
87
|
end # class Lexer
|
|
102
88
|
end # module SportDb
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
module SportDb
|
|
2
|
+
class Lexer
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def self._build_score( m )
|
|
6
|
+
## note - score is "generic"
|
|
7
|
+
## might be full-time (ft) or
|
|
8
|
+
## after extra-time (aet) or such
|
|
9
|
+
## or even undecided/unknown
|
|
10
|
+
## thus, use score1/score2 and NOT ft1/ft2
|
|
11
|
+
## thus, use (simply an) array e.g. [1,2]
|
|
12
|
+
## and NOT hash (table) e.g. { ft: [1,2] } !!!
|
|
13
|
+
|
|
14
|
+
score = [m[:score1].to_i(10),
|
|
15
|
+
m[:score2].to_i(10)]
|
|
16
|
+
|
|
17
|
+
score
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self._build_score_awd( m ) # score awarded (awd/awd.)
|
|
21
|
+
### note - use "generic" score for now
|
|
22
|
+
## to match A 3-0 B [awarded] etc.
|
|
23
|
+
score = [m[:score1].to_i(10),
|
|
24
|
+
m[:score2].to_i(10)]
|
|
25
|
+
## add score[:awarded] = true ???
|
|
26
|
+
## note - for now uses its own token e.g SCORE_AWD
|
|
27
|
+
score
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self._build_score_abd( m ) # score abandonded (abd/abd.)
|
|
31
|
+
### note - use "generic" score for now
|
|
32
|
+
score = [m[:score1].to_i(10),
|
|
33
|
+
m[:score2].to_i(10)]
|
|
34
|
+
## add score[:abd] = true ???
|
|
35
|
+
## note - for now uses its own token e.g SCORE_ABD
|
|
36
|
+
score
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def self._build_score_full( m )
|
|
41
|
+
score = {}
|
|
42
|
+
score[:p] = [m[:p1].to_i(10),
|
|
43
|
+
m[:p2].to_i(10)] if m[:p1] && m[:p2]
|
|
44
|
+
score[:et] = [m[:et1].to_i(10),
|
|
45
|
+
m[:et2].to_i(10)] if m[:et1] && m[:et2]
|
|
46
|
+
score[:ft] = [m[:ft1].to_i(10),
|
|
47
|
+
m[:ft2].to_i(10)] if m[:ft1] && m[:ft2]
|
|
48
|
+
score[:ht] = [m[:ht1].to_i(10),
|
|
49
|
+
m[:ht2].to_i(10)] if m[:ht1] && m[:ht2]
|
|
50
|
+
|
|
51
|
+
## add golden/silver flags
|
|
52
|
+
score[:golden] = true if m[:aetgg] ## golden goal (gg)/sudden death (sd)
|
|
53
|
+
score[:silver] = true if m[:aetsg] ## silver goal (sg)
|
|
54
|
+
|
|
55
|
+
score
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self._build_score_fuller( m )
|
|
59
|
+
score = {}
|
|
60
|
+
score[:p] = [m[:p1].to_i(10),
|
|
61
|
+
m[:p2].to_i(10)] if m[:p1] && m[:p2]
|
|
62
|
+
score[:et] = [m[:et1].to_i(10),
|
|
63
|
+
m[:et2].to_i(10)] if m[:et1] && m[:et2]
|
|
64
|
+
score[:ft] = [m[:ft1].to_i(10),
|
|
65
|
+
m[:ft2].to_i(10)] if m[:ft1] && m[:ft2]
|
|
66
|
+
score[:ht] = [m[:ht1].to_i(10),
|
|
67
|
+
m[:ht2].to_i(10)] if m[:ht1] && m[:ht2]
|
|
68
|
+
score[:agg] = [m[:agg1].to_i(10),
|
|
69
|
+
m[:agg2].to_i(10)] if m[:agg1] && m[:agg2]
|
|
70
|
+
|
|
71
|
+
if m[:away1] && m[:away2]
|
|
72
|
+
score[:away] = [m[:away1].to_i(10),
|
|
73
|
+
m[:away2].to_i(10)]
|
|
74
|
+
elsif m[:away] ## fallback if no away score; check away flag
|
|
75
|
+
score[:away] = true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
## add golden/silver flags
|
|
79
|
+
score[:golden] = true if m[:aetgg] ## golden goal (gg)/sudden death (sd)
|
|
80
|
+
score[:silver] = true if m[:aetsg] ## silver goal (sg)
|
|
81
|
+
|
|
82
|
+
score
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def self._build_score_fuller_more( m )
|
|
87
|
+
## SCORE + SCORE_FULLER_MORE
|
|
88
|
+
## note - after extra-time (aet) or full-time (ft)
|
|
89
|
+
## score may be present in SCORE!!!
|
|
90
|
+
score = {}
|
|
91
|
+
score[:p] = [m[:p1].to_i(10),
|
|
92
|
+
m[:p2].to_i(10)] if m[:p1] && m[:p2]
|
|
93
|
+
score[:et] = [m[:et1].to_i(10),
|
|
94
|
+
m[:et2].to_i(10)] if m[:et1] && m[:et2]
|
|
95
|
+
score[:ft] = [m[:ft1].to_i(10),
|
|
96
|
+
m[:ft2].to_i(10)] if m[:ft1] && m[:ft2]
|
|
97
|
+
score[:ht] = [m[:ht1].to_i(10),
|
|
98
|
+
m[:ht2].to_i(10)] if m[:ht1] && m[:ht2]
|
|
99
|
+
score[:agg] = [m[:agg1].to_i(10),
|
|
100
|
+
m[:agg2].to_i(10)] if m[:agg1] && m[:agg2]
|
|
101
|
+
|
|
102
|
+
if m[:away1] && m[:away2]
|
|
103
|
+
score[:away] = [m[:away1].to_i(10),
|
|
104
|
+
m[:away2].to_i(10)]
|
|
105
|
+
elsif m[:away] ## fallback if no away score; check away flag
|
|
106
|
+
score[:away] = true
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
## add golden/silver flags
|
|
110
|
+
score[:golden] = true if m[:aetgg] ## golden goal (gg)/sudden death (sd)
|
|
111
|
+
score[:silver] = true if m[:aetsg] ## silver goal (sg)
|
|
112
|
+
|
|
113
|
+
## add flag in score for et/ft/ht
|
|
114
|
+
## used for "dangling" (generic) score
|
|
115
|
+
score[:score] = 'et' if m[:aet] || m[:aetgg] || m[:aetsg]
|
|
116
|
+
score[:score] = 'ft' if m[:ft]
|
|
117
|
+
score[:score] = 'ht' if m[:ht]
|
|
118
|
+
|
|
119
|
+
score
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def self._build_score_legs( m )
|
|
124
|
+
legs = {}
|
|
125
|
+
|
|
126
|
+
############
|
|
127
|
+
### build leg1 (score)
|
|
128
|
+
score = {}
|
|
129
|
+
score[:ft] = [m[:leg1_ft1].to_i(10),
|
|
130
|
+
m[:leg1_ft2].to_i(10)]
|
|
131
|
+
legs['leg1'] = score
|
|
132
|
+
|
|
133
|
+
##################
|
|
134
|
+
### build leg2 (score)
|
|
135
|
+
score = {}
|
|
136
|
+
score[:ft] = [m[:leg2_ft1].to_i(10),
|
|
137
|
+
m[:leg2_ft2].to_i(10)] if m[:leg2_ft1] && m[:leg2_ft2]
|
|
138
|
+
score[:et] = [m[:leg2_et1].to_i(10),
|
|
139
|
+
m[:leg2_et2].to_i(10)] if m[:leg2_et1] && m[:leg2_et2]
|
|
140
|
+
score[:p] = [m[:leg2_p1].to_i(10),
|
|
141
|
+
m[:leg2_p2].to_i(10)] if m[:leg2_p1] && m[:leg2_p2]
|
|
142
|
+
legs['leg2'] = score
|
|
143
|
+
|
|
144
|
+
## check for (opt) aggregate - keep on "top-level"
|
|
145
|
+
legs[:agg] = [m[:agg1].to_i(10),
|
|
146
|
+
m[:agg2].to_i(10)] if m[:agg1] && m[:agg2]
|
|
147
|
+
legs[:away] = true if m[:away]
|
|
148
|
+
|
|
149
|
+
legs
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _build_score( m ) self.class._build_score( m ); end
|
|
154
|
+
def _build_score_awd( m ) self.class._build_score_awd( m ); end
|
|
155
|
+
def _build_score_abd( m ) self.class._build_score_abd( m ); end
|
|
156
|
+
def _build_score_full( m ) self.class._build_score_full( m ); end
|
|
157
|
+
def _build_score_fuller( m ) self.class._build_score_fuller( m ); end
|
|
158
|
+
def _build_score_fuller_more( m ) self.class._build_score_fuller_more( m ); end
|
|
159
|
+
def _build_score_legs( m ) self.class._build_score_legs( m ); end
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
###
|
|
165
|
+
## add parser helpers
|
|
166
|
+
|
|
167
|
+
def self._parse_score_full( str )
|
|
168
|
+
## note - strip - leading/trailing spaces automatic - why? why not?
|
|
169
|
+
|
|
170
|
+
m = Regexp.union(
|
|
171
|
+
SCORE_FULL_1ST_RE,
|
|
172
|
+
SCORE_FULL_RE ).match( str.strip )
|
|
173
|
+
|
|
174
|
+
if m && m.pre_match == '' && m.post_match == ''
|
|
175
|
+
pp m
|
|
176
|
+
_build_score_full( m )
|
|
177
|
+
elsif m
|
|
178
|
+
## note - match BUT not anchored to start and end-of-string!!!
|
|
179
|
+
## report, error somehow??
|
|
180
|
+
nil
|
|
181
|
+
else
|
|
182
|
+
nil ## no match - return nil
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
end # class Lexer
|
|
189
|
+
end # module SportDb
|