声明转文字: 编写程序将C语言的声明转换为文字描述

发布者:rocky96最新更新时间:2016-03-08 来源: eefocus关键字:声明转文字  编写程序  C语言  文字描述 手机看文章 扫描二维码
随时随地手机看文章
一. 程序功能
编写程序将C语言的声明转换为文字描述
比如, 输入char **argv,
会打印输出: argv: pointer to pointer to char
 
二. 程序源码
//main.c
#include
#include
#include
 
#define MAXTOKEN 100
 
enum {NAME, PARENS, BRACKETS};
 
int dcl(void);
int dirdcl(void);
int gettoken(void);
int tokentype;
char token[MAXTOKEN];
char name[MAXTOKEN];
char datatype[MAXTOKEN];
char out[1000];
 
int main(void)
{
    int flag;
    
    printf("Please input(ctrl+z to quit)\n");
    while (gettoken() != EOF) {
        strcpy(datatype, token);
        out[0] = '\0';
        flag = dcl();
        if (tokentype != '\n')
            printf("syntax error\n");
        if (flag == 1 && tokentype  == '\n')
            printf("%s: %s %s\n", name, out, datatype);    
    }    
    
    system("pause");
    return 0;
}
 
//gettoken.c
#include
#include
#include
 
#define BUFSIZE 100
 
enum {NAME, PARENS, BRACKETS};
enum {NO, YES};
 
extern int tokentype;
extern char token[];
int prevtoken = NO;
 
int n_getch(void);
void n_ungetch(int);
 
int gettoken(void)
{
    int c;
    char *p = token;
    
    if (prevtoken == YES) {
        prevtoken = NO;
        return tokentype;    
    }     
    while ((c = n_getch()) == ' ' || c == '\t')
        ;
    if (c == '(') {
        if ((c = n_getch()) == ')') {
            strcpy(token, "()"); 
            return tokentype = PARENS;   
        } else {
            n_ungetch(c);
            return tokentype = '(';    
        }
    } else if (c == '[') {
        for (*p++ = c; (*p++ = n_getch()) != ']';)
            ;
        *p = '\0';
        return tokentype = BRACKETS;    
    } else if (isalpha(c)) {
        for (*p++ = c; isalnum(c = n_getch());)
            *p++ = c;
        *p = '\0';
        n_ungetch(c);
        return tokentype = NAME;    
    } else
        return tokentype = c;
}
 
char buf[BUFSIZE];
int bufp = 0;
 
int n_getch(void)
{
    return (bufp > 0) ? buf[--bufp]: getchar();    
}
 
void n_ungetch(int c)
{
    if (bufp >= BUFSIZE)
        printf("new_ungetch: too many characters!\n");
    else
        buf[bufp++] = c;    
}
 
//dcl.c
#include
#include
#include
 
enum {NAME, PARENS, BRACKETS};
enum {NO, YES};
 
int dcl(void);
int dirdcl(void);
void errmsg(char *);
int gettoken(void);
void parmdcl(void);
 
extern int tokentype;
extern char token[];
extern char name[];
extern char datatype[];
extern char out[];
extern int prevtoken;
 
//dcl: parse a declarator
int dcl(void)
{
    int ns, flag;
    
    for (ns = 0; gettoken() == '*';)
        ns++;
    flag = dirdcl();
    while (ns-- > 0)
        strcat(out, " pointer to"); 
        
    return flag;   
}
 
//dirdcl: parse a direct declaration
int dirdcl(void)
{
    int type, flag = 1;
    
    if (tokentype == '(') {
        flag = dcl();
        if (tokentype != ')')
        {
            errmsg("error: missing )\n");
            flag = 0;   
        }    
    } else if (tokentype == NAME) {
        if (name[0] == '\0')
            strcpy(name, token);
    } else {
        prevtoken = YES;
        flag = 0;
    }    
    while ((type = gettoken()) == PARENS || type == BRACKETS || type == '(')
    {
        if (type == PARENS)
            strcat(out, " function returning");
        else if (type == '(') {
            strcat(out, " function expecting");
            parmdcl();
            strcat(out, " and returning");
        } else {
            strcat(out, " array");
            strcat(out, token);
            strcat(out, " of");    
        }    
    }    
    
    return flag;
}
 
//errmsg: print error message and indicate avail. token
void errmsg(char *msg)
{
    printf("%s", msg);
    prevtoken = YES;    
}
 
 
//parmdcl.c
#include
#include
#include
#include
 
 
#define MAXTOKEN 100
 
enum {NAME, PARENS, BRACKETS};
enum {NO, YES};
 
void dcl(void);
void errmsg(char *);
void dclspec(void);
int typespec(void);
int typequal(void);
int compare(char **, char **);
int gettoken(void);
 
extern int tokentype;
extern char token[];
extern char name[];
extern char datatype[];
extern char out[];
extern int prevtoken;
 
void parmdcl(void)
{
    do {
        dclspec();    
    } while (tokentype == ',');
    if (tokentype != ')') 
        errmsg("missing ) in parameter declaration\n");   
}
 
void dclspec(void)
{
    char temp[MAXTOKEN];
    
    temp[0] = '\0';
    gettoken();
    do {
        if (tokentype != NAME) {
            prevtoken = YES;
            dcl();    
        } else if (typespec() == YES) {
            strcat(temp, " "); 
            strcat(temp, token); 
            gettoken();  
        } else if (typequal() == YES) {
            strcat(temp, " ");
            strcat(temp, token);
            gettoken();    
        } else
            errmsg("unknown type in parameter list\n");    
    } while (tokentype != ',' && tokentype != ')');
    
    strcat(out, temp);
    if (tokentype == ',')
        strcat(out, ",");    
}
 
int typespec(void)
{
    static char *types[] = {"char", "int", "void"};
    char *pt = token;
    
    if (bsearch(&pt, types, sizeof(types)/sizeof(char *), sizeof(char *), compare) == NULL)
        return NO;
    else
        return YES;    
}
 
int typequal(void)
{
    static char *typeq[] = {"const", "volatile"};
    char *pt = token;
    
    if (bsearch(&pt, typeq, sizeof(typeq)/sizeof(char *), sizeof(char *), compare) == NULL)
        return NO;
    else
        return YES;    
}
 
int compare(char **s, char **t)
{
    return strcmp(*s, *t);    
}
 
 
三.程序小结
1. 程序缺陷
当输入 int a(
输入不了了 为什么呢?
关键字:声明转文字  编写程序  C语言  文字描述 引用地址:声明转文字: 编写程序将C语言的声明转换为文字描述

上一篇:自动识别启动模式Nand Or Nor
下一篇:文字转声明: 编写程序将特定格式的输入转换为C语言声明

推荐阅读最新更新时间:2024-03-16 14:46

C语言变量的存储类别
变量的存储类别分为自动、静态、寄存器和外部这四种。其中后两种我们暂不介绍,主要是自动变量和静态变量这两种。 函数中的局部变量,如果不加 static 这个关键字来修饰,都属于自动变量,也叫做动态存储变量。这种存储类别的变量,在调用该函数的时候系统会给他们分配存储空间,在函数调用结束后会自动释放这些存储空间。动态存储变量的关键字是 auto,但是这个关键字是可以省略的,所以我们平时都不用。 那么与动态变量对应的就是静态变量。首先,全局变量均是静态变量,此外,还有一种特殊的局部变量也是静态变量。即我们在定义局部变量时前边加上 static 这个关键字,加上这个关键字的变量就称之为静态局部变量,它的特点是,在整个生存期中只赋一次初值,在
[单片机]
A51与C语言的混合编程
我研究一上午,写了个程序,可谓麻雀虽小可五脏俱全,希望正在学习这块的人能少找点资料,少花点时间更快的掌握。 #include reg52.h /****在汇编中定义*****/ extern void delay(void) ; extern add(int a,int b); //测试汇编调用的代码(不想直接用汇编来走主程序) extern void test(); /***在汇编中定义的代码段****/ extern unsigned char cc; // C语言中定义的函数 void delay_c(); unsigned int addcc(unsigned int wd1,unsigned int wd2); //C语
[单片机]
详解i2c(三)c语言实现
为了加深对I2C总线的理解,用C语言模拟IIC总线,边看源代码边读波形: 如下图所示的写操作的时序图: 读时序的理解同理。对于时序不理解的朋友请参考“I2C总线之(二)---时序” 完整的程序如下: #include reg51.h #define uchar unsigned char #define uint unsigned int #define write_ADD 0xa0 #define read_ADD 0xa1 uchar a; sbit SDA=P2^0; sbit SCL=P2^1; void SomeNop(); //短延时 void init(); //初始化 void check_ACK
[单片机]
详解i2c(三)<font color='red'>c语言</font>实现
单片机中C语言延时函数
单片机C语言延时程序计算2009-11-02 22:15单片机C语言延时程序用C语言写出来程序非常的简练,它是一种模块化的语言,一种比汇编更高级的语言,但是就是这样一种语言也还是有它不足之处:它的延时很不好控制,我们常常很难知道一段延时程序它的精确延时到底是多少,这和汇编延时程序没法比。但有时后写程序又不得不要用到比较精确的延时,虽然说可以用混合编程的方式解决,但这种方式不是每个人都能掌握,且写起来也麻烦。所以,通过测试我给大家提供一个延时子程序模块,并以此给一个出我们经常用到的延时的数据表格。(注意:表格中的数据只适合我的延时模块,对其他的延时程序不适用,切忌!!!!!!!!别到时候延时不对来骂我) 延时模块:其中问号代
[单片机]
C语言中main函数return的总结
在函数中,如果碰到return 语句,那么程序就会返回调用该函数的下一条语句执行,也就是说跳出函数的执行,回到原来的地方继续执行下去。但是如果是在主函数中碰到return语句,那么整个程序就会停止,退出程序的执行。 -------------------------------------------------------------------------------------------------------------------------------------------------------------------- return是C++预定义的语句,它提供了种植函数执行的一种放大。当return语句提供了一
[单片机]
高效学习AVR单片机的方法
怎样可以成为单片机高手,下面是一些建议学习的流程。 一、购买一两本书,笔者推荐两本 《单片机 C语言开发入门指导》,《高档8位单片机ATmega128原理与开发应用指南》。买书的目的:看书大体了解单片机的结构和工作原理,了解基本概念和基础知识,其实新手是不可能完全看懂一本书的,如果你能,你已经是高手了,所以不要期望一字一句去搞懂书上说的到底是什么东西。看完书对相关内容有个概念性的了解就可以了。 二、开始动手配置开发环境,动手去做,实践出真知。笔者推荐使用ICC AVR + AVR studio +AVR mega16 + JTAG&ISP下载仿真器的组合。抄几个程序,增强一下自己的信心,看到自己的程序在单片机上跑起来,那种愉悦
[单片机]
单片机C语言code与data的作用
code的作用是告诉单片机,我定义的数据要放在ROM(程序存储区)里面,写入后就不能再更改,其实是相当与汇编里面的寻址MOVC(好像是),因为C语言中没办法详细描述存入的是ROM还是RAM(寄存器),所以在软件中添加了这一个语句起到代替汇编指令的作用,对应的还有data是存入RAM的意思。 程序可以简单的分为code(程序)区,和data (数据)区,code区在运行的时候是不可以更改的,data区放全局变量和临时变量,是要不断的改变的,cpu从code区读取指令,对data区的数据进行运算处理,因此code区存储在什么介质上并不重要,象以前的计算机程序存储在卡片上,code区也可以放在rom里面,也可以放在ram里面,也可以放在f
[单片机]
单片机使用C语言的好处
将C向MCU(俗称单片机)8051上的移植始于80年代的中后期。客观上讲,C向8051 MCU移植的难点不少。如:   (1)8051的非冯 诺依慢结构(程序与数据存储器空间分立),再加上片上又多了位寻址存储空间;   (2)片上的数据和程序存储器空间过小和同时存在着向片外扩展它们的可能;   (3)片上集成外围设备的被寄存器化(即SFR),而并不采用惯用的I/O地址空间;   (4)8051芯片的派生门类特别多(达到了上百种之多),而C语言对于它们的每一个硬件资源又无一例外地要能进行操作。   这些都是过去以MPU为基础的C语言所没有的。经过Keil/Franklin、Archmeades、IAR、BSO/Tasking等公司艰若
[单片机]
热门资源推荐
热门放大器推荐
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved