在Flex中,我可以在名称定义中使用a trailing模式,如下所示:
NAME foo$|bar
这会传递flex。
但我不喜欢写这样的正则表达式,没有空格,因为它们很难阅读。所以我想做得好:
NAME (?x: foo$ | bar )
但是现在这会导致flex失败,因为根据手册"‘$’, cannot be grouped inside parentheses"
。
如何在Flex中使用具有可读模式的尾随上下文?
答案 0 :(得分:2)
首先,回答你的问题:“如何在Flex中使用具有可读模式的尾随上下文?”。如果您坚持认为模式只有洒满空格才能读取,那么答案就是 “你不能。” 抱歉,但就是这样。 (?x:
标志在某个时刻被侵入弯曲,并且仍有很多粗糙的边缘。
在某种程度上,无关紧要,因为您不能将 $ 运算符用作r|s
正则表达式中的一个备选项的一部分。因此,即使您可以使用“可读语法”,也不会意味着您的意图。您当然可以使用以下“可读语法”(至少,我认为它是可读的)。它意味着不同的东西,但它是flex支持的$
运算符的唯一用途:
NAME (?x: foo | bar )$
以下是一些注释。
不,你不能。或者,更好地说,你可以写,但它不涉及尾随上下文,因为:在Flex中,我可以在名称定义中使用a trailing模式,如下所示:
NAME foo$|bar
...在规则末尾没有出现的'$'会丢失其特殊属性,并被视为普通字符。
(来自Flex manual;它是该点中的最后一个短语,表示您不能将尾随上下文运算符放在括号内。)
flex会拒绝:
这是真的(并且有点好奇)NAME (?x: foo$ | bar )
虽然它会接受:
NAME (?x: foo$| bar )
我会站出来说这是一个错误。仅当 $ 位于模式的末尾时,它才被识别为尾随上下文运算符。但是,检查它的代码只是检查下一个字符是否是空格,因为模式终止于第一个空白字符。 (该模式未在定义中解析;当它实际包含在某些规则模式中时会对其进行解析。)测试不会检查 $ 是否在(?x:
块内,所以在
(?x: foo$ | bar )
$ 是一个尾随上下文运算符,这是一个语法错误(运算符必须出现在模式的最后),而在
中(?x: foo$| bar )
$ 只是一个普通的角色,这是合法的,但也许是意外的。
最后,请注意:以下内容完全合法, $ 将被视为尾随上下文运算符,前提是该定义在模式的最后使用< / EM>:
NAME bar|foo$
然而,它可能并不意味着你认为它意味着什么。尾随上下文运算符的优先级低于交替运算符,因此只要扩展位于模式的末尾,就会将其解析为已写入
NAME (bar|foo)$
我强烈建议不要使用这样的定义。 (事实上,我通常不鼓励使用定义,部分原因是因为所有这些怪癖。)以 $ 结尾的定义被插入到引用模式中而不被括号括起来(以便< kbd> $ 可以视为运营商)。这会导致各种意外行为。例如,如果你写:
NAME bar|foo$
然后使用它:
x{NAME}y /* Some action */
最终结果就好像你写了
xbar|foo"$"y /* Some action */
(没有括号,但 $ 是常规字符。)
另一方面,如果你这样使用它:
x{NAME} /* Some action */
就像你写的那样
xbar|foo$ /* Some action */
其中 $ 是尾随上下文运算符,但由于该运算符的优先级较低,它最终等同于
(xbar|foo)$ /* Some action */
这些扩展不太可能是您想要的,而且阅读代码的任何人都不太可能期望这些结果。