蒟蒻的第一篇紫题题解!
思路
一眼模拟,还是大模拟。不由得想起了我编了 \(4\) 个小时的猪国杀……
输入
首先处理输入,这里我们用一个字符串数组来存储所有的输入,然后再进行处理。
while(getline(cin,sr))str[++cnt]=sr+'\n';
处理时需要双重循环,注意如果遍历到空格要跳过!(字符串内除外)
换行符在第一层循环末尾输出即可。
NUMBER
我们从最难处理的数字开始。
首先判断有没有 .
,再判断是不是十六进制,然后再逐个往后筛,看看能否加进这个数字中,用一个字符串 \(ans\) 来储存答案,记得在最后清零!
bool checknum(int x,int y){
char ch=str[x][y];
if(ch>='0'&&ch<='9'||ch=='e'||ch>='A'&&ch<='F'||ch>='a'&&ch<='f')return 1;
if(ch=='-'||ch=='+')if(str[x][y-1]=='e')return 1;else return 0;
if(ch=='.'&&!pd){pd=1;return 1;}
return 0;
}
if(str[i][j]>='0'&&str[i][j]<='9'||str[i][j]=='.'&&str[i][j+1]>='0'&&str[i][j+1]<='9'){
cout<<"[NUMBER] ";pd=0;
if(str[i][j]=='.')ans+=str[i][j],j++,pd=1;
if(str[i][j]=='0'&&(str[i][j+1]=='X'||str[i][j+1]=='x'))ans+=str[i][j],ans+=str[i][j+1],j+=2,pd=1;
while(checknum(i,j))ans+=str[i][j],j++;j--;
cout<<ans<<'\n';
ans="";
}
STRING
接着我们再来看如何处理字符串。
如果碰到 '
或 "
,就将从这个字符往后筛直到找到另一个 '
或 "
,不过如果这个 '
或 "
前一个字符是 \
,则需跳过继续往后筛。
bool checkstring(int x,int y,char tmp){
char ch1=str[x][y],ch2=str[x][y-1];
if(tmp!=ch1)return 1;
else{if(ch2=='\\')return 1;else return 0;}
return 0;
}
if(str[i][j]=='\''||str[i][j]=='\"'){
cout<<"[STRING] ";
ans+=str[i][j];
char tmp=str[i][j];j++;
while(checkstring(i,j,tmp))ans+=str[i][j],j++;
ans+=str[i][j];
cout<<ans<<'\n';
ans="";
}
SYMBOL
然后就是符号了。
直接用一个函数判断就行,但要注意先判断长度长的,避免重复。
int checksymbol(int x,int y){
char ch1=str[x][y],ch2=str[x][y+1];
if(ch1=='.'&&ch2=='.'&&str[x][y+2]=='.')return 3;
if(ch1=='.'&&ch2=='.'||ch1=='='&&ch2=='='||ch1=='>'&&ch2=='='||ch1=='<'&&ch2=='='||ch1=='~'&&ch2=='=')return 2;
/*+ - * / % ^ # == >= <= > < ~= ( ) { } [ ] ; : , . .. ... =*/
if(ch1=='.'||ch1==','||ch1==':'||ch1==';'||ch1=='='||ch1=='+'||ch1=='-'||ch1=='*'||ch1=='/'||ch1=='%'||ch1=='^'||ch1=='#'||ch1=='<'||ch1=='>'||ch1=='('||ch1==')'||ch1=='{'||ch1=='}'||ch1=='['||ch1==']')return 1;
return 0;
}
if(checksymbol(i,j)){
int tmp=checksymbol(i,j);
cout<<"[SYMBOL] ";
for(int k=0;k<tmp;k++)ans+=str[i][j+k];
j+=tmp,j--;
cout<<ans<<'\n';
ans="";
}
NAME&&RESERVED
保留字可以在名称里判断。
先找到一个字母,然后往后滤,只要后一个字符是字母、数字、下划线中的一个就压入 \(ans\) 中,最后整体判断 \(ans\) 属不属于保留字即可。
bool checkname(int x,int y){
char ch=str[x][y];
if(ch>='0'&&ch<='9'||ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'||ch=='_')return 1;
return 0;
}
bool checkreserved(string s){
for(int i=0;i<21;i++)if(s==RESERVED[i])return 1;
return 0;
}
if(str[i][j]>='a'&&str[i][j]<='z'||str[i][j]>='A'&&str[i][j]<='Z'){
while(checkname(i,j))ans+=str[i][j],j++;j--;
if(checkreserved(ans))cout<<"[RESERVED] "<<ans<<'\n';
else cout<<"[NAME] "<<ans<<'\n';
ans="";
}
COMMENT
只需要判断有没有两个连续的 _
,然后把后面的全部刨去,注意要输出换行符!
if(str[i][j]=='-'&&str[i][j+1]=='-')j=len-1;
完整代码
#include<bits/stdc++.h>
using namespace std;
string RESERVED[25]={"and","break","do","else","elseif","end","false","for","function","if","in","local","nil","not","or","repeat","return","then","true","until","while"};
string sr,str[1005],ans;
int cnt,len,j;
bool pd;
bool checknum(int x,int y){
char ch=str[x][y];
if(ch>='0'&&ch<='9'||ch=='e'||ch>='A'&&ch<='F'||ch>='a'&&ch<='f')return 1;
if(ch=='-'||ch=='+')if(str[x][y-1]=='e')return 1;else return 0;
if(ch=='.'&&!pd){pd=1;return 1;}
return 0;
}
bool checkstring(int x,int y,char tmp){
char ch1=str[x][y],ch2=str[x][y-1];
if(tmp!=ch1)return 1;
else{if(ch2=='\\')return 1;else return 0;}
return 0;
}
int checksymbol(int x,int y){
char ch1=str[x][y],ch2=str[x][y+1];
if(ch1=='.'&&ch2=='.'&&str[x][y+2]=='.')return 3;
if(ch1=='.'&&ch2=='.'||ch1=='='&&ch2=='='||ch1=='>'&&ch2=='='||ch1=='<'&&ch2=='='||ch1=='~'&&ch2=='=')return 2;
/*+ - * / % ^ # == >= <= > < ~= ( ) { } [ ] ; : , . .. ... =*/
if(ch1=='.'||ch1==','||ch1==':'||ch1==';'||ch1=='='||ch1=='+'||ch1=='-'||ch1=='*'||ch1=='/'||ch1=='%'||ch1=='^'||ch1=='#'||ch1=='<'||ch1=='>'||ch1=='('||ch1==')'||ch1=='{'||ch1=='}'||ch1=='['||ch1==']')return 1;
return 0;
}
bool checkname(int x,int y){
char ch=str[x][y];
if(ch>='0'&&ch<='9'||ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'||ch=='_')return 1;
return 0;
}
bool checkreserved(string s){
for(int i=0;i<21;i++)if(s==RESERVED[i])return 1;
return 0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while(getline(cin,sr))str[++cnt]=sr+'\n';
for(int i=1;i<=cnt;i++){
ans="";
len=str[i].length();
// cout<<str[i];
for(int j=0;j<len;j++){
if(str[i][j]==' ')continue;
else if(str[i][j]=='-'&&str[i][j+1]=='-')j=len-1;
else if(str[i][j]>='0'&&str[i][j]<='9'||str[i][j]=='.'&&str[i][j+1]>='0'&&str[i][j+1]<='9'){
cout<<"[NUMBER] ";pd=0;
if(str[i][j]=='.')ans+=str[i][j],j++,pd=1;
if(str[i][j]=='0'&&(str[i][j+1]=='X'||str[i][j+1]=='x'))ans+=str[i][j],ans+=str[i][j+1],j+=2,pd=1;
while(checknum(i,j))ans+=str[i][j],j++;j--;
cout<<ans<<'\n';
ans="";
}else if(str[i][j]=='\''||str[i][j]=='\"'){
cout<<"[STRING] ";
ans+=str[i][j];
char tmp=str[i][j];j++;
while(checkstring(i,j,tmp))ans+=str[i][j],j++;
ans+=str[i][j];
cout<<ans<<'\n';
ans="";
}else if(checksymbol(i,j)){
int tmp=checksymbol(i,j);
cout<<"[SYMBOL] ";
for(int k=0;k<tmp;k++)ans+=str[i][j+k];
j+=tmp,j--;
cout<<ans<<'\n';
ans="";
}else if(str[i][j]>='a'&&str[i][j]<='z'||str[i][j]>='A'&&str[i][j]<='Z'){
while(checkname(i,j))ans+=str[i][j],j++;j--;
if(checkreserved(ans))cout<<"[RESERVED] "<<ans<<'\n';
else cout<<"[NAME] "<<ans<<'\n';
ans="";
}
}
cout<<"[EOL]\n";
}
return 0;
}
标签:ch,return,&&,int,题解,Lexical,Analyzer,ch1,str
From: https://www.cnblogs.com/MithrilSwordXIV/p/18030353