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
data/lib/sportdb/parser.rb
CHANGED
|
@@ -1,112 +1,138 @@
|
|
|
1
|
-
## pulls in
|
|
2
1
|
require 'cocos'
|
|
3
2
|
|
|
4
3
|
|
|
5
|
-
####
|
|
6
|
-
# try a (simple) tokenizer/parser with regex
|
|
7
4
|
|
|
8
|
-
## note - match line-by-line
|
|
9
|
-
# avoid massive backtracking by definition
|
|
10
|
-
# that is, making it impossible
|
|
11
5
|
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
require_relative 'parser/version'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
require_relative 'parser/debuggable' ## generic debug/logger helper
|
|
14
10
|
|
|
15
11
|
|
|
16
|
-
require_relative 'parser/version'
|
|
17
12
|
|
|
18
13
|
##
|
|
19
|
-
##
|
|
20
|
-
|
|
14
|
+
## add shared/most basic regexes here
|
|
15
|
+
## todo - use ANY_RE to token_commons or such - for shared by many?
|
|
16
|
+
module SportDb
|
|
17
|
+
class Lexer
|
|
18
|
+
|
|
19
|
+
## general catch-all (RECOMMENDED (ALWAYS) use as last entry in union)
|
|
20
|
+
## to avoid advance of pos match!!!
|
|
21
|
+
ANY_RE = %r{
|
|
22
|
+
(?<any> .)
|
|
23
|
+
}ix
|
|
24
|
+
|
|
25
|
+
SPACES_RE = %r{
|
|
26
|
+
(?<spaces> [ ]{2,})
|
|
27
|
+
| (?<space> [ ])
|
|
28
|
+
}ix
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
end # class Lexer
|
|
32
|
+
end # module SportDb
|
|
21
33
|
|
|
22
|
-
## core machinery
|
|
23
34
|
|
|
24
35
|
require_relative 'parser/token-score'
|
|
36
|
+
require_relative 'parser/token-score_full'
|
|
25
37
|
require_relative 'parser/token-score_fuller'
|
|
26
38
|
require_relative 'parser/token-score_legs'
|
|
39
|
+
require_relative 'parser/token-score--helpers'
|
|
40
|
+
|
|
27
41
|
require_relative 'parser/token-time'
|
|
42
|
+
require_relative 'parser/token-date--names'
|
|
28
43
|
require_relative 'parser/token-date'
|
|
29
44
|
require_relative 'parser/token-date_duration'
|
|
45
|
+
require_relative 'parser/token-date--helpers'
|
|
46
|
+
|
|
30
47
|
require_relative 'parser/token-text'
|
|
48
|
+
require_relative 'parser/token-prop' ## team prop(erty) mode (note - must be before token)
|
|
31
49
|
require_relative 'parser/token-prop_name' ## a.k.a token-text_ii
|
|
32
50
|
require_relative 'parser/token-status'
|
|
51
|
+
require_relative 'parser/token-status_inline'
|
|
33
52
|
require_relative 'parser/token-note'
|
|
34
53
|
require_relative 'parser/token-goals'
|
|
35
|
-
require_relative 'parser/token-
|
|
54
|
+
require_relative 'parser/token-goals--helpers'
|
|
36
55
|
require_relative 'parser/token-geo'
|
|
37
56
|
require_relative 'parser/token-group'
|
|
38
57
|
require_relative 'parser/token-round'
|
|
39
|
-
require_relative 'parser/token-table'
|
|
40
58
|
require_relative 'parser/token'
|
|
41
59
|
|
|
42
60
|
|
|
43
|
-
|
|
44
|
-
require_relative 'parser/token_helpers'
|
|
61
|
+
|
|
45
62
|
|
|
46
63
|
|
|
47
64
|
require_relative 'parser/lexer_buffer' ## incl. Tokens (aka TokenBuffer)
|
|
65
|
+
require_relative 'parser/lexer_token'
|
|
66
|
+
|
|
67
|
+
require_relative 'parser/lexer-prep_doc'
|
|
68
|
+
require_relative 'parser/lexer-prep_line'
|
|
69
|
+
|
|
70
|
+
require_relative 'parser/lexer-logger' ## e.g. _trace, _warn, _info, etc.
|
|
71
|
+
require_relative 'parser/lexer-tokenize'
|
|
72
|
+
require_relative 'parser/lexer-on_round_def'
|
|
73
|
+
require_relative 'parser/lexer-on_group_def'
|
|
74
|
+
require_relative 'parser/lexer-on_prop_misc'
|
|
75
|
+
require_relative 'parser/lexer-on_prop_lineup'
|
|
76
|
+
require_relative 'parser/lexer-on_prop_penalties'
|
|
77
|
+
require_relative 'parser/lexer-on_goal'
|
|
78
|
+
require_relative 'parser/lexer-on_top'
|
|
48
79
|
require_relative 'parser/lexer'
|
|
49
|
-
require_relative 'parser/lexer_tty' ## teletype (tty) mode
|
|
50
80
|
|
|
51
81
|
|
|
52
82
|
## note - use "embeded" racc parser runtime
|
|
53
83
|
## MUST uncomment require 'racc/parser' in generated parser!!!
|
|
54
|
-
require_relative 'parser/
|
|
84
|
+
require_relative 'parser/parser-runtime'
|
|
55
85
|
|
|
56
86
|
require_relative 'parser/parser' ## auto-generated by racc (from parser.y)
|
|
57
|
-
require_relative 'parser/
|
|
58
|
-
|
|
87
|
+
require_relative 'parser/parser-top'
|
|
88
|
+
|
|
89
|
+
require_relative 'parser/parse_tree--core' ## incl. core extensions eg. as_json on Object/Array/Hash
|
|
90
|
+
require_relative 'parser/parse_tree'
|
|
91
|
+
require_relative 'parser/parse_tree-match'
|
|
92
|
+
require_relative 'parser/parse_tree-props'
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
## deprecated - remove old RaccMatchParser name sooner than later!!
|
|
96
|
+
## use Fbtxt.parse for "public" api
|
|
97
|
+
RaccMatchParser = SportDb::Parser
|
|
59
98
|
|
|
60
99
|
|
|
61
100
|
|
|
62
101
|
###
|
|
63
102
|
# make parser api (easily) available - why? why not?
|
|
103
|
+
#
|
|
104
|
+
# use Fbtxt.parse( txt ) &&
|
|
105
|
+
# Fbtxt.lex( txt) -- or Fbtxt.tokenize?
|
|
106
|
+
#
|
|
107
|
+
# Fbtxt.lex( txt,
|
|
108
|
+
# flatten: true|false, ## keep nested [] for lines (no NEWLINE tokens)
|
|
109
|
+
# transform: true|false ) ## builtin transforms eg. merge DATE & TIME => DATETIME, etc.
|
|
110
|
+
#
|
|
111
|
+
# how to deal with errors?
|
|
112
|
+
## always return [tokens, errors] or such?
|
|
113
|
+
## or return a Result struct - why? why not?
|
|
64
114
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
module Fbtxt
|
|
118
|
+
|
|
119
|
+
def self.lex( txt, flatten: true ) ## returns SportDb::LexerResult (ok?/tokens/errors)
|
|
120
|
+
lexer = SportDb::Lexer.new( txt )
|
|
121
|
+
## move "wrapping" into result obj inside lexer - why? why not?
|
|
122
|
+
tokens, errors = lexer.tokenize_with_errors( flatten: flatten )
|
|
123
|
+
SportDb::LexerResult.new( tokens, errors )
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.parse( txt ) ## returns SportDb::ParserResult (ok?/tree/errors)
|
|
127
|
+
parser = SportDb::Parser.new( txt )
|
|
128
|
+
## move "wrapping" into result obj inside parser - why? why not?
|
|
129
|
+
tree, errors = parser.parse_with_errors
|
|
130
|
+
SportDb::ParserResult.new( tree, errors )
|
|
131
|
+
end
|
|
132
|
+
end # module Fbtxt
|
|
74
133
|
|
|
75
134
|
|
|
76
135
|
|
|
77
|
-
module SportDb
|
|
78
|
-
class Parser
|
|
79
|
-
####################
|
|
80
|
-
# "default" lexer & parser (wraps RaccMatchParser)
|
|
81
|
-
|
|
82
|
-
def tokenize_with_errors( lines, debug: false )
|
|
83
|
-
lexer = Lexer.new( lines )
|
|
84
|
-
tokens, errors = lexer.tokenize_with_errors
|
|
85
|
-
[tokens, errors]
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
### convience helper - ignore errors by default
|
|
89
|
-
def tokenize( lines, debug: false )
|
|
90
|
-
tokens, _ = tokenize_with_errors( lines, debug: debug )
|
|
91
|
-
tokens
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def parse_with_errors( lines, debug: false )
|
|
96
|
-
## todo/check - if lines needs to chack for array of lines and such
|
|
97
|
-
## or handled by tokenizer???
|
|
98
|
-
parser = RaccMatchParser.new( lines )
|
|
99
|
-
tree, errors = parser.parse_with_errors
|
|
100
|
-
[tree, errors]
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
### convience helper - ignore errors by default
|
|
104
|
-
def parse( lines, debug: false )
|
|
105
|
-
tree, _ = parse_with_errors( lines, debug: debug )
|
|
106
|
-
tree
|
|
107
|
-
end
|
|
108
|
-
end # class Parser
|
|
109
|
-
end # module SportDb
|
|
110
136
|
|
|
111
137
|
|
|
112
138
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sportdb-parser
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gerald Bauer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cocos
|
|
@@ -72,32 +72,50 @@ files:
|
|
|
72
72
|
- README.md
|
|
73
73
|
- Rakefile
|
|
74
74
|
- lib/sportdb/parser.rb
|
|
75
|
-
- lib/sportdb/parser/
|
|
75
|
+
- lib/sportdb/parser/debuggable.rb
|
|
76
|
+
- lib/sportdb/parser/lexer-logger.rb
|
|
77
|
+
- lib/sportdb/parser/lexer-on_goal.rb
|
|
78
|
+
- lib/sportdb/parser/lexer-on_group_def.rb
|
|
79
|
+
- lib/sportdb/parser/lexer-on_prop_lineup.rb
|
|
80
|
+
- lib/sportdb/parser/lexer-on_prop_misc.rb
|
|
81
|
+
- lib/sportdb/parser/lexer-on_prop_penalties.rb
|
|
82
|
+
- lib/sportdb/parser/lexer-on_round_def.rb
|
|
83
|
+
- lib/sportdb/parser/lexer-on_top.rb
|
|
84
|
+
- lib/sportdb/parser/lexer-prep_doc.rb
|
|
85
|
+
- lib/sportdb/parser/lexer-prep_line.rb
|
|
86
|
+
- lib/sportdb/parser/lexer-tokenize.rb
|
|
76
87
|
- lib/sportdb/parser/lexer.rb
|
|
77
88
|
- lib/sportdb/parser/lexer_buffer.rb
|
|
78
|
-
- lib/sportdb/parser/
|
|
89
|
+
- lib/sportdb/parser/lexer_token.rb
|
|
90
|
+
- lib/sportdb/parser/parse_tree--core.rb
|
|
91
|
+
- lib/sportdb/parser/parse_tree-match.rb
|
|
92
|
+
- lib/sportdb/parser/parse_tree-props.rb
|
|
93
|
+
- lib/sportdb/parser/parse_tree.rb
|
|
94
|
+
- lib/sportdb/parser/parser-runtime.rb
|
|
95
|
+
- lib/sportdb/parser/parser-top.rb
|
|
79
96
|
- lib/sportdb/parser/parser.rb
|
|
80
|
-
- lib/sportdb/parser/
|
|
81
|
-
- lib/sportdb/parser/
|
|
82
|
-
- lib/sportdb/parser/racc_tree.rb
|
|
97
|
+
- lib/sportdb/parser/token-date--helpers.rb
|
|
98
|
+
- lib/sportdb/parser/token-date--names.rb
|
|
83
99
|
- lib/sportdb/parser/token-date.rb
|
|
84
100
|
- lib/sportdb/parser/token-date_duration.rb
|
|
85
101
|
- lib/sportdb/parser/token-geo.rb
|
|
102
|
+
- lib/sportdb/parser/token-goals--helpers.rb
|
|
86
103
|
- lib/sportdb/parser/token-goals.rb
|
|
87
104
|
- lib/sportdb/parser/token-group.rb
|
|
88
105
|
- lib/sportdb/parser/token-note.rb
|
|
89
106
|
- lib/sportdb/parser/token-prop.rb
|
|
90
107
|
- lib/sportdb/parser/token-prop_name.rb
|
|
91
108
|
- lib/sportdb/parser/token-round.rb
|
|
109
|
+
- lib/sportdb/parser/token-score--helpers.rb
|
|
92
110
|
- lib/sportdb/parser/token-score.rb
|
|
111
|
+
- lib/sportdb/parser/token-score_full.rb
|
|
93
112
|
- lib/sportdb/parser/token-score_fuller.rb
|
|
94
113
|
- lib/sportdb/parser/token-score_legs.rb
|
|
95
114
|
- lib/sportdb/parser/token-status.rb
|
|
96
|
-
- lib/sportdb/parser/token-
|
|
115
|
+
- lib/sportdb/parser/token-status_inline.rb
|
|
97
116
|
- lib/sportdb/parser/token-text.rb
|
|
98
117
|
- lib/sportdb/parser/token-time.rb
|
|
99
118
|
- lib/sportdb/parser/token.rb
|
|
100
|
-
- lib/sportdb/parser/token_helpers.rb
|
|
101
119
|
- lib/sportdb/parser/version.rb
|
|
102
120
|
homepage: https://github.com/sportdb/sport.db
|
|
103
121
|
licenses:
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
###
|
|
2
|
-
# generic block text/txt helper
|
|
3
|
-
|
|
4
|
-
## todo/chekc - find a better name SectTxt or ??
|
|
5
|
-
|
|
6
|
-
class BlockTxt
|
|
7
|
-
|
|
8
|
-
def self.parse( txt ) new( txt); end
|
|
9
|
-
def self.read( path ) parse( read_text( path )); end
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def initialize( txt )
|
|
13
|
-
@sects = _parse( txt )
|
|
14
|
-
self
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def size() @sects.size; end
|
|
18
|
-
|
|
19
|
-
def each( &blk ) @sects.each( &blk ); end
|
|
20
|
-
def each_with_index( &blk ) @sects.each_with_index( &blk ); end
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def text
|
|
24
|
-
## only get all txt1 parts joined as single all-in-one string txt
|
|
25
|
-
@sects.map {|sect| sect[0] }.join( "\n" )
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def dump ## for debugging
|
|
30
|
-
puts "==> sects (#{@sects.size}):"
|
|
31
|
-
pp @sects
|
|
32
|
-
puts " #{@sects.size} sect(s)"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
##
|
|
37
|
-
# quick support for __END__
|
|
38
|
-
END_RE = %r{ ^
|
|
39
|
-
[ ]* __END__ [ ]*
|
|
40
|
-
.*?
|
|
41
|
-
\z ## note - until end-of-string/file !!!
|
|
42
|
-
}mx
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
## SECT_RE (old) = %r{^
|
|
46
|
-
## [ ]* --- [ ]*
|
|
47
|
-
## $}x
|
|
48
|
-
##
|
|
49
|
-
## do NOT use --- (used in fbtxt and markdown and yaml etc.)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
## e.g. § or §§ or § § § or such
|
|
53
|
-
## maybe allow :: § :: or such too or --- § --- or such
|
|
54
|
-
SECT_RE = %r{^
|
|
55
|
-
[ ]* §
|
|
56
|
-
([ ]*§)*
|
|
57
|
-
[ ]*
|
|
58
|
-
$}x
|
|
59
|
-
|
|
60
|
-
## split by " => or =====> "
|
|
61
|
-
## todo/check - subsect?? find a better name? in/out or txt1/txt2
|
|
62
|
-
SUBSECT_RE = %r{^
|
|
63
|
-
[ ]*
|
|
64
|
-
=+ >
|
|
65
|
-
[ ]*
|
|
66
|
-
$}x
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def _parse( txt )
|
|
71
|
-
blocks = [] ## note - holds [txt,exp] pairs
|
|
72
|
-
|
|
73
|
-
txt = txt.sub( END_RE, '' )
|
|
74
|
-
|
|
75
|
-
## split by §
|
|
76
|
-
sections = txt.split( SECT_RE )
|
|
77
|
-
|
|
78
|
-
sections.each_with_index do |sect,i|
|
|
79
|
-
## puts ">>> start #{i+1}"
|
|
80
|
-
## pp sect
|
|
81
|
-
## puts "<<< end #{i+1}"
|
|
82
|
-
|
|
83
|
-
txt1, txt2 = sect.split( SUBSECT_RE )
|
|
84
|
-
blocks << [txt1,txt2]
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
blocks
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
end # class BlockTxt
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
###
|
|
96
|
-
# function-style helpers
|
|
97
|
-
|
|
98
|
-
def read_blocktxt( path ); BlockTxt.read( path ); end
|
|
99
|
-
def parse_blocktxt( txt ); BlockTxt.new( txt ); end
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
module SportDb
|
|
2
|
-
class Lexer
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
########
|
|
6
|
-
## experimental teletype mode
|
|
7
|
-
## only space, A-Z and 0-9 allowed
|
|
8
|
-
IS_TTY_LINE_RE = %r{ \A
|
|
9
|
-
## note - use NEGATIVE lookahead to exclude blank lines
|
|
10
|
-
(?! [ ]*\z)
|
|
11
|
-
|
|
12
|
-
[A-Z0-9 ]+
|
|
13
|
-
\z
|
|
14
|
-
}x
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
TTY_SPACES_RE = %r{ (?<spaces> [ ]{2,}) |
|
|
18
|
-
(?<space> [ ])
|
|
19
|
-
}x
|
|
20
|
-
TTY_NUM_RE = %r{ \b (?<num> \d+ ) \b
|
|
21
|
-
}x
|
|
22
|
-
|
|
23
|
-
##
|
|
24
|
-
## note - TEXT for now allows A, 1A, A1, A1A, A1 B1 C1,
|
|
25
|
-
## A1AA1 2B22 3C33
|
|
26
|
-
## - single space only for concat
|
|
27
|
-
## text segments MUST NOT be all numbers e.g. 1, 11, etc.
|
|
28
|
-
TTY_TEXT_RE = %r{ \b (?<text>
|
|
29
|
-
(?:
|
|
30
|
-
[A-Z] ## MUST start with letter
|
|
31
|
-
|
|
|
32
|
-
[0-9]+[A-Z] ## or numbers followed by letter
|
|
33
|
-
)
|
|
34
|
-
[0-9A-Z]*
|
|
35
|
-
(?:
|
|
36
|
-
### allow move segements separated
|
|
37
|
-
## by single space
|
|
38
|
-
[ ]
|
|
39
|
-
(?:
|
|
40
|
-
[A-Z] ## MUST start with letter
|
|
41
|
-
|
|
|
42
|
-
[0-9]+[A-Z] ## or numbers followed by letter
|
|
43
|
-
)
|
|
44
|
-
[0-9A-Z]*
|
|
45
|
-
)*
|
|
46
|
-
)
|
|
47
|
-
\b
|
|
48
|
-
}x
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
TTY_RE = Regexp.union(
|
|
52
|
-
TTY_SPACES_RE,
|
|
53
|
-
TTY_TEXT_RE,
|
|
54
|
-
TTY_NUM_RE,
|
|
55
|
-
## fix add ANY_RE,
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def _tokenize_tty_line( line )
|
|
60
|
-
line = line.strip
|
|
61
|
-
|
|
62
|
-
tokens = []
|
|
63
|
-
|
|
64
|
-
## track last offsets - to report error on no match
|
|
65
|
-
## or no match in end of string
|
|
66
|
-
offsets = [0,0]
|
|
67
|
-
pos = 0
|
|
68
|
-
m = nil
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
while m = TTY_RE.match( line, pos )
|
|
72
|
-
offsets = [m.begin(0), m.end(0)]
|
|
73
|
-
|
|
74
|
-
if offsets[0] != pos
|
|
75
|
-
## match NOT starting at start/begin position!!!
|
|
76
|
-
## report parse error!!!
|
|
77
|
-
msg = "!! WARN - tokenize (tty) error - skipping >#{line[pos..(offsets[0]-1)]}< @#{offsets[0]},#{offsets[1]} in line >#{line}<"
|
|
78
|
-
puts msg
|
|
79
|
-
log( msg )
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
pos = offsets[1]
|
|
83
|
-
|
|
84
|
-
t = if m[:spaces] || m[:space]
|
|
85
|
-
nil ## skip spaces
|
|
86
|
-
elsif m[:text]
|
|
87
|
-
[:TTY_TEXT, m[:text]]
|
|
88
|
-
elsif m[:num]
|
|
89
|
-
[:TTY_NUM, m[:num].to_i(10)]
|
|
90
|
-
else
|
|
91
|
-
## report error/raise expection
|
|
92
|
-
puts "!!! TTY TOKENIZE ERROR - no match found"
|
|
93
|
-
nil
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
tokens << t if t
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
## check if no match in end of string
|
|
100
|
-
if offsets[1] != line.size
|
|
101
|
-
msg = "!! WARN - tokenize (tty) error - skipping >#{line[offsets[1]..-1]}< @#{offsets[1]},#{line.size} in line >#{line}<"
|
|
102
|
-
puts msg
|
|
103
|
-
log( msg )
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
tokens
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
end # class Lexer
|
|
110
|
-
end # module SportDb
|
|
111
|
-
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
####
|
|
3
|
-
# RaccMatchParser support machinery (incl. node classes/abstract syntax tree)
|
|
4
|
-
|
|
5
|
-
class RaccMatchParser
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def initialize( txt, debug: false )
|
|
9
|
-
## puts "==> txt:"
|
|
10
|
-
## puts txt
|
|
11
|
-
|
|
12
|
-
@tree = []
|
|
13
|
-
@errors = []
|
|
14
|
-
|
|
15
|
-
### todo:
|
|
16
|
-
## - pass along debug flag
|
|
17
|
-
lexer = SportDb::Lexer.new( txt, debug: debug )
|
|
18
|
-
## note - use tokenize_with_errors and add/collect tokenize errors
|
|
19
|
-
@tokens, @errors = lexer.tokenize_with_errors
|
|
20
|
-
## pp @tokens
|
|
21
|
-
|
|
22
|
-
## quick hack - convert to racc format single char literal tokens e.g. '@' etc.
|
|
23
|
-
@tokens = @tokens.map do |tok|
|
|
24
|
-
if tok.size == 1
|
|
25
|
-
[tok[0].to_s, tok[0].to_s]
|
|
26
|
-
else
|
|
27
|
-
tok
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def debug( value ) @debug = value; end ### fix: use setter-style e.g. debug=(value) !!!
|
|
34
|
-
def debug?() @debug == true; end
|
|
35
|
-
|
|
36
|
-
## debug - trace / print message
|
|
37
|
-
def trace( msg )
|
|
38
|
-
puts " [parse] " + msg if debug?
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def next_token
|
|
45
|
-
tok = @tokens.shift
|
|
46
|
-
trace( "next_token => #{tok.pretty_inspect}" )
|
|
47
|
-
tok
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# on_error do |error_token_id, error_value, value_stack|
|
|
51
|
-
# puts "Parse error on token: #{error_token_id}, value: #{error_value}"
|
|
52
|
-
# end
|
|
53
|
-
|
|
54
|
-
def parse_with_errors
|
|
55
|
-
trace( "start parse:" )
|
|
56
|
-
do_parse
|
|
57
|
-
[@tree, @errors]
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def parse ## convenience shortcut (ignores errors)
|
|
61
|
-
tree, _ = parse_with_errors
|
|
62
|
-
tree
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
attr_reader :errors
|
|
67
|
-
def errors?() @errors.size > 0; end
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def on_error(error_token_id, error_value, value_stack)
|
|
71
|
-
## auto-add error_token (as string)
|
|
72
|
-
error_token = Racc_token_to_s_table[error_token_id]
|
|
73
|
-
args = [error_token, error_token_id, error_value, value_stack]
|
|
74
|
-
puts
|
|
75
|
-
puts "!! on parse error:"
|
|
76
|
-
puts "args=#{args.pretty_inspect}"
|
|
77
|
-
|
|
78
|
-
@errors << "parse error on token: #{error_token} (#{error_token_id}) with value: #{error_value}, stack: #{value_stack.pretty_inspect}"
|
|
79
|
-
## exit 1 ## exit for now - get and print more info about context etc.!!
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
=begin
|
|
84
|
-
on_error do |error_token_id, error_value, value_stack|
|
|
85
|
-
puts "Parse error on token: #{error_token_id}, value: #{error_value}"
|
|
86
|
-
end
|
|
87
|
-
=end
|
|
88
|
-
end # class RaccMatchParser
|