当前位置:网站首页>C专家编程 第3章 分析C语言的声明 3.8 理解所有分析过程的代码段
C专家编程 第3章 分析C语言的声明 3.8 理解所有分析过程的代码段
2022-08-03 16:09:00 【weixin_客子光阴】
/*主要的数据结构是一个堆栈,我们从左向右读取,把各个标记依次压入堆栈,直到读到标识符为止然后我们继续向右读入一个标记,也就是标识符右边的那个标记。接着,观察标识符左边的那个标记(需要从堆栈中弹出)。
*/
struct token {
char type;
char string[MAXTOKENLEN];
};
/*保存第一个标识之前的所有标记*/
struct token stack[MAXTOKENS];
/*保存刚读入的那个标记*/
struct token this;
/*伪码如下:
实用程序-------------*/
classify_string(字符串分类)
/*查看当前的标记,
*通过this.type返回一个值,内容为"type"(类型),
*"qualifier"(限定符)或"identifier"标识符
*/
gettoken(取标记);
/*把下一个标记读入this.string
*如果是字母数字组合,调用classify_string
*否则,它必是一个单字符标记,this.type = 该标记;
*用一个nul结束this.string
*/
read_to_first_identifier(读至第一个标识符)
/*调用gettoken,并把标记压入到堆栈中,直到遇到第一个
*标识符
*Print"identifier is"(标识符是), this.string
*继续调用gettoken
*/
//解析程序
deal_with_function_args(处理函数参数)
//当读取越过右括号')'后,打印"函数返回"
deal_with_arrays(处理函数数组)
//当你读取"[size]"后,将其打印并继续向右读取。
deal_with_any_pointers(处理任何指针)
//当你从堆栈中读取"*"时,打印"指向...的指针"并将其弹出堆栈。
deal_with_declarator(处理声明器)
if this.type is '[' deal_with_arrays
if this.type is '(' deal_with_function_args
deal_with_any_pointers
while 堆栈里还有东西
if 它是一个左括号'('
将其弹出堆栈,并调用gettoken;应该获得右括号')'
deal_with_declarator
else 将其弹出堆栈并打印它
//主程序___________
main
read_to_first_identifier
deal_with_declaration
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define MAXTOKENS 100
#define MAXTOKENLEN 64
enum type_tag {
IDENTIFIER, QUALIFIER, TYPE
};
struct token {
char type;
char string[MAXTOKENLEN];
};
int top = -1;
struct token stack[MAXTOKENS];
struct token this_2;
#define pop stack[top--]
#define push(s) stack[++top] = s
enum type_tag classify_string(void)
/*判断标识符的类型*/
{
char *s = this_2.string;
if (!strcmp(s, "const")) {
strcpy(s, "read-only");
return QUALIFIER;
}
if (!strcmp(s, "volatile")) {
return QUALIFIER;
}
if (!strcmp(s, "void")) {
return TYPE;
}
if (!strcmp(s, "char")) {
return TYPE;
}
if (!strcmp(s, "signed")) {
return TYPE;
}
if (!strcmp(s, "unsigned")) {
return TYPE;
}
if (!strcmp(s, "short")) {
return TYPE;
}
if (!strcmp(s, "int")) {
return TYPE;
}
if (!strcmp(s, "long")) {
return TYPE;
}
if (!strcmp(s, "float")) {
return TYPE;
}
if (!strcmp(s, "double")) {
return TYPE;
}
if (!strcmp(s, "struct")) {
return TYPE;
}
if (!strcmp(s, "union")) {
return TYPE;
}
if (!strcmp(s, "enum")) {
return TYPE;
}
return IDENTIFIER;
}
void gettoken(void) /*读取下一个标记到this_2*/
{
char *p = this_2.string;
/*省略空白字符*/
while ((*p = getchar()) == ' ');
if (isalnum(*p)) {
/*读入的标识符以A-Z或0-9开头*/
while (isalnum(*++p = getchar()));
ungetc(*p, stdin);
*p = '\0';
this_2.type = classify_string();
return;
}
if (*p == '*') {
strcpy(this_2.string, "pointer to");
this_2.type = '*';
return;
}
this_2.string[1] = '\0';
this_2.type = *p;
return;
}
/*理解所有分析过程的代码段*/
void read_to_first_identifier() {
gettoken();
while (this_2.type != IDENTIFIER) {
push(this_2);
gettoken();
}
printf("%s is ", this_2.string);
gettoken();
}
void deal_with_arrays() {
while(this_2.type == '[') {
printf("array ");
gettoken(); /*数字或']'*/
if (isdigit(this_2.string[0])) {
printf("0..%d ", atoi(this_2.string) - 1);
gettoken(); /*读取']' */
}
gettoken(); /*读取']'之后的再一个标记*/
printf("of ");
}
}
void deal_with_function_args() {
while(this_2.type != ')') {
gettoken();
}
gettoken(); /*读取')'之后的再一个标记*/
printf("function returning ");
}
void deal_with_pointers() {
while (stack[top].type == '*') {
printf("%s ", pop.string);
}
}
deal_with_declarator() {
/*处理标识符之后可能存在的数组/函数*/
switch(this_2.type) {
case '[': deal_with_arrays(); break;
case '(': deal_with_function_args(); break;
}
deal_with_pointers();
/*处理在读入到标识符之前压入到堆栈中的符号*/
while (top >= 0) {
if (stack[top].type == '(') {
pop;
gettoken(); /*读取')'符号*/
deal_with_declarator();
} else {
printf("%s ", pop.string);
}
}
}
int main() {
read_to_first_identifier();
deal_with_declarator();
printf("\n");
return 0;
}
/* 输出:

*/
/*小启发*/
/*使字符串的比较看上去更自然
*strcmp()函数用于比较两个字符串:它所存在的一个问题是:当两个字符串相等时函数的返回值
*为零。当字符串比较是条件语句的一部分时,这个问题就是导致令人费解的代码:
*/
if (!strcmp(s, "volatile")) return QUALIFIER;
/*返回值零使条件语句的结果为假,所以我们不得不对其取反,得到需要的结果
*这里有一个更好的办法
*/
#define STRCMP(a, R, b) (strcmp(a, b) R 0)
if (STRCMP(s, ==, "volatile"))
Data Structures with Abstract Data Types
这本书覆盖了范围很广的数据结构,包括字符串、列表、堆栈、队列、树,堆、集合和图。
推荐大家阅读本书。
边栏推荐
- How to get the 2 d space prior to ViT?UMA & Hong Kong institute of technology & ali SP - ViT, study for visual Transformer 2 d space prior knowledge!.
- Difference and performance comparison between HAL and LL library of STM32
- WordPress 5.2.3 更新,升级出现请求超时的解决方法
- 下午见!2022京东云数据库新品发布会
- QT QT 】 【 to have developed a good program for packaging into a dynamic library
- C语言01、数据类型、变量常量、字符串、转义字符、注释
- 将 Windows 事件日志错误加载到 SQL 表中
- GTK实现旋转加载动画
- Introduction to the advantages of the new generation mesh network protocol T-Mesh wireless communication technology
- 参与便有奖,《新程序员》杂志福利来袭!
猜你喜欢

如何选择合适的导电滑环型号

How much do you know about the intelligent operation and maintenance service of data warehouse based on DMS?

【深度学习】今日bug(8月2)

QT QT 】 【 to have developed a good program for packaging into a dynamic library

基于DMS的数仓智能运维服务,知多少?

Yuan xiaolin: Volvo focus on travel security, and put it perfectly

To add digital wings to education, NetEase Yunxin released the overall solution of "Internet + Education"

面了个腾讯35k出来的,他让我见识到什么叫精通MySQL调优

protobuf 反射使用总结

一文看懂推荐系统:召回03:基于用户的协同过滤(UserCF),要计算用户之间的相似度
随机推荐
Small Tools(4) 整合Seata1.5.2分布式事务
CopyOnWriteArrayList详解
小熊派——无线联网开发
spark入门学习-1
全新探险者以40万的产品击穿豪华SUV价格壁垒
字典表(还需要输入2个字)
Hannah荣获第六季完美童模全球总决赛全球人气总冠军
【Unity入门计划】制作RubyAdventure01-玩家的创建&移动
请问下阿里云全托管flink能执行两条flink sql命令么?
【翻译】关于扩容一个百万级别用户系统的六个课程
一文看懂推荐系统:召回03:基于用户的协同过滤(UserCF),要计算用户之间的相似度
WordPress 5.2.3 更新,升级出现请求超时的解决方法
甲方不让用开源【监控软件】?大不了我自己写一个
ffplay视频播放原理分析
基于DMS的数仓智能运维服务,知多少?
C语言04、操作符
C语言03、数组
实时渲染流程操作复杂吗,如何实现?
移动应用出海,你的“网络优化”拖后腿了吗?
How much do you know about the intelligent operation and maintenance service of data warehouse based on DMS?