版权声明:本文为博主原创文章,欢迎转载,转载请贴上博客地址 http://blog.csdn.net/xdg_blog https://blog.csdn.net/xdg_blog/article/details/52865143
/*------------------------------------
author:XD_G
location:SWUN
time:05/2016
course:Compiler
teacher:Wei Zhou
如果认识周伟老师,请代我向他问好!
------------------------------------*/
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <fstream>//files
#include <iomanip>//put_time()
#include <ctime>//time
#include <sstream>//stringstream
#include <direct.h>//_mkdir()
using namespace std;
#pragma region 全局变量
/// Lexical Analysis
const int MAX_PROCESS_SIZE(100);
const vector<string > reserveWordTable = { "function","if","then","while","do","endfunc" };
int SYN(-1);
int SYNPREV(SYN);
string token;
vector<string > subStrSet;
vector<int > lineNumber;
vector<string > LexAlysResultTab;
int lineNum(0);
/// Syntax Analysis
class AnalysisUnit {
public:
int SYN;
string token;
int LineNum;
AnalysisUnit() :SYN(0), token(""), LineNum(0) {}
};
bool LEX_ALYS_ERROR(false);
vector<AnalysisUnit > LexAlysUnitTab;
vector<AnalysisUnit >::iterator pUnitTab = LexAlysUnitTab.begin();
vector<string > SynAlysResultTab;
bool SYN_ALYS_ERROR(false);
vector<vector<AnalysisUnit > > sameLineUnitSet;
bool doFlag(false);
bool ifFlag(false);
vector<char > parenthesesStack;//()
bool semicolonErrorFlag = false;
bool intoFlag = false;
#pragma endregion
#pragma region 创建输出文件名字符串
///函数作用(使用系统时间生成文件名字符串)
///参数(可选参数1:字符串前缀,可选参数2:文件后缀名,例如".txt"、“.log”
///返回值(根据当前的系统时间以及提供的参数生成的带后缀名的字符串)
string getNowTimeFileName(const string preStr = "", const string suffixalNameStr = "") {//获取当前的系统时间以创建文件名
static string pastTime;
time_t t = time(NULL);
tm tm = *localtime(&t);
string nowTime;
stringstream os;
os.clear();
os << put_time(&tm, "%y%m%d_%H%M%S");
nowTime = os.str();
string fileName;
static short k = 0;
if (nowTime != pastTime && (!nowTime.empty())) {//因为获取时间只精确到秒,但是程序可以在一秒之内创建数百个文件,所以要对文件名进行区分
fileName = preStr + " - " + nowTime + "_0000" + suffixalNameStr;
k = 0;
}
else {
char extra[5];
sprintf_s(extra, sizeof(extra), "%04d", ++k);//
fileName = preStr + " - " + nowTime + "_" + extra + suffixalNameStr;
}
pastTime = nowTime;
return fileName;
}
#pragma endregion
/************************ Lexical Analysis *******************************/
//将输入字符串进行预处理并分割
void originStrPartition(const string source, vector<string > &destination) {
if (source.size() == 0)
return;
int num(1);
string temp;
for (string::const_iterator p = source.cbegin(); p != source.cend(); ++p) {
if ('\n' != *p && ' ' != *p && '\t' != *p)
temp.push_back(*p);
else {
if (!temp.empty()) {
destination.push_back(temp);
lineNumber.push_back(num);
}
if ('\n' == *p)
++num;
temp.clear();
}
}
if (!temp.empty()) {
destination.push_back(temp);
lineNumber.push_back(num);
}
temp.clear();
}
//处理预处理之后的字符串为单个字符的情况
void singleChar(string str) {
SYN = -1;
token.clear();
char ch = *str.begin();
if (ch >= 'a' && ch <= 'z' || ch >= 'A'&& ch <= 'Z') {
token.push_back(ch);
SYN = 10;
return;
}
if (ch >= '0' && ch <= '9') {
token.push_back(ch);
SYN = 11;
return;
}
switch (ch) {
case '<':
token.push_back(ch);
SYN = 20;
case '>':
token.push_back(ch);
SYN = 23;
break;
case '=':
token.push_back(ch);
SYN = 18;
break;
case '!':
token.push_back(ch);
SYN = -1 - lineNum;
break;
case '+':
token.push_back(ch);
SYN = 13;
break;
case '-':
token.push_back(ch);
SYN = 14;
break;
case '*':
token.push_back(ch);
SYN = 15;
break;
case '/':
token.push_back(ch);
SYN = 16;
break;
case ';':
token.push_back(ch);
SYN = 26;
break;
case '(':
token.push_back(ch);
SYN = 27;
break;
case ')':
token.push_back(ch);
SYN = 28;
break;
case '#':
token.push_back(ch);
SYN = 0;
break;
case '\n':
break;
case ' ':
break;
case '\t':
break;
default:
token.push_back(ch);
SYN = -1 - lineNum;
}
}
//以字符串为单位处理
void scanner(string::iterator &ch, string &str) {
SYN = -1;
token.clear();
if (*ch >= 'a'&& *ch <= 'z' || *ch >= 'A'&& *ch <= 'Z') {
while (*ch >= 'a' && *ch <= 'z' || *ch >= 'A' && *ch <= 'Z' || *ch >= '0' && *ch <= '9') {//判断字符串为变量名形式
token.push_back(*ch);
if (++ch == str.end())
break;
}
SYN = 10;
for (auto p = reserveWordTable.begin(); p != reserveWordTable.end(); ++p) {
if (token == *p) {
SYN = p - reserveWordTable.begin() + 1;
break;
}
}
if (ch == str.end())
return;
}
else {
bool eStatus = false;//是否进入科学记数法判断阶段
if ('.' == *ch) {
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
//判断之前识别的单元是否为关键词或者运算符
bool opFlag1 = (SYNPREV >= 13 && SYNPREV <= 25) || (SYNPREV >= 1 && SYNPREV <= 6) || -1 == SYNPREV;
if (*ch == '0' || opFlag1 && (('+' == *ch || '-' == *ch) && *(ch + 1) == '0')) {
if ('+' == *ch || '-' == *ch) {
token.push_back(*ch++);
}
if (*(str.end() - 1) == '0') {
SYN = 11;
token.push_back(*ch++);
return;
}
if (*(ch + 1) >= '0' && *(ch + 1) <= '9') {//如果首字符为0,并且第二个字符依然为数字字符
//不能存在前导零//+
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
token.push_back(*ch++);
if ('.' == *ch) {//如果0之后的'.'后面没有数字字符
if (*(str.end() - 1) == '.') {
//小数点不能处于数字末端//+
SYN = -1 - lineNum;//+
while (ch != str.end())//+
token.push_back(*ch++);//+
return;
}
if (*(ch + 1) >= '0' && *(ch + 1) <= '9') {//如果小数点之后有数字字符
SYN = 11;
token.push_back(*ch++);
}
else {//"0...3"
//小数点之后需要存在数字//+
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
while (*ch >= '0' && *ch <= '9') {//循环读取小数点之后的数字字符
token.push_back(*ch);
if (++ch == str.end())
break;
}
if (ch == str.end())
return;
if ('E' != *ch && 'e' != *ch && '+' != *ch && '-' != *ch && '*' != *ch && '/' != *ch && ')' != *ch && ';' != *ch) {
SYN = -1 - lineNum;//+
while ('E' != *ch && 'e' != *ch && '+' != *ch && '-' != *ch && '*' != *ch && '/' != *ch && ')' != *ch && ';' != *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
if ('.' == *ch) {//存在多个小数点
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);
if (ch == str.end())
break;
}
return;
}
else if ('e' == *ch || 'E' == *ch)
eStatus = true;
else {//处理形如"+0.001;"这样的形式
SYN = 11;
return;
}
}
else {//处理形如"+0;"、"0;"这样的形式
SYN = 11;
return;
}
}
//判断之前识别的单元是否为关键词或者运算符
bool opFlag = (SYNPREV >= 13 && SYNPREV <= 25) || (SYNPREV >= 1 && SYNPREV <= 6) || -1 == SYNPREV;
if ((*ch >= '1' && *ch <= '9') || opFlag && (('+' == *ch || '-' == *ch) && (*(ch + 1) >= '1' && *(ch + 1) <= '9'))) {
if ('+' == *ch || '-' == *ch) {
token.push_back(*ch++);
}
while (*ch >= '0' && *ch <= '9') {
token.push_back(*ch);
if (++ch == str.end())
break;
}
SYN = 11;
if (ch == str.end())
return;
if ('.' != *ch && 'E' != *ch && 'e' != *ch && '+' != *ch && '-' != *ch && '*' != *ch && '/' != *ch && ')' != *ch && ';' != *ch) {
SYN = -1 - lineNum;//+
while ('.' != *ch && 'E' != *ch && 'e' != *ch && '+' != *ch && '-' != *ch && '*' != *ch && '/' != *ch && ')' != *ch && ';' != *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
if ('.' == *ch || 'e' == *ch || 'E' == *ch) {
if ('.' == *ch) {
if (*(str.end() - 1) == '.') {//"3.3e."
//小数点不能处于数字末端//+
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
if (*(ch + 1) >= '0' && *(ch + 1) <= '9') {
token.push_back(*ch++);
}
else {
//小数点之后需要存在数字//+
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
while (*ch >= '0' && *ch <= '9') {
token.push_back(*ch);
if (++ch == str.end())
break;
}
if (ch == str.end())
return;
if ('.' == *ch) {
SYN = -1 - lineNum;//+
while (1) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
if ('E' != *ch && 'e' != *ch && '+' != *ch && '-' != *ch && '*' != *ch && '/' != *ch && ')' != *ch && ';' != *ch) {
SYN = -1 - lineNum;//+
while ('E' != *ch && 'e' != *ch && '+' != *ch && '-' != *ch && '*' != *ch && '/' != *ch && ')' != *ch && ';' != *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
if ('.' == *ch) {//存在多个小数点
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);
if (ch == str.end())
break;
}
return;
}
if ('e' == *ch || 'E' == *ch)
eStatus = true;
else {//"+11.1"
SYN = 11;
return;
}
}
else if ('e' == *ch || 'E' == *ch)
eStatus = true;
else {//处理形如"+1.0;"这样的形式
SYN = 11;
return;
}
}
else {
SYN = 11;
return;
}
}
if (eStatus) {//如果读到E或者e
if (*(str.end() - 1) == 'e' || *(str.end() - 1) == 'E') {//"+211e"
SYN = -1 - lineNum;
token.push_back(*ch++);
return;
}
token.push_back(*ch++);//将字符指针从e或E转到下一位
if (*(str.end() - 1) == '+' || *(str.end() - 1) == '-') {//"'+211e+'"
//不能处于数字末端//+
SYN = -1 - lineNum;//+
token.push_back(*ch++);
return;
}
if ('+' == *ch || '-' == *ch) {
token.push_back(*ch++);
}
if ('.' == *ch) {//"123e.123"
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
if (*ch >= '1' && *ch <= '9') {
token.push_back(*ch++);
if (ch != str.end())
while (*ch >= '0' && *ch <= '9') {
token.push_back(*ch);
if (++ch == str.end())
break;
}
if (ch == str.end())
return;
if ('+' != *ch && '-' != *ch && '*' != *ch && '/' != *ch && ')' != *ch && ';' != *ch) {
SYN = -1 - lineNum;//+
while ('+' != *ch && '-' != *ch && '*' != *ch && '/' != *ch && ')' != *ch && ';' != *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
if ('.' == *ch) {//如果在指数部分存在小数点
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);
if (ch == str.end())
break;
}
return;
}
}
else {
if ('0' == *ch) {
//不能存在前导零//+
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
else {//"7.8e+;"
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
return;
}
}
}
else if ('.' == *ch && (*(ch + 1) >= '0' && *(ch + 1) <= '9')) {//".123"
token.push_back(*ch++);
SYN = -1 - lineNum;//+
while ((*ch >= '0' && *ch <= '9') || '.' == *ch || 'e' == *ch || 'E' == *ch) {
token.push_back(*ch++);//+
if (ch == str.end())
break;
}
}
else {
switch (*ch) {
case '<':
if (ch == prev(str.end())) {
token.push_back(*ch);
SYN = 20;
++ch;
}
else
if (*(ch + 1) == '=') {//
token.push_back(*ch);
token.push_back(*(ch + 1));
SYN = 21;
ch += 2;
}
else {
token.push_back(*ch);
SYN = 20;
++ch;
}
break;
case '>':
if (ch == prev(str.end())) {
token.push_back(*ch);
SYN = 23;
++ch;
}
else
if (*(ch + 1) == '=') {
token.push_back(*ch);
token.push_back(*(ch + 1));
SYN = 24;
ch += 2;
}
else {
token.push_back(*ch);
SYN = 23;
++ch;
}
break;
case '=':
if (ch == prev(str.end())) {
token.push_back(*ch);
SYN = 18;
++ch;
}
else
if (*(ch + 1) == '=') {
token.push_back(*ch);
token.push_back(*(ch + 1));
SYN = 25;
ch += 2;
}
else {
token.push_back(*ch);
SYN = 18;
++ch;
}
break;
case '!':
if (ch == prev(str.end())) {
SYN = -1 - lineNum;
token.push_back(*ch);
++ch;
}
else
if (*(ch + 1) == '=') {
token.push_back(*ch);
token.push_back(*(ch + 1));
SYN = 22;
ch += 2;
}
break;
case '+':
token.push_back(*ch);
SYN = 13;
++ch;
break;
case '-':
token.push_back(*ch);
SYN = 14;
++ch;
break;
case '*':
token.push_back(*ch);
SYN = 15;
++ch;
break;
case '/':
token.push_back(*ch);
SYN = 16;
++ch;
break;
case ';':
token.push_back(*ch);
SYN = 26;
++ch;
break;
case '(':
token.push_back(*ch);
SYN = 27;
++ch;
break;
case ')':
token.push_back(*ch);
SYN = 28;
++ch;
break;
case '#':
token.push_back(*ch);
SYN = 0;
break;
case '\n':
break;
case ' ':
break;
case '\t':
break;
default:
token.push_back(*ch++);
SYN = -1 - lineNum;
}
}
}
}
//将结果格式化为字符串
void LexAlysProcess(string str) {
string resultStr;
if (str.size() != 1) {
string::iterator ch = str.begin();
do {
if (str.end() == ch)
break;
scanner(ch, str);
SYNPREV = SYN;
if (SYN < -1) {
LEX_ALYS_ERROR = true;
int num = -1 - SYN;
char buff[10];
itoa(num, buff, 10);
string temp(buff);
resultStr = "(ERROR IN LINE:" + temp + ",'" + token + "')";
LexAlysResultTab.push_back(resultStr);
}
else if (-1 != SYN) {
char buff[10];
itoa(SYN, buff, 10);
string temp(buff);
if (10 == SYN)
resultStr = "(" + temp + ",'" + token + "')";
else
resultStr = "(" + temp + "," + token + ")";
AnalysisUnit TEM;
TEM.SYN = SYN;
TEM.token = token;
TEM.LineNum = lineNum;
LexAlysUnitTab.push_back(TEM);
LexAlysResultTab.push_back(resultStr);
}
else {
LEX_ALYS_ERROR = true;
resultStr = "(ERROR)";
LexAlysResultTab.push_back(resultStr);
}
} while (0 != SYN);
}
else {
singleChar(str);
SYNPREV = SYN;
if (-1 != SYN) {
char buff[10];
itoa(SYN, buff, 10);
string temp(buff);
if (10 == SYN)
resultStr = "(" + temp + "," + "'" + token + "'" + ")";
else
resultStr = "(" + temp + "," + token + ")";
AnalysisUnit TEM;
TEM.SYN = SYN;
TEM.token = token;
TEM.LineNum = lineNum;
LexAlysUnitTab.push_back(TEM);
LexAlysResultTab.push_back(resultStr);
}
}
}
/************************ Syntax Analysis *******************************/
void expr();
void stat();
void factor();
void term();
void yucu();
void lrparser();
void parenthesesJudge();
string PTSART(string info, int flag = 0) {
string TEM;
if (0 == flag) {
TEM = "ERROR! " + info + " IN LINE :";
char buff[10];
if ("NEED ';'" == info)
itoa((pUnitTab - 1)->LineNum, buff, 10);
else if (intoFlag && ("NEED '('" == info || "NEED ')'" == info)) {
vector<AnalysisUnit >::iterator p = pUnitTab;
while (p->LineNum == pUnitTab->LineNum)
--p;
itoa(p->LineNum, buff, 10);
}
else
itoa(pUnitTab->LineNum, buff, 10);
string LNStr(buff);
TEM += LNStr;
}
else if (1 == flag) {
TEM = info;
}
return TEM;
}
void moveToNextLine() {
while (26 != pUnitTab->SYN && 0 != pUnitTab->SYN && 6 != pUnitTab->SYN)
++pUnitTab;
parenthesesStack.clear();
}
void factor() {//因子
if (0 == pUnitTab->SYN)
return;
if (10 == pUnitTab->SYN || 11 == pUnitTab->SYN) {
++pUnitTab;
}
else {
if (27 == pUnitTab->SYN) {
parenthesesJudge();
++pUnitTab;
expr();
while (28 == pUnitTab->SYN) {//)
parenthesesJudge();
++pUnitTab;
}
}
else {
SynAlysResultTab.push_back(PTSART("EXPRESSION ERROR"));
SYN_ALYS_ERROR = true;
//moveToNextLine();//
}
}
}
void term() {//项
if (0 == pUnitTab->SYN)
return;
factor();
while (15 == pUnitTab->SYN || 16 == pUnitTab->SYN) {//* /
++pUnitTab;
if (10 != pUnitTab->SYN && 11 != pUnitTab->SYN && 27 != pUnitTab->SYN) {//ID NUM (
SynAlysResultTab.push_back(PTSART("NEED OPERAND"));
SYN_ALYS_ERROR = true;
int LN = pUnitTab->LineNum;
while (LN == pUnitTab->LineNum) {
parenthesesJudge();
++pUnitTab;
}
intoFlag = true;
}
else {
factor();
}
}
}
void expr() {//表达式
if (0 == pUnitTab->SYN)
return;
term();
while (13 == pUnitTab->SYN || 14 == pUnitTab->SYN || (pUnitTab->SYN >= 20 && pUnitTab->SYN <= 25)) {//+ - > < >= <= ==
++pUnitTab;
if (10 != pUnitTab->SYN && 11 != pUnitTab->SYN && 27 != pUnitTab->SYN) {
SynAlysResultTab.push_back(PTSART("NEED OPERAND"));
SYN_ALYS_ERROR = true;
int LN = pUnitTab->LineNum;
while (LN == pUnitTab->LineNum) {
parenthesesJudge();
++pUnitTab;
}
intoFlag = true;
}
else {
term();
}
}
}
void parenthesesJudge() {//()
if (27 == pUnitTab->SYN)
parenthesesStack.push_back('(');
else if (28 == pUnitTab->SYN) {
if (!parenthesesStack.empty()) {
if ('(' == *prev(parenthesesStack.end())) {
parenthesesStack.pop_back();
}
else {
parenthesesStack.push_back(')');
}
}
else {
parenthesesStack.push_back(')');
}
}
}
void stat() {//语句
if (0 == pUnitTab->SYN)
return;
if (2 == pUnitTab->SYN || 4 == pUnitTab->SYN /*|| 5 == pUnitTab->SYN*/) {//if while
int startFlag = pUnitTab->SYN;
++pUnitTab;
expr();
while (28 == pUnitTab->SYN) {//)
parenthesesJudge();
++pUnitTab;
}
if (2 == startFlag) {
if (3 != pUnitTab->SYN) {
SynAlysResultTab.push_back(PTSART("NEED 'then'"));
SYN_ALYS_ERROR = true;
}
}
if (4 == startFlag && true == doFlag) {
if (26 != pUnitTab->SYN) {//;
if (10 == pUnitTab->SYN || 11 == pUnitTab->SYN || 27 == pUnitTab->SYN) {
SynAlysResultTab.push_back(PTSART("NEED OPERATOR"));
SYN_ALYS_ERROR = true;
int LN = pUnitTab->LineNum;
while (LN == pUnitTab->LineNum) {
parenthesesJudge();
++pUnitTab;
}
intoFlag = true;
}
else if (!intoFlag) {
SynAlysResultTab.push_back(PTSART("NEED ';'"));
SYN_ALYS_ERROR = true;
semicolonErrorFlag = true;
}
}
}
}
else if (5 == pUnitTab->SYN) {//do
doFlag = true;
++pUnitTab;
stat();
}
else if (10 == pUnitTab->SYN) {//ID
++pUnitTab;
if (18 == pUnitTab->SYN) {//=
++pUnitTab;
expr();
while (28 == pUnitTab->SYN) {//)
parenthesesJudge();
++pUnitTab;
}
if (26 != pUnitTab->SYN) {//;
if ((pUnitTab->LineNum == (pUnitTab - 1)->LineNum) && (10 == pUnitTab->SYN || 11 == pUnitTab->SYN || 27 == pUnitTab->SYN)) {
SynAlysResultTab.push_back(PTSART("NEED OPERATOR"));
SYN_ALYS_ERROR = true;
int LN = pUnitTab->LineNum;
while (LN == pUnitTab->LineNum) {
parenthesesJudge();
++pUnitTab;
}
intoFlag = true;
}
else if (!intoFlag) {
SynAlysResultTab.push_back(PTSART("NEED ';'"));
SYN_ALYS_ERROR = true;
semicolonErrorFlag = true;
}
}
}
else {
if (pUnitTab->SYN > 19 && pUnitTab->SYN < 26) {
--pUnitTab;
expr();//a<b;
}
else {
SynAlysResultTab.push_back(PTSART("NEED '='"));
SYN_ALYS_ERROR = true;
}
}
}
else {
if (27 == pUnitTab->SYN) {//(
parenthesesJudge();
++pUnitTab;
stat();
}
else {
SynAlysResultTab.push_back(PTSART("STATEMENT ERROR"));
SYN_ALYS_ERROR = true;
int LN = pUnitTab->LineNum;
while (LN == pUnitTab->LineNum) {
++pUnitTab;
}
intoFlag = true;
}
}
}
void yucu() {//语句串
if (0 == pUnitTab->SYN)
return;
stat();
while (26 == pUnitTab->SYN || 3 == pUnitTab->SYN || true == semicolonErrorFlag || true == intoFlag) {//; then
if (!parenthesesStack.empty()) {
if (')' == *parenthesesStack.begin()) {
SynAlysResultTab.push_back(PTSART("NEED '('"));
SYN_ALYS_ERROR = true;
}
else {
SynAlysResultTab.push_back(PTSART("NEED ')'"));
SYN_ALYS_ERROR = true;
}
}
parenthesesStack.clear();
if (0 != pUnitTab->SYN) {//# endfunc
if (!semicolonErrorFlag && !intoFlag)
++pUnitTab;
semicolonErrorFlag = false;
intoFlag = false;
if (6 != pUnitTab->SYN) {
stat();
}
}
else
return;
}
}
void lrparser() {//程序
if (1 == pUnitTab->SYN) {
++pUnitTab;
yucu();
if (6 == pUnitTab->SYN) {//endfunc
++pUnitTab;
if (0 == pUnitTab->SYN && !SYN_ALYS_ERROR) {//#
SynAlysResultTab.push_back(PTSART("SUCCESS", 1));
}
}
else {
SynAlysResultTab.push_back(PTSART("ERROR! NEED 'endfunc'", 1));
SYN_ALYS_ERROR = true;
}
}
else {
SynAlysResultTab.push_back(PTSART("ERROR! NEED 'function'", 1));
SYN_ALYS_ERROR = true;
yucu();
if (6 != pUnitTab->SYN) {
SynAlysResultTab.push_back(PTSART("ERROR! NEED 'endfunc'", 1));
SYN_ALYS_ERROR = true;
}
}
}
/************************ Main *******************************/
int main(int argc, char *argv[]) {
int displayFlag(argc);
string originStr;
if (1 != argc) {//当参数数量大于1时
cout << "Display in Console?(Y/N):";
char readKey = getchar();
if ('Y' == readKey || 'y' == readKey || '\n' == readKey)
displayFlag = 1;
}
if (1 == argc) {//当不指定参数时,手动进行输入数据
cout << "Please input string:" << endl;
int temp(0);
char charSet[MAX_PROCESS_SIZE];
char ch;
do {
scanf("%c", &ch);
charSet[temp++] = ch;
} while (ch != '#' && temp < MAX_PROCESS_SIZE);
string inputStr(charSet);
originStr = inputStr;
}
else if (2 == argc || 3 == argc) {//当指定一个或者两个参数时,从文件读入数据
if (2 == argc && 1 != displayFlag)//当只指定一个参数时,输出路径为工程目录下的"Output"文件夹
_mkdir("Output");
ifstream infile(argv[1]);
if (!infile)
exit(1);
char buff[MAX_PROCESS_SIZE];
string fileStr;
bool firstRead = true;
while (infile.good() && !infile.eof()) {
memset(buff, 0, MAX_PROCESS_SIZE);
infile.getline(buff, MAX_PROCESS_SIZE);
if (true == firstRead) {
fileStr += buff;
firstRead = false;
}
else
fileStr = fileStr + '\n' + buff;
}
originStr = fileStr;
infile.close();
}
else
exit(1);
originStr.erase(find(originStr.begin(), originStr.end(), '#'), originStr.end());
originStr += " #";
originStrPartition(originStr, subStrSet);//原始字符串分割
for (vector<string >::iterator p = subStrSet.begin(); p != subStrSet.end(); ++p) {
lineNum = *(lineNumber.begin() + distance(subStrSet.begin(), p));
LexAlysProcess(*p);
}
if (!LEX_ALYS_ERROR) {
pUnitTab = LexAlysUnitTab.begin();
lrparser();
}
string LexAlysResultOutputStr = "\t";
string SynAlysResultOutputStr = "\t";
for (auto p : LexAlysResultTab) {
LexAlysResultOutputStr += p + "\n\t";
}
for (auto p : SynAlysResultTab) {
SynAlysResultOutputStr += p + "\n\t";
}
if (1 == displayFlag) {
cout << "\nLexical Analysis Result:\n" << endl;
cout << LexAlysResultOutputStr << endl;
cout << "\nSyntax Analysis Result:\n" << endl;
if (LEX_ALYS_ERROR) {
cout << "Lexical Analysis Failed" << endl;
}
else {
cout << SynAlysResultOutputStr << endl;
}
}
if (2 == displayFlag) {
ofstream outfile;
outfile.open(".\\Output\\" + getNowTimeFileName("Output File", ".txt"));
outfile << "Lexical Analysis Result:\n" << endl;
outfile << LexAlysResultOutputStr;
outfile << "Syntax Analysis Result:\n" << endl;
if (LEX_ALYS_ERROR) {
outfile << "Lexical Analysis Failed" << endl;
}
else {
outfile << SynAlysResultOutputStr << endl;
}
outfile.close();
}
else if (3 == displayFlag) {
ofstream outfile;
outfile.open(argv[2]);
outfile << "Lexical Analysis Result:\n" << endl;
outfile << LexAlysResultOutputStr;
outfile << "Syntax Analysis Result:\n" << endl;
if (LEX_ALYS_ERROR) {
outfile << "Lexical Analysis Failed" << endl;
}
else {
outfile << SynAlysResultOutputStr << endl;
}
outfile.close();
}
system("pause");
return 0;
}