zoukankan      html  css  js  c++  java
  • 词法分析器 (c++实现) 简单实现

    参考种别码

    勿抄,请不要限制你的想象力。

    改进之处:遇到不能识别的应该继续往后识别,功能未完善。
    思路:看代码就懂了;
    Talk is cheap. Show me the code.

    #include <bits/stdc++.h>//万用头文件
    using namespace std;
    //——————————全局变量——————————
    struct Keyword
    {
    	string token;
    	int syn;
    }Key[13];
    
    int syn,tag=1;//种别码,标记
    string token;
    int i = 0;//全局变量作为下标
    //————————————————————————————
    
    bool judletter(char ch)//判断字符
    {
    	if (ch>='A'&& ch<='Z'|| ch >= 'a'&& ch <= 'z')
    		return 1;
    	else
    		return 0;
    }
    
    bool judnum(char num)//判断数字
    {
    	if (num>='0'&&num<='9')
    		return 1;
    	else
    		return 0;
    }
    
    int scan(string input)//对单个字符块进行扫描
    {
    	if (input[i]==' ')//空格
    	{
    		syn = -2;
    		i++;
    		return syn;
    	}
    	token = "";//NULL默认为0,不为空
    
    	if (judnum(input[i]))//数字开头
    	{
    		int sum = 0;
    		while (judnum(input[i]))
    		{
    			sum = 10 * sum + (input[i] - '0');
    			i++;
    			syn = 20;
    		}
    		token += to_string(sum);
    		return syn;
    	}
    	if (judletter(input[i]))//字母开头可能为1、标识符 2、关键字
    	{
    		while (judletter(input[i])||judnum( input[i]))
    		{
    			token += input[i];
    			i++;
    		}
    		syn = 10;//标识符(e.g.变量、常量)
    		for (int j = 1; j <= 12; j++)//
    		{
    			if (token == Key[j].token)
    			{
    				syn = Key[j].syn;
    				return syn;
    			}
    		}
    		return syn;
    	}
    	else //符号
    	{
    		token = "";
    		switch (input[i]) {
    		case'=':
    			syn = 21;
    			i++;
    			token = "=";
    			if (input[i]=='=')
    			{
    				syn = 39;
    				i++;
    				token = "==";
    			}
    			return syn;
    			break;//多余,习惯case+break
    		case '+':
    			syn = 22;
    			i++;
    			token = "+";
    			return syn;
    		case'-':
    			syn = 23;
    			i++;
    			token = "-";
    			return syn;
    		case'*':
    			syn = 24;
    			i++;
    			token = "*";
    			return syn;
    		case'/':
    			syn = 25;
    			i++;
    			token = "/";
    			return syn;
    		case'(':
    			syn = 26;
    			i++;
    			token = "(";
    			return syn;
    		case')':
    			syn = 27;
    			i++;
    			token = ")";
    			return syn;
    		case'[':
    			syn = 28;
    			i++;
    			token = "[";
    			return syn;
    		case']':
    			syn = 29;
    			i++;
    			token = "]";
    			return syn;
    		case'{':
    			syn = 30;
    			i++;
    			token = "{";
    			return syn;
    		case'}':
    			syn = 31;
    			i++;
    			token = "}";
    			return syn;
    		case',':
    			syn = 32;
    			i++;
    			token = ",";
    			return syn;
    		case':':
    			syn = 33;
    			i++;
    			token = ":";
    			return syn;
    		case';':
    			syn = 34;
    			i++;
    			token = ";";
    			return syn;
    		case'>':
    			syn = 35;
    			i++;
    			token = ">";
    			if (input[i] == '=')
    			{
    				syn = 37;
    				i++;
    				token = ">=";
    			}
    			return syn;
    		case'<':
    			syn = 36;
    			i++;
    			token = "<";
    			if (input[i] == '=')
    			{
    				syn = 38;
    				i++;
    				token = "<=";
    			}
    			return syn;
    		case'!':
    			syn = -1;//若只有一个!则报错
    			i++;
    			if (input[i] == '=')
    			{
    				syn = 40;
    				i++;
    				token = "!=";
    			}
    			return syn;
    
    		case'"'://此处仍需改进 ,"也应该作为一个单独单词符号,拥有种别码
    			syn = -1;
    			token += input[i];
    			i++;
    			while (input[i] != '"')
    			{
    				if (input[i] == '#')
    				{
    					tag = 0;
    					break;
    				}
    				else
    				{
    					token += input[i];
    					i++;
    				}
    			}
    			//————————————
    			if (tag)
    			{
    				token += input[i];
    				i++;
    				syn = 50;
    				return syn;
    			}
    			else
    			{
    				syn = -3;
    				return syn;
    			}
    		case '#':
    			syn = 0;
    			return syn;
    			break;
    
    		default:
    			syn = -1;
    			return syn;
    			break;
    		}
    	}
    
    }
    
    void initial()//初始化保留字
    {
    	Key[1] = { "main",1 };
    	Key[2] = { "int",2 };
    	Key[3] = { "char",3 };
    	Key[4] = { "if",4 };
    	Key[5] = { "else",5 };
    	Key[6] = { "for",6 };
    	Key[7] = { "while",7 };
    	Key[8] = { "return",8 };
    	Key[9] = { "void",9 };
    	Key[10] = { "STRING",50 };
    	Key[11] = { "ID",10 };
    	Key[12] = { "INT",20 };
    }
    
    string input()//读取本地文件,code.txt位于本项目cpp存放地,若更改位置则需输入相应地址,
    //注:window的地址和代码地址两个地址符相反/
    {
    	//把全部文件读取放入string a中
    	ifstream in("code.txt", ios::in);
    	istreambuf_iterator<char> beg(in), end;
    	string a(beg, end);//或者string a;a.assign(beg,end);
    	in.close();
    	return a;
    }
    
    void output(string a)//输出,循环在此实现
    {
    	cout << "(种别码,token/sum)" << endl;
    	int syn;
    	do
    	{
    		syn = scan(a);
    		switch (syn)
    		{
    		case -1:
    			cout << "error 非法字符" << endl;
    			syn = 0;
    			break;
    		case -2:
    			break;
    		case -3:
    			cout << "语法错误(引号不全)" << endl;
    			syn = 0;
    		default:
    			cout << "(" << syn << "," << token << ")" << endl;
    		}
    	} while (syn!=0);
    }
    
    int main()
    {
    	initial();//初始化
    	string a = input();//读取文件置入字符串a中,样例把换行读成/n
    	//cout << "请输入以#结尾的字符串" << endl;
    	/*若想cmd内输入,则把input()那一行换成下面这些;
    	string a;
    	//getline(cin,a);
    	*/
    	cout << "读取到的字符串为:" << a << endl;
    	output(a);
    	return 0;
    }
    
    
  • 相关阅读:
    array_map()与array_shift()搭配使用 PK array_column()函数
    Educational Codeforces Round 8 D. Magic Numbers
    hdu 1171 Big Event in HDU
    hdu 2844 poj 1742 Coins
    hdu 3591 The trouble of Xiaoqian
    hdu 2079 选课时间
    hdu 2191 珍惜现在,感恩生活 多重背包入门题
    hdu 5429 Geometric Progression 高精度浮点数(java版本)
    【BZOJ】1002: [FJOI2007]轮状病毒 递推+高精度
    hdu::1002 A + B Problem II
  • 原文地址:https://www.cnblogs.com/gidear/p/14198340.html
Copyright © 2011-2022 走看看