AI开发C语言应用按步走,表达式计算器calc的第十三步,逻辑值、逻辑运算符、比较运算符(v2.0)

calc13 — 逻辑值、逻辑运算符、比较运算符(v2.0)

1. 概述

本次迭代将 calc 升级至v2.0,新增完整的逻辑运算和比较运算支持,与 C 语言运算符语义一致。

版本变化1.02.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||左结合
2expr_and&&左结合
3expr_equality==!=左结合
4expr_relational<<=>>=左结合
5expr_additive+-左结合
6expr_multiplicative*/%左结合
7unary-!右结合

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 关键字识别

在标识符读取之后,检查是否为truefalse

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]true1PASS[33]false0PASS[34]!true →0PASS[35]!false →1PASS[36]!!true →1PASS[37]3==31PASS[38]3!=30PASS[39]3<51PASS[40]3>50PASS[41]3<=31PASS[42]3>=50PASS[43]true&&false0PASS[44]true||false1PASS[45](3<5)&&(3==3)1PASS[46]!true&&false0PASS[47]3+5==81PASS[48]3+5*2==131============================================48passed,0failed,48total============================================

6.2 优先级验证

表达式结果验证点
3+5==81+优先于==
true||false&&false1&&优先于||
!true&&false0!优先于&&
(3<5)&&(3==3)1括号最高优先级
3+5*2==131*优先于++优先于==