ast_ast 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -0
- data/lib/ast_ast/token.rb +3 -3
- data/lib/ast_ast/tokeniser.rb +20 -3
- data/lib/ast_ast/version.rb +1 -1
- data/spec/ast_ast/tokeniser_spec.rb +26 -8
- metadata +2 -2
data/Rakefile
CHANGED
data/lib/ast_ast/token.rb
CHANGED
@@ -3,7 +3,7 @@ module Ast
|
|
3
3
|
attr_accessor :type, :value
|
4
4
|
|
5
5
|
def initialize(type, value)
|
6
|
-
@type = type
|
6
|
+
@type = type
|
7
7
|
@value = value
|
8
8
|
end
|
9
9
|
|
@@ -45,9 +45,9 @@ module Ast
|
|
45
45
|
#
|
46
46
|
def to_s
|
47
47
|
if @value.nil?
|
48
|
-
"
|
48
|
+
"<#{@type.inspect}>"
|
49
49
|
else
|
50
|
-
"
|
50
|
+
"<#{@type.inspect}, #{@value.inspect}>"
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
data/lib/ast_ast/tokeniser.rb
CHANGED
@@ -114,6 +114,20 @@ module Ast
|
|
114
114
|
@rules << Rule.new(nil, regex, block)
|
115
115
|
end
|
116
116
|
|
117
|
+
# Define a block to run when no match is found, as with +.token+ the block
|
118
|
+
# should return a token instance. The block will only be passed a single
|
119
|
+
# character at a time.
|
120
|
+
#
|
121
|
+
# @example
|
122
|
+
#
|
123
|
+
# missing do |i|
|
124
|
+
# Ast::Token.new(i, i)
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
def self.missing(&block)
|
128
|
+
@missing ||= block
|
129
|
+
end
|
130
|
+
|
117
131
|
# Takes the input and uses the rules that were created to scan it.
|
118
132
|
#
|
119
133
|
# @param [String]
|
@@ -122,6 +136,7 @@ module Ast
|
|
122
136
|
# @return [Tokens]
|
123
137
|
#
|
124
138
|
def self.tokenise(input)
|
139
|
+
@rules ||= []
|
125
140
|
@scanner = StringScanner.new(input)
|
126
141
|
|
127
142
|
result = Tokens.new
|
@@ -143,9 +158,11 @@ module Ast
|
|
143
158
|
end
|
144
159
|
end
|
145
160
|
unless m # if no match happened
|
146
|
-
# obviously no rule matches this so
|
147
|
-
#
|
148
|
-
|
161
|
+
# obviously no rule matches this so invoke missing if it exists
|
162
|
+
ch = @scanner.getch # this advances pointer as well
|
163
|
+
if @missing
|
164
|
+
result << @missing.call(ch)
|
165
|
+
end
|
149
166
|
end
|
150
167
|
end
|
151
168
|
result
|
data/lib/ast_ast/version.rb
CHANGED
@@ -35,18 +35,18 @@ describe Ast::Tokeniser do
|
|
35
35
|
|
36
36
|
describe ".rule" do
|
37
37
|
|
38
|
-
class
|
38
|
+
class KlassRule < Ast::Tokeniser
|
39
39
|
rule :over, /b/
|
40
40
|
end
|
41
41
|
|
42
42
|
it "adds a new rule to list" do
|
43
|
-
|
44
|
-
|
43
|
+
KlassRule.rule(:test, /c/)
|
44
|
+
KlassRule.rules.map {|i| i.name}.should include :test
|
45
45
|
end
|
46
46
|
|
47
47
|
it "overwrites existing rules with same name" do
|
48
|
-
|
49
|
-
|
48
|
+
KlassRule.rule(:over, /a/)
|
49
|
+
KlassRule.rules.find_all {|i| i.name == :over}.size.should == 1
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -68,9 +68,27 @@ describe Ast::Tokeniser do
|
|
68
68
|
|
69
69
|
end
|
70
70
|
|
71
|
+
describe ".missing" do
|
72
|
+
|
73
|
+
class KlassMissing < Ast::Tokeniser
|
74
|
+
missing do |i|
|
75
|
+
Ast::Token.new(i, i)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it "creates a proc" do
|
80
|
+
KlassMissing.missing.should be_kind_of Proc
|
81
|
+
end
|
82
|
+
|
83
|
+
it "invokes the proc when a match is not found" do
|
84
|
+
KlassMissing.tokenise("abc").to_a.should == [["a", "a"], ["b", "b"], ["c", "c"]]
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
71
89
|
describe ".tokenise" do
|
72
90
|
|
73
|
-
class
|
91
|
+
class KlassTokenise < Ast::Tokeniser
|
74
92
|
|
75
93
|
commands = %w(git commit status)
|
76
94
|
|
@@ -92,10 +110,10 @@ describe Ast::Tokeniser do
|
|
92
110
|
|
93
111
|
end
|
94
112
|
|
95
|
-
specify {
|
113
|
+
specify { KlassTokenise.tokenise("").should be_kind_of Ast::Tokens }
|
96
114
|
|
97
115
|
it "retuns the correct tokens" do
|
98
|
-
r =
|
116
|
+
r = KlassTokenise.tokenise("git --along -sh aword")
|
99
117
|
r.to_a.should == [[:command, "git"], [:long, "along"], [:short, "s"], [:short, "h"], [:word, "aword"]]
|
100
118
|
end
|
101
119
|
|