我正在为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正则表达式是贪婪的,我猜它将两个分区视为正则表达式。
答案 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
规则本身仅在除法运算符无效的上下文中匹配。
很抱歉让人失望,但我希望这会有所帮助。