kpeg 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.hoeignore +12 -0
- data/Gemfile +3 -0
- data/Manifest.txt +9 -0
- data/README.rdoc +3 -3
- data/Rakefile +2 -0
- data/bin/kpeg +9 -2
- data/examples/lua_string/lua_string.kpeg.rb +0 -2
- data/examples/tiny_markdown/Rakefile +3 -0
- data/examples/tiny_markdown/driver.rb +10 -0
- data/examples/tiny_markdown/node.rb +107 -0
- data/examples/tiny_markdown/sample.md +51 -0
- data/examples/tiny_markdown/tiny_markdown.kpeg +199 -0
- data/examples/tiny_markdown/tiny_markdown.kpeg.rb +3892 -0
- data/lib/kpeg.rb +1 -1
- data/lib/kpeg/compiled_parser.rb +0 -4
- data/lib/kpeg/format_parser.kpeg +1 -1
- data/lib/kpeg/format_parser.rb +0 -4
- data/lib/kpeg/string_escape.rb +0 -4
- data/test/test_kpeg_format.rb +19 -0
- metadata +30 -30
- data/.gemtest +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51480429b1da586193cac01b5aacafc05b79e338
|
4
|
+
data.tar.gz: c5df043d969c4a8149cdd83cb8733b2fa0d05ed3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93fc5844b6f727b5bc946e5d33449c93a0828ddc4177da0d479e474cf67a5e0cf3ad9fb57bd6e9ccb461e2fa2f84d90ed613af6963c3881539ec3a905a83c5f8
|
7
|
+
data.tar.gz: 1b03c363938623ba1f9abdea0ca0b06106bf038f5c0bf6e00a3090ea7751936d5a74b3626612bda7879b2a34f0f11143e066bd4cea1ade45d77f33717004ec20
|
data/.hoeignore
ADDED
data/Gemfile
ADDED
data/Manifest.txt
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
.autotest
|
2
|
+
.hoeignore
|
2
3
|
.travis.yml
|
4
|
+
Gemfile
|
3
5
|
History.txt
|
4
6
|
LICENSE
|
5
7
|
Manifest.txt
|
@@ -17,6 +19,12 @@ examples/lua_string/lua_string.kpeg.rb
|
|
17
19
|
examples/phone_number/README.md
|
18
20
|
examples/phone_number/phone_number.kpeg
|
19
21
|
examples/phone_number/phone_number.rb
|
22
|
+
examples/tiny_markdown/Rakefile
|
23
|
+
examples/tiny_markdown/driver.rb
|
24
|
+
examples/tiny_markdown/node.rb
|
25
|
+
examples/tiny_markdown/sample.md
|
26
|
+
examples/tiny_markdown/tiny_markdown.kpeg
|
27
|
+
examples/tiny_markdown/tiny_markdown.kpeg.rb
|
20
28
|
examples/upper/README.md
|
21
29
|
examples/upper/upper.kpeg
|
22
30
|
examples/upper/upper.rb
|
@@ -42,5 +50,6 @@ test/test_kpeg_format.rb
|
|
42
50
|
test/test_kpeg_format_parser_round_trip.rb
|
43
51
|
test/test_kpeg_grammar.rb
|
44
52
|
test/test_kpeg_grammar_renderer.rb
|
53
|
+
test/test_kpeg_string_escape.rb
|
45
54
|
vim/syntax_kpeg/ftdetect/kpeg.vim
|
46
55
|
vim/syntax_kpeg/syntax/kpeg.vim
|
data/README.rdoc
CHANGED
@@ -143,13 +143,13 @@ Once you have the generated parser, include that file into your new grammar
|
|
143
143
|
Then create a variable to hold to foreign interface and pass it the class name
|
144
144
|
of your parser. In this case my parser class name is Literal
|
145
145
|
|
146
|
-
%
|
146
|
+
%foreign_grammar = Literal
|
147
147
|
|
148
148
|
You can then use rules defined in the foreign grammar in the local grammar
|
149
149
|
file like so
|
150
150
|
|
151
|
-
sentence = (%
|
152
|
-
%
|
151
|
+
sentence = (%foreign_grammar.alpha %foreign_grammar.space*)+
|
152
|
+
%foreign_grammar.period
|
153
153
|
|
154
154
|
=== Comments
|
155
155
|
|
data/Rakefile
CHANGED
data/bin/kpeg
CHANGED
@@ -8,7 +8,7 @@ require 'kpeg/grammar_renderer'
|
|
8
8
|
require 'optparse'
|
9
9
|
|
10
10
|
options = {}
|
11
|
-
OptionParser.new do |o|
|
11
|
+
optparser = OptionParser.new do |o|
|
12
12
|
o.banner = "Usage: kpeg [options]"
|
13
13
|
|
14
14
|
o.on("-t", "--test", "Syntax check the file only") do |v|
|
@@ -42,7 +42,14 @@ OptionParser.new do |o|
|
|
42
42
|
o.on("-d", "--debug", "Debug parsing the file") do |v|
|
43
43
|
options[:debug] = v
|
44
44
|
end
|
45
|
-
end
|
45
|
+
end
|
46
|
+
|
47
|
+
optparser.parse!
|
48
|
+
|
49
|
+
if ARGV.empty?
|
50
|
+
puts optparser.help
|
51
|
+
exit 1
|
52
|
+
end
|
46
53
|
|
47
54
|
file = ARGV.shift
|
48
55
|
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module TinyMarkdown
|
2
|
+
class Node
|
3
|
+
def to_html
|
4
|
+
if !self.respond_to?(:content)
|
5
|
+
return ""
|
6
|
+
end
|
7
|
+
if self.content.kind_of?(Array)
|
8
|
+
self.content.map(&:to_html).join("")
|
9
|
+
elsif self.content.kind_of?(TinyMarkdown::Node)
|
10
|
+
self.content.to_html
|
11
|
+
elsif self.content
|
12
|
+
self.content.to_s
|
13
|
+
else
|
14
|
+
""
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
if self.respond_to?(:content)
|
20
|
+
'#<'+self.class.to_s+' content="'+self.content.to_s+'">'
|
21
|
+
else
|
22
|
+
'#<'+self.class.to_s+'>'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class HeadlineNode
|
28
|
+
def to_html
|
29
|
+
children = self.content.map(&:to_html).join("")
|
30
|
+
"<h#{level}>#{children}</h#{level}>\n"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class TextNode
|
35
|
+
def to_html
|
36
|
+
self.content.to_s
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class BlockQuoteNode
|
41
|
+
def to_html
|
42
|
+
children = self.content.map(&:to_html).join("")
|
43
|
+
"<blockquote>#{children}</blockquote>\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class BulletListNode
|
48
|
+
def to_html
|
49
|
+
children = self.content.map(&:to_html).join("")
|
50
|
+
"<ul>\n#{children}</ul>\n"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class BulletListItemNode
|
55
|
+
def to_html
|
56
|
+
children = self.content.map(&:to_html).join("")
|
57
|
+
"<li>#{children}</li>\n"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class PlainNode
|
62
|
+
def to_html
|
63
|
+
self.content.map(&:to_html).join("")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class ParaNode
|
68
|
+
def to_html
|
69
|
+
children = self.content.map(&:to_html).join("")
|
70
|
+
"<p>#{children}</p>\n"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class VerbatimNode
|
75
|
+
def to_html
|
76
|
+
children = self.content.map(&:to_html).join("")
|
77
|
+
"<pre><code>#{children}</code></pre>\n"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class InlineElementNode
|
82
|
+
def to_html
|
83
|
+
children = self.content.map(&:to_html).join("")
|
84
|
+
"<#{self.name}>#{children}</#{self.name}>"
|
85
|
+
end
|
86
|
+
|
87
|
+
def inspect
|
88
|
+
'#<'+self.class.to_s+' name="'+self.name.to_s+'" content="'+self.content.to_s+'">'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class LineBreakNode
|
93
|
+
def to_html
|
94
|
+
"<br />\n"
|
95
|
+
end
|
96
|
+
|
97
|
+
def inspect
|
98
|
+
"\\n"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class HorizontalRuleNode
|
103
|
+
def to_html
|
104
|
+
"<hr />\n"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# test
|
2
|
+
|
3
|
+
## inline
|
4
|
+
|
5
|
+
### strong1
|
6
|
+
|
7
|
+
aaa **bbb** cc *dd*
|
8
|
+
|
9
|
+
### strong2
|
10
|
+
|
11
|
+
ee _fff_ gg __hhh__
|
12
|
+
|
13
|
+
### code
|
14
|
+
|
15
|
+
iii `jjjjj` kk `lll`
|
16
|
+
|
17
|
+
## block
|
18
|
+
|
19
|
+
### bullet
|
20
|
+
|
21
|
+
* mmm
|
22
|
+
* nnnnn
|
23
|
+
* ooo
|
24
|
+
|
25
|
+
### quote
|
26
|
+
|
27
|
+
> pppp
|
28
|
+
> qqqq
|
29
|
+
> rrrr
|
30
|
+
>
|
31
|
+
> inlines are ignored **sss** ttt __uuu__
|
32
|
+
|
33
|
+
### verbatim
|
34
|
+
|
35
|
+
before verbatim.
|
36
|
+
|
37
|
+
yyyy
|
38
|
+
zzzz
|
39
|
+
1111
|
40
|
+
|
41
|
+
this is verbatim
|
42
|
+
2222
|
43
|
+
this is verbatim
|
44
|
+
|
45
|
+
after verbatim.
|
46
|
+
|
47
|
+
### Horizontal Rule
|
48
|
+
|
49
|
+
|
50
|
+
- - - - -
|
51
|
+
|
@@ -0,0 +1,199 @@
|
|
1
|
+
%% name = TinyMarkdown::Parser
|
2
|
+
%% ast-location = ::TinyMarkdown
|
3
|
+
%% document = ast DocumentNode(compiler, position, content)
|
4
|
+
%% para = ast ParaNode(compiler, position, content)
|
5
|
+
%% plain = ast PlainNode(compiler, position, content)
|
6
|
+
%% text = ast TextNode(compiler, position, content)
|
7
|
+
%% headline = ast HeadlineNode(compiler, position, level, content)
|
8
|
+
%% block_quote = ast BlockQuoteNode(compiler, position, content)
|
9
|
+
%% verbatim = ast VerbatimNode(compiler, position, content)
|
10
|
+
%% horizontal_rule = ast HorizontalRuleNode(compiler, position)
|
11
|
+
%% bullet_list = ast BulletListNode(compiler, position, content)
|
12
|
+
%% list = ast ListNode(compiler, position, content)
|
13
|
+
%% bullet_list_item = ast BulletListItemNode(compiler, position, content)
|
14
|
+
%% linebreak = ast LineBreakNode(compiler, position)
|
15
|
+
%% inline_element = ast InlineElementNode(compiler, position, name, content)
|
16
|
+
|
17
|
+
%% {
|
18
|
+
attr_reader :ast
|
19
|
+
|
20
|
+
class Position
|
21
|
+
attr_accessor :pos, :line, :col
|
22
|
+
def initialize(compiler)
|
23
|
+
@pos = compiler.pos
|
24
|
+
@line = compiler.current_line
|
25
|
+
@col = compiler.current_column
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def position
|
30
|
+
Position.new(self)
|
31
|
+
end
|
32
|
+
}
|
33
|
+
|
34
|
+
root = Start
|
35
|
+
|
36
|
+
Start = &. Doc:c { @ast = c }
|
37
|
+
|
38
|
+
Doc = Block*:c
|
39
|
+
~document(self, position, c)
|
40
|
+
|
41
|
+
Block = BlankLine*
|
42
|
+
( BlockQuote
|
43
|
+
| Verbatim
|
44
|
+
| HorizontalRule
|
45
|
+
| Heading
|
46
|
+
| BulletList
|
47
|
+
| Para
|
48
|
+
| Plain )
|
49
|
+
|
50
|
+
Para = NonindentSpace Inlines:a BlankLine+ ~para(self, position, a)
|
51
|
+
|
52
|
+
Plain = Inlines:a ~plain(self, position, a)
|
53
|
+
|
54
|
+
AtxInline = !Newline !(Sp '#'* Sp Newline) Inline:c { c }
|
55
|
+
|
56
|
+
AtxStart = < /######|#####|####|###|##|#/ > { text.length }
|
57
|
+
|
58
|
+
AtxHeading = AtxStart:level Sp AtxInline+:c (Sp "#"* Sp)? Newline ~headline(self, position, level, c)
|
59
|
+
|
60
|
+
Heading = AtxHeading
|
61
|
+
|
62
|
+
BlockQuote = BlockQuoteRaw:c ~block_quote(self, position, c)
|
63
|
+
|
64
|
+
BlockQuoteRaw = ( '>' ' '? Line:c { c })+:cc { cc }
|
65
|
+
|
66
|
+
NonblankIndentedLine = !BlankLine IndentedLine:c { c }
|
67
|
+
|
68
|
+
VerbatimChunk = (BlankLine { text(self,position,"\n") } )*:c1
|
69
|
+
(NonblankIndentedLine:c { [c, text(self,position,"\n")] })+:c2 { c1 + c2.flatten }
|
70
|
+
|
71
|
+
Verbatim = VerbatimChunk+:cc ~verbatim(self, position, cc.flatten)
|
72
|
+
|
73
|
+
HorizontalRule = NonindentSpace
|
74
|
+
( '*' Sp '*' Sp '*' (Sp '*')*
|
75
|
+
| '-' Sp '-' Sp '-' (Sp '-')*
|
76
|
+
| '_' Sp '_' Sp '_' (Sp '_')*)
|
77
|
+
Sp Newline BlankLine+ ~horizontal_rule(self, position)
|
78
|
+
|
79
|
+
Bullet = !HorizontalRule NonindentSpace ('+' | '*' | '-') Spacechar+
|
80
|
+
|
81
|
+
BulletList = &Bullet ListTight:c ~bullet_list(self, position, c)
|
82
|
+
|
83
|
+
ListTight = ListItemTight+:cc
|
84
|
+
BlankLine* !Bullet
|
85
|
+
{ cc }
|
86
|
+
|
87
|
+
ListItemTight = Bullet ListBlock:c ~bullet_list_item(self, position, c)
|
88
|
+
|
89
|
+
ListBlock = !BlankLine Line:c ListBlockLine*:cc { cc.unshift(c) }
|
90
|
+
|
91
|
+
ListBlockLine = !BlankLine
|
92
|
+
!( Indent? Bullet )
|
93
|
+
!HorizontalRule
|
94
|
+
OptionallyIndentedLine
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
Inlines = ( !Endline Inline:c { c }
|
99
|
+
| Endline:c &Inline { c } )+:cc Endline?
|
100
|
+
{ cc }
|
101
|
+
|
102
|
+
Inline = Str
|
103
|
+
| Endline
|
104
|
+
| Space
|
105
|
+
| Strong
|
106
|
+
| Emph
|
107
|
+
| Code
|
108
|
+
| Symbol
|
109
|
+
|
110
|
+
Space = Spacechar+:c ~text(self, position, c.join(""))
|
111
|
+
|
112
|
+
Str = NormalChar+:c1
|
113
|
+
StrChunk*:c2
|
114
|
+
~text(self, position, (c1+c2).join(""))
|
115
|
+
|
116
|
+
StrChunk = (NormalChar:c { [c] } | '_'+:c1 NormalChar:c2 { c1.push(c2) } )+:cc { cc.flatten }
|
117
|
+
|
118
|
+
|
119
|
+
Endline = LineBreak | TerminalEndline | NormalEndline
|
120
|
+
|
121
|
+
NormalEndline = Sp Newline !BlankLine !'>' !AtxStart
|
122
|
+
!(Line ('='+ | '-'+) Newline)
|
123
|
+
~text(self, position, "\n")
|
124
|
+
|
125
|
+
TerminalEndline = Sp Newline Eof ~text(self, position, "\n")
|
126
|
+
|
127
|
+
LineBreak = " " NormalEndline ~linebreak(self, position)
|
128
|
+
|
129
|
+
Symbol = SpecialChar:c ~text(self, position, c)
|
130
|
+
|
131
|
+
|
132
|
+
Emph = EmphStar | EmphUl
|
133
|
+
|
134
|
+
Whitespace = Spacechar | Newline
|
135
|
+
|
136
|
+
EmphStar = '*' !Whitespace
|
137
|
+
( !'*' Inline:b { b }
|
138
|
+
| StrongStar:b { b }
|
139
|
+
)+:c
|
140
|
+
'*'
|
141
|
+
~inline_element(self, position, :em, c)
|
142
|
+
|
143
|
+
EmphUl = '_' !Whitespace
|
144
|
+
( !'_' Inline:b { b }
|
145
|
+
| StrongUl:b { b }
|
146
|
+
)+:c
|
147
|
+
'_'
|
148
|
+
~inline_element(self, position, :em, c)
|
149
|
+
|
150
|
+
Strong = StrongStar | StrongUl
|
151
|
+
|
152
|
+
StrongStar = "**" !Whitespace
|
153
|
+
( !"**" Inline:b { b })+:c
|
154
|
+
"**"
|
155
|
+
~inline_element(self, position, :strong, c)
|
156
|
+
|
157
|
+
StrongUl = "__" !Whitespace
|
158
|
+
( !"__" Inline:b { b })+:c
|
159
|
+
"__"
|
160
|
+
~inline_element(self, position, :strong, c)
|
161
|
+
|
162
|
+
|
163
|
+
|
164
|
+
Ticks1 = < /`/ > !'`' { text }
|
165
|
+
Ticks2 = < /``/ > !'`' { text }
|
166
|
+
|
167
|
+
Code = ( Ticks1 Sp
|
168
|
+
( !'`' Nonspacechar )+:c
|
169
|
+
Sp Ticks1 ~text(self, position, c.join(""))
|
170
|
+
| Ticks2 Sp
|
171
|
+
( !'``' Nonspacechar )+:c
|
172
|
+
Sp Ticks2 ~text(self, position, c.join(""))
|
173
|
+
):cc
|
174
|
+
~inline_element(self, position, :code, [cc])
|
175
|
+
|
176
|
+
|
177
|
+
BlankLine = Sp Newline
|
178
|
+
|
179
|
+
Quoted = '"' (!'"' .)* '"' | '\'' (!'\'' .)* '\''
|
180
|
+
Eof = !.
|
181
|
+
Spacechar = < / |\t/ > { text }
|
182
|
+
Nonspacechar = !Spacechar !Newline <.> { text }
|
183
|
+
Newline = "\n" | "\r" "\n"?
|
184
|
+
Sp = Spacechar*
|
185
|
+
Spnl = Sp (Newline Sp)?
|
186
|
+
##SpecialChar = '~' | '*' | '_' | '`' | '&' | '[' | ']' | '(' | ')' | '<' | '!' | '#' | "\\" | "'" | '"'
|
187
|
+
SpecialChar = < /[~*_`&\[\]()<!#\\'"]/ > { text }
|
188
|
+
NormalChar = !( SpecialChar | Spacechar | Newline ) <.> { text }
|
189
|
+
AlphanumericAscii = < /[A-Za-z0-9]/ > { text }
|
190
|
+
Digit = < /[0-9]/ > { text }
|
191
|
+
|
192
|
+
NonindentSpace = < / | | |/ > { text }
|
193
|
+
Indent = < /\t| / > { text }
|
194
|
+
IndentedLine = Indent Line:c { c }
|
195
|
+
OptionallyIndentedLine = Indent? Line
|
196
|
+
|
197
|
+
Line = RawLine:c { c }
|
198
|
+
RawLine = (( < /[^\r\n]*/ > ) Newline { text } | < /.+/ > Eof { text }):c ~text(self, position, c)
|
199
|
+
|