解析Peg.JS中的段落

时间:2017-06-23 13:36:42

标签: javascript pegjs

我正在尝试学习peg.js并希望解析简单的"块"但是我正在努力解决如何在没有得到可能的无限循环的情况下对顺序线进行分组的问题。我的语法错误。

目标:

line 1

line 3
line 4

line 6

解析后会变为:

{
   "type": "root",
   "children": [
      { type: "para", content: "line 1" },
      { type: "para", content: "line 3\nline 4" },
      { type: "para", content: "line 6" },
   ]
}

换句话说:

  • 第一行是它自己的一个段落,因为它后跟一个空行
  • 第三行和第四行是一个段落,因为它们后跟一个空行
  • 第六行是一个段落,因为它是最后一行(一个或多个)

我可以编写一个匹配行和空行的语法(参见http://peg.arcanis.fr/4f4NdP/),但是我尝试获取多个连续行后跟一个空白行(或EOF)变成段落的任何内容都以递归错误。我觉得这是一个非常简单的事情,我只是因为我以前没有使用过PEG而失踪。

我知道我可以在初始化程序块中编写一个全局函数并跟踪最后一个元素并使其成为上下文,但我觉得这并不像我应该那样使用语法。

1 个答案:

答案 0 :(得分:2)

你知道那些星期你在某些事情上挣扎了一天左右然后最后放弃,吞下你的骄傲并发出问题叠加溢出......然后十分钟后找出答案?是的!那是我的一周。我认为写出问题的过程会让你以不同的方式思考问题而你的突触会再次开始射击......

无论如何,这是解决方案:http://peg.arcanis.fr/4f4NdP/2/

后人的语法:

start = head:Para tail:(newline Para)*
   {
      var t;

      t = tail.reduce(function(memo, element) {
         return memo.concat(element[1]);
      }, []);

      return {
         type: 'root',
         children: [ head ].concat(t),
      }
   }

Para = text:LineOfText+
   { return { type: 'para', content: text.join('\n') } }

LineOfText = text:$(char+) EOL
   { return text }

char = [^\n\r]
newline = '\n' / '\r' '\n'?
EOL = newline / !.

输入:

line 1

line 3
line 4

line 6

输出:

{
   "type": "root",
   "children": [
      {
         "type": "para",
         "content": "line 1"
      },
      {
         "type": "para",
         "content": "line 3
line 4"
      },
      {
         "type": "para",
         "content": "line 6"
      }
   ]
}