cirru-parser 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +4 -0
- data/ast/comma.json +12 -0
- data/ast/demo.json +50 -0
- data/ast/folding.json +35 -0
- data/ast/html.json +145 -0
- data/ast/indent.json +23 -0
- data/ast/line.json +17 -0
- data/ast/parentheses.json +24 -0
- data/ast/quote.json +14 -0
- data/ast/spaces.json +6 -0
- data/ast/unfolding.json +21 -0
- data/cirru-parser.gemspec +24 -0
- data/examples/comma.cirru +5 -0
- data/examples/demo.cirru +8 -0
- data/examples/folding.cirru +8 -0
- data/examples/html.cirru +22 -0
- data/examples/indent.cirru +6 -0
- data/examples/line.cirru +8 -0
- data/examples/parentheses.cirru +6 -0
- data/examples/quote.cirru +6 -0
- data/examples/spaces.cirru +2 -0
- data/examples/unfolding.cirru +6 -0
- data/lib/cirru/parser/version.rb +5 -0
- data/lib/cirru/parser.rb +352 -0
- data/lib/cirru/tree.rb +103 -0
- data/test.rb +36 -0
- metadata +116 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b6ac2eeb4bb72612594291c6c3c61d8342b0742c
|
4
|
+
data.tar.gz: 21b6c31e839a4d76a12184e33699abf9d5fa60a8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bb83cffa5b4118d5e580a2a39e12a2a6489a277d48e1291b9591d57bb1b91c5761d960cf717235329e45247d429e52c3e5669e8cdbabf95e0ffa776b00d7ed3a
|
7
|
+
data.tar.gz: 8823508745902d2691012641b8d31ef5866430dd33ca0a421a808a187824d872120fa45d76471a24e8fbeb23ca749b3b686eff7f2e3f9077cbadb65639fc097d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 jiyinyiyong
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Cirru::Parser
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'cirru-parser'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install cirru-parser
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it ( https://github.com/[my-github-username]/cirru-parser/fork )
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/ast/comma.json
ADDED
data/ast/demo.json
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
[
|
2
|
+
[
|
3
|
+
"define",
|
4
|
+
"a",
|
5
|
+
[
|
6
|
+
"read",
|
7
|
+
"cd"
|
8
|
+
],
|
9
|
+
[
|
10
|
+
"if",
|
11
|
+
[
|
12
|
+
">",
|
13
|
+
"a",
|
14
|
+
"cd"
|
15
|
+
],
|
16
|
+
[
|
17
|
+
"print",
|
18
|
+
"demo"
|
19
|
+
],
|
20
|
+
[
|
21
|
+
"print",
|
22
|
+
"not demo"
|
23
|
+
]
|
24
|
+
]
|
25
|
+
],
|
26
|
+
[
|
27
|
+
"say",
|
28
|
+
[
|
29
|
+
"print",
|
30
|
+
"a",
|
31
|
+
[
|
32
|
+
"save",
|
33
|
+
[
|
34
|
+
"b",
|
35
|
+
[
|
36
|
+
"x",
|
37
|
+
[
|
38
|
+
"c",
|
39
|
+
"8"
|
40
|
+
]
|
41
|
+
]
|
42
|
+
]
|
43
|
+
]
|
44
|
+
]
|
45
|
+
],
|
46
|
+
[
|
47
|
+
"print",
|
48
|
+
"fun"
|
49
|
+
]
|
50
|
+
]
|
data/ast/folding.json
ADDED
data/ast/html.json
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
[
|
2
|
+
[
|
3
|
+
"doctype"
|
4
|
+
],
|
5
|
+
[
|
6
|
+
"html",
|
7
|
+
[
|
8
|
+
"head",
|
9
|
+
[
|
10
|
+
"title",
|
11
|
+
[
|
12
|
+
"=",
|
13
|
+
"a"
|
14
|
+
]
|
15
|
+
],
|
16
|
+
[
|
17
|
+
"link",
|
18
|
+
[
|
19
|
+
":rel",
|
20
|
+
"a"
|
21
|
+
],
|
22
|
+
[
|
23
|
+
":href",
|
24
|
+
"b"
|
25
|
+
]
|
26
|
+
],
|
27
|
+
[
|
28
|
+
"link",
|
29
|
+
[
|
30
|
+
":rel",
|
31
|
+
"icon"
|
32
|
+
],
|
33
|
+
[
|
34
|
+
":href",
|
35
|
+
"a"
|
36
|
+
]
|
37
|
+
],
|
38
|
+
[
|
39
|
+
"meta",
|
40
|
+
[
|
41
|
+
":charset",
|
42
|
+
"utf-8"
|
43
|
+
]
|
44
|
+
]
|
45
|
+
],
|
46
|
+
[
|
47
|
+
"body",
|
48
|
+
[
|
49
|
+
"#about",
|
50
|
+
[
|
51
|
+
".line",
|
52
|
+
[
|
53
|
+
"a",
|
54
|
+
[
|
55
|
+
":href",
|
56
|
+
"a"
|
57
|
+
],
|
58
|
+
[
|
59
|
+
"=",
|
60
|
+
"b"
|
61
|
+
]
|
62
|
+
],
|
63
|
+
[
|
64
|
+
"span",
|
65
|
+
[
|
66
|
+
"=",
|
67
|
+
" "
|
68
|
+
]
|
69
|
+
],
|
70
|
+
[
|
71
|
+
"a",
|
72
|
+
[
|
73
|
+
":href",
|
74
|
+
"a"
|
75
|
+
],
|
76
|
+
[
|
77
|
+
"=",
|
78
|
+
"b"
|
79
|
+
]
|
80
|
+
]
|
81
|
+
],
|
82
|
+
[
|
83
|
+
".line",
|
84
|
+
[
|
85
|
+
"span",
|
86
|
+
[
|
87
|
+
"=",
|
88
|
+
"a"
|
89
|
+
]
|
90
|
+
]
|
91
|
+
]
|
92
|
+
],
|
93
|
+
[
|
94
|
+
"#list",
|
95
|
+
[
|
96
|
+
".year",
|
97
|
+
[
|
98
|
+
"=",
|
99
|
+
"2014"
|
100
|
+
]
|
101
|
+
],
|
102
|
+
[
|
103
|
+
".month",
|
104
|
+
[
|
105
|
+
"=",
|
106
|
+
"May"
|
107
|
+
]
|
108
|
+
],
|
109
|
+
[
|
110
|
+
".post",
|
111
|
+
[
|
112
|
+
"a.link",
|
113
|
+
[
|
114
|
+
":href"
|
115
|
+
],
|
116
|
+
[
|
117
|
+
"="
|
118
|
+
]
|
119
|
+
]
|
120
|
+
],
|
121
|
+
[
|
122
|
+
".month",
|
123
|
+
[
|
124
|
+
"=",
|
125
|
+
"Apr"
|
126
|
+
]
|
127
|
+
],
|
128
|
+
[
|
129
|
+
".post",
|
130
|
+
[
|
131
|
+
"a.link",
|
132
|
+
[
|
133
|
+
":href",
|
134
|
+
"a"
|
135
|
+
],
|
136
|
+
[
|
137
|
+
"=",
|
138
|
+
"b"
|
139
|
+
]
|
140
|
+
]
|
141
|
+
]
|
142
|
+
]
|
143
|
+
]
|
144
|
+
]
|
145
|
+
]
|
data/ast/indent.json
ADDED
data/ast/line.json
ADDED
data/ast/quote.json
ADDED
data/ast/unfolding.json
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cirru/parser'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "cirru-parser"
|
8
|
+
spec.version = Cirru::Parser::VERSION
|
9
|
+
spec.authors = ["jiyinyiyong"]
|
10
|
+
spec.email = ["jiyinyiyong@gmail.com"]
|
11
|
+
spec.summary = %q{Cirru Parser in Ruby}
|
12
|
+
spec.description = %q{Manually convert cirru-parser into Ruby}
|
13
|
+
spec.homepage = "http://cirru.org"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency 'json', '~> 0.3.16'
|
24
|
+
end
|
data/examples/demo.cirru
ADDED
data/examples/html.cirru
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
doctype
|
3
|
+
|
4
|
+
html
|
5
|
+
head
|
6
|
+
title $ = a
|
7
|
+
link (:rel a) $ :href b
|
8
|
+
link (:rel icon) $ :href a
|
9
|
+
meta $ :charset utf-8
|
10
|
+
body
|
11
|
+
#about
|
12
|
+
.line
|
13
|
+
a (:href a) $ = b
|
14
|
+
span $ = " "
|
15
|
+
a (:href a) $ = b
|
16
|
+
.line $ span $ = a
|
17
|
+
#list
|
18
|
+
.year $ = 2014
|
19
|
+
.month $ = May
|
20
|
+
.post $ a.link (:href) $ =
|
21
|
+
.month $ = Apr
|
22
|
+
.post $ a.link (:href a) $ = b
|
data/examples/line.cirru
ADDED
data/lib/cirru/parser.rb
ADDED
@@ -0,0 +1,352 @@
|
|
1
|
+
|
2
|
+
require "cirru/parser/version"
|
3
|
+
require 'cirru/tree'
|
4
|
+
|
5
|
+
module Cirru
|
6
|
+
module Parser
|
7
|
+
def self.parse(code, filename)
|
8
|
+
buffer = nil
|
9
|
+
|
10
|
+
state = { name: :indent,
|
11
|
+
x: 1,
|
12
|
+
y: 1,
|
13
|
+
level: 1,
|
14
|
+
indent: 0,
|
15
|
+
indented: 0,
|
16
|
+
nest: 0,
|
17
|
+
path: filename
|
18
|
+
}
|
19
|
+
|
20
|
+
xs = []
|
21
|
+
while code.length > 0
|
22
|
+
res = parsing xs, buffer, state, code
|
23
|
+
xs, buffer, state, code = *res
|
24
|
+
end
|
25
|
+
res = parsing xs, buffer, state, code
|
26
|
+
res = res.map do |item|
|
27
|
+
Tree.resolveDollar item
|
28
|
+
end
|
29
|
+
res = res.map do |item|
|
30
|
+
Tree.resolveComma item
|
31
|
+
end
|
32
|
+
res
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.pare(code, filename)
|
36
|
+
res = self.parse code, filename
|
37
|
+
# p 'before shorten', res
|
38
|
+
shorten res
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def shorten(xs)
|
45
|
+
if xs.is_a? Array
|
46
|
+
xs.map do |item|
|
47
|
+
shorten(item)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
xs[:text]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# eof
|
55
|
+
|
56
|
+
def escape_eof(xs, buffer, state, code)
|
57
|
+
raise 'EOF in escape state'
|
58
|
+
end
|
59
|
+
|
60
|
+
def string_eof(xs, buffer, state, code)
|
61
|
+
raise 'EOF in string state'
|
62
|
+
end
|
63
|
+
|
64
|
+
def space_eof(xs, buffer, state, code)
|
65
|
+
xs
|
66
|
+
end
|
67
|
+
|
68
|
+
def token_eof(xs, buffer, state, code)
|
69
|
+
buffer[:ex] = state[:x]
|
70
|
+
buffer[:ey] = state[:y]
|
71
|
+
# p 'appendBuffer', xs, state[:level], buffer
|
72
|
+
xs = Tree.appendBuffer xs, state[:level], buffer
|
73
|
+
buffer = nil
|
74
|
+
xs
|
75
|
+
end
|
76
|
+
|
77
|
+
def indent_eof(xs, buffer, state, code)
|
78
|
+
xs
|
79
|
+
end
|
80
|
+
|
81
|
+
# escape
|
82
|
+
|
83
|
+
def escape_newline(xs, buffer, state, code)
|
84
|
+
raise 'newline while escape'
|
85
|
+
end
|
86
|
+
|
87
|
+
def escape_n(xs, buffer, state, code)
|
88
|
+
state[:x] += 1
|
89
|
+
buffer[:text] += '\n'
|
90
|
+
state[:name] = :string
|
91
|
+
[xs, buffer, state, code[1..-1]]
|
92
|
+
end
|
93
|
+
|
94
|
+
def escape_t(xs, buffer, state, code)
|
95
|
+
state[:x] += 1
|
96
|
+
buffer[:text] += '\t'
|
97
|
+
state[:name] = :string
|
98
|
+
[xs, buffer, state, code[1..-1]]
|
99
|
+
end
|
100
|
+
|
101
|
+
def escape_else(xs, buffer, state, code)
|
102
|
+
state[:x] += 1
|
103
|
+
buffer[:text] += code[0]
|
104
|
+
state[:name] = :string
|
105
|
+
[xs, buffer, state, code[1..-1]]
|
106
|
+
end
|
107
|
+
|
108
|
+
#string
|
109
|
+
|
110
|
+
def string_backslash(xs, buffer, state, code)
|
111
|
+
state[:name] = :escape
|
112
|
+
state[:x] += 1
|
113
|
+
[xs, buffer, state, code[1..-1]]
|
114
|
+
end
|
115
|
+
|
116
|
+
def string_newline(xs, buffer, state, code)
|
117
|
+
raise 'newline in a string'
|
118
|
+
end
|
119
|
+
|
120
|
+
def string_quote(xs, buffer, state, code)
|
121
|
+
state[:name] = :token
|
122
|
+
state[:x] += 1
|
123
|
+
[xs, buffer, state, code[1..-1]]
|
124
|
+
end
|
125
|
+
|
126
|
+
def string_else(xs, buffer, state, code)
|
127
|
+
state[:x] += 1
|
128
|
+
buffer[:text] += code[0]
|
129
|
+
[xs, buffer, state, code[1..-1]]
|
130
|
+
end
|
131
|
+
|
132
|
+
# space
|
133
|
+
|
134
|
+
def space_space(xs, buffer, state, code)
|
135
|
+
state[:x] += 1
|
136
|
+
[xs, buffer, state, code[1..-1]]
|
137
|
+
end
|
138
|
+
|
139
|
+
def space_newline(xs, buffer, state, code)
|
140
|
+
if state[:nest] != 0
|
141
|
+
raise 'incorrect nesting'
|
142
|
+
end
|
143
|
+
state[:name] = :indent
|
144
|
+
state[:x] = 1
|
145
|
+
state[:y] += 1
|
146
|
+
state[:indented] = 0
|
147
|
+
[xs, buffer, state, code[1..-1]]
|
148
|
+
end
|
149
|
+
|
150
|
+
def space_open(xs, buffer, state, code)
|
151
|
+
nesting = Tree.createNesting(1)
|
152
|
+
xs = Tree.appendList xs, state[:level], nesting
|
153
|
+
state[:nest] += 1
|
154
|
+
state[:level] += 1
|
155
|
+
state[:x] += 1
|
156
|
+
[xs, buffer, state, code[1..-1]]
|
157
|
+
end
|
158
|
+
|
159
|
+
def space_close(xs, buffer, state, code)
|
160
|
+
state[:nest] -= 1
|
161
|
+
state[:level] -= 1
|
162
|
+
if state[:nest] < 0
|
163
|
+
raise 'close at space'
|
164
|
+
end
|
165
|
+
state[:x] += 1
|
166
|
+
[xs, buffer, state, code[1..-1]]
|
167
|
+
end
|
168
|
+
|
169
|
+
def space_quote(xs, buffer, state, code)
|
170
|
+
state[:name] = :string
|
171
|
+
buffer = {text: '',
|
172
|
+
x: state[:x],
|
173
|
+
y: state[:y],
|
174
|
+
path: state[:path]
|
175
|
+
}
|
176
|
+
state[:x] += 1
|
177
|
+
[xs, buffer, state, code[1..-1]]
|
178
|
+
end
|
179
|
+
|
180
|
+
def space_else(xs, buffer, state, code)
|
181
|
+
state[:name] = :token
|
182
|
+
buffer = { text: code[0],
|
183
|
+
x: state[:x],
|
184
|
+
y: state[:y],
|
185
|
+
path: state[:path]
|
186
|
+
}
|
187
|
+
state[:x] += 1
|
188
|
+
[xs, buffer, state, code[1..-1]]
|
189
|
+
end
|
190
|
+
|
191
|
+
# token
|
192
|
+
|
193
|
+
def token_space(xs, buffer, state, code)
|
194
|
+
state[:name] = :space
|
195
|
+
buffer[:ex] = state[:x]
|
196
|
+
buffer[:ey] = state[:y]
|
197
|
+
xs = Tree.appendBuffer xs, state[:level], buffer
|
198
|
+
state[:x] += 1
|
199
|
+
buffer = nil
|
200
|
+
[xs, buffer, state, code[1..-1]]
|
201
|
+
end
|
202
|
+
|
203
|
+
def token_newline(xs, buffer, state, code)
|
204
|
+
state[:name] = :indent
|
205
|
+
buffer[:ex] = state[:x]
|
206
|
+
buffer[:ey] = state[:y]
|
207
|
+
xs = Tree.appendBuffer xs, state[:level], buffer
|
208
|
+
state[:indented] = 0
|
209
|
+
state[:x] = 1
|
210
|
+
state[:y] += 1
|
211
|
+
buffer = nil
|
212
|
+
[xs, buffer, state, code[1..-1]]
|
213
|
+
end
|
214
|
+
|
215
|
+
def token_open(xs, buffer, state, code)
|
216
|
+
raise 'open parenthesis in token'
|
217
|
+
end
|
218
|
+
|
219
|
+
def token_close(xs, buffer, state, code)
|
220
|
+
state[:name] = :space
|
221
|
+
buffer[:ex] = state[:x]
|
222
|
+
buffer[:ey] = state[:y]
|
223
|
+
xs = Tree.appendBuffer xs, state[:level], buffer
|
224
|
+
buffer = nil
|
225
|
+
[xs, buffer, state, code]
|
226
|
+
end
|
227
|
+
|
228
|
+
def token_quote(xs, buffer, state, code)
|
229
|
+
state[:name] = :string
|
230
|
+
state[:x] += 1
|
231
|
+
[xs, buffer, state, code[1..-1]]
|
232
|
+
end
|
233
|
+
|
234
|
+
def token_else(xs, buffer, state, code)
|
235
|
+
buffer[:text] += code[0]
|
236
|
+
state[:x] += 1
|
237
|
+
[xs, buffer, state, code[1..-1]]
|
238
|
+
end
|
239
|
+
|
240
|
+
# indent
|
241
|
+
|
242
|
+
def indent_space(xs, buffer, state, code)
|
243
|
+
state[:indented] += 1
|
244
|
+
state[:x] += 1
|
245
|
+
[xs, buffer, state, code[1..-1]]
|
246
|
+
end
|
247
|
+
|
248
|
+
def indent_newilne(xs, buffer, state, code)
|
249
|
+
state[:x] = 1
|
250
|
+
state[:y] += 1
|
251
|
+
state[:indented] = 0
|
252
|
+
[xs, buffer, state, code[1..-1]]
|
253
|
+
end
|
254
|
+
|
255
|
+
def indent_close(xs, buffer, state, code)
|
256
|
+
raise 'close parenthesis at indent'
|
257
|
+
end
|
258
|
+
|
259
|
+
def indent_else(xs, buffer, state, code)
|
260
|
+
state[:name] = :space
|
261
|
+
if (state[:indented] % 2) == 1
|
262
|
+
raise 'odd indentation'
|
263
|
+
end
|
264
|
+
indented = state[:indented] / 2
|
265
|
+
diff = indented - state[:indent]
|
266
|
+
|
267
|
+
if diff <= 0
|
268
|
+
nesting = Tree.createNesting 1
|
269
|
+
xs = Tree.appendList xs, (state[:level] + diff - 1), nesting
|
270
|
+
elsif diff > 0
|
271
|
+
nesting = Tree.createNesting diff
|
272
|
+
xs = Tree.appendList xs, state[:level], nesting
|
273
|
+
end
|
274
|
+
|
275
|
+
state[:level] += diff
|
276
|
+
state[:indent] = indented
|
277
|
+
[xs, buffer, state, code]
|
278
|
+
end
|
279
|
+
|
280
|
+
# parse
|
281
|
+
|
282
|
+
def parsing(xs, buffer, state, code)
|
283
|
+
args = [xs, buffer, state, code]
|
284
|
+
# puts "\n"
|
285
|
+
# puts "xs: \t#{xs}"
|
286
|
+
# puts "buf: \t#{buffer}"
|
287
|
+
# puts "state: \t#{state[:name]}"
|
288
|
+
# print "code: \t"; p "#{code}"
|
289
|
+
# scope = {code, xs, buffer, state}
|
290
|
+
# window.debugData.push (lodash.cloneDeep scope)
|
291
|
+
eof = code.length == 0
|
292
|
+
char = code[0]
|
293
|
+
case state[:name]
|
294
|
+
when :escape
|
295
|
+
if eof then return escape_eof(*args)
|
296
|
+
else
|
297
|
+
case char
|
298
|
+
when "\n" then return escape_newline(*args)
|
299
|
+
when 'n' then return escape_n(*args)
|
300
|
+
when 't' then return escape_t(*args)
|
301
|
+
else return escape_else(*args)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
when :string
|
305
|
+
if eof then return string_eof(*args)
|
306
|
+
else
|
307
|
+
case char
|
308
|
+
when "\\" then return string_backslash(*args)
|
309
|
+
when "\n" then return string_newline(*args)
|
310
|
+
when '"' then return string_quote(*args)
|
311
|
+
else return string_else(*args)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
when :space
|
315
|
+
if eof then return space_eof(*args)
|
316
|
+
else
|
317
|
+
case char
|
318
|
+
when ' ' then return space_space(*args)
|
319
|
+
when "\n" then return space_newline(*args)
|
320
|
+
when '(' then return space_open(*args)
|
321
|
+
when ')' then return space_close(*args)
|
322
|
+
when '"' then return space_quote(*args)
|
323
|
+
else return space_else(*args)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
when :token
|
327
|
+
if eof then return token_eof(*args)
|
328
|
+
else
|
329
|
+
case char
|
330
|
+
when ' ' then return token_space(*args)
|
331
|
+
when "\n" then return token_newline(*args)
|
332
|
+
when '(' then return token_open(*args)
|
333
|
+
when ')' then return token_close(*args)
|
334
|
+
when '"' then return token_quote(*args)
|
335
|
+
else return token_else(*args)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
when :indent
|
339
|
+
if eof then return indent_eof(*args)
|
340
|
+
else
|
341
|
+
case char
|
342
|
+
when ' ' then return indent_space(*args)
|
343
|
+
when "\n" then return indent_newilne(*args)
|
344
|
+
when ')' then return indent_close(*args)
|
345
|
+
else return indent_else(*args)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
else
|
349
|
+
p state[:name]
|
350
|
+
raise "not matching any state"
|
351
|
+
end
|
352
|
+
end
|
data/lib/cirru/tree.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
|
2
|
+
module Tree
|
3
|
+
def self.appendBuffer(*args)
|
4
|
+
appendBufferHelper(*args)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.appendList(*args)
|
8
|
+
appendListHelper(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.createNesting(n)
|
12
|
+
createHelper [], n
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.resolveDollar(*args)
|
16
|
+
# p 'resolveDollar args', args
|
17
|
+
resolveDollarHelper *args
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.resolveComma(*args)
|
21
|
+
resolveCommaHelper(*args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def appendBufferHelper(xs, level, buffer)
|
26
|
+
if level == 0
|
27
|
+
xs[0..-1] + [buffer]
|
28
|
+
else
|
29
|
+
res = appendBufferHelper xs[-1], (level - 1), buffer
|
30
|
+
xs[0...-1] + [res]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def appendListHelper(xs, level, list)
|
35
|
+
if level == 0
|
36
|
+
xs + [list]
|
37
|
+
else
|
38
|
+
res = appendListHelper xs[-1], (level - 1), list
|
39
|
+
xs[0...-1] + [res]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def createHelper(xs, n)
|
44
|
+
if n <= 1
|
45
|
+
xs
|
46
|
+
else
|
47
|
+
list = createHelper xs, (n - 1)
|
48
|
+
[list]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def dollarHelper(before, after)
|
54
|
+
if after.length == 0
|
55
|
+
return before
|
56
|
+
end
|
57
|
+
cursor = after[0]
|
58
|
+
if cursor.is_a? Array
|
59
|
+
chunk = resolveDollarHelper cursor
|
60
|
+
dollarHelper (before + [chunk]), after[1..-1]
|
61
|
+
elsif cursor[:text] == '$'
|
62
|
+
chunk = resolveDollarHelper after[1..-1]
|
63
|
+
before + [chunk]
|
64
|
+
else
|
65
|
+
dollarHelper (before + [cursor]), after[1..-1]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def resolveDollarHelper(xs)
|
70
|
+
# p 'calling resolveDollarHelper', xs
|
71
|
+
if xs.length == 0
|
72
|
+
return xs
|
73
|
+
end
|
74
|
+
dollarHelper [], xs
|
75
|
+
end
|
76
|
+
|
77
|
+
def commaHelper(before, after)
|
78
|
+
if after.length == 0
|
79
|
+
return before
|
80
|
+
end
|
81
|
+
cursor = after[0]
|
82
|
+
if (cursor.is_a? Array) and (cursor.length > 0)
|
83
|
+
head = cursor[0]
|
84
|
+
if head.is_a? Array
|
85
|
+
chunk = resolveCommaHelper cursor
|
86
|
+
commaHelper (before + [chunk]), after[1..-1]
|
87
|
+
elsif head[:text] == ','
|
88
|
+
commaHelper before, ((resolveCommaHelper cursor[1..-1]) + after[1..-1])
|
89
|
+
else
|
90
|
+
chunk = resolveCommaHelper cursor
|
91
|
+
commaHelper (before + [chunk]), after[1..-1]
|
92
|
+
end
|
93
|
+
else
|
94
|
+
commaHelper (before + [cursor]), after[1..-1]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def resolveCommaHelper(xs)
|
99
|
+
if xs.length == 0
|
100
|
+
return xs
|
101
|
+
end
|
102
|
+
commaHelper [], xs
|
103
|
+
end
|
data/test.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib")
|
5
|
+
|
6
|
+
require 'cirru/parser'
|
7
|
+
|
8
|
+
names = [
|
9
|
+
'comma',
|
10
|
+
'demo',
|
11
|
+
'folding',
|
12
|
+
'html',
|
13
|
+
'indent',
|
14
|
+
'line',
|
15
|
+
'parentheses',
|
16
|
+
'quote',
|
17
|
+
'spaces',
|
18
|
+
'unfolding'
|
19
|
+
]
|
20
|
+
|
21
|
+
def test(name)
|
22
|
+
code = IO.read "examples/#{name}.cirru"
|
23
|
+
ast = Cirru::Parser.pare(code, 'file')
|
24
|
+
genereated = JSON.generate ast
|
25
|
+
expected = JSON.generate JSON.parse(IO.read("ast/#{name}.json"))
|
26
|
+
if genereated == expected
|
27
|
+
print "\nok:\t", name
|
28
|
+
else
|
29
|
+
print "\nfailed:\t", name
|
30
|
+
print genereated
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
names.each do |name|
|
35
|
+
test name
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cirru-parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- jiyinyiyong
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.3.16
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.3.16
|
55
|
+
description: Manually convert cirru-parser into Ruby
|
56
|
+
email:
|
57
|
+
- jiyinyiyong@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- ast/comma.json
|
68
|
+
- ast/demo.json
|
69
|
+
- ast/folding.json
|
70
|
+
- ast/html.json
|
71
|
+
- ast/indent.json
|
72
|
+
- ast/line.json
|
73
|
+
- ast/parentheses.json
|
74
|
+
- ast/quote.json
|
75
|
+
- ast/spaces.json
|
76
|
+
- ast/unfolding.json
|
77
|
+
- cirru-parser.gemspec
|
78
|
+
- examples/comma.cirru
|
79
|
+
- examples/demo.cirru
|
80
|
+
- examples/folding.cirru
|
81
|
+
- examples/html.cirru
|
82
|
+
- examples/indent.cirru
|
83
|
+
- examples/line.cirru
|
84
|
+
- examples/parentheses.cirru
|
85
|
+
- examples/quote.cirru
|
86
|
+
- examples/spaces.cirru
|
87
|
+
- examples/unfolding.cirru
|
88
|
+
- lib/cirru/parser.rb
|
89
|
+
- lib/cirru/parser/version.rb
|
90
|
+
- lib/cirru/tree.rb
|
91
|
+
- test.rb
|
92
|
+
homepage: http://cirru.org
|
93
|
+
licenses:
|
94
|
+
- MIT
|
95
|
+
metadata: {}
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
require_paths:
|
99
|
+
- lib
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
requirements: []
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 2.0.14
|
113
|
+
signing_key:
|
114
|
+
specification_version: 4
|
115
|
+
summary: Cirru Parser in Ruby
|
116
|
+
test_files: []
|