在 Lex 中检查有效的算术表达式(在 C 中)

Checking Valid Arithmetic Expression in Lex (in C)

我必须在 lex 中编写代码来检查算术表达式是否有效。我知道我可以使用 yacc 很容易地做到这一点,但只在 lex 中做并不是那么容易。

我写了下面的代码,但由于某种原因不起作用。 除此之外,我也不知道如何处理二元运算符。

我的错误代码:

%{
#include <stdio.h>
/* Will be using stack to check the validity of arithetic expressions */
char stack[100];
int top = 0;
int validity =0;S
%}
operand [a-zA-Z0-9_]+

%%
  /* Will consider unary operators (++,--), binary operators(+,-,*,/,^), braces((,)) and assignment operators (=,+=,-=,*=,^=) */
"("                { stack[top++]='(';}
")"                { if(stack[top]!=')') yerror(); else top--;}
[+|"-"|*|/|^|%]    { if(stack[top]!='$') yerror(); else stack[top]=='&';}
"++"          { if(stack[top]!='$') yerror(); else top--;}
[+"-"*^%]?=        { if(top) yerror();}
operand            { if(stack[top]=='&') top--; else stack[top++]='$';}

%%

int yerror()
{
    printf("Invalid Arithmetic Expression\n");
}

首先,了解如何在 Flex 中编写正则表达式。 (Patterns, Flex manual).

字符class([])内,引号、星号和竖线都不是特殊的。要包含 -],您可以使用 \ 转义它们或将它们放在列表的开头,或者在 - 的情况下在结尾。

所以在:

[+|"-"|*|/|^|%]

| 只是列表中的另一个字符,包含它五次不会改变任何内容。 "-" 是一个仅由字符 " 组成的字符范围,尽管我想本意是包括 -。可能你想要[-+*/^%][+\-*/^%].

flex 扫描器无法猜测 +(例如)是一元运算符而不是二元运算符,并将它两次放入列表中规则不会做任何事情;第一条规则将始终生效。

最后,如果您在模式中使用定义(如 operand),则必须将它们括在大括号中:{operand};否则,flex 会将其解释为一个简单的关键字。

以及赋值本身的提示:有效的未加括号的算术表达式可以简化为正则表达式:

term    {prefix-operator}*{operand}{postfix-operator}*
expr    {term}({infix-operator}{term})*

但是您不能直接使用它,因为 (a) 它不处理括号,(b) 您可能需要允许空格,并且 (c) 它没有正确拒绝 a+++++b因为 C 坚持词法扫描的 "maximal munch" 规则,所以这与正确的表达式 a++ + ++b.

不同

但是,您可以将上述正则表达式转换为非常简单的两态状态机。