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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -1
  3. data/Manifest.txt +25 -7
  4. data/Rakefile +23 -0
  5. data/lib/sportdb/parser/debuggable.rb +53 -0
  6. data/lib/sportdb/parser/lexer-logger.rb +20 -0
  7. data/lib/sportdb/parser/lexer-on_goal.rb +167 -0
  8. data/lib/sportdb/parser/lexer-on_group_def.rb +31 -0
  9. data/lib/sportdb/parser/lexer-on_prop_lineup.rb +79 -0
  10. data/lib/sportdb/parser/lexer-on_prop_misc.rb +123 -0
  11. data/lib/sportdb/parser/lexer-on_prop_penalties.rb +40 -0
  12. data/lib/sportdb/parser/lexer-on_round_def.rb +37 -0
  13. data/lib/sportdb/parser/lexer-on_top.rb +133 -0
  14. data/lib/sportdb/parser/lexer-prep_doc.rb +131 -0
  15. data/lib/sportdb/parser/lexer-prep_line.rb +63 -0
  16. data/lib/sportdb/parser/lexer-tokenize.rb +468 -0
  17. data/lib/sportdb/parser/lexer.rb +122 -1376
  18. data/lib/sportdb/parser/lexer_buffer.rb +8 -37
  19. data/lib/sportdb/parser/lexer_token.rb +126 -0
  20. data/lib/sportdb/parser/parse_tree--core.rb +29 -0
  21. data/lib/sportdb/parser/parse_tree-match.rb +309 -0
  22. data/lib/sportdb/parser/parse_tree-props.rb +233 -0
  23. data/lib/sportdb/parser/parse_tree.rb +202 -0
  24. data/lib/sportdb/parser/parser-top.rb +102 -0
  25. data/lib/sportdb/parser/parser.rb +1253 -1392
  26. data/lib/sportdb/parser/token-date--helpers.rb +130 -0
  27. data/lib/sportdb/parser/token-date--names.rb +108 -0
  28. data/lib/sportdb/parser/token-date.rb +20 -192
  29. data/lib/sportdb/parser/token-date_duration.rb +8 -27
  30. data/lib/sportdb/parser/token-geo.rb +16 -16
  31. data/lib/sportdb/parser/token-goals--helpers.rb +114 -0
  32. data/lib/sportdb/parser/token-goals.rb +101 -255
  33. data/lib/sportdb/parser/token-group.rb +8 -22
  34. data/lib/sportdb/parser/token-prop.rb +178 -124
  35. data/lib/sportdb/parser/token-prop_name.rb +48 -39
  36. data/lib/sportdb/parser/token-round.rb +21 -35
  37. data/lib/sportdb/parser/token-score--helpers.rb +189 -0
  38. data/lib/sportdb/parser/token-score.rb +9 -393
  39. data/lib/sportdb/parser/token-score_full.rb +331 -0
  40. data/lib/sportdb/parser/token-status.rb +44 -46
  41. data/lib/sportdb/parser/token-status_inline.rb +112 -0
  42. data/lib/sportdb/parser/token-text.rb +41 -31
  43. data/lib/sportdb/parser/token-time.rb +29 -26
  44. data/lib/sportdb/parser/token.rb +90 -158
  45. data/lib/sportdb/parser/version.rb +2 -2
  46. data/lib/sportdb/parser.rb +88 -62
  47. metadata +27 -9
  48. data/lib/sportdb/parser/blocktxt.rb +0 -99
  49. data/lib/sportdb/parser/lexer_tty.rb +0 -111
  50. data/lib/sportdb/parser/racc_parser.rb +0 -88
  51. data/lib/sportdb/parser/racc_tree.rb +0 -557
  52. data/lib/sportdb/parser/token-table.rb +0 -149
  53. data/lib/sportdb/parser/token_helpers.rb +0 -92
  54. /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