问题在于,-
某些解析器人员称之为“领先集”,float
因此解析器不知道后面的不是 a float
,而是愉快地继续尝试解析一个。由 PEGjs 实现的解析器的 Parsing Expression Grammar 样式不会在符号内进行回溯。
避免这种情况的唯一方法是向解析器提供更多信息,说明您正在尝试做什么,以避免通过允许-
在前导集 ofstr
和 in 中引入的前导集歧义float
。您可以通过强制解析器[0-9]+
在看到-
. 实际上,我怀疑您的语法不能准确地表示您想要完成的内容,因为它也允许使用0123-456
or123.456-789.987.123
之类的字符串float
。您需要强制将-
a 作为可选的第一个字符,float
然后需要一串数字才能使其正确浮动。
我建议你这样写你的语法:
start = val
ln = [\n\r]
float = digits:$('-'? [0-9]+ '.'? [0-9]*
/ '-'? '.' [0-9]+) { return parseFloat(digits, 10) }
str = str:$(!ln !"\"" .)+
val = float / str
The first part of float
captures the case where there are digits before the decimal point or the decimal point is missing. The second part captures the case where there are no digits before the decimal point, but it is present, and it enforces the requirement of digits after the decimal point in this case.
The fact that you have val = float / str
rather than val = str / float
is critical also. You have to try to match a float
before you try to match a str
for this to work. I'm not really sure about that definition for str
, but I don't know the language you're trying to parse.