我必须在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");
}
答案 0 :(得分:1)
首先,学习如何在Flex中编写正则表达式。 (Patterns, Flex manual)。
在角色类([
... ]
)中,引号,星号和竖线都不是特殊的。要包含 - 或] ,您可以使用 \ 将它们转义或将它们放在列表的开头,或者放在案例中 - 的结尾。
所以:
[+|"-"|*|/|^|%]
| 只是列表中的另一个字符,包含它五次不会改变任何内容。 "-"
是一个只包含字符“的字符范围,虽然我认为其意图是包含 - 。可能你想要[-+*/^%]
或[+\-*/^%]
。
灵活扫描程序无法猜测 + (例如)是一元运算符而不是二元运算符,并且在规则列表中将它放两次不会任何事情;第一条规则将永远生效。
最后,如果您在模式中使用定义(如operand
),则必须将它们括在大括号中:{operand}
;否则,flex会将其解释为一个简单的关键字。
提示赋值本身:一个有效的无表达式算术表达式可以简化为正则表达式:
term {prefix-operator}*{operand}{postfix-operator}*
expr {term}({infix-operator}{term})*
但你不能直接使用它,因为(a)它不处理括号,(b)你可能需要允许空格,(c)它没有正确拒绝a+++++b
因为C坚持词汇扫描的“最大咀嚼”规则,因此与正确的表达式a++ + ++b
不同。
但是,您可以将上述正则表达式转换为非常简单的双状态状态机。