2017-06-23 52 views
0

我在学习peg.js,希望解析文本的简单“块”,但是在如何对顺序行进行分组时没有从我的语法中获得“可能的无限循环”错误而挣扎。解析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" }, 
    ] 
} 

换句话说:

  • 线一个是它自己的段落,因为它后面是空白线
  • 第三和第四行是一个段落,因为它们是foll一个空行欠
  • 六号线是一个段落,因为它是最后一行(S)(一个或多个)

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

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

回答

1

你知道那些星期你在某一天挣扎了一天左右,然后最终放弃,吞下你的骄傲,并发布一个问题堆栈溢出......然后十分钟后找出答案?是的!这是我的一周。我觉得写出来的问题的过程中让你觉得以不同的方式问题,你的突触重新开始或东西烧...

总之,这里的解决方案: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" 
     } 
    ] 
}