Regex JavaCC'的解释和解决方案;“安全警告”;正则表达式选项:FOO永远不能匹配为:BAR";?
我正在一个业余项目中自学如何使用JavaCC,并且有一个简单的语法来编写解析器。解析器的一部分包括以下内容:Regex JavaCC'的解释和解决方案;“安全警告”;正则表达式选项:FOO永远不能匹配为:BAR";?,regex,parsing,javacc,Regex,Parsing,Javacc,我正在一个业余项目中自学如何使用JavaCC,并且有一个简单的语法来编写解析器。解析器的一部分包括以下内容: TOKEN : { < DIGIT : (["0"-"9"]) > } TOKEN : { < INTEGER : (<DIGIT>)+ > } TOKEN : { < INTEGER_PAIR : (<INTEGER>){2} > } TOKEN : { < FLOAT : (<NEGATE>)? <I
TOKEN : { < DIGIT : (["0"-"9"]) > }
TOKEN : { < INTEGER : (<DIGIT>)+ > }
TOKEN : { < INTEGER_PAIR : (<INTEGER>){2} > }
TOKEN : { < FLOAT : (<NEGATE>)? <INTEGER> | (<NEGATE>)? <INTEGER> "." <INTEGER> | (<NEGATE>)? <INTEGER> "." | (<NEGATE>)? "." <INTEGER> > }
TOKEN : { < FLOAT_PAIR : (<FLOAT>){2} > }
TOKEN : { < NUMBER_PAIR : <FLOAT_PAIR> | <INTEGER_PAIR> > }
TOKEN : { < NEGATE : "-" > }
我相信这是一个简单的概念,但我不理解警告,因为我是解析器生成和正则表达式的新手
这个警告是什么意思(尽可能地用新手术语)?我没有使用JavaCC,但数字对可能不明确 我认为问题可以归结为这样一个事实,即相同的事物可以与FLOAT_对和INTEGER_对匹配,因为FLOAT可以匹配整数
但这只是一个猜测,从未见过JavaCC语法:)这可能意味着对于每个
FLOAT\u对
,您只会得到一个FLOAT\u对
令牌,而不是一个NUMBER\u对
令牌。FLOAT\u对
规则已经匹配了所有的输入,JavaCC将不会试图找到进一步的匹配规则。这将是我的解释,但我不知道JavaCC,所以请恕我直言
也许你可以指定,
NUMBER\u PAIR
是主要产品,并且你不想得到任何其他标记作为结果。我不知道JavaCC,但我是一名编译工程师
FLOAT\u对
规则不明确。考虑下面的文本:
0.0
这可能是FLOAT 0
,然后是FLOAT.0
;或者它可以是FLOAT 0。
后跟FLOAT 0
;两者都会导致浮点数对。或者它可以是单个浮点0.0
不过,更重要的是,你正在用一种永远不可能奏效的方式对作文进行词汇分析。考虑这个数字:
12345
这可以被解析为整数12、整数345
,从而产生整数对
。或者它可以被解析为整数123,整数45
,另一个整数对
。或者它可以是另一个令牌整数12345
。问题的存在是因为您不需要在INTEGER\u对
(或FLOAT\u对
)的词法元素之间留空格
在lexer中,几乎不应该尝试处理这样的配对。相反,您应该将普通数字(INTEGER
和FLOAT
)作为标记处理,并在解析器中处理诸如求反和配对之类的事情,在解析器中已处理并去除了空格
(例如,您将如何处理“---42”
?这是大多数编程语言中的一个有效表达式,它将正确计算多个求反,但不会由lexer处理。)
另外,请注意,lexer中的一位数整数不会匹配为
整数
,它们将显示为数字
。不过,我不知道JavaCC的正确语法可以为您解决这个问题。您想要的是定义数字
而不是作为一个标记,而只是一些您可以在其他标记的定义中使用的东西;或者,在规则中使用数字的任何地方直接嵌入数字的定义([0-9]
)。感谢Barry Kelly的回答,我想出的解决方案是:
SKIP : { < #TO_SKIP : " " | "\t" > }
TOKEN : { < #DIGIT : (["0"-"9"]) > }
TOKEN : { < #DIGITS : (<DIGIT>)+ > }
TOKEN : { < INTEGER : <DIGITS> > }
TOKEN : { < INTEGER_PAIR : (<INTEGER>) (<TO_SKIP>)+ (<INTEGER>) > }
TOKEN : { < FLOAT : (<NEGATE>)?<DIGITS>"."<DIGITS> | (<NEGATE>)?"."<DIGITS> > }
TOKEN : { < FLOAT_PAIR : (<FLOAT>) (<TO_SKIP>)+ (<FLOAT>) > }
TOKEN : { < #NUMBER : <FLOAT> | <INTEGER> > }
TOKEN : { < NUMBER_PAIR : (<NUMBER>) (<TO_SKIP>)+ (<NUMBER>) >}
TOKEN : { < NEGATE : "-" > }
SKIP:{<#TO_SKIP:|“\t”>}
令牌:{<#数字:([“0”-“9”])>}
标记:{<#数字:()+>}
标记:{}
标记:{}
标记:{}
令牌:{}
令牌:{<#编号:|>}
令牌:{}
标记:{<否定:“-”>}
我完全忘记了包含用于分隔两个标记的空格,我还使用了“#”符号来停止标记的匹配,并且仅用于其他标记的定义中。以上内容由JavaCC编译,没有警告或错误
但是,正如Barry所指出的,这样做是有原因的。我不确定,我更改了Float,因此它无法匹配整数-{,但仍然收到了警告。我对此感到惊讶,因为你说的似乎完全合乎逻辑:)嗯。。。我仍然认为这与歧义有关,但老实说,因为我没有尝试过JavaCC,所以我在这里对你没有任何实际用处。。。我会推迟,希望知道的人会回答。
SKIP : { < #TO_SKIP : " " | "\t" > }
TOKEN : { < #DIGIT : (["0"-"9"]) > }
TOKEN : { < #DIGITS : (<DIGIT>)+ > }
TOKEN : { < INTEGER : <DIGITS> > }
TOKEN : { < INTEGER_PAIR : (<INTEGER>) (<TO_SKIP>)+ (<INTEGER>) > }
TOKEN : { < FLOAT : (<NEGATE>)?<DIGITS>"."<DIGITS> | (<NEGATE>)?"."<DIGITS> > }
TOKEN : { < FLOAT_PAIR : (<FLOAT>) (<TO_SKIP>)+ (<FLOAT>) > }
TOKEN : { < #NUMBER : <FLOAT> | <INTEGER> > }
TOKEN : { < NUMBER_PAIR : (<NUMBER>) (<TO_SKIP>)+ (<NUMBER>) >}
TOKEN : { < NEGATE : "-" > }