jkf 0.4.3 → 0.5.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.
@@ -1,118 +1,104 @@
1
- module Jkf::Parser
2
- # Base of Parser
3
- class Base
4
- # start parse
5
- #
6
- # @param [String] input
7
- #
8
- # @return [Hash] JKF
9
- def parse(input)
10
- @input = input.clone
11
-
12
- @current_pos = 0
13
- @reported_pos = 0
14
- @cached_pos = 0
15
- @cached_pos_details = { line: 1, column: 1, seenCR: false }
16
- @max_fail_pos = 0
17
- @max_fail_expected = []
18
- @silent_fails = 0
19
-
20
- @result = parse_root
21
-
22
- if success? && @current_pos == @input.size
23
- return @result
24
- else
25
- fail(type: "end", description: "end of input") if failed? && @current_pos < input.size
26
- raise ParseError
1
+ require 'strscan'
2
+
3
+ module Jkf
4
+ module Parser
5
+ # Base of Parser
6
+ class Base
7
+ # start parse
8
+ #
9
+ # @param [String] input
10
+ #
11
+ # @return [Hash] JKF
12
+ def parse(input)
13
+ @scanner = StringScanner.new(input.dup)
14
+ @reported_pos = 0
15
+ @max_fail_pos = 0
16
+
17
+ @result = parse_root
18
+
19
+ if success? && @scanner.eos?
20
+ @result
21
+ else
22
+ record_failure(type: 'end', description: 'end of input') if failed? && @scanner.pos < input.size
23
+ raise ParseError
24
+ end
27
25
  end
28
- end
29
26
 
30
- protected
27
+ protected
31
28
 
32
- def success?
33
- @result != :failed
34
- end
29
+ def success?
30
+ @result != :failed
31
+ end
35
32
 
36
- def failed?; !success?; end
37
-
38
- # match regexp
39
- def match_regexp(reg)
40
- ret = nil
41
- if matched = reg.match(@input[@current_pos])
42
- ret = matched.to_s
43
- @current_pos += ret.size
44
- else
45
- ret = :failed
46
- fail(type: "class", value: reg.inspect, description: reg.inspect) if @silent_fails == 0
33
+ def failed?; !success?; end
34
+
35
+ def match_regexp(reg)
36
+ matched = @scanner.scan(reg)
37
+ unless matched
38
+ record_failure(type: 'class', value: reg.inspect, description: reg.inspect)
39
+ return :failed
40
+ end
41
+ matched
47
42
  end
48
- ret
49
- end
50
43
 
51
- # match string
52
- def match_str(str)
53
- ret = nil
54
- if @input[@current_pos, str.size] == str
55
- ret = str
56
- @current_pos += str.size
57
- else
58
- ret = :failed
59
- fail(type: "literal", value: str, description: "\"#{str}\"") if @slient_fails == 0
44
+ def match_str(str)
45
+ matched = @scanner.scan(str)
46
+ unless matched
47
+ record_failure(type: 'literal', value: str, description: str.inspect)
48
+ return :failed
49
+ end
50
+ matched
60
51
  end
61
- ret
62
- end
63
52
 
64
- # match space
65
- def match_space
66
- match_str(" ")
67
- end
53
+ # match space
54
+ def match_space
55
+ match_str(' ')
56
+ end
68
57
 
69
- # match space one or more
70
- def match_spaces
71
- stack = []
72
- matched = match_space
73
- while matched != :failed
74
- stack << matched
58
+ # match space one or more
59
+ def match_spaces
60
+ stack = []
75
61
  matched = match_space
62
+ while matched != :failed
63
+ stack << matched
64
+ matched = match_space
65
+ end
66
+ stack
76
67
  end
77
- stack
78
- end
79
68
 
80
- # match digit
81
- def match_digit
82
- match_regexp(/^\d/)
83
- end
69
+ # match digit
70
+ def match_digit
71
+ match_regexp(/\d/)
72
+ end
84
73
 
85
- # match digits
86
- def match_digits
87
- stack = []
88
- matched = match_digit
89
- while matched != :failed
90
- stack << matched
74
+ # match digits
75
+ def match_digits
76
+ stack = []
91
77
  matched = match_digit
78
+ while matched != :failed
79
+ stack << matched
80
+ matched = match_digit
81
+ end
82
+ stack
92
83
  end
93
- stack
94
- end
95
84
 
96
- # match digit one ore more
97
- def match_digits!
98
- matched = match_digits
99
- if matched.empty?
100
- :failed
101
- else
102
- matched
85
+ # match digit one ore more
86
+ def match_digits!
87
+ matched = match_digits
88
+ if matched.empty?
89
+ :failed
90
+ else
91
+ matched
92
+ end
103
93
  end
104
- end
105
94
 
106
- # record failure
107
- def fail(expected)
108
- return if @current_pos < @max_fail_pos
95
+ def record_failure(expected)
96
+ return if @scanner.pos < @max_fail_pos
109
97
 
110
- if @current_pos > @max_fail_pos
111
- @max_fail_pos = @current_pos
112
- @max_fail_expected = []
113
- end
98
+ return unless @scanner.pos > @max_fail_pos
114
99
 
115
- @max_fail_expected << expected
100
+ @max_fail_pos = @scanner.pos
101
+ end
116
102
  end
117
103
  end
118
104
  end