PEG.js中如何忽略空格

21
我想在我的语法中忽略空格和换行符,以便它们不会出现在PEG.js输出中。此外,方括号内的文字应该返回一个新数组。 语法
start
  = 'a'? sep+ ('cat'/'dog') sep* '(' sep* stmt_list sep* ')'

stmt_list
  = exp: [a-zA-Z]+ { return new Array(exp.join('')) }

sep
  = [' '\t\r\n]

测试用例

a dog( Harry )

输出

[
   "a",
   [
      " "
   ],
   "dog",
   [],
   "(",
   [
      " "
   ],
   [
       "Harry"
   ],
   [
      " "
   ],
   ")"
]

我想要的输出

[
   "a",
   "dog",
   [
      "Harry"
   ]
]
1个回答

29

你需要更细致地分解语法,使用更多的“非终结符”(我不确定在PEG中是否是这样称呼它们的):

start
  = article? animal stmt_list

article
  = article:'a' __ { return article; }

animal
  = animal:('cat'/'dog') _ { return animal; }

stmt_list
  = '(' _ exp:[a-zA-Z]+ _ ')' { return [ exp.join('') ]; }

// optional whitespace
_  = [ \t\r\n]*

// mandatory whitespace
__ = [ \t\r\n]+

感谢提出这个问题!

编辑: 为了增加可读性,有两种产生方式:___


谢谢!只有一件事:尝试使用dog(Harry)。冠词应该是可选的。将?'a'(在冠词中)移到start(在文章开头)仍然会返回一个空字符串...这与PEG.js有关吗? - Matthias
那么它也将允许 adog(Harry)。不管怎样,也许我正在使用错误的工具... 我有一个 xdot 语法(xdot 基于 dot),我想解析并绘制到画布上。你知道除了编写自己的解析器或使用像 canviz(功能不够)之类的东西之外,还有什么其他节省时间的方法来评估文件的语法吗? - Matthias
使用原始代码(与我的答案相同),“dog(Harry)”将被正确解析。 “article”作为一个空字符串返回到结果中,但它确实被解析了。 - Pointy
2
关于如何解析 dot 文件,语法足够复杂,我认为你需要一个“真正”的解析器。当然它不一定是 PEG;你可以用 JavaScript 编写自己的递归下降解析器,或者使用类似 Jison 的工具。我没有 PEG 解析的经验,但我觉得它很有趣。 :-) - Pointy
3
不是 [' '\t\r\n],而是 [ \t\r\n][' '\t\r\n] 会匹配 ' - alsotang
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接