小C语言--词法分析程序SDUT

本文解析了小C语言的关键字、自定义标识符、整数、界符和运算符的语法规则,并展示了如何通过词法分析实现它们的识别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description
小C语言文法

  1. <程序>→<main关键字>(){<声明序列><语句序列>}

  2. <声明序列>→<声明序列><声明语句>|<声明语句>|<空>

  3. <声明语句>→<标识符表>;

  4. <标识符表>→<标识符>,<标识符表>|<标识符>

  5. <语句序列>→<语句序列><语句>|<语句>

  6. <语句>→< if语句>|< while语句>|< for语句>|<复合语句>|<赋值语句>

  7. < if语句>→< if关键字>(<表达式>)<复合语句>|(<表达式>)<复合语句>< else关键字><复合语句>

  8. < while语句>→< while关键字>(<表达式>)<复合语句>

  9. < for语句>→< for关键字>(<表达式>;<表达式>;<表达式>)<复合语句>

  10. <复合语句>→{<语句序列>}

  11. <赋值语句>→<表达式>;

  12. <表达式>→<标识符>=<算数表达式>|<布尔表达式>

  13. <布尔表达式>→<算数表达式> |<算数表达式><关系运算符><算数表达式>

  14. <关系运算符>→>|<|>=|<=|==|!=

  15. <算数表达式>→<算数表达式>+<项>|<算数表达式>-<项>|<项>

  16. <项>→<项>*<因子>|<项>/<因子>|<因子>

  17. <因子>→<标识符>|<无符号整数>|(<算数表达式>)

  18. <标识符>→<字母>|<标识符><字母>|<标识符><数字>

  19. <无符号整数>→<数字>|<无符号整数><数字>

  20. <字母>→a|b|…|z|A|B|…|Z

  21. <数字>→0|1|2|3|4|5|6|7|8|9

  22. < main关键字>→main

  23. < if关键字>→if

  24. < else关键字>→else

  25. < for关键字>→for

  26. < while关键字>→while

  27. < int关键字>→int

每行单词数不超过10个
小C语言文法如上,现在我们对小C语言写的一个源程序进行词法分析,分析出关键字、自定义标识符、整数、界符
和运算符。
关键字:main if else for while int
自定义标识符:除关键字外的标识符
整数:无符号整数
界符:{ } ( ) , ;
运算符:= + - * / < <= > >= == !=


#include <iostream>
#include <string>

using namespace std;

string keyword[6] = {"main", "if", "else", "for", "while", "int"};
string boun[6] = {"{", "}", "(", ")", ";", ","};
string oper[8] = {"=", "+", "-", "*", "/", "<", ">", "!"}; 
// , "<=", ">=", "==", "!=",
//这里只是存储单字符的运算符,这样可以方便下面进行判断,
//由于双字符的运算发第二个都是“=”,所以在判断结束后,需要再判断其下一个字符是否是“=”
//【注意】:不要遗漏“!”
string temp = "";
//★★★这个非常重要,由于关键字、自定义标识符、数字,这三项的长度是不一定的,
//所以如果一个字符既不是界符,也不是运算符,则该字符是上述单词中的一个字符,
//需要存储起来,这里的temp就是存储多字节单词的

void check()//检查存储的单词,是关键字、自定义标识符、数字中的哪一种
{
    if (temp == "")//如果没有存储任何单词,直接返回
        return;
    if (temp[0] >= '0' && temp[0] <= '9')//由于程序一定是合法的,所以只要第一个字符是数字,整个单词就是数字
    {

        cout << "(integer," << temp << ")" << endl;
        temp = "";//该函数中,对单词判断结束后需要将单词置零
        return;
    }
    for (int i = 0; i < 6; i++)
    {
        if (temp == keyword[i])
        {
            cout << "(keyword," << temp << ")" << endl;
            temp = "";
            return;
        }
    }
    cout << "(identifier," << temp << ")" << endl;
    temp = "";
    return;
}

int main()
{
    string str;     //定义一个字符串,存放输入的程序字符串
    while (cin >> str)//循环输入,直至输入结束
    {
        int len = str.length(); //计算输入的字符串的长度
        for (int i = 0; i < len; i++)//读取每一个字符
        {
            bool flag = true;//设置一个表示位,用来表示是否已经判断出该字符的词性
           
            // ☆判断是否是界符,这一部分是最简单的,可以优先考虑
            for (int j = 0; j < 6; j++) 
            {
                if (str[i] == boun[j][0])
                {
                    //如果遇见界符、运算符或者一行的结束,则标志这单词的结束
                    check();//判断存储的单词
                    cout << "(boundary," << str[i] << ")" << endl;//输出界符
                    flag = false;//置标记位为假
                    break;
                }
            }

            //如果标记位为假,说明已经判断结束
            if (!flag)
                continue;
            
            
            // ☆判断是否是运算符
            for (int j = 0; j < 8; j++) 
            {
                if (str[i] == oper[j][0])
                {
                    //如果遇见界符、运算符或者一行的结束,则标志这单词的结束
                    check();//判断存储的单词
                    //由于运算符,有单字节和双字节,所以要单独判断其下一个字符
                    if (i + 1 < len && str[i + 1] == '=')//先判断是否有下一个字符,然后判断是否为“=”
                    {
                        cout << "(operator," << str[i] << "=)" << endl;
                        i++;//★★★一定不要遗漏
                    }
                    else
                    {
                        cout << "(operator," << str[i] << ")" << endl;
                    }
                    flag = false;
                    break;
                }
            }
            if (!flag)
                continue;
            //如果程序可以执行到这里,说明上面的两个continue语句都没有执行,说明该字符是多字节单词的一个字节
            temp += str[i];
        }
        //如果遇见界符、运算符或者一行的结束,则标志这单词的结束,当上面的for循环结束,说明一行的结束,也是单词结束的标志
        check();
    }
}

/*
循环读入程序,读入时将空白字符已经过滤,即读入后不会再有空白字符。
这里可以先将程序分成两部分,第一部分为对界符和运算符的判断,第二部分是对关键字、自定义标识符、整数的判断。
第一部分:
    界符的判断只需要按照boun数组进行对比即可,运算符先进行单运算符的对比,然后还要特殊判断两个字符的运算符
第二部分:
    这些大部分不是单个字符,所以如何判断一个单词的结束非常重要。
    因为读入的字符串没有空格等空白字符,所以判断这一类单词的结束有以下几种情况:
    1.读入的这一行字符串已经读取结束。
    2.有第一部分的字符读入。
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

碧羽o(* ̄▽ ̄*)ブ回雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值