-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathlexer.rb
More file actions
124 lines (94 loc) · 2.97 KB
/
lexer.rb
File metadata and controls
124 lines (94 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#--
# DO NOT MODIFY!!!!
# This file is automatically generated by rex 1.0.7
# from lexical definition file "gherkin.rex".
#++
require 'racc/parser'
# Compile with: rex gherkin.rex -o lexer.rb
class GherkinRuby::Parser < Racc::Parser
require 'strscan'
class ScanError < StandardError ; end
attr_reader :lineno
attr_reader :filename
attr_accessor :state
def scan_setup(str)
@ss = StringScanner.new(str)
@lineno = 1
@state = nil
end
def action
yield
end
def scan_str(str)
scan_setup(str)
do_parse
end
alias :scan :scan_str
def load_file( filename )
@filename = filename
File.open(filename, "r") do |f|
scan_setup(f.read)
end
end
def scan_file( filename )
load_file(filename)
do_parse
end
def next_token
return if @ss.eos?
# skips empty actions
until token = _next_token or @ss.eos?; end
token
end
def _next_token
text = @ss.peek(1)
@lineno += 1 if text == "\n"
token = case @state
when nil
case
when (text = @ss.scan(/[ \t]+/))
;
when (text = @ss.scan(/\#.*$/))
;
when (text = @ss.scan(/\n/))
action { [:NEWLINE, text] }
when (text = @ss.scan(/Feature:/))
action { [:FEATURE, text[0..-2]] }
when (text = @ss.scan(/Background:/))
action { [:BACKGROUND, text[0..-2]] }
when (text = @ss.scan(/Scenario:/))
action { [:SCENARIO, text[0..-2]] }
when (text = @ss.scan(/@(\w|-|:)+/))
action { [:TAG, text[1..-1]] }
when (text = @ss.scan(/Given/))
action { [:GIVEN, text] }
when (text = @ss.scan(/When/))
action { [:WHEN, text] }
when (text = @ss.scan(/Then/))
action { [:THEN, text] }
when (text = @ss.scan(/And/))
action { [:AND, text] }
when (text = @ss.scan(/But/))
action { [:BUT, text] }
when (text = @ss.scan(/\*/))
action { [:STAR, text] }
when (text = @ss.scan(/[^#\n]*/))
action { [:TEXT, text.strip] }
else
text = @ss.string[@ss.pos .. -1]
raise ScanError, "can not match: '" + text + "'"
end # if
else
raise ScanError, "undefined state: '" + state.to_s + "'"
end # case state
token
end # def _next_token
def tokenize(code)
scan_setup(code)
tokens = []
while token = next_token
tokens << token
end
tokens
end
end # class