Skip to content

Commit

Permalink
Merge pull request #610 from sethkinast/peg
Browse files Browse the repository at this point in the history
clean up PEG grammar a little bit
  • Loading branch information
prashn64 committed Apr 14, 2015
2 parents 13807c8 + 70b986f commit f833b34
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 50 deletions.
62 changes: 39 additions & 23 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@

peg$c0 = [],
peg$c1 = function(p) {
return ["body"]
.concat(p)
.concat([['line', line()], ['col', column()]]);
var body = ["body"].concat(p);
return withPosition(body);
},
peg$c2 = { type: "other", description: "section" },
peg$c3 = peg$FAILED,
Expand All @@ -66,13 +65,13 @@
peg$c7 = function(t, b, e, n) {
e.push(["param", ["literal", "block"], b]);
t.push(e);
return t.concat([['line', line()], ['col', column()]]);
return withPosition(t)
},
peg$c8 = "/",
peg$c9 = { type: "literal", value: "/", description: "\"/\"" },
peg$c10 = function(t) {
t.push(["bodies"]);
return t.concat([['line', line()], ['col', column()]]);
return withPosition(t)
},
peg$c11 = /^[#?\^<+@%]/,
peg$c12 = { type: "class", value: "[#?\\^<+@%]", description: "[#?\\^<+@%]" },
Expand All @@ -91,7 +90,7 @@
peg$c25 = { type: "other", description: "bodies" },
peg$c26 = function(p) { return ["bodies"].concat(p) },
peg$c27 = { type: "other", description: "reference" },
peg$c28 = function(n, f) { return ["reference", n, f].concat([['line', line()], ['col', column()]]) },
peg$c28 = function(n, f) { return withPosition(["reference", n, f]) },
peg$c29 = { type: "other", description: "partial" },
peg$c30 = ">",
peg$c31 = { type: "literal", value: ">", description: "\">\"" },
Expand All @@ -100,7 +99,7 @@
peg$c34 = function(k) {return ["literal", k]},
peg$c35 = function(s, n, c, p) {
var key = (s === ">") ? "partial" : s;
return [key, n, c, p].concat([['line', line()], ['col', column()]]);
return withPosition([key, n, c, p])
},
peg$c36 = { type: "other", description: "filters" },
peg$c37 = "|",
Expand All @@ -109,10 +108,18 @@
peg$c40 = { type: "other", description: "special" },
peg$c41 = "~",
peg$c42 = { type: "literal", value: "~", description: "\"~\"" },
peg$c43 = function(k) { return ["special", k].concat([['line', line()], ['col', column()]]) },
peg$c43 = function(k) { return withPosition(["special", k]) },
peg$c44 = { type: "other", description: "identifier" },
peg$c45 = function(p) { var arr = ["path"].concat(p); arr.text = p[1].join('.').replace(/,line,\d+,col,\d+/g,''); return arr; },
peg$c46 = function(k) { var arr = ["key", k]; arr.text = k; return arr; },
peg$c45 = function(p) {
var arr = ["path"].concat(p);
arr.text = p[1].join('.').replace(/,line,\d+,col,\d+/g,'');
return arr;
},
peg$c46 = function(k) {
var arr = ["key", k];
arr.text = k;
return arr;
},
peg$c47 = { type: "other", description: "number" },
peg$c48 = function(n) { return ['literal', n]; },
peg$c49 = { type: "other", description: "float" },
Expand All @@ -122,26 +129,26 @@
peg$c53 = { type: "other", description: "unsigned_integer" },
peg$c54 = /^[0-9]/,
peg$c55 = { type: "class", value: "[0-9]", description: "[0-9]" },
peg$c56 = function(digits) { return parseInt(digits.join(""), 10); },
peg$c56 = function(digits) { return makeInteger(digits); },
peg$c57 = { type: "other", description: "signed_integer" },
peg$c58 = "-",
peg$c59 = { type: "literal", value: "-", description: "\"-\"" },
peg$c60 = function(sign, n) { return n*-1; },
peg$c60 = function(sign, n) { return n * -1; },
peg$c61 = { type: "other", description: "integer" },
peg$c62 = { type: "other", description: "path" },
peg$c63 = function(k, d) {
d = d[0];
if (k && d) {
d.unshift(k);
return [false, d].concat([['line', line()], ['col', column()]]);
return withPosition([false, d])
}
return [true, d].concat([['line', line()], ['col', column()]]);
return withPosition([true, d])
},
peg$c64 = function(d) {
if (d.length > 0) {
return [true, d[0]].concat([['line', line()], ['col', column()]]);
return withPosition([true, d[0]])
}
return [true, []].concat([['line', line()], ['col', column()]]);
return withPosition([true, []])
},
peg$c65 = { type: "other", description: "key" },
peg$c66 = /^[a-zA-Z_$]/,
Expand All @@ -159,15 +166,15 @@
peg$c78 = { type: "other", description: "inline" },
peg$c79 = "\"",
peg$c80 = { type: "literal", value: "\"", description: "\"\\\"\"" },
peg$c81 = function() { return ["literal", ""].concat([['line', line()], ['col', column()]]) },
peg$c82 = function(l) { return ["literal", l].concat([['line', line()], ['col', column()]]) },
peg$c83 = function(p) { return ["body"].concat(p).concat([['line', line()], ['col', column()]]) },
peg$c81 = function() { return withPosition(["literal", ""]) },
peg$c82 = function(l) { return withPosition(["literal", l]) },
peg$c83 = function(p) { return withPosition(["body"].concat(p)) },
peg$c84 = function(l) { return ["buffer", l] },
peg$c85 = { type: "other", description: "buffer" },
peg$c86 = function(e, w) { return ["format", e, w.join('')].concat([['line', line()], ['col', column()]]) },
peg$c86 = function(e, w) { return withPosition(["format", e, w.join('')]) },
peg$c87 = { type: "any", description: "any character" },
peg$c88 = function(c) {return c},
peg$c89 = function(b) { return ["buffer", b.join('')].concat([['line', line()], ['col', column()]]) },
peg$c89 = function(b) { return withPosition(["buffer", b.join('')]) },
peg$c90 = { type: "other", description: "literal" },
peg$c91 = /^[^"]/,
peg$c92 = { type: "class", value: "[^\"]", description: "[^\"]" },
Expand All @@ -181,13 +188,13 @@
peg$c100 = "`}",
peg$c101 = { type: "literal", value: "`}", description: "\"`}\"" },
peg$c102 = function(char) {return char},
peg$c103 = function(rawText) { return ["raw", rawText.join('')].concat([['line', line()], ['col', column()]]) },
peg$c103 = function(rawText) { return withPosition(["raw", rawText.join('')]) },
peg$c104 = { type: "other", description: "comment" },
peg$c105 = "{!",
peg$c106 = { type: "literal", value: "{!", description: "\"{!\"" },
peg$c107 = "!}",
peg$c108 = { type: "literal", value: "!}", description: "\"!}\"" },
peg$c109 = function(c) { return ["comment", c.join('')].concat([['line', line()], ['col', column()]]) },
peg$c109 = function(c) { return withPosition(["comment", c.join('')]) },
peg$c110 = /^[#?\^><+%:@\/~%]/,
peg$c111 = { type: "class", value: "[#?\\^><+%:@\\/~%]", description: "[#?\\^><+%:@\\/~%]" },
peg$c112 = "{",
Expand Down Expand Up @@ -2688,6 +2695,15 @@
return s0;
}


function makeInteger(arr) {
return parseInt(arr.join(''), 10);
}
function withPosition(arr) {
return arr.concat([['line', line()], ['col', column()]]);
}


peg$result = peg$startRuleFunction();

if (peg$result !== peg$FAILED && peg$currPos === input.length) {
Expand Down
78 changes: 51 additions & 27 deletions src/dust.pegjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
{
function makeInteger(arr) {
return parseInt(arr.join(''), 10);
}
function withPosition(arr) {
return arr.concat([['line', line()], ['col', column()]]);
}
}

start
= body

Expand All @@ -6,9 +15,8 @@ start
---------------------------------------------------------------------------------------------------------------------------------------*/
body
= p:part* {
return ["body"]
.concat(p)
.concat([['line', line()], ['col', column()]]);
var body = ["body"].concat(p);
return withPosition(body);
}

/*-------------------------------------------------------------------------------------------------------------------------------------
Expand All @@ -22,7 +30,9 @@ part
plus bodies plus end_tag or sec_tag_start followed by a slash and closing brace
---------------------------------------------------------------------------------------------------------------------------------------*/
section "section"
= t:sec_tag_start ws* rd b:body e:bodies n:end_tag? &{
= t:sec_tag_start ws* rd b:body e:bodies n:end_tag?
// non-self-closing format
&{
if( (!n) || (t[1].text !== n.text) ) {
error("Expected end tag for "+t[1].text+" but it was not found.");
}
Expand All @@ -31,11 +41,13 @@ section "section"
{
e.push(["param", ["literal", "block"], b]);
t.push(e);
return t.concat([['line', line()], ['col', column()]]);
return withPosition(t)
}
/ t:sec_tag_start ws* "/" rd {
// self-closing format
/ t:sec_tag_start ws* "/" rd
{
t.push(["bodies"]);
return t.concat([['line', line()], ['col', column()]]);
return withPosition(t)
}

/*-------------------------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -80,7 +92,7 @@ bodies "bodies"
---------------------------------------------------------------------------------------------------------------------------------------*/
reference "reference"
= ld n:identifier f:filters rd
{ return ["reference", n, f].concat([['line', line()], ['col', column()]]) }
{ return withPosition(["reference", n, f]) }

/*-------------------------------------------------------------------------------------------------------------------------------------
partial is defined as matching a opening brace followed by a > plus anything that matches with key or inline plus
Expand All @@ -90,7 +102,7 @@ partial "partial"
= ld s:(">"/"+") ws* n:(k:key {return ["literal", k]} / inline) c:context p:params ws* "/" rd
{
var key = (s === ">") ? "partial" : s;
return [key, n, c, p].concat([['line', line()], ['col', column()]]);
return withPosition([key, n, c, p])
}

/*-------------------------------------------------------------------------------------------------------------------------------------
Expand All @@ -105,14 +117,24 @@ filters "filters"
---------------------------------------------------------------------------------------------------------------------------------------*/
special "special"
= ld "~" k:key rd
{ return ["special", k].concat([['line', line()], ['col', column()]]) }
{ return withPosition(["special", k]) }

/*-------------------------------------------------------------------------------------------------------------------------------------
identifier is defined as matching a path or key
---------------------------------------------------------------------------------------------------------------------------------------*/
identifier "identifier"
= p:path { var arr = ["path"].concat(p); arr.text = p[1].join('.').replace(/,line,\d+,col,\d+/g,''); return arr; }
/ k:key { var arr = ["key", k]; arr.text = k; return arr; }
= p:path
{
var arr = ["path"].concat(p);
arr.text = p[1].join('.').replace(/,line,\d+,col,\d+/g,'');
return arr;
}
/ k:key
{
var arr = ["key", k];
arr.text = k;
return arr;
}

number "number"
= n:(float / integer) { return ['literal', n]; }
Expand All @@ -121,10 +143,10 @@ float "float"
= l:integer "." r:unsigned_integer { return parseFloat(l + "." + r); }

unsigned_integer "unsigned_integer"
= digits:[0-9]+ { return parseInt(digits.join(""), 10); }
= digits:[0-9]+ { return makeInteger(digits); }

signed_integer "signed_integer"
= sign:'-' n:unsigned_integer { return n*-1; }
= sign:'-' n:unsigned_integer { return n * -1; }

integer "integer"
= signed_integer / unsigned_integer
Expand All @@ -133,19 +155,21 @@ integer "integer"
path is defined as matching a key plus one or more characters of key preceded by a dot
---------------------------------------------------------------------------------------------------------------------------------------*/
path "path"
= k:key? d:(array_part / array)+ {
= k:key? d:(array_part / array)+
{
d = d[0];
if (k && d) {
d.unshift(k);
return [false, d].concat([['line', line()], ['col', column()]]);
return withPosition([false, d])
}
return [true, d].concat([['line', line()], ['col', column()]]);
return withPosition([true, d])
}
/ "." d:(array_part / array)* {
/ "." d:(array_part / array)*
{
if (d.length > 0) {
return [true, d[0]].concat([['line', line()], ['col', column()]]);
return withPosition([true, d[0]])
}
return [true, []].concat([['line', line()], ['col', column()]]);
return withPosition([true, []])
}

/*-------------------------------------------------------------------------------------------------------------------------------------
Expand All @@ -166,9 +190,9 @@ array_part "array_part"
double quotes plus inline_part followed by the closing double quotes
---------------------------------------------------------------------------------------------------------------------------------------*/
inline "inline"
= '"' '"' { return ["literal", ""].concat([['line', line()], ['col', column()]]) }
/ '"' l:literal '"' { return ["literal", l].concat([['line', line()], ['col', column()]]) }
/ '"' p:inline_part+ '"' { return ["body"].concat(p).concat([['line', line()], ['col', column()]]) }
= '"' '"' { return withPosition(["literal", ""]) }
/ '"' l:literal '"' { return withPosition(["literal", l]) }
/ '"' p:inline_part+ '"' { return withPosition(["body"].concat(p)) }

/*-------------------------------------------------------------------------------------------------------------------------------------
inline_part is defined as matching a special or reference or literal
Expand All @@ -178,9 +202,9 @@ inline_part

buffer "buffer"
= e:eol w:ws*
{ return ["format", e, w.join('')].concat([['line', line()], ['col', column()]]) }
{ return withPosition(["format", e, w.join('')]) }
/ b:(!tag !raw !comment !eol c:. {return c})+
{ return ["buffer", b.join('')].concat([['line', line()], ['col', column()]]) }
{ return withPosition(["buffer", b.join('')]) }

/*-------------------------------------------------------------------------------------------------------------------------------------
literal is defined as matching esc or any character except the double quotes and it cannot be a tag
Expand All @@ -194,10 +218,10 @@ esc

raw "raw"
= "{`" rawText:(!"`}" char:. {return char})* "`}"
{ return ["raw", rawText.join('')].concat([['line', line()], ['col', column()]]) }
{ return withPosition(["raw", rawText.join('')]) }
comment "comment"
= "{!" c:(!"!}" c:. {return c})* "!}"
{ return ["comment", c.join('')].concat([['line', line()], ['col', column()]]) }
{ return withPosition(["comment", c.join('')]) }

/*-------------------------------------------------------------------------------------------------------------------------------------
tag is defined as matching an opening brace plus any of #?^><+%:@/~% plus 0 or more whitespaces plus any character or characters that
Expand Down

0 comments on commit f833b34

Please sign in to comment.