我在代码源中使用Flex替换数字表达式:
例如:
Input string: ... echo "test"; if ($isReady) $variable = 2 * 5; ...
Desired result string: ... echo "test"; if ($isReady) $variable = 10; ...
我的代码:
%{
#include <stdio.h>
#include <stdlib.h>
%}
MYEXP [0-9]+[ \t\n\r]*\+[ \t\n\r]*[0-9]+
%%
{MYEXP} {
printf("multiplication ");
// code for processing
}
%%
void main()
{
yylex();
}
如何使用Flex处理乘法?或者我必须用C语言处理?
答案 0 :(得分:1)
一些答案在评论中,但问题尚未在两年内得到答复。为了完成的目的,我认为一些注意事项对于将来会想到这样的事情的人来说会很有用。
简单的算术表达式,在问题中举例说明的形式可以通过flex这样的工具识别,它使用FSA(有限状态自动机 - 或FSM有限状态机)匹配正则表达式。这在语法简单id + id
时有效,但在表达式变得更复杂时失败。 id + id * id
中运算符优先级的处理和((id + id) * (id + id))
之类的嵌套括号意味着常规语法不再有效。这需要无上下文语法。 (计算机科学专业的学生应该从乔姆斯基语言理论中知道这一点)。因此,只能在flex
中执行操作以获得最简单的表达形式。</ p>
仅包含常量的简单表达式的替换是一种称为常量折叠的优化,并且由大多数编译器作为标准执行。将此作为大多数代码的预处理形式执行将不会产生任何改进。因此,在提议编写工具来完成这样的工作时,你必须反思它是否必不可少!
现在回到问题的实际细节,这些细节已在评论中找到;是的,每个运营商都需要一条规则,加法和乘法;当匹配时,需要一个子串来获取操作数。它看起来像这样:
MYplusEXP [0-9]+[ \t\n\r]*\+[ \t\n\r]*[0-9]+
MYmultEXP [0-9]+[ \t\n\r]*\*[ \t\n\r]*[0-9]+
%%
char [20] left; char * right;
{MYplusEXP} {right = strstr(yytext,"+"); /* yytext is already terminated with \0 */
strncopy(left,yytext,right-yytext+1);
printf("%d",atoi(left)+atoi(right));
}
{MYmultEXP} {right = strstr(yytext,"*");
strncopy(left,yytext,right-yytext+1);
printf("%d",atoi(left)*atoi(right));
}
然而,在做了指针算法
之后,我觉得有点脏总之,使用其他工具可能会更好,或者完全没有!