用flex替换数字表达式

时间:2012-12-04 05:52:12

标签: flex-lexer

我在代码源中使用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语言处理?

1 个答案:

答案 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));
             }

然而,在做了指针算法

之后,我觉得有点脏

总之,使用其他工具可能会更好,或者完全没有!