jkf 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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