www.pudn.com > Yacc.zip > syntax.cpp, change:2014-05-13,size:8721b


#include "syntax.h" 
 
Syntax::Syntax(char * fn_in, char * fn_syn, char * fn_ers) 
{ 
    char line[MAX_LINE];    //读入的行 
    struct Word theword;    //读入的单词 
    int tmp;    //临时变量 
 
    id_index = 0; 
    lp_index = 0; 
 
 
    //将词法分析结果读入wordlist 
    inFile.open(fn_in); 
    if (!inFile.is_open()) 
    { 
        return; 
    } 
    inFile.getline(line, MAX_LINE); 
    while(!inFile.eof()) 
    { 
        sscanf(line, "%d\t", &(theword.detail)); 
        theword.value.int_val = 0; 
        if (theword.detail == P_INTLITERAL) 
        { 
            sscanf(line, "%d\t%d\t%d\t%d", &tmp, &(theword.line), &(theword.col), &(theword.value.int_val)); 
        } 
        else 
        { 
            sscanf(line, "%d\t%d\t%d\t%s", &tmp, &(theword.line), &(theword.col), &(theword.value.name)); 
        } 
        wordlist.push_back(theword); 
        inFile.getline(line, MAX_LINE); 
    } 
    theword.detail = P_EOF; 
    theword.value.int_val = 0; 
    wordlist.push_back(theword); 
    inFile.close(); 
 
    //创建输出和错误文件 
    FILE * fp; 
    fp = fopen(fn_syn, "w"); 
    fclose(fp); 
    fp = fopen(fn_ers, "w"); 
    fclose(fp); 
    synFile.open(fn_syn, ios::out | ios::app); 
    ersFile.open(fn_ers, ios::out | ios::app); 
} 
 
Syntax::~Syntax() 
{ 
    if (!synFile.is_open()) 
    { 
        synFile.close(); 
    } 
    if (!ersFile.is_open()) 
    { 
        ersFile.close(); 
    } 
} 
 
void Syntax::MakeTree() 
{ 
    synFile << "语法分析开始" << endl; 
    ptr = wordlist.begin(); 
    Deal_Prg(); 
    synFile << "语法分析结束" << endl; 
} 
 
void Syntax::Deal_Prg() 
{ 
    if (((Word)*ptr).detail == P_WHILE || ((Word)*ptr).detail == P_IDENTIFIER) 
    { 
        Deal_Stc(); 
        Deal_Prg(); 
    } 
    else if (((Word)*ptr).detail == P_EOF) 
    { 
        return; 
    } 
    else 
    { 
        TellError("非法的语句起始单词"); 
    } 
} 
 
void Syntax::Deal_Stc() 
{ 
    if (((Word)*ptr).detail == P_WHILE) 
    { 
        Deal_Swh(); 
    } 
    else if (((Word)*ptr).detail == P_IDENTIFIER) 
    { 
        Deal_Sas(); 
    } 
    else 
    { 
        TellError("非法的语句起始单词"); 
    } 
} 
 
void Syntax::Deal_Sas() 
{ 
    char lvalue[MAX_WORD]; 
    synFile << "赋值语句" << endl; 
    if (((Word)*ptr).detail == P_IDENTIFIER) 
    { 
        synFile << "  左值是" << ((Word)*ptr).value.name << endl; 
        strcpy(lvalue, ((Word)*ptr).value.name); 
        ptr++; 
        if (((Word)*ptr).detail == P_EQ) 
        { 
            synFile << "  右值是"; 
            ptr++; 
            Deal_Exp(); 
            if (((Word)*ptr).detail == P_SEMI) 
            { 
                ptr++; 
            } 
            else 
            { 
                TellError("语句结束缺少“;”"); 
            } 
        } 
        else 
        { 
            TellError("标识符后仅允许使用“=”赋值"); 
        } 
    } 
    else 
    { 
        TellError("非法的语句起始单词"); 
    } 
} 
 
void Syntax::Deal_Swh() 
{ 
    synFile << "循环体开始" << endl; 
    if (((Word)*ptr).detail == P_WHILE) 
    { 
        ptr++; 
        if (((Word)*ptr).detail == P_LPAREN) 
        { 
            ptr++; 
            Deal_Exr(); 
            if (((Word)*ptr).detail == P_RPAREN) 
            { 
                ptr++; 
                Deal_Sas(); 
            } 
            else 
            { 
                TellError("while语句的比较表达式缺少“)”"); 
            } 
        } 
        else 
        { 
            TellError("while语句的比较表达式缺少“(”"); 
        } 
    } 
    else 
    { 
         TellError("非法的语句起始单词"); 
    } 
    synFile << "循环体结束" << endl; 
} 
 
void Syntax::Deal_Exr() 
{ 
    int cmp_detail; //比较运算符的详细属性字 
    struct Word lvalue, rvalue; //比较对象 
    synFile << "比较表达式" << endl; 
    synFile << "  左值"; 
    Deal_Val(&lvalue); 
    synFile << endl; 
    synFile << "  "; 
    Deal_Cmp(&cmp_detail); 
    synFile << endl; 
    synFile << "  右值"; 
    Deal_Val(&rvalue); 
    synFile << endl; 
    synFile << "  的时候为真" << endl; 
     
} 
 
void Syntax::Deal_Cmp(int * _detail) 
{ 
    *_detail = ((Word)*ptr).detail; 
    if (((Word)*ptr).detail == P_GT) 
    { 
        synFile << "大于"; 
        ptr++; 
    } 
    else if (((Word)*ptr).detail == P_LT) 
    { 
        synFile << "小于"; 
        ptr++; 
    } 
    else 
    { 
        TellError("比较表达式中仅允许使用“>”和“<”运算"); 
    } 
} 
 
void Syntax::Deal_Add(bool _sign, struct Word * word) 
{ 
    if (((Word)*ptr).detail == P_PLUS) 
    { 
        if (word != NULL) 
        { 
            word->detail = P_PLUS; 
            word->value.is_sign = false; 
        } 
        synFile << "+"; 
        ptr->value.is_sign = _sign; 
        ptr++; 
    } 
    else if (((Word)*ptr).detail == P_SUB) 
    { 
        if (word != NULL) 
        { 
            word->detail = P_SUB; 
            word->value.is_sign = false; 
        } 
        synFile << "-"; 
        ptr->value.is_sign = _sign; 
        ptr++; 
    } 
    else 
    { 
        TellError("此处期待出现“+”或“-”运算符"); 
    } 
} 
 
void Syntax::Deal_Mul(struct Word * word) 
{ 
    if (((Word)*ptr).detail == P_STAR) 
    { 
        if (word != NULL) 
        { 
            word->detail = P_STAR; 
            strcpy(word->value.name, "*"); 
        } 
        synFile << "*"; 
        ptr++; 
    } 
    else if (((Word)*ptr).detail == P_SLASH) 
    { 
        if (word != NULL) 
        { 
            word->detail = P_SLASH; 
            strcpy(word->value.name, "/"); 
        } 
        synFile << "/"; 
        ptr++; 
    } 
    else 
    { 
        TellError("此处期待出现“*”或“/”运算符"); 
    } 
} 
 
void Syntax::Deal_Val(struct Word * word) 
{ 
    if (((Word)*ptr).detail == P_IDENTIFIER) 
    { 
        if (word != NULL) 
        { 
            word->detail = P_IDENTIFIER; 
            strcpy(word->value.name, ((Word)*ptr).value.name); 
        } 
        synFile << ((Word)*ptr).value.name; 
        ptr++; 
    } 
    else if (((Word)*ptr).detail == P_PLUS || ((Word)*ptr).detail == P_SUB || ((Word)*ptr).detail == P_INTLITERAL) 
    { 
        int _val; 
        Deal_Int(&_val); 
        if (word != NULL) 
        { 
            word->detail = P_INTLITERAL; 
            word->value.int_val = _val; 
        } 
    } 
    else 
    { 
        TellError("非法的操作数"); 
    } 
} 
 
void Syntax::Deal_Int(int * int_val) 
{ 
    int sign = 1;   //1为正,-1为负 
    if (((Word)*ptr).detail == P_PLUS || ((Word)*ptr).detail == P_SUB) 
    { 
        sign = (((Word)*ptr).detail == P_PLUS) ? 1 : -1; 
        Deal_Add(true); 
        if (((Word)*ptr).detail == P_INTLITERAL) 
        { 
            if (int_val != NULL) 
            { 
                *int_val = sign * ((Word)*ptr).value.int_val; 
            } 
            synFile << ((Word)*ptr).value.int_val; 
            ptr++; 
        } 
        else 
        { 
            TellError("此处期待出现一个操作数"); 
        } 
    } 
    else if (((Word)*ptr).detail == P_INTLITERAL) 
    { 
        if (int_val != NULL) 
        { 
            *int_val = ((Word)*ptr).value.int_val; 
        } 
        synFile << ((Word)*ptr).value.int_val; 
        ptr++; 
    } 
    else 
    { 
        TellError("此处期待出现一个操作数"); 
    } 
} 
 
void Syntax::Deal_Exp() 
{ 
    synFile << "四则表达式"; 
    struct Word theoptr; 
    theoptr.detail = P_BAR; 
    optr.push(theoptr); 
    Deal_Ext(); 
    Deal_Ex1(); 
    synFile << endl; 
    opnd.pop(); 
} 
 
void Syntax::Deal_Ex1() 
{ 
    if (((Word)*ptr).detail == P_PLUS || ((Word)*ptr).detail == P_SUB) 
    { 
        struct Word theoptr; 
        Deal_Add(false, &theoptr); 
        Deal_Ext(); 
        Deal_Ex1(); 
    } 
    else 
    { 
        //ε 
    } 
} 
 
void Syntax::Deal_Ext() 
{ 
    struct Word theopnd; 
    Deal_Val(&theopnd); 
    opnd.push(theopnd); 
    Deal_Et1(); 
} 
 
void Syntax::Deal_Et1() 
{ 
    if (((Word)*ptr).detail == P_STAR || ((Word)*ptr).detail == P_SLASH) 
    { 
        struct Word theoptr, theopnd; 
        Deal_Mul(&theoptr); 
        Deal_Val(&theopnd); 
        opnd.push(theopnd); 
        Deal_Et1(); 
    } 
} 
 
void Syntax::TellError(const char * reason) 
{ 
    ersFile << "语法错误:" << reason << endl; 
    ersFile << "  位置:第" << ptr->line << "行,第" << ptr->col << "列" << endl; 
} 
 
int Syntax::Id_To_Index(const char * id) 
{ 
    int ret = -1; 
    for (idptr = idlist.begin(); idptr != idlist.end(); idptr++) 
    { 
        if (!strcmp(id, ((IdType)*idptr).name)) 
        { 
            ret = ((IdType)*idptr).index; 
            break; 
        } 
    } 
    return ret; 
} 
 
 
bool Syntax::Ready() 
{ 
    return !(wordlist.empty()); 
}