149 lines
4.8 KiB
C++
149 lines
4.8 KiB
C++
//
|
|
// Created by kagura on 4/24/24.
|
|
//
|
|
|
|
#include "Parser.h"
|
|
|
|
Parser::Parser(const char *filename) {
|
|
file.open(filename,ios::in);
|
|
if (!file.is_open()){
|
|
printf("文件打开失败\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
void Parser::parse() {
|
|
char curr;
|
|
string name; // 当前获取到的名称
|
|
while (file.get(curr)){
|
|
switch (state) {
|
|
case VOID:
|
|
if (curr >='0' && curr <='9'){ // 整数
|
|
state = INTEGER;
|
|
name += curr;
|
|
} else if (curr == ' ' || curr == '\n' || curr == '\t') { // 空格.去掉
|
|
continue;
|
|
} else if ((curr >='a' && curr <='z') || (curr >='A' && curr <='Z') || curr == '_'){ // 名称
|
|
state = NAME;
|
|
name += curr;
|
|
} else if (curr == '/'){
|
|
file.get(curr);
|
|
if (curr == '/'){
|
|
state = COMMENT_LINE;
|
|
} else if (curr == '*'){
|
|
state = COMMENT_BLOCK;
|
|
} else{
|
|
state = VOID;
|
|
}
|
|
} else if (classifier.isIsolator(curr)){
|
|
printf("(5,\"%c\")\n",curr);
|
|
append_result(format("{}",curr));
|
|
state = VOID;
|
|
} else if (classifier.isOperator(curr)){
|
|
// 多读下一个字符
|
|
char c = file.peek();
|
|
if (c=='='){
|
|
printf("(4,\"%c%c\")\n",curr,c);
|
|
append_result(format("{}{}",curr,c));
|
|
file.get(curr);
|
|
} else if (curr == '>'||curr == '<'||curr == '+'||curr == '-'||curr == '&'||curr == '|'){
|
|
// 可能是++ -- << >> && || << >>
|
|
if (c == curr){
|
|
printf("(4,\"%c%c\")\n",curr,c);
|
|
append_result(format("{}{}",curr,c));
|
|
file.get(curr);
|
|
} else{
|
|
printf("(4,\"%c\")\n",curr);
|
|
append_result(format("{}",curr));
|
|
}
|
|
} else{
|
|
printf("(4,\"%c\")\n",curr);
|
|
append_result(format("{}",curr));
|
|
}
|
|
}
|
|
|
|
else{
|
|
state = VOID;
|
|
}
|
|
break;
|
|
case INTEGER:
|
|
if (curr >='0' && curr <='9'){ // 整数
|
|
name += curr;
|
|
} else if (curr == ';') {
|
|
printf("(3,\"%s\")\n",name.c_str());
|
|
append_result(name);
|
|
file.unget();
|
|
name.clear();
|
|
state = VOID;
|
|
} else if (curr == ' ' || curr == '\n' || curr == '\t') { // 空格
|
|
printf("(3,\"%s\")\n",name.c_str());
|
|
result += name; // 去掉空格
|
|
name.clear();
|
|
state = VOID;
|
|
} else{
|
|
state = VOID;
|
|
}
|
|
break;
|
|
case NAME:
|
|
if ((curr >='a' && curr <='z') || (curr >='A' && curr <='Z') || (curr >='0' && curr <='9')){
|
|
name += curr;
|
|
} else {
|
|
if (classifier.isreserveNames(name)){
|
|
printf("(1,\"%s\")\n",name.c_str());
|
|
}else{
|
|
printf("(2,\"%s\")\n",name.c_str());
|
|
}
|
|
append_result(name);
|
|
name.clear();
|
|
file.unget(); // 回退一个字符
|
|
state = VOID;
|
|
}
|
|
break;
|
|
case COMMENT_LINE:
|
|
if (curr == '\n'){
|
|
state = VOID;
|
|
}
|
|
break;
|
|
case COMMENT_BLOCK:
|
|
if (curr == '*'){
|
|
file.get(curr);
|
|
if (curr == '/'){
|
|
state = VOID;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Parser::print_result() {
|
|
cout<<result<<endl;
|
|
}
|
|
|
|
void Parser::append_result(const string &name) {
|
|
if (state==NAME){
|
|
if (classifier.isIsolator(name[0])||classifier.isOperator(name[0])){ // 不用加空格
|
|
result += name;
|
|
}else {
|
|
if (classifier.isreserveNames(name)){
|
|
result += name + " ";
|
|
}else{
|
|
result += name;
|
|
}
|
|
}
|
|
}else if (last_state==SEMICOLON){
|
|
if (name != ";"){
|
|
result += name;
|
|
last_state = VOID;
|
|
}
|
|
}else{
|
|
result += name;
|
|
}
|
|
|
|
if (name == ";"){
|
|
last_state = SEMICOLON;
|
|
}
|
|
}
|
|
|
|
|
|
|