fbtxt-parser 0.9.0 → 0.9.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -1
  3. data/Manifest.txt +0 -37
  4. data/README.md +4 -8
  5. data/Rakefile +2 -1
  6. data/lib/fbtxt/parser/parse_tree-match.rb +3 -1
  7. data/lib/fbtxt/parser/parse_tree-props.rb +39 -10
  8. data/lib/fbtxt/parser/parser-top.rb +0 -9
  9. data/lib/fbtxt/parser/parser.rb +879 -843
  10. data/lib/fbtxt/parser/version.rb +1 -1
  11. data/lib/fbtxt/parser.rb +14 -82
  12. metadata +18 -41
  13. data/lib/fbtxt/parser/debuggable.rb +0 -53
  14. data/lib/fbtxt/parser/lexer-logger.rb +0 -20
  15. data/lib/fbtxt/parser/lexer-on_goal.rb +0 -167
  16. data/lib/fbtxt/parser/lexer-on_group_def.rb +0 -31
  17. data/lib/fbtxt/parser/lexer-on_prop_lineup.rb +0 -79
  18. data/lib/fbtxt/parser/lexer-on_prop_misc.rb +0 -123
  19. data/lib/fbtxt/parser/lexer-on_prop_penalties.rb +0 -40
  20. data/lib/fbtxt/parser/lexer-on_round_def.rb +0 -37
  21. data/lib/fbtxt/parser/lexer-on_top.rb +0 -133
  22. data/lib/fbtxt/parser/lexer-prep_doc.rb +0 -131
  23. data/lib/fbtxt/parser/lexer-prep_line.rb +0 -63
  24. data/lib/fbtxt/parser/lexer-tokenize.rb +0 -468
  25. data/lib/fbtxt/parser/lexer.rb +0 -231
  26. data/lib/fbtxt/parser/lexer_buffer.rb +0 -68
  27. data/lib/fbtxt/parser/lexer_token.rb +0 -126
  28. data/lib/fbtxt/parser/token-date--helpers.rb +0 -130
  29. data/lib/fbtxt/parser/token-date--names.rb +0 -108
  30. data/lib/fbtxt/parser/token-date.rb +0 -200
  31. data/lib/fbtxt/parser/token-date_duration.rb +0 -171
  32. data/lib/fbtxt/parser/token-geo.rb +0 -134
  33. data/lib/fbtxt/parser/token-goals--helpers.rb +0 -114
  34. data/lib/fbtxt/parser/token-goals.rb +0 -306
  35. data/lib/fbtxt/parser/token-group.rb +0 -29
  36. data/lib/fbtxt/parser/token-note.rb +0 -40
  37. data/lib/fbtxt/parser/token-prop.rb +0 -309
  38. data/lib/fbtxt/parser/token-prop_name.rb +0 -83
  39. data/lib/fbtxt/parser/token-round.rb +0 -88
  40. data/lib/fbtxt/parser/token-score--helpers.rb +0 -189
  41. data/lib/fbtxt/parser/token-score.rb +0 -60
  42. data/lib/fbtxt/parser/token-score_full.rb +0 -331
  43. data/lib/fbtxt/parser/token-score_fuller.rb +0 -434
  44. data/lib/fbtxt/parser/token-score_legs.rb +0 -59
  45. data/lib/fbtxt/parser/token-status.rb +0 -192
  46. data/lib/fbtxt/parser/token-status_inline.rb +0 -112
  47. data/lib/fbtxt/parser/token-text.rb +0 -221
  48. data/lib/fbtxt/parser/token-time.rb +0 -144
  49. data/lib/fbtxt/parser/token.rb +0 -224
@@ -1,68 +0,0 @@
1
-
2
- module Fbtxt
3
-
4
- ## note - Tokens was placed inside Lexer - keep "top-level" for now inside Fbtxt
5
- ## for easier reuse with (new) lexer variants!!
6
-
7
- ## transforms
8
- ##
9
- ## Netherlands 1-2 (1-1) England
10
- ## => text => team
11
- ## score|vs
12
- ## text => team
13
-
14
-
15
-
16
- ## token iter/find better name
17
- ## e.g. TokenBuffer/Scanner or such ??
18
- class Tokens
19
- def initialize( tokens )
20
- @tokens = tokens
21
- @pos = 0
22
- end
23
-
24
- def pos() @pos; end
25
- def eos?() @pos >= @tokens.size; end
26
-
27
-
28
-
29
-
30
- ## pattern e.g. [:TEXT, [:VS,:SCORE], :TEXT]
31
- def match?( *pattern )
32
- ## puts " starting match? #{pattern.inspect} @ #{@pos}"
33
- pattern.each_with_index do |types,offset|
34
- tok = peek(offset)
35
- return false if tok.nil? ## no more tokens (cannot match)
36
-
37
- ## if single symbol wrap in array
38
- types = types.is_a?(Array) ? types : [types]
39
- return false unless types.include?( tok.type )
40
- end
41
- true
42
- end
43
-
44
-
45
-
46
- def cur() peek(0); end
47
-
48
- def peek(offset=1)
49
- ## return nil if eos
50
- if @pos+offset >= @tokens.size
51
- nil
52
- else
53
- @tokens[@pos+offset]
54
- end
55
- end
56
-
57
- def next
58
- # if @pos >= @tokens.size
59
- # raise ArgumentError, "end of array - #{@pos} >= #{@tokens.size}"
60
- # end
61
- # throw (standard) end of iteration here why? why not?
62
-
63
- t = @tokens[@pos]
64
- @pos += 1
65
- t
66
- end
67
- end # class Tokens
68
- end # module Fbtxt
@@ -1,126 +0,0 @@
1
- module Fbtxt
2
- class Lexer
3
-
4
-
5
-
6
- class Token
7
-
8
- ## Token.newline( lineno: 1, offset: [1,2] )
9
- ## maps to =>
10
- ## Token.new( :NEWLINE, "\n", lineno: 1, offset: [1,2])
11
- ##
12
- ## use self.nl ?
13
- def self.newline( lineno:, offset: [])
14
- new( :NEWLINE, "\n", lineno: lineno, offset: offset )
15
- end
16
-
17
- ## Token.literal( ",", lineno: 4, offset: [5,6])
18
- ## # maps to =>
19
- ## Token.new( ",", ",", lineno: 4, offset: [5,6])
20
- ##
21
- ## use self.lit?
22
- def self.literal( literal, lineno:, offset: [])
23
- new( literal, literal, lineno: lineno, offset: offset )
24
- end
25
-
26
- ## or use virt or pseudo - why? why not?
27
- def self.virtual( type, lineno:, offset: [])
28
- ## note - offset (start/end) should be same number (zero-width assertions!!)
29
- ## e.g. :GOALS_COMPAT, "<|GOALS_COMPAT|>"
30
- new( type, '', lineno: lineno, offset: offset )
31
- end
32
-
33
-
34
- attr_reader :type, :text,
35
- :lineno, :offset
36
-
37
- def initialize( type, text='',
38
- lineno:, offset: [],
39
- value: nil )
40
- @type = type
41
- @text = text # note - lexeme (string from source)
42
- @lineno = lineno # note - lineno (integer number - not line as string) !!!
43
-
44
- raise TypeError, "type Array required for offset; got #{offset.inspect}" unless offset.is_a?( Array )
45
- @offset = offset # note - for now char offset [start,end] in line (NOT absolute!!)
46
- # maybe latter add MatchData#byteoffset instead - why? why not?
47
- @value = value # might be (union of) string/array/hash
48
- end
49
-
50
- def value
51
- ## note - if value is not set (nil) return text (lexeme)
52
- ## no need to duplicate text as value
53
- @value.nil? ? @text : @value
54
- end
55
-
56
-
57
- ## note: do NOT use as_text/text to avoid confusion with (raw) text (lexeme)
58
- ##
59
- ## use
60
- ## as_str -- value (as String)
61
- ## as_int -- value (as Integer)
62
- ## as_hash -- value (as Hash)
63
- ## as_ary -- value (as Array)
64
-
65
- def as_str
66
- raise TypeError, "token value #{@value.inspect} is #{@value.class.name} NOT string; sorry" if @value && !@value.is_a?(String)
67
- ## note - if value is not set (nil) return text (lexeme)
68
- ## no need to duplicate text as value
69
- @value.nil? ? @text : @value
70
- end
71
-
72
- def as_int
73
- raise TypeError, "token value #{@value.inspect} is #{@value.class.name} NOT integer; sorry" if !@value.is_a?(Integer)
74
- @value
75
- end
76
-
77
- def as_hash
78
- raise TypeError, "token value #{@value.inspect} is #{@value.class.name} NOT hash; sorry" if !@value.is_a?(Hash)
79
- @value
80
- end
81
-
82
- def as_ary
83
- raise TypeError, "token value #{@value.inspect} is #{@value.class.name} NOT array; sorry" if !@value.is_a?(Array)
84
- @value
85
- end
86
-
87
-
88
- def to_legacy
89
- ## return old "legacy" array format
90
- if @value.nil?
91
- [@type, @text]
92
- else
93
- [@type, [@text, @value]]
94
- end
95
- end
96
-
97
-
98
- ## pretty print
99
- def pretty_print( printer )
100
- ## check for literal e.g. "," etc.
101
- if @type.is_a?( String ) && @type == @text && @value.nil?
102
- printer.text( "[#{@type.inspect}" )
103
- elsif @type.is_a?( Symbol ) && @text == '' && @value.nil?
104
- ## assume virtual token (zero-width)
105
- ## use <!...!> style
106
- printer.text( "[<|#{@type}|>" )
107
- else
108
- printer.text( "[#{@type.inspect} #{@text.inspect}" )
109
- printer.text( ", #{value.inspect}") if @value
110
- end
111
-
112
-
113
- printer.text( " @#{@lineno}" )
114
- ## note - for now print only start_offset (offset[0])
115
- ## to keep dump/output shorter
116
- ## note - start counting columns at one (NOT zero), thus, add +1 !!
117
- printer.text( ":#{@offset[0]+1}" ) if @offset.is_a?(Array) && @offset.size == 2
118
- printer.text( "]" )
119
- end
120
-
121
- end # class Token
122
-
123
-
124
-
125
- end # class Lexer
126
- end # module Fbtxt
@@ -1,130 +0,0 @@
1
- module Fbtxt
2
- class Lexer
3
-
4
-
5
- ## "internal" date helpers
6
- def self._build_date( m )
7
- date = {}
8
- ## map month names
9
- ## note - allow any/upcase JULY/JUL etc. thus ALWAYS downcase for lookup
10
- date[:y] = m[:year].to_i(10) if m[:year]
11
- ## check - use y too for two-digit year or keep separate - why? why not?
12
- date[:yy] = m[:yy].to_i(10) if m[:yy] ## two digit year (e.g. 25 or 78 etc.)
13
- date[:m] = m[:month].to_i(10) if m[:month]
14
- date[:m] = MONTH_MAP[ m[:month_name].downcase ] if m[:month_name]
15
- date[:d] = m[:day].to_i(10) if m[:day]
16
- date[:wday] = DAY_MAP[ m[:day_name].downcase ] if m[:day_name]
17
-
18
- date
19
- end
20
-
21
- def self._build_date_legs( m )
22
- legs = {}
23
- ## map month names
24
- ## note - allow any/upcase JULY/JUL etc. thus ALWAYS downcase for lookup
25
- date = {}
26
- date[:m] = MONTH_MAP[ m[:month_name1].downcase ]
27
- date[:d] = m[:day1].to_i(10)
28
- legs[:date1] = date
29
-
30
- date = {}
31
- date[:m] = MONTH_MAP[ m[:month_name2].downcase ] if m[:month_name2]
32
- date[:d] = m[:day2].to_i(10)
33
- legs[:date2] = date
34
-
35
- legs
36
- end
37
-
38
-
39
- def self._build_duration( m )
40
- ## todo/check/fix - if end: works for kwargs!!!!!
41
- duration = { start: {}, end: {}}
42
-
43
- duration[:start][:y] = m[:year1].to_i(10) if m[:year1]
44
- duration[:start][:m] = MONTH_MAP[ m[:month_name1].downcase ] if m[:month_name1]
45
- duration[:start][:d] = m[:day1].to_i(10) if m[:day1]
46
- duration[:start][:wday] = DAY_MAP[ m[:day_name1].downcase ] if m[:day_name1]
47
-
48
- duration[:end][:y] = m[:year2].to_i(10) if m[:year2]
49
- duration[:end][:m] = MONTH_MAP[ m[:month_name2].downcase ] if m[:month_name2]
50
- duration[:end][:d] = m[:day2].to_i(10) if m[:day2]
51
- duration[:end][:wday] = DAY_MAP[ m[:day_name2].downcase ] if m[:day_name2]
52
-
53
- duration
54
- end
55
-
56
-
57
-
58
-
59
- def _build_date( m ) self.class._build_date( m ); end
60
- def _build_date_legs( m ) self.class._build_date_legs( m ); end
61
- def _build_duration( m ) self.class._build_duration( m ); end
62
-
63
-
64
-
65
-
66
- #############
67
- ## "top-level" add a date parser helper
68
-
69
- ## note: parse_date - returns Date object
70
- ## _parse_date (with underscore) - return hash of "parsed" regex match data!!
71
-
72
- def self.parse_date( str, start: nil )
73
- if m = _parse_date( str )
74
- year = m[:y]
75
- yy = m[:yy]
76
-
77
- ####
78
- ## support two digit shortcut for year
79
- if yy && year.nil?
80
- ###
81
- ## for now assume 00,01 to 30 is 2000,2001 to 2030
82
- ## and 31 to 99 is 1931 to 1999
83
- year = yy <= 30 ? 2000+yy : 1900+yy
84
- end
85
-
86
- month = m[:m]
87
- day = m[:d]
88
- wday = m[:wday]
89
-
90
-
91
- if year.nil? ## try to calculate year
92
- raise ArgumentError, "year required in date >#{str}< or pass along start date" if start.nil?
93
-
94
- year = if month > start.month ||
95
- (month == start.month && day >= start.day)
96
- # assume same year as start_at event (e.g. 2013 for 2013/14 season)
97
- start.year
98
- else
99
- # assume year+1 as start_at event (e.g. 2014 for 2013/14 season)
100
- start.year+1
101
- end
102
- end
103
- Date.new( year,month,day )
104
- else
105
- raise ArgumentError, "unexpected date format; cannot parse >#{str}<"
106
- end
107
- end
108
-
109
-
110
-
111
- def self._parse_date( str )
112
- ## note - strip - leading/trailing spaces automatic - why? why not?
113
- m = DATE_RE.match( str.strip )
114
-
115
- if m && m.pre_match == '' && m.post_match == ''
116
- ## return hash table with captured components
117
- date = _build_date( m )
118
- date
119
- elsif m
120
- ## note - match BUT not anchored to start and end-of-string!!!
121
- ## report, error somehow??
122
- nil
123
- else
124
- nil ## no match - return nil
125
- end
126
- end
127
-
128
-
129
- end # class Lexer
130
- end # module Fbtxt
@@ -1,108 +0,0 @@
1
- module Fbtxt
2
- class Lexer
3
-
4
-
5
- def self.parse_names( txt )
6
- lines = [] # array of lines (with words)
7
-
8
- txt.each_line do |line|
9
- line = line.strip
10
-
11
- next if line.empty?
12
- next if line.start_with?( '#' ) ## skip comments too
13
-
14
- ## strip inline (until end-of-line) comments too
15
- ## e.g. Janvier Janv Jan ## check janv in use??
16
- ## => Janvier Janv Jan
17
-
18
- line = line.sub( /#.*/, '' ).strip
19
- ## pp line
20
-
21
- values = line.split( /[ \t]+/ )
22
- ## pp values
23
-
24
- ## todo/fix -- add check for duplicates
25
- lines << values
26
- end
27
- lines
28
-
29
- end # method parse
30
-
31
-
32
- def self.build_names( lines )
33
- ## join all words together into a single string e.g.
34
- ## January|Jan|February|Feb|March|Mar|April|Apr|May|June|Jun|...
35
- lines.map { |line| line.join('|') }.join('|')
36
- end
37
-
38
-
39
- def self.build_map( lines, downcase: false )
40
- ## note: downcase name!!!
41
- ## build a lookup map that maps the word to the index (line no) plus 1 e.g.
42
- ## {"january" => 1, "jan" => 1,
43
- ## "february" => 2, "feb" => 2,
44
- ## "march" => 3, "mar" => 3,
45
- ## "april" => 4, "apr" => 4,
46
- ## "may" => 5,
47
- ## "june" => 6, "jun" => 6, ...
48
- lines.each_with_index.reduce( {} ) do |h,(line,i)|
49
- line.each do |name|
50
- h[ downcase ? name.downcase : name ] = i+1
51
- end ## note: start mapping with 1 (and NOT zero-based, that is, 0)
52
- h
53
- end
54
- end
55
-
56
-
57
-
58
-
59
- MONTH_LINES = parse_names( <<TXT )
60
- January Jan
61
- February Feb
62
- March Mar
63
- April Apr
64
- May
65
- June Jun
66
- July Jul
67
- August Aug
68
- September Sept Sep
69
- October Oct
70
- November Nov
71
- December Dec
72
- TXT
73
-
74
- MONTH_NAMES = build_names( MONTH_LINES )
75
- # pp MONTH_NAMES
76
- MONTH_MAP = build_map( MONTH_LINES, downcase: true )
77
- # pp MONTH_MAP
78
-
79
-
80
-
81
- DAY_LINES = parse_names( <<TXT )
82
- Monday Mon Mo
83
- Tuesday Tues Tue Tu
84
- Wednesday Wed We
85
- Thursday Thurs Thur Thu Th
86
- Friday Fri Fr
87
- Saturday Sat Sa
88
- Sunday Sun Su
89
- TXT
90
-
91
- DAY_NAMES = build_names( DAY_LINES )
92
- # pp DAY_NAMES
93
- DAY_MAP = build_map( DAY_LINES, downcase: true )
94
- # pp DAY_MAP
95
-
96
-
97
- #=>
98
- # "January|Jan|February|Feb|March|Mar|April|Apr|May|June|Jun|
99
- # July|Jul|August|Aug|September|Sept|Sep|October|Oct|
100
- # November|Nov|December|Dec"
101
- #
102
- # "Monday|Mon|Mo|Tuesday|Tues|Tue|Tu|Wednesday|Wed|We|
103
- # Thursday|Thurs|Thur|Thu|Th|Friday|Fri|Fr|
104
- # Saturday|Sat|Sa|Sunday|Sun|Su"
105
-
106
-
107
- end # class Lexer
108
- end # module Fbtxt
@@ -1,200 +0,0 @@
1
- module Fbtxt
2
- class Lexer
3
-
4
-
5
-
6
- # e.g. Fri Aug 9
7
- # Fri Aug 9
8
- ## Fri, Aug 9
9
- ## Fri, Aug 9 2024
10
- ## Fri, Aug 9, 2024
11
- ## Aug 9, 2024
12
- ## Aug 9, 2024
13
- ## note - eat-up optional comma after DAY_NAMES!!
14
- ##
15
- ## note - Fri Aug/9 no longer supported!!!
16
- DATE_I_RE = %r{
17
- (?<date>
18
- \b
19
- ## optional day name
20
- ((?<day_name>#{DAY_NAMES})
21
- (?: ,?[ ]+)
22
- )?
23
- (?<month_name>#{MONTH_NAMES})
24
- [ ]
25
- (?<day>\d{1,2})
26
- \b
27
- ## optional year
28
- ( ,? [ ] ## note - comma optinal with single space required for now
29
- (?<year>\d{4}) ## optional year 2025 (yyyy)
30
- \b
31
- )?
32
- )}ix
33
-
34
-
35
- ### todo/fix - add (opt) day_name later
36
- ## add (opt) year later
37
- # e.g. Aug 9 & Aug 10
38
- ### note - allow shortcut e.g. Aug 9 & 10
39
- DATE_LEGS_I_RE = %r{
40
- (?<date_legs>
41
- \b
42
- (?<month_name1>#{MONTH_NAMES})
43
- [ ]
44
- (?<day1>\d{1,2})
45
- [ ] & [ ]
46
- (?:
47
- (?<month_name2>#{MONTH_NAMES})
48
- [ ]
49
- )? ## note - make 2nd month_name optional
50
- (?<day2>\d{1,2})
51
- \b
52
- )}ix
53
-
54
-
55
- ###
56
- # e.g. 3 June or 10 June
57
- ## note - allow more spaces between DAY_NAMES and DAY e.g.
58
- ## Sun 1 Mar
59
- ## Wed 4 Mar
60
- ## Sat 14 Mar
61
- ## Sat 11 Apr
62
- ## Sat 11 Apr 2021
63
- ## Sat 11 Apr 21
64
- ##
65
- ## Sat, 11 Apr
66
- ## note - eat-up optional comma after DAY_NAMES!!
67
- ##
68
- ## note - Sat 14 Mar 17:30
69
- ## check two-digit year (with NEGATIVE lookahead for time!!!)
70
-
71
- DATE_II_RE = %r{
72
- (?<date>
73
- \b
74
- ## optional day name
75
- ((?<day_name>#{DAY_NAMES})
76
- (?: ,?[ ]+)
77
- )?
78
- (?<day>\d{1,2})
79
- [ ]
80
- (?<month_name>#{MONTH_NAMES})
81
- \b
82
- ## optional year
83
- ( [ ]
84
- (?:
85
- (?<year>\d{4}) ## optional year 2025 (yyyy)
86
- |
87
- (?:
88
- (?<yy>\d{2}) ## optional year 25 (yy)
89
- ## check NEGATIVE lookahead
90
- (?! :|[:h]\d{2})
91
- )
92
- )
93
- \b
94
- )?
95
- )}ix
96
-
97
-
98
- # e.g. iso-date - 2011-08-25
99
- ## note - allow/support ("shortcuts") e.g 2011-8-25 or 2011-8-3 / 2011-08-03 etc.
100
- DATE_III_A_RE = %r{
101
- (?<date>
102
- \b
103
- (?<year>\d{4})
104
- -
105
- (?<month>\d{1,2})
106
- -
107
- (?<day>\d{1,2})
108
- \b
109
- )}ix
110
-
111
- ## starting w/ day/month/year e.g. 25-08-2011
112
- DATE_III_B_RE = %r{
113
- (?<date>
114
- \b
115
- ## optional day name
116
- ((?<day_name>#{DAY_NAMES})
117
- (?: ,?[ ]+)
118
- )?
119
- (?<day>\d{1,2})
120
- -
121
- (?<month>\d{1,2})
122
- -
123
- (?<year>\d{4})
124
- \b
125
- )}ix
126
-
127
-
128
-
129
- ## allow (short)"european" style 8.8.
130
- ## note - assume day/month!!!
131
- DATE_IIII_RE = %r{
132
- (?<date>
133
- \b
134
- ## optional day name
135
- ((?<day_name>#{DAY_NAMES})
136
- (?: ,?[ ]+)
137
- )?
138
- (?<day>\d{1,2})
139
- \.
140
- (?<month>\d{1,2})
141
- \.
142
- (?: (?:
143
- (?<year>\d{4}) ## optional year 2025 (yyyy)
144
- |
145
- (?<yy>\d{2}) ## optional year 25 (yy)
146
- )
147
- \b
148
- )?
149
- )
150
- }ix
151
-
152
-
153
- ####################
154
- ### 04/03/2026 or 4/3/2026
155
- ## 04/03/26 or 4/3/26
156
- ## 04/03 or 4/3
157
- DATE_IIIII_RE = %r{
158
- (?<date>
159
- \b
160
- ## optional day name
161
- ((?<day_name>#{DAY_NAMES})
162
- (?: ,?[ ]+)
163
- )?
164
- (?<day>\d{1,2})
165
- /
166
- (?<month>\d{1,2})
167
- \b
168
- (?:
169
- /
170
- (?:
171
- (?<year>\d{4}) ## optional year 2025 (yyyy)
172
- |
173
- (?<yy>\d{2}) ## optional year 25 (yy)
174
- )
175
- \b
176
- )?
177
- )
178
- }ix
179
-
180
-
181
-
182
- #############################################
183
- # map tables
184
- # note: order matters; first come-first matched/served
185
- DATE_RE = Regexp.union(
186
- DATE_I_RE,
187
- DATE_II_RE,
188
- DATE_III_A_RE, ## e.g. 1973-08-14
189
- DATE_III_B_RE,
190
- DATE_IIII_RE, ## e.g. 8.8. or 8.13.79 or 08.14.1973
191
- DATE_IIIII_RE, ## e.g. 08/14/1973
192
- )
193
-
194
- ## todo - add more format style here; change to Regexp.union later!!!
195
- DATE_LEGS_RE = DATE_LEGS_I_RE
196
-
197
-
198
-
199
- end # class Lexer
200
- end # module Fbtxt