如何使用 Flex 在可读模式中使用尾随上下文?
how to use trailing context in readable patterns with Flex?
在 Flex 中,我可以像这样在名称定义中使用尾随模式:
NAME foo$|bar
这通过了 flex。
但我不喜欢这样写没有空格的正则表达式,因为它们很难阅读。所以我想好好做:
NAME (?x: foo$ | bar )
但是现在 flex 失败了,因为根据手册,"‘$’, cannot be grouped inside parentheses"
.
恕我直言,这很愚蠢,允许一些构造,但不允许以可读的方式描述它。
如何在 Flex 中使用具有可读模式的尾随上下文?
首先,回答您的问题:“如何在 Flex 中使用具有可读模式的尾随上下文?”。如果您坚持只有在模式中撒上空格时模式才可读,那么答案是 “你不能。” 对不起,但就是这样这是。 (?x:
flag 在某些时候被 hack 到 flex 中,仍然有很多粗糙的边缘。
在某种程度上,这无关紧要,因为您不能将 $ 运算符用作 r|s
正则表达式中一个替代项的一部分。因此,即使您可以使用“可读语法”,它也不会是您想要的。您当然可以使用以下“可读语法”(至少,我认为它是可读的)。这意味着不同的东西,但它是 flex 支持的 $
运算符的唯一用途:
NAME (?x: foo | bar )$
下面是一些注释。
In Flex, I can use the a trailing pattern in a name definition like this:
NAME foo$|bar
不,你不能。或者,更好地说,您可以这样写,但它不涉及尾随上下文,因为:
…a '$' which does not occur at the end of a rule loses its special properties and is treated as a normal character.
(来自 Flex manual;这是该点中的最后一个短语,表示您不能将尾随上下文运算符放在括号内。)
flex 确实会拒绝(并且有点奇怪):
NAME (?x: foo$ | bar )
尽管它会接受:
NAME (?x: foo$| bar )
我会冒险说这是一个错误。仅当 $ 位于模式末尾时,它才会被识别为尾随上下文运算符。但是,检查的代码只是检查下一个字符是否为空白,因为模式在第一个空白字符处终止。 (模式不在定义中解析;当它实际包含在某些规则模式中时,它会被解析。)测试不检查 $ 是否在 [=24= 中] 块,所以在
(?x: foo$ | bar )
$是尾随上下文运算符,属于语法错误(运算符必须出现在模式的最末尾),而在
(?x: foo$| bar )
$只是一个普通字符,合法但可能出乎意料。
最后,注意一点:以下是完全合法的,$ 将被视为尾随上下文运算符,前提是定义用于模式的最后:
NAME bar|foo$
但是,它可能也不是您认为的意思。尾随上下文运算符的优先级低于交替运算符,因此只要扩展位于模式的末尾,就会像写入一样进行解析
NAME (bar|foo)$
我强烈建议不要使用这样的定义。 (事实上,我通常不鼓励使用定义,部分原因是所有这些怪癖。)以 $ 结尾的定义被插入到引用模式中而没有被括号包围(所以$ 可以被视为运算符)。这会导致各种意想不到的行为。例如,如果您写:
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 */
这些扩展中的任何一个都不太可能是您想要的,阅读您的代码的人更不可能期望得到这些结果。
在 Flex 中,我可以像这样在名称定义中使用尾随模式:
NAME foo$|bar
这通过了 flex。
但我不喜欢这样写没有空格的正则表达式,因为它们很难阅读。所以我想好好做:
NAME (?x: foo$ | bar )
但是现在 flex 失败了,因为根据手册,"‘$’, cannot be grouped inside parentheses"
.
恕我直言,这很愚蠢,允许一些构造,但不允许以可读的方式描述它。
如何在 Flex 中使用具有可读模式的尾随上下文?
首先,回答您的问题:“如何在 Flex 中使用具有可读模式的尾随上下文?”。如果您坚持只有在模式中撒上空格时模式才可读,那么答案是 “你不能。” 对不起,但就是这样这是。 (?x:
flag 在某些时候被 hack 到 flex 中,仍然有很多粗糙的边缘。
在某种程度上,这无关紧要,因为您不能将 $ 运算符用作 r|s
正则表达式中一个替代项的一部分。因此,即使您可以使用“可读语法”,它也不会是您想要的。您当然可以使用以下“可读语法”(至少,我认为它是可读的)。这意味着不同的东西,但它是 flex 支持的 $
运算符的唯一用途:
NAME (?x: foo | bar )$
下面是一些注释。
In Flex, I can use the a trailing pattern in a name definition like this:
NAME foo$|bar
不,你不能。或者,更好地说,您可以这样写,但它不涉及尾随上下文,因为:
…a '$' which does not occur at the end of a rule loses its special properties and is treated as a normal character.
(来自 Flex manual;这是该点中的最后一个短语,表示您不能将尾随上下文运算符放在括号内。)
flex 确实会拒绝(并且有点奇怪):
NAME (?x: foo$ | bar )
尽管它会接受:
NAME (?x: foo$| bar )
我会冒险说这是一个错误。仅当 $ 位于模式末尾时,它才会被识别为尾随上下文运算符。但是,检查的代码只是检查下一个字符是否为空白,因为模式在第一个空白字符处终止。 (模式不在定义中解析;当它实际包含在某些规则模式中时,它会被解析。)测试不检查 $ 是否在 [=24= 中] 块,所以在
(?x: foo$ | bar )
$是尾随上下文运算符,属于语法错误(运算符必须出现在模式的最末尾),而在
(?x: foo$| bar )
$只是一个普通字符,合法但可能出乎意料。
最后,注意一点:以下是完全合法的,$ 将被视为尾随上下文运算符,前提是定义用于模式的最后:
NAME bar|foo$
但是,它可能也不是您认为的意思。尾随上下文运算符的优先级低于交替运算符,因此只要扩展位于模式的末尾,就会像写入一样进行解析
NAME (bar|foo)$
我强烈建议不要使用这样的定义。 (事实上,我通常不鼓励使用定义,部分原因是所有这些怪癖。)以 $ 结尾的定义被插入到引用模式中而没有被括号包围(所以$ 可以被视为运算符)。这会导致各种意想不到的行为。例如,如果您写:
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 */
这些扩展中的任何一个都不太可能是您想要的,阅读您的代码的人更不可能期望得到这些结果。