lexing gawk代码区分正则表达式

时间:2012-09-30 21:19:34

标签: c++ regex awk lex

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

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

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

有正则表达式

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

而不是预期的分工操作。如何将flex识别为数学表达式?

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

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

并且我的运算符列表应该包含除法运算符:

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

但是由于flex正则表达式是贪婪的,我猜它将两个分区视为正​​则表达式。

1 个答案:

答案 0 :(得分:2)

我认为不可能定义一个简单的令牌表达式来明确地识别正则表达式。 Posix spec for Awk注意到了歧义:

  

在某些情况下,用于包围ERE的斜杠('/')   也可以是分部运营商。这应该在这样的方面解决   这样一种方式,即除法运算符出现在哪里,斜线就是   假设是分部运营商。 (没有一元师   操作者。)

后来:

  

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

(“ERE”代表“扩展正则表达式。”)从这一点来看,我认为你可以安全地得出结论,awk的一个标记化器必须知道语法上下文,因此没有可能成功的正则表达式识别正则表达式令牌。

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

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

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

很抱歉让人失望,但我希望这会有所帮助。