任务描述
使用C/C++语言编写PL/0编译程序的词法分析程序。 需要注意的点: (1)识别非法字符:如 @ 、 & 和 ! 等; (2)识别非法单词:数字开头的数字字母组合; (3)标识符和无符号整数的长度不超过8位; (4)能自动识别并忽略/* */及//格式的注释信息; (5)词法分析过程中遇到错误后能继续往下识别,并输出错误信息。
编程要求
完成上述编程任务,将C/C++语言源程序复制粘贴到右侧代码编辑器,点击“评测”按钮,运行程序,系统会自动进行结果对比。
测试说明
平台会对你编写的代码进行测试:
测试输入:
const a = 10;
var b, c;
procedure fun1;
if a <= 10 then
begin
c := b + a;
end;
begin
read(b);
while b # 0 do
begin
call fun1;
write(2 * c);
read(b);
end
end.
预期输出:
(保留字,const)
(标识符,a)
(运算符,=)
(无符号整数,10)
(界符,;)
(保留字,var)
(标识符,b)
(界符,,)
(标识符,c)
(界符,;)
(保留字,procedure)
(标识符,fun1)
(界符,;)
(保留字,if)
(标识符,a)
(运算符,<=)
(无符号整数,10)
(保留字,then)
(保留字,begin)
(标识符,c)
(运算符,:=)
(标识符,b)
(运算符,+)
(标识符,a)
(界符,;)
(保留字,end)
(界符,;)
(保留字,begin)
(保留字,read)
(界符,()
(标识符,b)
(界符,))
(界符,;)
(保留字,while)
(标识符,b)
(运算符,#)
(无符号整数,0)
(保留字,do)
(保留字,begin)
(保留字,call)
(标识符,fun1)
(界符,;)
(保留字,write)
(界符,()
(无符号整数,2)
(运算符,*)
(标识符,c)
(界符,))
(界符,;)
(保留字,read)
(界符,()
(标识符,b)
(界符,))
(界符,;)
(保留字,end)
(保留字,end)
(界符,.)
测试输入:
const 2a = 123456789;
var b, c;
//单行注释
/*
* 多行注释
*/
procedure function1;
if 2a <= 10 then
begin
c := b + a;
end;
begin
read(b);
while b @ 0 do
begin
call function1;
write(2 * c);
read(b);
end
end.
预期输出:
(保留字,const)
(非法字符(串),2a,行号:1)
(运算符,=)
(无符号整数越界,123456789,行号:1)
(界符,;)
(保留字,var)
(标识符,b)
(界符,,)
(标识符,c)
(界符,;)
(保留字,procedure)
(标识符长度超长,function1,行号:10)
(界符,;)
(保留字,if)
(非法字符(串),2a,行号:11)
(运算符,<=)
(无符号整数,10)
(保留字,then)
(保留字,begin)
(标识符,c)
(运算符,:=)
(标识符,b)
(运算符,+)
(标识符,a)
(界符,;)
(保留字,end)
(界符,;)
(保留字,begin)
(保留字,read)
(界符,()
(标识符,b)
(界符,))
(界符,;)
(保留字,while)
(标识符,b)
(非法字符(串),@,行号:17)
(无符号整数,0)
(保留字,do)
(保留字,begin)
(保留字,call)
(标识符长度超长,function1,行号:19)
(界符,;)
(保留字,write)
(界符,()
(无符号整数,2)
(运算符,*)
(标识符,c)
(界符,))
(界符,;)
(保留字,read)
(界符,()
(标识符,b)
(界符,))
(界符,;)
(保留字,end)
(保留字,end)
(界符,.)
代码展示:
#include<bits/stdc++.h>
using namespace std;
map<string,int> B, Y;
map<char,int> J, y;
string s;
int F;
int main()
{
B["const"]=B["var"]=B["procedure"]=B["begin"]=B["end"]=B["odd"]=B["if"]=B["then"]=B["call"]=B["while"]=B["do"]=B["read"]=B["write"]=1;
Y["+"]=Y["-"]=Y["*"]=Y["/"]=Y["<"]=Y["<="]=Y[">"]=Y[">="]=Y["#"]=Y["="]=Y[":="]=1;
y['+']=y['-']=y['*']=y['/']=y['<']=y['>']=y['=']=y['#']=y[':']=1;
J['(']=J[')']=J[',']=J[';']=J['.']=1;
string s1 = "//", s2 = "/*", s3 = "*/", str;
for(int id = 1; getline( cin, s); id++) {
int f = 0;
for(int i=0; s[i]!='\0'; i++) {
while(s[i]!='\0' && (s[i]==' ' || s[i]=='\t')) i++;
int f1 = 0, f2 = 0, f3 = 0, f4 = 0, flog = 0;
int j1 = i, j2 = i;
if(!((s[i]>='0'&&s[i]<='9') || (s[i]>='a'&&s[i]<='z') || (s[i]>='A'&&s[i]<='Z') || y[s[i]]==1 || J[s[i]]==1)) flog = 1;
while(s[j1]!='\0' && ((s[j1]>='0'&&s[j1]<='9') || (s[j1]>='a'&&s[j1]<='z') || (s[j1]>='A'&&s[j1]<='Z')) ) {
if( s[j1]>='0'&& s[j1]<='9' ) f1 = 1;
else f2 = 1;
j1 ++;
}
while(s[j2]!='\0' && y[ s[j2] ] == 1) f3 = 1, j2 ++;
if(J[ s[i] ] == 1) f4 = 1;
if(f1 || f2) str = s.substr( i, j1-i);
if(f1 == 1 && f2 == 0 && !f && !F) {
if(str.size() <= 8) cout<<"(无符号整数,"<<str<<")"<<endl;
else cout<<"(无符号整数越界,"<<str<<",行号:"<<id<<")"<<endl;
}
else if(f2 == 1 && B[str] != 1 && !f && !F) {
if(s[i]>='0' && s[i]<='9') cout<<"(非法字符(串),"<<str<<",行号:"<<id<<")"<<endl;
else if(str.size() <= 8) cout<<"(标识符,"<<str<<")"<<endl;
else cout<<"(标识符长度超长,"<<str<<",行号:"<<id<<")"<<endl;
}
else if(f2 == 1 && B[str] == 1 && !f && !F) cout<<"(保留字,"<<str<<")"<<endl;
else if( f3 == 1) {
str = s.substr( i, j2-i);
if(str == s1) f = 1;
else if(str == s2) F = 1;
else if(str == s3) F = 0;
else if(!f && !F)
cout<<"(运算符,"<<str<<")"<<endl;
}
else if(f4 == 1 && !f && !F)
cout<<"(界符,"<<s[i]<<")"<<endl;
else if(flog == 1 && !f && !F) cout<<"(非法字符(串),"<<s[i]<<",行号:"<<id<<")"<<endl;
if(j1 != i) i = j1 - 1;
else if(j2 != i) i = j2 - 1;
}
}
return 0;
}