I have essentially the same question as PEG for Python style indentation, but I\'d like to get a little more direction regarding this answer.
The answer successfully gen
Parser:
// do not use result cache, nor line and column tracking
{ var indentStack = [], indent = ""; }
start
= INDENT? l:line
{ return l; }
line
= SAMEDENT line:(!EOL c:. { return c; })+ EOL?
children:( INDENT c:line* DEDENT { return c; })?
{ var o = {}; o[line] = children; return children ? o : line.join(""); }
EOL
= "\r\n" / "\n" / "\r"
SAMEDENT
= i:[ \t]* &{ return i.join("") === indent; }
INDENT
= &(i:[ \t]+ &{ return i.length > indent.length; }
{ indentStack.push(indent); indent = i.join(""); pos = offset; })
DEDENT
= { indent = indentStack.pop(); }
Input:
a
b
c
d
z
y
x
Output:
{
"a": [
"b",
"c",
{
"d": [
"z",
"y",
"x"
]
}
]
}
It cannot parse an empty object (last x), however, it should be easy to solve. Trick here is the SAMEDENT rule, it succeeds when indentation level hasn't changed. INDENT and DEDENT change current indentation level without changing position in text pos = offset.