-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathParser.peg
More file actions
39 lines (38 loc) · 3.32 KB
/
Parser.peg
File metadata and controls
39 lines (38 loc) · 3.32 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
@namespace Link.Foundation.Links.Notation
@classname Parser
@using System.Linq
document <IList<Link<string>>> = #{ state["IndentationStack"] = new Stack<int>(); state["IndentationStack"].Push(0); state["BaseIndentation"] = -1; } skipEmptyLines l:links _ eof { l.ToLinksList() } / #{ state["IndentationStack"] = new Stack<int>(); state["IndentationStack"].Push(0); state["BaseIndentation"] = -1; } _ eof { new List<Link<string>>() }
skipEmptyLines = ([ \t]* [\r\n])*
links <IList<LinksGroup<string>>> = fl:firstLine list:line* POP_INDENTATION { new List<LinksGroup<string>> { fl }.Concat(list).ToList() }
firstLine <LinksGroup<string>> = SET_BASE_INDENTATION l:element { l }
line <LinksGroup<string>> = CHECK_INDENTATION l:element { l }
element <LinksGroup<string>> = e:anyLink PUSH_INDENTATION l:links { new LinksGroup<string>(e, l) } / e:anyLink { new LinksGroup<string>(e) }
referenceOrLink <Link<string>> = l:multiLineAnyLink { l } / i:reference { i }
anyLink <Link<string>> = ml:multiLineAnyLink eol { ml } / il:indentedIdLink { il } / sl:singleLineAnyLink { sl }
multiLineAnyLink <Link<string>> = multiLineValueLink / multiLineLink
singleLineAnyLink <Link<string>> = fl:singleLineLink eol { fl } / vl:singleLineValueLink eol { vl }
multiLineValueAndWhitespace <Link<string>> = value:referenceOrLink _ { value }
multiLineValues <IList<Link<string>>> = _ list:multiLineValueAndWhitespace* { list }
singleLineValueAndWhitespace <Link<string>> = __ value:referenceOrLink { value }
singleLineValues <IList<Link<string>>> = list:singleLineValueAndWhitespace+ { list }
singleLineLink <Link<string>> = __ id:(reference) __ ":" v:singleLineValues { new Link<string>(id, v) }
multiLineLink <Link<string>> = openBracket _ id:(reference) _ ":" v:multiLineValues _ closeBracket { new Link<string>(id, v) }
singleLineValueLink <Link<string>> = v:singleLineValues { new Link<string>(v) }
multiLineValueLink <Link<string>> = openBracket v:multiLineValues _ closeBracket { new Link<string>(v) }
openBracket = "(" / "{" / "["
closeBracket = ")" / "}" / "]"
indentedIdLink <Link<string>> = id:(reference) __ ":" eol { new Link<string>(id) }
reference <string> = doubleQuotedReference / singleQuotedReference / simpleReference
simpleReference <string> = "" referenceSymbol+
doubleQuotedReference <string> = '"' r:([^"]+) '"' { string.Join("", r) }
singleQuotedReference <string> = "'" r:([^']+) "'" { string.Join("", r) }
SET_BASE_INDENTATION = spaces:" "* #{ if ((int)state["BaseIndentation"] == -1) state["BaseIndentation"] = spaces.Count; }
PUSH_INDENTATION = spaces:" "* #{ state["NormalizedIndent"] = spaces.Count - ((int)state["BaseIndentation"] == -1 ? 0 : (int)state["BaseIndentation"]); if ((int)state["NormalizedIndent"] < 0) state["NormalizedIndent"] = 0; } &{ (int)state["NormalizedIndent"] > (int)state["IndentationStack"].Peek() } #{ state["IndentationStack"].Push((int)state["NormalizedIndent"]); }
POP_INDENTATION = #{ state["IndentationStack"].Pop(); }
CHECK_INDENTATION = spaces:" "* #{ state["NormalizedIndent"] = spaces.Count - ((int)state["BaseIndentation"] == -1 ? 0 : (int)state["BaseIndentation"]); if ((int)state["NormalizedIndent"] < 0) state["NormalizedIndent"] = 0; } &{ (int)state["NormalizedIndent"] >= (int)state["IndentationStack"].Peek() }
eol = __ ("" [\r\n]+ / eof)
eof = !.
__ = [ \t]*
_ = whiteSpaceSymbol*
whiteSpaceSymbol = [ \t\n\r]
referenceSymbol = [^ \t\n\r(:)\[\]{}]