2

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

4

1 回答 1

2

一些答案在评论中,但这个问题两年来还没有答案。我认为一些笔记,为了完成的目的,对将来想这样的事情的人很有用。

问题中举例说明的简单算术表达式可以被 flex 之类的工具识别,它使用 FSA(有限状态自动机 - 或 FSM 有限状态机)匹配正则表达式。这在语法很简单时有效id + id,但在表达式变得更复杂时会失败。处理运算符优先级id + id * id和类似的嵌套括号((id + id) * (id + id))意味着常规语法不再起作用。这需要上下文无关的语法。(计算机科学专业的学生应该从乔姆斯基语言理论中了解这一点)。所以这些运算只能以flex最简单的表达形式来执行。

替换仅包含常量的简单表达式是一种称为常量折叠的优化,大多数编译器都将其作为标准执行。将此作为对大多数代码进行预处理的一种形式不会产生任何改进。因此,在提议编写工具来完成这样的工作时,您必须考虑它是否必要!

现在回到评论中提到的问题的实际细节;是的,每个运算符、加法和乘法都需要一个规则;并且当匹配时,将需要一个子字符串来获取操作数。它看起来像这样:

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

但是我在做那个指针运算后感觉有点脏

总之,使用其他工具可能会更好,或者根本不使用!

于 2015-01-23T16:49:06.823 回答