编译原理-词法分析

编译原理-词法分析

编译原理 实验一作业

分类

  1. 关键字

    • 特殊的标识符,在标识符中进行判断即可
    • 用一个数组存放所有定义的关键字
  2. 标识符

    • <字母>|<下划线>{<字母>|<数字>|<下划线>}
    • 不是关键字
  3. 常数

    • 数字常量

      1. 整数
      	111
      	001(可以0开头 等价于 1)
      2. 小数(有且只有一个小数点)
      	111.1
      	011.100(小数点后允许有多余的0)
      
    • 字符常量
      ‘c’ 单引号括一个字符(字符不能为空)

    • 字符串常量
      “string” 双引号括起来的字符串(可以为空串)

  4. 运算符 在界限符后判断

    1. 单一符号(无扩展)的运算符
    	?
    	:
    2. <符号>[=]的运算符
    	= ==
    	! !=
    	^ ^=
    	* *=
    	/ /=
    	% %=
    3. <符号>[符号][=]的运算符
    	& && &=
    	| || |=
    	+ ++ +=
    	- -- -=
    4. <符号>[符号][=] 或 <符号>[=]的运算符
    	< << <<= <=
    	> >> >>= >=
    
  5. 界限符

    • 在常量判断后调用 可以将之前条件只完成一半的算入 界限符
    1. 对称符号
    	[ ]
    	( )
    	{ }
    	' '
    	" "
    2. 单一符号
    	~
    	`
    	@
    	#
    	$
    	\
    3. 注释
    	/* */	(/**/内整片区域)
    	//		(//后面的整行内容)
    

通用函数、全局变量与结构体

结构体

  • 用于记录存储词法分析的结果的二元式结构体
  • ( 类型号 , 词串 )
  • 两种构造函数
  • toString()方法便于输出
/*二元式结构体*/
typedef struct node{
    int type = 0;
    string s = "";
    node(int t,string str){ type = t,s = str; }
    node(int t,char c){ type = t,s += c; }
    string toString(){return "( " + to_string(type) + " , " + s + " )";}
};

全局变量

/*全局变量*/
//存储输出内容的二元式
vector<node>ans;
//输入文本
string text;
int typeCnt[10];//各种类型的数量
//关键字集合
set<string>keys;
//界限符集合
set<char>boundarySymbols;

通用函数

/*工具函数*/
//去字符串两边的空白
void trim(string & s){
    int end = s.length() - 1;
    int begin = 0;
    while(begin < end && isblank(s[begin])){ begin++; }
    while(end > begin && isblank(s[end])){ end--; }
    s = s.substr(begin,end - begin + 1);
}
//判断当前下标是否还有字符
bool exist(int pos){
    return pos < text.length();
}

主函数

int main(){
    init();//初始化函数
    while(true){
        reset();//重置信息函数
        scan();//读入文本函数
        analysis();//词法分析函数
        print();//结果输出函数
    }
	return 0;
}

需要导入的头文件

#include <iostream>
#include <string>
#include <set>
#include <vector>
#include <fstream>

using namespace std;

初始化函数 init()

  • init()

    /*初始化函数*/
    void init(){
        cout << "[词法分析器]\n"
            "0. 非法字符\n"
            "1. 关键字\n"
            "2. 标识符\n"
            "3. 常量[整数、小数、字符常量、字符串常量]\n"
            "4. 运算符\n"
            "5. 界限符[常见非运算符、括号、引号、注释]\n\n";
        /*关键字初始化*/
        initKeys();
        /*界限符初始化*/
        initBoundarySymbols();
    }
    
  • initKeys()

    /*关键字*/
    //关键字集合
    set<string>keys;
    //初始化函数
    void initKeys(){
        string keysString[] = {
            "char",
            "int",
            "bool",
            "short",
            "long",
            "float",
            "double",
            "string",
            "void",
            "return",
            "sign",
            "goto",
            "while",
            "for",
            "if",
            "else",
            "switch",
            "case",
            "main",
            "include",
            "using",
            "namespace"
            "printf",
            "scanf",
            "cos",
            "sqrt",
            "sin",
            "typedef",
            "struct",
            "class"
        };
        for(string s : keysString){
            keys.insert(s);
        }
    }
    
  • initBoundarySymbols()

    //界限符集合初始化函数
    void initBoundarySymbols(){
        char chars[] = {
            ',',
            ';',
            '[',
            ']',
            '{',
            '}',
            '(',
            ')',
            '#',
            '$',
            '~',
            '`',
            '@',
            '\\',
            //如果是没有闭合的双引号或单引号则算入界限符 (因此 字符常量和字符串常量要在界限符之前进行判断)
            '\"',
            '\'',
            //如果是非小数的小数点则算入界限符 (因此 小数常量要在界限符之前进行判断)
            '.'
        };
        for(char c : chars){
            boundarySymbols.insert(c);
        }
    }
    

重置信息函数 reset()

/*重置信息*/
void reset(){
    //清空结果集
    ans.clear();
    //将文本设置为空串
    text = "";
    //将类型计数器清0
    for(auto cnt : typeCnt)cnt = 0;
}

文本读入函数 scan()

/*数据输入
两种输入方式
0:读取一行输入
非0:根据文件地址读取文本
*/
void scan(){
    cout << "请选择文本输入方式[0:读入一行]、[1:根据文件地址读取文件](输入任何非0字符则视为1)" << endl;
    string s;
    cin >> s;
    getchar();//读取回车符
    if(s == "0"){
        cout << "请输入一行需要进行语法分析的数据:" << endl;
        getline(cin,text);
    } else{
        string path;
        printf("\n请输入需要进行词法分析的文件地址(英文地址):\n");
        getline(cin,path);
        ifstream f(path);
        if(!f.is_open()){
            cerr << "打开文件失败!:" << path << endl;
        } else{
            string s;
            while(getline(f,s)){
                text += s;
                text += '\n';
           
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值