解析缩进水平PEG.js(Parse indentation level with PEG.js)

2019-07-30 15:13发布

我基本上是同样的问题, PEG为Python风格的缩进 ,但我想获得关于多一点的方向这个答案 。

答案成功产生被输入的每行以“INDENT”和线之间的“DEDENT语言”字符串数组。 好像他几乎是用PEG.js来标记,但没有真正的分析正在发生的事情。

所以,我怎么能延长他的榜样,做一些实际的解析?

举个例子,我怎样才能改变这种语法:

start = obj
obj = id:id children:(indent obj* outdent)?
      {
          var o = {};
          o[id] = children[1];
          return (children[1] ? o : id);
      }
id = [a-z]
indent = '{'
outdent = '}'

使用缩进而不是括号划定区块,并仍然得到同样的输出?

(使用http://pegjs.majda.cz/online来测试使用以下输入该语法: a{bcd{zyx{}}}

Answer 1:

分析器:

// 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(); }

输入:

a
  b
  c
  d
    z
    y
    x

输出:

{
   "a": [
      "b",
      "c",
      {
         "d": [
            "z",
            "y",
            "x"
         ]
      }
   ]
}

它不能解析一个空对象(最后x ),但是,它应该很容易解决。 绝招这里是SAMEDENT规则,它成功时缩进级别并没有改变。 INDENTDEDENT改变当前缩进水平,而不改变以文本位置pos = offset



文章来源: Parse indentation level with PEG.js