在上一节中,我们实现了困难的数组定义部分;在这一节中,我们着手实现比较简单的逻辑运算,此外我们也会实现识别负数。
SysY语言中包含的逻辑运算符有:
- 一元逻辑运算符
!
- 二元逻辑运算符
&&
和||
它们语法定义如下
单目运算符: UnaryOp → ‘!’ 注:’!'仅出现在条件表达式中
逻辑与表达式: LAndExp → EqExp | LAndExp ‘&&’ EqExp
逻辑或表达式: LOrExp → LAndExp | LOrExp ‘||’ LAndExp
修改词法分析
与往常一样,我们从添加新单词开始。 这次有几个:
输入 | 单词类型 |
---|---|
|| |
T_LOGOR |
&& |
T_LOGAND |
! |
T_LOGNOT |
修改scan()函数,增加对这些单词的解析。
// 扫描并返回在输入中找到的下一个单词。
// 如果标记有效则返回 1,如果没有标记则返回 0
int scan(struct token *t)
{
/*......其他代码......*/
case '!': if((c = get_nextchr()) == '=')
{
t->token = T_NE;
}
else
{
putchar(c);
t->token = T_LOGNOT;
}
break;
/*......其他代码......*/
case '&': if ((c = get_nextchr()) == '&')
{
t->token = T_LOGAND;
}
else
{
put_backchr(c);
}
break;
case '|': if ((c = get_nextchr()) == '|')
{
t->token = T_LOGOR;
}
else
{
put_backchr(c);
}
break;
/*......其他代码......*/
}
修改语法分析
现在我们需要解析这些运算符。其中一些运算符是二元的运算符:||
、&&
,剩余的是一元的!
。我们已经有优先权二元运算符的框架。我们可以简单地添加新的运算符到框架。
我们首先要修改单词类型和AST节点操作类型的顺序,使其可以区分运算符。
// 单词类型
enum
{
T_EOF,
// 运算符
T_EQU, T_LOGOR, T_LOGAND, T_EQ, T_NE, T_LT, T_GT, T_LE, T_GE,
T_ADD, T_SUB, T_MUL