sportdb-parser 0.7.1 → 0.7.2

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -1
  3. data/Manifest.txt +17 -4
  4. data/lib/sportdb/parser/lexer-on_goal.rb +172 -0
  5. data/lib/sportdb/parser/lexer-on_group_def.rb +31 -0
  6. data/lib/sportdb/parser/lexer-on_prop_lineup.rb +79 -0
  7. data/lib/sportdb/parser/lexer-on_prop_misc.rb +110 -0
  8. data/lib/sportdb/parser/lexer-on_prop_penalties.rb +40 -0
  9. data/lib/sportdb/parser/lexer-on_round_def.rb +37 -0
  10. data/lib/sportdb/parser/lexer-on_top.rb +125 -0
  11. data/lib/sportdb/parser/lexer-prep_doc.rb +131 -0
  12. data/lib/sportdb/parser/lexer-prep_line.rb +63 -0
  13. data/lib/sportdb/parser/lexer-tokenize.rb +449 -0
  14. data/lib/sportdb/parser/lexer.rb +133 -1363
  15. data/lib/sportdb/parser/lexer_buffer.rb +8 -37
  16. data/lib/sportdb/parser/lexer_token.rb +126 -0
  17. data/lib/sportdb/parser/parser.rb +1104 -1403
  18. data/lib/sportdb/parser/racc_parser.rb +36 -32
  19. data/lib/sportdb/parser/racc_tree.rb +65 -98
  20. data/lib/sportdb/parser/token-date--helpers.rb +130 -0
  21. data/lib/sportdb/parser/token-date--names.rb +108 -0
  22. data/lib/sportdb/parser/token-date.rb +20 -192
  23. data/lib/sportdb/parser/token-date_duration.rb +8 -27
  24. data/lib/sportdb/parser/token-geo.rb +16 -16
  25. data/lib/sportdb/parser/token-goals--helpers.rb +114 -0
  26. data/lib/sportdb/parser/token-goals.rb +103 -249
  27. data/lib/sportdb/parser/token-group.rb +8 -22
  28. data/lib/sportdb/parser/token-prop.rb +138 -124
  29. data/lib/sportdb/parser/token-prop_name.rb +48 -39
  30. data/lib/sportdb/parser/token-round.rb +21 -35
  31. data/lib/sportdb/parser/token-score--helpers.rb +189 -0
  32. data/lib/sportdb/parser/token-score.rb +9 -393
  33. data/lib/sportdb/parser/token-score_full.rb +331 -0
  34. data/lib/sportdb/parser/token-status.rb +44 -46
  35. data/lib/sportdb/parser/token-status_inline.rb +112 -0
  36. data/lib/sportdb/parser/token-text.rb +41 -31
  37. data/lib/sportdb/parser/token-time.rb +29 -26
  38. data/lib/sportdb/parser/token.rb +58 -159
  39. data/lib/sportdb/parser/version.rb +1 -1
  40. data/lib/sportdb/parser.rb +45 -17
  41. metadata +19 -6
  42. data/lib/sportdb/parser/blocktxt.rb +0 -99
  43. data/lib/sportdb/parser/lexer_tty.rb +0 -111
  44. data/lib/sportdb/parser/token-table.rb +0 -149
  45. data/lib/sportdb/parser/token_helpers.rb +0 -92
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17e2ccd1472c3f56b5c1f4f4374e66de6b5297c67a5a0fa86206489ac560a00e
4
- data.tar.gz: 1c6de22e1c9dda2cc2a0b75654737882b7ce4c7e9f191b61889887c844fc35b9
3
+ metadata.gz: 35a69fdc1a31058e1a0069e89106bb68f2c9bbff10465a4111d0d0bf0eb3a210
4
+ data.tar.gz: 98f2e0b3f1d21d71b783d96c6e5cac7f2357d436951cae0865558a2289dd2bca
5
5
  SHA512:
6
- metadata.gz: ac121460004ce5f4287668ea8753feee5729124a265474bfcf065775ffd099a5f867109fc16b2d8d46b6ee7a327bdc8b4c14539f22d1ef43ee285f457097eae0
7
- data.tar.gz: 340afd868ceceeaa31532ea89251d5bfa2874f649933a18124bb4a5ba28e837c3a59284144d376f17c125ca93c12436cc473c7fda94a3b72866960fdc2c9cba8
6
+ metadata.gz: b7f43a3c0fd14130b2f5c278b0d0742b4a2d71a489383b80c8a8349c70ebb14280c54b53fc008782c9b539b4ffa4df1442c2f4e82e70ebea05a695343472f613
7
+ data.tar.gz: 7b636234a8a66671f35d5d7bdc0113b2df0131b9e065e86eb8f8c688b58ce2eb4d931e21a91a69bfb23dab5d56ed2b78d04400fd308c960fe9f1eb3653f5ab53
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.7.1
1
+ ### 0.7.2
2
2
  ### 0.0.1 / 2024-07-12
3
3
 
4
4
  * Everything is new. First release.
data/Manifest.txt CHANGED
@@ -3,30 +3,43 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/sportdb/parser.rb
6
- lib/sportdb/parser/blocktxt.rb
6
+ lib/sportdb/parser/lexer-on_goal.rb
7
+ lib/sportdb/parser/lexer-on_group_def.rb
8
+ lib/sportdb/parser/lexer-on_prop_lineup.rb
9
+ lib/sportdb/parser/lexer-on_prop_misc.rb
10
+ lib/sportdb/parser/lexer-on_prop_penalties.rb
11
+ lib/sportdb/parser/lexer-on_round_def.rb
12
+ lib/sportdb/parser/lexer-on_top.rb
13
+ lib/sportdb/parser/lexer-prep_doc.rb
14
+ lib/sportdb/parser/lexer-prep_line.rb
15
+ lib/sportdb/parser/lexer-tokenize.rb
7
16
  lib/sportdb/parser/lexer.rb
8
17
  lib/sportdb/parser/lexer_buffer.rb
9
- lib/sportdb/parser/lexer_tty.rb
18
+ lib/sportdb/parser/lexer_token.rb
10
19
  lib/sportdb/parser/parser.rb
11
20
  lib/sportdb/parser/parser_runtime.rb
12
21
  lib/sportdb/parser/racc_parser.rb
13
22
  lib/sportdb/parser/racc_tree.rb
23
+ lib/sportdb/parser/token-date--helpers.rb
24
+ lib/sportdb/parser/token-date--names.rb
14
25
  lib/sportdb/parser/token-date.rb
15
26
  lib/sportdb/parser/token-date_duration.rb
16
27
  lib/sportdb/parser/token-geo.rb
28
+ lib/sportdb/parser/token-goals--helpers.rb
17
29
  lib/sportdb/parser/token-goals.rb
18
30
  lib/sportdb/parser/token-group.rb
19
31
  lib/sportdb/parser/token-note.rb
20
32
  lib/sportdb/parser/token-prop.rb
21
33
  lib/sportdb/parser/token-prop_name.rb
22
34
  lib/sportdb/parser/token-round.rb
35
+ lib/sportdb/parser/token-score--helpers.rb
23
36
  lib/sportdb/parser/token-score.rb
37
+ lib/sportdb/parser/token-score_full.rb
24
38
  lib/sportdb/parser/token-score_fuller.rb
25
39
  lib/sportdb/parser/token-score_legs.rb
26
40
  lib/sportdb/parser/token-status.rb
27
- lib/sportdb/parser/token-table.rb
41
+ lib/sportdb/parser/token-status_inline.rb
28
42
  lib/sportdb/parser/token-text.rb
29
43
  lib/sportdb/parser/token-time.rb
30
44
  lib/sportdb/parser/token.rb
31
- lib/sportdb/parser/token_helpers.rb
32
45
  lib/sportdb/parser/version.rb
@@ -0,0 +1,172 @@
1
+ module SportDb
2
+ class Lexer
3
+
4
+
5
+
6
+
7
+ GOAL_RE = Regexp.union(
8
+ SPACES_RE,
9
+ GOAL_NONE_RE,
10
+ GOAL_MINUTE_RE,
11
+ GOAL_MINUTE_NA_RE,
12
+ GOAL_COUNT_RE,
13
+ PROP_NAME_RE, ## note - (re)use prop name for now for (player) name
14
+ GOAL_SEP_ALT_RE, ## note - add dash (-) with (required) spaces
15
+ / (?<sym> [;,)]) /x
16
+ ## todo/fix - add ANY_RE !!!!
17
+ )
18
+
19
+ def _on_goal( m, ctx: )
20
+
21
+ if m[:space] || m[:spaces]
22
+ nil ## skip space(s)
23
+ elsif m[:goals_none] ## note - eats-up semicolon!! e.g. -; or - ;
24
+ # was:[:GOALS_NONE,"<|GOALS_NONE|>"]
25
+ ## use literal text!!
26
+ Token.new( :GOALS_NONE, m[:goals_none],
27
+ lineno: ctx.lineno, offset: m.offset(:goals_none))
28
+ elsif m[:goal_sep_alt]
29
+ # was: [:GOAL_SEP_ALT, "<|GOAL_SEP_ALT|>" ] ## e.g. dash (-) WITH leading & trailing space required
30
+ Token.new( :GOAL_SEP_ALT, m[:goal_sep_alt],
31
+ lineno: ctx.lineno, offset: m.offset(:goal_sep_alt))
32
+ elsif m[:prop_name] ## note - change prop_name to player
33
+ Token.new( :PLAYER, m[:name],
34
+ lineno: ctx.lineno, offset: m.offset(:name))
35
+ elsif m[:goal_minute]
36
+ Token.new( :GOAL_MINUTE, m[:goal_minute],
37
+ lineno: ctx.lineno, offset: m.offset(:goal_minute),
38
+ value: _build_goal_minute( m ))
39
+ elsif m[:goal_minute_na]
40
+ ## note - (re)use GOAL_MINUTE token; no extra GOAL_MINUTE_NA or such - why? why not?
41
+ ## make sure to handle 'm' => nil upstream!!!
42
+ ## change to 999 or -1 or such - why? why not?
43
+ Token.new( :GOAL_MINUTE, m[:goal_minute_na],
44
+ lineno: ctx.lineno, offset: m.offset(:goal_minute_na),
45
+ value: _build_goal_minute_na( m ))
46
+ elsif m[:goal_count]
47
+ Token.new( :GOAL_COUNT, m[:goal_count],
48
+ lineno: ctx.lineno, offset: m.offset(:goal_count),
49
+ value: _build_goal_count( m ))
50
+ elsif m[:sym]
51
+ case m[:sym]
52
+ when ')' ## leave goal mode!!
53
+ _trace( "LEAVE GOAL_RE MODE" )
54
+ @re = RE
55
+ ## note - use/return GOAL_END token - change to GOAL_END_PAREN(THESIS)
56
+ ## or GOAL_PAREN_CLOSE/END ???
57
+ ## fix - use ) too - why? why not?
58
+ ## was: [:GOALS_END, '<|GOALS_END|>']
59
+ Token.virtual( :GOALS_END, lineno: ctx.lineno )
60
+ else
61
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
62
+ end
63
+ else
64
+ ctx.warn_on_else( m, mode: 'GOAL' )
65
+ nil
66
+ end
67
+ end
68
+
69
+
70
+
71
+
72
+ GOAL_ALT_RE = Regexp.union(
73
+ SPACES_RE,
74
+ SCORE_RE, ## e.g. 1-0, 0-1, etc.
75
+ GOAL_MINUTE_RE,
76
+ GOAL_TYPE_RE,
77
+ PROP_NAME_RE, ## note - (re)use prop name for now for (player) name
78
+ / (?<sym> [,)]) /x ## note - no semicolon (;)
79
+ ## todo/fix - add ANY_RE !!!!
80
+ )
81
+
82
+ def _on_goal_alt( m, ctx: )
83
+
84
+ if m[:space] || m[:spaces]
85
+ nil ## skip space(s)
86
+ elsif m[:prop_name] ## note - change prop_name to player
87
+ Token.new(:PLAYER, m[:name],
88
+ lineno: ctx.lineno, offset: m.offset(:name))
89
+ elsif m[:goal_minute]
90
+ Token.new( :GOAL_MINUTE, m[:goal_minute],
91
+ lineno: ctx.lineno, offset: m.offset(:goal_minute),
92
+ value: _build_goal_minute( m ))
93
+ elsif m[:goal_type]
94
+ Token.new( :GOAL_TYPE,m[:goal_type],
95
+ lineno: ctx.lineno, offset: m.offset(:goal_type),
96
+ value: _build_goal_type( m ))
97
+ elsif m[:score]
98
+ Token.new( :SCORE, m[:score],
99
+ lineno: ctx.lineno, offset: m.offset(:score),
100
+ value: _build_score( m ))
101
+ elsif m[:sym]
102
+ case m[:sym]
103
+ when ')' ## leave goal mode!!
104
+ _trace( "LEAVE GOAL_ALT_RE MODE" )
105
+ @re = RE
106
+ ## note - use/return GOAL_END token - change to GOAL_END_PAREN(THESIS)
107
+ ## or GOAL_PAREN_CLOSE/END ???
108
+ ## [:GOALS_END, '<|GOALS_END|>']
109
+ Token.virtual( :GOALS_END, lineno: ctx.lineno )
110
+ else
111
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
112
+ end
113
+ else
114
+ ctx.warn_on_else( m, mode: 'GOAL_ALT' )
115
+ nil
116
+ end
117
+ end
118
+
119
+
120
+
121
+ GOAL_COMPAT_RE = Regexp.union(
122
+ SPACES_RE,
123
+ SCORE_RE, ## e.g. 1-0, 0-1, etc.
124
+ MINUTE_RE, ## note - matches minute e.g. 92, 7, 7' 7+3, etc.
125
+ GOAL_TYPE_RE,
126
+ PROP_NAME_RE, ## note - (re)use prop name for now for (player) name
127
+ / (?<sym> [,)]) /x ## note - no semicolon (;)
128
+ ## todo/fix - add ANY_RE !!!!
129
+ )
130
+
131
+
132
+ def _on_goal_compat( m, ctx: ) ## note - m is MatchData object
133
+
134
+ if m[:space] || m[:spaces]
135
+ nil ## skip space(s)
136
+ elsif m[:prop_name] ## note - change prop_name to player
137
+ Token.new(:PLAYER, m[:name],
138
+ lineno: ctx.lineno, offset: m.offset(:name))
139
+ elsif m[:minute]
140
+ Token.new(:MINUTE, m[:minute],
141
+ lineno: ctx.lineno, offset: m.offset(:minute),
142
+ value: _build_minute( m ))
143
+ elsif m[:goal_type]
144
+ Token.new( :GOAL_TYPE,m[:goal_type],
145
+ lineno: ctx.lineno, offset: m.offset(:goal_type),
146
+ value: _build_goal_type( m ))
147
+
148
+ elsif m[:score]
149
+ Token.new( :SCORE, m[:score],
150
+ lineno: ctx.lineno, offset: m.offset(:score),
151
+ value: _build_score( m ))
152
+ elsif m[:sym]
153
+ case m[:sym]
154
+ when ')' ## leave goal mode!!
155
+ _trace( "LEAVE GOAL_COMPAT_RE MODE" )
156
+ @re = RE
157
+ ## note - use/return GOAL_END token - change to GOAL_END_PAREN(THESIS)
158
+ ## or GOAL_PAREN_CLOSE/END ???
159
+ ## [:GOALS_END, '<|GOALS_END|>']
160
+ Token.virtual( :GOALS_END, lineno: ctx.lineno )
161
+ else
162
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
163
+ end
164
+ else
165
+ ctx.warn_on_else( m, mode: 'GOAL_COMPAT' )
166
+ nil
167
+ end
168
+ end
169
+
170
+
171
+ end ## class Lexer
172
+ end ## module SportDb
@@ -0,0 +1,31 @@
1
+ module SportDb
2
+ class Lexer
3
+
4
+
5
+
6
+ ### note - add comma (,) as optional separator
7
+ GROUP_DEF_RE = Regexp.union( SPACES_RE,
8
+ TEXT_RE,
9
+ / (?<sym> [:|,] ) /x,
10
+ ANY_RE,
11
+ )
12
+
13
+
14
+ def _on_group_def( m, ctx: ) ## note - m is MatchData object
15
+
16
+ if m[:spaces] || m[:space]
17
+ nil ## skip spaces
18
+ elsif m[:text]
19
+ Token.new(:TEAM, m[:text],
20
+ lineno: ctx.lineno, offset: m.offset(:text))
21
+ elsif m[:sym]
22
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
23
+ else
24
+ ctx.warn_on_else( m, mode: 'GROUP_DEF' )
25
+ nil
26
+ end
27
+ end
28
+
29
+
30
+ end ## class Lexer
31
+ end ## module SportDb
@@ -0,0 +1,79 @@
1
+ module SportDb
2
+ class Lexer
3
+
4
+
5
+
6
+ PROP_LINEUP_RE = Regexp.union(
7
+ SPACES_RE,
8
+ MINUTE_RE, ## e.g. 44 or 44' or 45+1 or 45+1' etc.
9
+
10
+ INLINE_CAPTAIN, ## e.g. [c]
11
+ INLINE_YELLOW, ## e.g. [Y] or [Y 44] or [Y 44'] or [Y 45+1']
12
+ INLINE_YELLOW_RED, ## e.g. [Y/R] or [Y/R 78]
13
+ INLINE_RED, ## e.g. [R] or [R 42] or [R 42']
14
+
15
+ PROP_KEY_INLINE_RE,
16
+ PROP_NAME_RE,
17
+ / (?<sym> [;,()\[\]-]) /x
18
+ ## todo/fix - add ANY_RE here too!!!
19
+ )
20
+
21
+
22
+ def _on_prop_lineup( m, ctx: ) ## note - m is MatchData object
23
+
24
+ if m[:space] || m[:spaces]
25
+ nil ## skip space(s)
26
+ elsif m[:prop_key] ## check for inline prop keys
27
+ key = m[:key]
28
+ ## supported for now coach/trainer (add manager?)
29
+ if ['coach',
30
+ 'trainer'].include?( key.downcase )
31
+ ## use PROP_COACH or COACH_KEY or such - why? why not?
32
+ Token.new(:COACH, m[:key],
33
+ lineno: ctx.lineno, offset: m.offset(:key))
34
+ else
35
+ ## report error - for unknown (inline) prop key in lineup
36
+ nil
37
+ end
38
+ elsif m[:inline_captain]
39
+ Token.new(:INLINE_CAPTAIN, m[:inline_captain],
40
+ lineno: ctx.lineno, offset: m.offset(:inline_captain))
41
+ elsif m[:inline_yellow]
42
+ card = {}
43
+ card[:m] = m[:minute].to_i(10) if m[:minute]
44
+ card[:offset] = m[:offset].to_i(10) if m[:offset]
45
+ Token.new(:INLINE_YELLOW, m[:inline_yellow],
46
+ lineno: ctx.lineno, offset: m.offset(:inline_yellow),
47
+ value: card)
48
+ elsif m[:inline_red]
49
+ card = {}
50
+ card[:m] = m[:minute].to_i(10) if m[:minute]
51
+ card[:offset] = m[:offset].to_i(10) if m[:offset]
52
+ Token.new(:INLINE_RED, m[:inline_red],
53
+ lineno: ctx.lineno, offset: m.offset(:inline_red),
54
+ value: card)
55
+ elsif m[:inline_yellow_red]
56
+ card = {}
57
+ card[:m] = m[:minute].to_i(10) if m[:minute]
58
+ card[:offset] = m[:offset].to_i(10) if m[:offset]
59
+ Token.new(:INLINE_YELLOW_RED, m[:inline_yellow_red],
60
+ lineno: ctx.lineno, offset: m.offset(:inline_yellow_red),
61
+ value: card)
62
+ elsif m[:prop_name]
63
+ Token.new(:PROP_NAME, m[:name],
64
+ lineno: ctx.lineno, offset: m.offset(:prop_name))
65
+ elsif m[:minute]
66
+ Token.new(:MINUTE, m[:minute],
67
+ lineno: ctx.lineno, offset: m.offset(:minute),
68
+ value: _build_minute( m ))
69
+ elsif m[:sym]
70
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
71
+ else
72
+ ctx.warn_on_else( m, mode: 'PROP_LINEUP' )
73
+ nil
74
+ end
75
+ end
76
+
77
+
78
+ end ## class Lexer
79
+ end ## module SportDb
@@ -0,0 +1,110 @@
1
+ module SportDb
2
+ class Lexer
3
+
4
+
5
+
6
+ ## note - no inline keys possible
7
+ ## todo/fix - use custom (limited) prop basics too
8
+ PROP_CARDS_RE = Regexp.union(
9
+ SPACES_RE,
10
+ MINUTE_RE,
11
+ PROP_NAME_RE,
12
+ / (?<sym> [;,-]) /x
13
+ ## todo/fix - add ANY_RE here too!!!
14
+ )
15
+
16
+
17
+ def _on_prop_cards( m, ctx: ) ## note - m is MatchData object
18
+
19
+ if m[:space] || m[:spaces]
20
+ nil ## skip space(s)
21
+ elsif m[:prop_name]
22
+ Token.new(:PROP_NAME, m[:name],
23
+ lineno: ctx.lineno, offset: m.offset(:prop_name))
24
+ elsif m[:minute]
25
+ Token.new(:MINUTE, m[:minute],
26
+ lineno: ctx.lineno, offset: m.offset(:minute),
27
+ value: _build_minute( m ))
28
+ elsif m[:sym]
29
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
30
+ else
31
+ ctx.warn_on_else( m, mode: 'PROP_CARDS' )
32
+ nil
33
+ end
34
+ end
35
+
36
+
37
+
38
+ PROP_ATTENDANCE_RE = Regexp.union(
39
+ SPACES_RE,
40
+ ENCLOSED_NAME_RE, # e.g. (sold out) etc. why? why not?
41
+ PROP_NUM_RE, # e.g. 28 000 or 28_000 (NOT 28,000 is not valid!!!)
42
+ ## todo/fix - add ANY_RE here too!!!
43
+ )
44
+
45
+ def _on_prop_attendance( m, ctx: ) ## note - m is MatchData object
46
+
47
+ if m[:space] || m[:spaces]
48
+ nil ## skip space(s)
49
+ elsif m[:enclosed_name]
50
+ ## reserverd for use for sold out or such (in the future) - why? why not?
51
+ Token.new(:ENCLOSED_NAME, m[:name],
52
+ lineno: ctx.lineno, offset: m.offset(:name))
53
+ elsif m[:num]
54
+ Token.new(:PROP_NUM, m[:num],
55
+ lineno: ctx.lineno, offset: m.offset(:num),
56
+ value: m[:value].to_i(10))
57
+ else
58
+ ctx.warn_on_else( m, mode: 'PROP_ATTENDANCE' )
59
+ nil
60
+ end
61
+ end
62
+
63
+
64
+
65
+ PROP_REFEREE_RE = Regexp.union(
66
+ SPACES_RE,
67
+ ENCLOSED_NAME_RE, # e.g. (sold out) etc. why? why not?
68
+ PROP_NUM_RE, # e.g. 28 000 or 28_000 (NOT 28,000 is not valid!!!)
69
+ PROP_KEY_INLINE_RE,
70
+ PROP_NAME_RE,
71
+ / (?<sym> [;,]) /x
72
+ ## todo/fix - add ANY_RE here too!!!
73
+ )
74
+
75
+ def _on_prop_referee( m, ctx: ) ## note - m is MatchData object
76
+
77
+ if m[:space] || m[:spaces]
78
+ nil ## skip space(s)
79
+ elsif m[:prop_key] ## check for inline prop keys
80
+ key = m[:key]
81
+ ## supported for now coach/trainer (add manager?)
82
+ if ['att', 'attn', 'attendance' ].include?( key.downcase )
83
+ ## use ATTENDANCE_PROP or ATTENDANCE_KEY or such - why? why not?
84
+ Token.new(:ATTENDANCE, m[:key],
85
+ lineno: ctx.lineno, offset: m.offset(:key))
86
+ else
87
+ ## report error - for unknown (inline) prop key in lineup
88
+ nil
89
+ end
90
+ elsif m[:prop_name] ## note - change prop_name to player or to (plain) name?
91
+ Token.new(:PROP_NAME, m[:name],
92
+ lineno: ctx.lineno, offset: m.offset(:prop_name))
93
+ elsif m[:num]
94
+ Token.new(:PROP_NUM, m[:num],
95
+ lineno: ctx.lineno, offset: m.offset(:num),
96
+ value: m[:value].to_i(10))
97
+ elsif m[:enclosed_name]
98
+ ## use HOLD,SAVE,POST or such keys - why? why not?
99
+ Token.new(:ENCLOSED_NAME, m[:name],
100
+ lineno: ctx.lineno, offset: m.offset(:name))
101
+ elsif m[:sym]
102
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
103
+ else
104
+ ctx.warn_on_else( m, mode: 'PROP_REFEREE' )
105
+ nil
106
+ end
107
+ end
108
+
109
+ end ## class Lexer
110
+ end ## module SportDb
@@ -0,0 +1,40 @@
1
+ module SportDb
2
+ class Lexer
3
+
4
+
5
+
6
+
7
+ PROP_PENALTIES_RE = Regexp.union(
8
+ SPACES_RE,
9
+ SCORE_RE, # e.g. 1-1 etc.
10
+ ENCLOSED_NAME_RE, # e.g. (save), (post), etc.
11
+ PROP_NAME_RE,
12
+ / (?<sym> [;,]) /x ## add [] too - why? why not?
13
+ ## todo/fix - add ANY_RE here too!!!
14
+ )
15
+
16
+ def _on_prop_penalties( m, ctx: ) ## note - m is MatchData object
17
+ if m[:space] || m[:spaces]
18
+ nil ## skip space(s)
19
+ elsif m[:prop_name] ## note - change prop_name to player
20
+ Token.new(:PROP_NAME, m[:name],
21
+ lineno: ctx.lineno, offset: m.offset(:prop_name))
22
+ elsif m[:enclosed_name]
23
+ ## use HOLD,SAVE,POST or such keys - why? why not?
24
+ Token.new(:ENCLOSED_NAME, m[:name],
25
+ lineno: ctx.lineno, offset: m.offset(:name))
26
+ elsif m[:score]
27
+ Token.new( :SCORE, m[:score],
28
+ lineno: ctx.lineno, offset: m.offset(:score),
29
+ value: _build_score( m ))
30
+ elsif m[:sym]
31
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
32
+ else
33
+ ctx.warn_on_else( m, mode: 'PROP_PENALTIES ')
34
+ nil
35
+ end
36
+ end
37
+
38
+
39
+ end ## class Lexer
40
+ end ## module SportDb
@@ -0,0 +1,37 @@
1
+ module SportDb
2
+ class Lexer
3
+
4
+
5
+
6
+ ### note - add comma (,) as optional separator
7
+ ROUND_DEF_RE = Regexp.union( SPACES_RE,
8
+ DURATION_RE, # note - duration MUST match before date
9
+ DATE_RE, ## note - date must go before time (e.g. 12.12. vs 12.12)
10
+ / (?<sym> [:|,] ) /x,
11
+ ANY_RE
12
+ )
13
+
14
+
15
+ def _on_round_def( m, ctx: ) ## note - m is MatchData object
16
+
17
+
18
+ if m[:spaces] || m[:space]
19
+ nil ## skip spaces
20
+ elsif m[:date]
21
+ Token.new(:DATE, m[:date],
22
+ lineno: ctx.lineno, offset: m.offset(:date),
23
+ value: _build_date(m))
24
+ elsif m[:duration]
25
+ Token.new(:DURATION, m[:duration],
26
+ lineno: ctx.lineno, offset: m.offset(:duration),
27
+ value: _build_duration( m ))
28
+ elsif m[:sym]
29
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
30
+ else
31
+ ctx.warn_on_else( m, mode: 'ROUND_DEF' )
32
+ nil
33
+ end
34
+ end
35
+
36
+ end ## class Lexer
37
+ end ## module SportDb
@@ -0,0 +1,125 @@
1
+ module SportDb
2
+ class Lexer
3
+
4
+
5
+ def _on_top( m, ctx: ) ## note - m is MatchData object
6
+
7
+ ## note - top-level (for now always) assumes TEAM for TEXT match!!
8
+ ## fix/fix/fix change TEXT_RE/:text to TEAM_RE/:team !!!
9
+
10
+ if m[:space] || m[:spaces]
11
+ nil ## skip space(s)
12
+ elsif m[:text] then Token.new(:TEAM, m[:text],
13
+ lineno: ctx.lineno, offset: m.offset(:text))
14
+ elsif m[:team_home] then Token.new(:TEAM_HOME, m[:team_home],
15
+ lineno: ctx.lineno, offset: m.offset(:team_home))
16
+ elsif m[:team_away] then Token.new(:TEAM_AWAY, m[:team_away],
17
+ lineno: ctx.lineno, offset: m.offset(:team_away))
18
+ elsif m[:team_neutral] then Token.new(:TEAM_NEUTRAL, m[:team_neutral],
19
+ lineno: ctx.lineno, offset: m.offset(:team_neutral))
20
+
21
+ ## (match) status e.g. cancelled, awarded, etc.
22
+ ## inline: w/o - walkover
23
+ ## n/p - not played
24
+ ## bye
25
+ ## abd/abd. - abandoned
26
+ ## void
27
+ ## susp/susp. - suspended
28
+ ## ppd/ppd. or postp/postp. - postponed
29
+ ## awd/awd. - awarded
30
+ ## canc/canc. - cancelled/canceled
31
+ elsif m[:inline_wo] then Token.new(:INLINE_WO, m[:inline_wo],
32
+ lineno: ctx.lineno, offset: m.offset(:inline_wo))
33
+ elsif m[:inline_np] then Token.new(:INLINE_NP, m[:inline_np],
34
+ lineno: ctx.lineno, offset: m.offset(:inline_np))
35
+ elsif m[:inline_bye] then Token.new(:INLINE_BYE, m[:inline_bye],
36
+ lineno: ctx.lineno, offset: m.offset(:inline_bye))
37
+ elsif m[:inline_abd] then Token.new(:INLINE_ABD, m[:inline_abd],
38
+ lineno: ctx.lineno, offset: m.offset(:inline_abd))
39
+ elsif m[:inline_void] then Token.new(:INLINE_VOID, m[:inline_void],
40
+ lineno: ctx.lineno, offset: m.offset(:inline_void))
41
+ elsif m[:inline_susp] then Token.new(:INLINE_SUSP, m[:inline_susp],
42
+ lineno: ctx.lineno, offset: m.offset(:inline_susp))
43
+ elsif m[:inline_ppd] then Token.new(:INLINE_PPD, m[:inline_ppd],
44
+ lineno: ctx.lineno, offset: m.offset(:inline_ppd))
45
+ elsif m[:inline_awd] then Token.new(:INLINE_AWD, m[:inline_awd],
46
+ lineno: ctx.lineno, offset: m.offset(:inline_awd))
47
+ elsif m[:inline_canc] then Token.new(:INLINE_CANC, m[:inline_canc],
48
+ lineno: ctx.lineno, offset: m.offset(:inline_canc))
49
+ elsif m[:status] then Token.new(:STATUS, m[:status],
50
+ lineno: ctx.lineno, offset: m.offset(:status),
51
+ value: _build_status( m ))
52
+ elsif m[:note]
53
+ ### todo/check:
54
+ ## use value hash - why? why not? or simplify to:
55
+ ## [:NOTE, [m[:note], {note: m[:note] } ]]
56
+ Token.new(:NOTE, m[:note],
57
+ lineno: ctx.lineno, offset: m.offset(:note))
58
+
59
+ elsif m[:attendance]
60
+ att = {}
61
+ att[:value] = m[:value].gsub( '_', '' ).to_i(10)
62
+ ## note - for token id use INLINE_ATTENDANCE (ATTENDANCE in use for prop!!!)
63
+ Token.new(:INLINE_ATTENDANCE, m[:attendance],
64
+ lineno: ctx.lineno, offset: m.offset(:attendance),
65
+ value: att)
66
+
67
+ elsif m[:time] then Token.new(:TIME, m[:time],
68
+ lineno: ctx.lineno, offset: m.offset(:time),
69
+ value: _build_time(m))
70
+ elsif m[:date] then Token.new(:DATE, m[:date],
71
+ lineno: ctx.lineno, offset: m.offset(:date),
72
+ value: _build_date(m))
73
+ elsif m[:date_legs] then Token.new(:DATE_LEGS, m[:date_legs],
74
+ lineno: ctx.lineno, offset: m.offset(:date_legs),
75
+ value: _build_date_legs(m))
76
+
77
+ elsif m[:score_legs] then Token.new(:SCORE_LEGS, m[:score_legs],
78
+ lineno: ctx.lineno, offset: m.offset(:score_legs),
79
+ value: _build_score_legs( m ))
80
+ elsif m[:score_full] then Token.new(:SCORE_FULL, m[:score_full],
81
+ lineno: ctx.lineno, offset: m.offset(:score_full),
82
+ value: _build_score_full( m ))
83
+ elsif m[:score_fuller] then Token.new(:SCORE_FULLER, m[:score_fuller],
84
+ lineno: ctx.lineno, offset: m.offset(:score_fuller),
85
+ value: _build_score_fuller( m ))
86
+ elsif m[:score_fuller_more] then Token.new(:SCORE_FULLER_MORE, m[:score_fuller_more],
87
+ lineno: ctx.lineno, offset: m.offset(:score_fuller_more),
88
+ value: _build_score_fuller_more( m ))
89
+ elsif m[:score] then Token.new(:SCORE, m[:score],
90
+ lineno: ctx.lineno, offset: m.offset(:score),
91
+ value: _build_score( m ))
92
+ elsif m[:score_awd] then Token.new(:SCORE_AWD, m[:score_awd],
93
+ lineno: ctx.lineno, offset: m.offset(:score_awd),
94
+ value: _build_score_awd( m ))
95
+ elsif m[:score_abd] then Token.new(:SCORE_ABD, m[:score_abd],
96
+ lineno: ctx.lineno, offset: m.offset(:score_abd),
97
+ value: _build_score_abd( m ))
98
+
99
+ elsif m[:vs] then Token.new(:VS, m[:vs],
100
+ lineno: ctx.lineno, offset: m.offset(:vs))
101
+ elsif m[:sym]
102
+ case m[:sym] ## return symbols "inline" as is - why? why not?
103
+ when '@' ## enter geo mode
104
+ _trace( 'ENTER GEO_RE MODE' )
105
+ @re = GEO_RE
106
+ @geo_count = 0
107
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
108
+ when '(' ## enter goal scorer mode on "free-floating" open paranthesis!!!
109
+ _trace( 'ENTER GOAL_RE MODE' )
110
+ @re = GOAL_RE
111
+ ## note - eat-up ( for now; do NOT pass along as token
112
+ ## pass along "virutal" INLINE GOALS - why? why not?
113
+ Token.virtual( :INLINE_GOALS, lineno: ctx.lineno )
114
+ else
115
+ Token.literal( m[:sym], lineno: ctx.lineno, offset: m.offset(:sym))
116
+ end
117
+ else
118
+ ctx.warn_on_else( m )
119
+ nil
120
+ end
121
+ end
122
+
123
+
124
+ end ## class Lexer
125
+ end ## module SportDb