c语言 词法分析程序的设计 编译原理

本文章实现内容:

以二元式形式输出单词(单词种类,值)

关键字: if、int、for、while、do、return、break、continue;单词种别码为1。

标识符;单词种别码为2

常数为无符号整形数;单词种别码为3。

运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为4。

分隔符包括: ,、;、{、}、(、);单词种别码为5;

输入数据举例:

编辑一个文本文件 text.txt,在文件中输入如下内容:

main()
{
int a,b;
a = 10;
b = a + 20;
}

输出结果

(2,“main”)
(5,“(”)
(5,“)”)
(5,“{”)
(1,“int”)
(2,“a”)
(5,“,”)
(2,“b”)
(5,“;”)
(2,“a”)
(4,“=”)
(3,“10”)
(5,“;”)
(2,“b”)
(4,“=”)
(2,“a”)
(4,“+”)
(3,“20”)
(5,“;”)
(5,“}”)
代码如下:
#include<stdio.h>
#include <string.h>
#define N 20
// 输出结果
void output(char *str,int a,int b,int type)
{
    printf("(%d,“",type);
    int i;
    for(i=a;i<=b;i++)
        printf("%c",str[i]);
    printf("”)\n");
}

// 判断字符串一部分是否属于关键字
int iskeywords(char *str,int a,int b)
{
    char keywords[8][10]={"if","int","for","while",
        "do","return","break","continue"};  // 关键字
    int i,n=8;
    char s[20];
    for(i=0;i<=b-a;i++) // 拷贝字符
        s[i]=str[a+i];
    s[i] = '\0';
    for(i=0;i<n;i++)    // 判断是否存在,存在返回1,否则返回2
    {
        if(strcmp(s,keywords[i])==0)
            return 1;
    }
    return 2;
}
// 判断字符是否属于运算符或分隔符的一部分。
int belong_to(char str,int type)
{
    int t = 0,i = 0,n;
    char library[10];
    if(type==4){
        strcpy(library , "+-*/=><!"); // 运算符
        n = 8;}
    else{
        strcpy(library , ",;{}()"); // 分隔符
        n = 6;}
    for(i=0;i<n;i++)    // 判断是否存在,存在返回1或2,否则返回0
    {
        if(str == library[i])
        {
            if(type==4&&i>=4)// 后面能跟=号
                t=2;
            else
                t=1;
            return t;
        }
    }
    return t;
}
// 分离+判断,打印输出类型
void scan(char *str,int n)
{
    // 7种类型(最后输出1-5)
    // -1
    // 0: 初始
    // 1: 关键字,在keywords中
    // 2: 标识符
    // 3: 常数(无符号整型)
    // 4: 运算符和界符:+ - * / = > < >= <= !=
    // 5: 分隔符: , ; { } ( )
    int i,type=0;
    for(i=n;i<strlen(str);i++)
    {
        switch(type)
        {
        case 0: // 初始态
            if(str[i]==' '){ // 空格跳过
                n+=1;
                continue;}
            else
            if(str[i]=='\0'||str[i]=='\n') // 是结束
                return;
            else
            if((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z'))
                type = 1;   //是字母,可能是关键字或标识符
            else
            if(str[i]>='0'&&str[i]<='9')
                type = 3;   //是数字,常数
            else{
            type = belong_to(str[i],4);
            if(type >0) // 是运算符
            {
                if(type == 2&&str[i+1]=='=') //是能跟=号的运算符,后面是=号
                    i = i+1; // 结束位置后移
                output(str,n,i,4); // 输出+递归+结束
                scan(str,i+1);
                return;
            }
            else
            if(belong_to(str[i],5))//是分隔符
            {
                output(str,n,i,5); // 输出+递归+结束
                scan(str,i+1);
                return;
            }
            else{
                printf("失败");
                printf("%c",str[i]);
                return;
            }
            }

            break;
        case 1:// 关键字或标识符
            if(!((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')))
            {//不是字母了
                if(str[i]>='0'&&str[i]<='9')    // 是数字
                    type = 2;
                else    // 非字母数字
                {
                    type = iskeywords(str,n,i-1);
                    output(str,n,i-1,type); // 输出+递归+结束
                    scan(str,i);
                    return;
                }
            }
            break;
        case 2:// 标识符
            if(!((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')))
            {//不是字母了
                if(!(str[i]>='0'&&str[i]<='9'))
                {// 不是数字
                    output(str,n,i-1,type); // 输出+递归+结束
                    scan(str,i);
                    return;
                }
            }
            break;
        case 3:
            if(!(str[i]>='0'&&str[i]<='9'))
            {// 不是数字
                output(str,n,i-1,type); // 输出+递归+结束
                scan(str,i);
                return;
            }
            break;
        default :
            printf("%d失败\n",type);
                return;
        }
    }
    return ;
}

int main()
{
    FILE *p=fopen("text.txt","r"); //只读打开文件
    if(p==NULL) // 没有文件提示
    {
        printf("缺少文件“text.txt”");
        exit(0);
    }
    char str[20];
    while(fgets(str, N, p) != NULL) // 一行一行读取
    {
        scan(str,0);
    }
    fclose(p);  // 关闭文件
}

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值