5

我正在尝试为 PEG.js 编写一个简单的语法,它可以匹配如下内容:

some text;
arbitrary other text that can also have µnicode; different expression;
let's escape the \; semicolon, and \not recognized escapes are not a problem;
possibly last expression not ending with semicolon

所以基本上这些是一些用分号分隔的文本。我的简化语法如下所示:

start
= flow:Flow

Flow
= instructions:Instruction*

Instruction
= Empty / Text

TextCharacter
= "\\;" /
.

Text
= text:TextCharacter+ ';' {return text.join('')}

Empty
= Semicolon

Semicolon "semicolon"
= ';'

问题是,如果我在输入中输入分号以外的任何内容,我会得到:

SyntaxError: Expected ";", "\\;" or any character but end of input found.

如何解决这个问题?我读过 PEG.js 无法匹配输入的结尾。

4

1 回答 1

10

你有(至少)2个问题:

TextCharacter不应该匹配任何字符.)。它应该匹配除反斜杠和分号之外的任何字符,或者它应该匹配转义字符:

TextCharacter
 = [^\\;]
 / "\\" .

第二个问题是您的语法要求您的输入以分号结尾(但您的输入不以 结尾;)。

像这样的东西怎么样:

start
 = instructions

instructions
 = instruction (";" instruction)* ";"?

instruction
 = chars:char+ {return chars.join("").trim();}

char
 = [^\\;]
 / "\\" c:. {return ""+c;}

它将按如下方式解析您的输入:

[
   "some text",
   [
      [
         ";",
         "arbitrary other text that can also have µnicode"
      ],
      [
         ";",
         "different expression"
      ],
      [
         ";",
         "let's escape the ; semicolon, and not recognized escapes are not a problem"
      ],
      [
         ";",
         "possibly last expression not ending with semicolon"
      ]
   ]
]

请注意,尾随分号现在是可选的。

于 2012-10-05T12:02:37.707 回答