我使用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语言处理?
发布于 2015-01-24 00:49:07
一些答案在评论中,但两年来这个问题还没有以答案结束。我想,出于完成的目的,一些笔记对将来想要做这样的事情的人会很有用。
简单的算术表达式,在问题中举例的形式可以被像flex这样的工具识别,它使用FSA (有限状态自动机-或FSM有限状态机)匹配正则表达式。当语法是简单的id + id时,这是有效的,但当表达式变得更复杂时,这是失败的。处理id + id * id中的运算符优先级和((id + id) * (id + id))之类的内容中的嵌套括号意味着常规语法不能再工作。这需要一个上下文无关文法。(计算机科学专业的学生应该从乔姆斯基语言理论中了解这一点)。因此,对于最简单的表达式形式,这些操作只能在flex中执行。
简单表达式的替换只包含常量,这是一种称为constant folding的优化,大多数编译器都将其作为标准执行。将其作为大多数代码的一种预处理形式不会产生任何改进。因此,当你提议编写工具来做这样的工作时,你必须反思它是否是必要的!
现在来看看问题的实际细节,这些细节已经在评论中找到了;是的,每个运算符、加法和乘法都需要一个规则;当匹配时,需要一个子串来提取操作数。它看起来像这样:
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));
}然而,在做了指针运算之后,我觉得有点脏
总而言之,使用其他工具可能更好,或者根本不使用!
https://stackoverflow.com/questions/13696905
复制相似问题