2

我正在为 gawk 脚本编写一个弹性解析器。我在区分正斜杠 (/) 字符的用途时遇到了问题。

显然,单个 / 将是除法运算符,但两个斜杠既可以是正则表达式也可以是除法。现在,它解析

int((r-1)/3)*3+int((c-1)/3)+1

因为有正则表达式

/3)*3+int((c-1)/

而不是预期的分裂行动。如何让 flex 将其识别为数学表达式?

现在,这是我在 gawk 中识别正则表达式的 flex 正则表达式:

EXT_REG_EXP "\/"("\\\/"|[^\/\n])*"\/"

并且除法运算符应该被我的运算符列表捕获:

OPERATOR "+"|"-"|"*"|"/"|"%"|"^"|"!"|">"|"<"|"|"|"?"|":"|"~"|"$"|"="

但是由于 flex 正则表达式是贪婪的,我猜它会将两个除法视为正则表达式。

4

1 回答 1

3

我认为不可能定义一个简单的标记表达式来明确识别正则表达式。awk的Posix 规范因此指出了歧义:

在某些情况下,用于包围 ERE 的斜线 ('/') 也可以是除法运算符。这应该以这样一种方式解决,即在除法运算符出现的任何地方,斜线都被假定为除法运算符。(没有一元除法运算符。)

然后:

标记 ERE 与标记 '/' 和 DIV_ASSIGN 之间存在词汇歧义。当输入序列在任何句法上下文中以斜杠字符开头时,其中标记“/”或 DIV_ASSIGN 可能作为有效程序中的下一个标记出现,则应识别这两个标记中可以识别的较长者。在令牌 ERE 可能作为有效程序中的下一个令牌出现的任何其他句法上下文中,令牌 ERE 应被识别。

(“ERE”代表“扩展正则表达式”。)由此,我认为您可以安全地得出结论,Awk 的标记器必须了解语法上下文,因此没有可能的正则表达式可以成功识别正则表达式令牌。

还值得研究如何定义 Awk 本身(或至少一个实现)来解析正则表达式。在最初的 Awk(有时称为 One True Awk)中,识别正则表达式是解析器的工作,当它发现它应该期望读取一个正则表达式时,它显式地将词法分析器设置为“正则表达式模式”:

reg_expr:
      '/' {startreg();} REGEXPR '/'     { $$ = $3; }
    ;

startreg()lex.c中定义的函数。)reg_expr规则本身只在除法运算符无效的上下文中匹配。

很抱歉让您失望了,但我希望这仍然会有所帮助。

于 2012-10-01T01:26:00.380 回答