NJUPT-Compile/1/Parser.cpp

150 lines
4.8 KiB
C++
Raw Normal View History

2024-06-15 15:40:42 +02:00
//
// 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;
}
}