Last active
June 6, 2016 22:58
-
-
Save tomjakubowski/508f585aa624a05a36a94e35ac487766 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Grammar for pegjs | |
// missing: floating point numbers, sets, "discard" | |
{ | |
function Sym(name, prefix) { | |
this.name = name; | |
this.prefix = prefix; | |
} | |
Sym.prototype.toString = function() { | |
return 'Sym(' + (this.prefix ? this.prefix + '/' : '') + this.name + ')'; | |
}; | |
function Keyword(name, prefix) { | |
this.isKeyword = true; | |
this.name = name; | |
this.prefix = prefix; | |
} | |
Keyword.prototype.toString = function() { | |
return 'Keyword(:' + (this.prefix ? this.prefix + '/' : '') + this.name + ')'; | |
}; | |
function Tagged(sym, element) { | |
this.sym = sym; | |
this.element = element; | |
} | |
Tagged.prototype.toString = function() { | |
return 'Tagged(' + this.symbol.toString() + ', ' + this.element.toString() + ')'; | |
}; | |
} | |
start | |
= value | |
value | |
= tagged_element | |
/ element | |
tagged_element | |
= '#' tag:tag rws elem:element { return new Tagged(tag, elem); } | |
tag | |
= name:tagname '/' prefix:tagname { return new Sym(name, prefix); } | |
/ t:tagname { return new Sym(t); } | |
tagname | |
= head:tagstart tail:(namerest)* { return text(); } | |
tagstart | |
= [a-zA-Z] | |
element | |
= atom | |
/ composite | |
atom | |
= nil | |
/ boolean | |
/ string | |
/ integer | |
/ keyword | |
/ symbol | |
nil | |
= 'nil' { return null; } | |
boolean | |
= 'true' { return true; } | |
/ 'false' { return false; } | |
string | |
= '"' xs:strchar* '"' { return xs.join(''); } | |
strchar | |
= [^"\\] | |
/ '\\' seq:( 't' { return '\t'; } | |
/ 'r' { return '\r'; } | |
/ 'n' { return '\n'; } | |
/ '"' { return '\"'; } | |
/ '\\' { return '\\';}) { return seq; } | |
integer | |
= x:int 'N'? { return x; } | |
int | |
= [+-]? x:[1-9] xs:[0-9]* { return parseInt(text(), 10); } | |
/ [+-]? x:[0-9] { return parseInt(text()); } | |
keyword | |
= ':' sym:symbol { return new Keyword(sym.name, sym.prefix); } | |
symbol | |
= prefix:name '/' name:name { return new Sym(name, prefix); } | |
/ name:name { return new Sym(name); } | |
name | |
= head:namestart tail:(namerest)* { | |
return text(); | |
} | |
namestart "start of identifier" | |
= [a-zA-Z.*+!\-_?$%&=<>] | |
namerest "legal identifier character" | |
= namestart / [0-9#:] | |
composite | |
= map | |
/ vector | |
map | |
= '{' ws | |
pairs:( | |
head:kvpair | |
tail:(rws kv:kvpair { return kv; })* | |
{ return [head].concat(tail); } | |
)? | |
ws '}' { | |
let ob = {}; | |
if (!pairs) return ob; | |
for (let i = 0; i < pairs.length; i++) { | |
ob[pairs[i][0]] = pairs[i][1]; | |
} | |
return ob; | |
} | |
kvpair | |
= key:value rws val: value { return [key, val]; } | |
vector | |
= '[' ws | |
values:( | |
head:value | |
tail:(rws v:value { return v; })* | |
{ return [head].concat(tail); } | |
)? | |
ws ']' { return values ? values : []; } | |
_ "whitespace" | |
= [ \t\n\r,] | |
/ ';' [^\n]* '\n' | |
// optional whitespace | |
ws "whitespace" | |
= _* | |
// required whitespace | |
rws "whitespace" | |
= _+ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment