AI开发C语言应用按步走,表达式计算器calc的第十三步,逻辑值、逻辑运算符、比较运算符(v2.0)
calc13 — 逻辑值、逻辑运算符、比较运算符(v2.0)
1. 概述
本次迭代将 calc 升级至v2.0,新增完整的逻辑运算和比较运算支持,与 C 语言运算符语义一致。
版本变化:1.0→2.0
新增功能:
| 类别 | 运算符/关键字 | 说明 |
|---|---|---|
| 逻辑值 | true/false | 对应 1.0 / 0.0 |
| 逻辑非 | ! | 一元运算符,!0= 1,!非0= 0 |
| 逻辑与 | && | 二元运算符,两者非零则 1 |
| 逻辑或 | || | 二元运算符,任一非零则 1 |
| 相等 | ==/!= | 比较两个值是否相等/不等 |
| 关系 | </<=/>/>= | 比较两个值的大小关系 |
2. 变更清单
| 文件 | 操作 | 说明 |
|---|---|---|
Makefile | 编辑 | VERSION = 2.0;test 目标分隔符 ` |
parse.h | 编辑 | TokenType 枚举新增 10 个类型;注释更新 |
parse.c | 重写 | 多字符运算符识别(==!=<=>=&&||);关键字true/false识别;update_expect/token_name同步更新 |
eval.c | 重写 | 新增 4 层语法层(expr_or/expr_and/expr_equality/expr_relational);factor增加TRUE/FALSE分支;unary增加!分支 |
test.expr | 编辑 | 新增 17 个逻辑/比较测试用例,总数 31→48 |
3. 运算符优先级
3.1 完整优先级表(从低到高)
| 优先级 | 语法层 | 运算符 | 结合性 |
|---|---|---|---|
| 1 (最低) | expr_or | || | 左结合 |
| 2 | expr_and | && | 左结合 |
| 3 | expr_equality | ==!= | 左结合 |
| 4 | expr_relational | <<=>>= | 左结合 |
| 5 | expr_additive | +- | 左结合 |
| 6 | expr_multiplicative | */% | 左结合 |
| 7 | unary | -! | 右结合 |
3.2 文法扩展
expr → expr_or expr_or → expr_and (('||') expr_and)* expr_and → expr_equality (('&&') expr_equality)* expr_equality → expr_relational (('==' | '!=') expr_relational)* expr_relational → expr_additive (('<' | '<=' | '>' | '>=') expr_additive)* expr_additive → expr_multiplicative (('+' | '-') expr_multiplicative)* expr_multiplicative → unary (('*' | '/' | '%') unary)* unary → ('-' | '!') unary | factor factor → NUMBER | IDENTIFIER | TRUE | FALSE | '(' expr ')'4. 词法分析器扩展
4.1 多字符运算符识别
在parse_next中,单字符switch之前先检查多字符序列:
/* 多字符运算符 */if(*input_pos=='='&&*(input_pos+1)=='='){tok.type=TOKEN_EQ;input_pos+=2;column+=2;...}if(*input_pos=='!'&&*(input_pos+1)=='='){...}// !=if(*input_pos=='<'&&*(input_pos+1)=='='){...}// <=if(*input_pos=='>'&&*(input_pos+1)=='='){...}// >=if(*input_pos=='&'&&*(input_pos+1)=='&'){...}// &&if(*input_pos=='|'&&*(input_pos+1)=='|'){...}// ||4.2 关键字识别
在标识符读取之后,检查是否为true或false:
if(strcmp(tok.data.name,"true")==0){tok.type=TOKEN_TRUE;}elseif(strcmp(tok.data.name,"false")==0){tok.type=TOKEN_FALSE;}else{tok.type=TOKEN_IDENTIFIER;}5. 求值器扩展
5.1 逻辑运算
// expr_or — 逻辑或doubleresult=(left!=0.0||right!=0.0)?1.0:0.0;// expr_and — 逻辑与doubleresult=(left!=0.0&&right!=0.0)?1.0:0.0;// unary — 逻辑非doubleresult=(val==0.0)?1.0:0.0;5.2 比较运算
// expr_equality — 相等/不等doubleresult=(left==right)?1.0:0.0;// ==doubleresult=(left!=right)?1.0:0.0;// !=// expr_relational — 关系比较doubleresult=(left<right)?1.0:0.0;// <doubleresult=(left<=right)?1.0:0.0;// <=doubleresult=(left>right)?1.0:0.0;// >doubleresult=(left>=right)?1.0:0.0;// >=6. 测试验证
6.1 回归测试
$maketest============================================calc — 测试套件============================================PASS[1](90-18)/3+15 →39... PASS[32]true→1PASS[33]false→0PASS[34]!true →0PASS[35]!false →1PASS[36]!!true →1PASS[37]3==3→1PASS[38]3!=3→0PASS[39]3<5→1PASS[40]3>5→0PASS[41]3<=3→1PASS[42]3>=5→0PASS[43]true&&false→0PASS[44]true||false→1PASS[45](3<5)&&(3==3)→1PASS[46]!true&&false→0PASS[47]3+5==8→1PASS[48]3+5*2==13→1============================================48passed,0failed,48total============================================6.2 优先级验证
| 表达式 | 结果 | 验证点 |
|---|---|---|
3+5==8 | 1 | +优先于== |
true||false&&false | 1 | &&优先于|| |
!true&&false | 0 | !优先于&& |
(3<5)&&(3==3) | 1 | 括号最高优先级 |
3+5*2==13 | 1 | *优先于+,+优先于== |