⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syntax.cpp

📁 使用C++实现的Java语言子集词法、语法、语义分析器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    {
        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 << "四则表达式";
    Asm_Comment("四则表达式开始");
    struct Word theoptr;
    theoptr.detail = P_BAR;
    optr.push(theoptr);
    Deal_Ext();
    Deal_Ex1();
    synFile << endl;
    Asm_Expression(&theoptr);
    opnd.pop();
    Asm_Comment("四则表达式结束");
}

void Syntax::Deal_Ex1()
{
    if (((Word)*ptr).detail == P_PLUS || ((Word)*ptr).detail == P_SUB)
    {
        struct Word theoptr;
        Deal_Add(false, &theoptr);
        Asm_Expression(&theoptr);
        Deal_Ext();
        Deal_Ex1();
    }
    else
    {
        //ε
    }
}

void Syntax::Deal_Ext()
{
    struct Word theopnd;
    Deal_Val(&theopnd);
    opnd.push(theopnd);
    if (theopnd.detail == P_IDENTIFIER)
    {
        Asm_ToStack(theopnd.value.name);
    }
    else if (theopnd.detail == P_INTLITERAL)
    {
        Asm_ToStack(theopnd.value.int_val);
    }
    Deal_Et1();
}

void Syntax::Deal_Et1()
{
    if (((Word)*ptr).detail == P_STAR || ((Word)*ptr).detail == P_SLASH)
    {
        struct Word theoptr, theopnd;
        Deal_Mul(&theoptr);
        Asm_Expression(&theoptr);
        Deal_Val(&theopnd);
        opnd.push(theopnd);
        if (theopnd.detail == P_IDENTIFIER)
        {
            Asm_ToStack(theopnd.value.name);
        }
        else if (theopnd.detail == P_INTLITERAL)
        {
            Asm_ToStack(theopnd.value.int_val);
        }
        Deal_Et1();
    }
    else
    {
        //ε
    }
}

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;
}

void Syntax::Asm_Define(const char * id)
{
    //首次对某变量赋值时,定义这个变量
    if (Id_To_Index(id) < 0)
    {
        struct IdType newid;
        newid.index = id_index++;
        strcpy(newid.name, id);
        idlist.push_back(newid);
        char item[MAX_LINE];
        sprintf(item, "%s%d%s \'%s\', 0\n", DATA_NAME, newid.index, DATA_IDDB, id);
        strcat(asm_data, item);
        sprintf(item, "%s%d%s", DATA_HEAD, newid.index, DATA_ITEM);
        strcat(asm_data, item);
    }
}

void Syntax::Asm_Assign(const char * id)
{
    char item[MAX_LINE];
    Asm_PopToReg("AX");
    sprintf(item, "        MOV     %s%d, AX\n", DATA_HEAD, Id_To_Index(id));

    strcat(asm_code, item);
}

void Syntax::Asm_ToReg(const char * id, const char * regname)
{
    char item[MAX_LINE];
    sprintf(item, "        MOV     %s, [%s%d]\n", regname, DATA_HEAD, Id_To_Index(id));
    strcat(asm_code, item);
}

void Syntax::Asm_ToReg(const int imnum, const char * regname)
{
    char item[MAX_LINE];
    sprintf(item, "        MOV     %s, %d\n", regname, imnum);
    strcat(asm_code, item);
}

void Syntax::Asm_ToStack(const char * id)
{
    Asm_ToReg(id, "SI");
    char item[MAX_LINE];
    sprintf(item, "        PUSH    SI\n");
    strcat(asm_code, item);
}

void Syntax::Asm_ToStack(const int imnum)
{
    Asm_ToReg(imnum, "SI");
    char item[MAX_LINE];
    sprintf(item, "        PUSH    SI\n");
    strcat(asm_code, item);
}

void Syntax::Asm_PopToReg(const char * regname)
{
    char item[MAX_LINE];
    sprintf(item, "        POP     %s\n", regname);
    strcat(asm_code, item);
}

void Syntax::Asm_WhileBegin()
{
    char item[MAX_LINE];
    sprintf(item, "%s%d:\n", WHILE_BEGIN, lp_index);
    strcat(asm_code, item);
}

void Syntax::Asm_WhileLoop(const char * jump)
{
    char item[MAX_LINE];
    Asm_PopToReg("BX");
    Asm_PopToReg("AX");
    sprintf(item, "        CMP     AX, BX\n");
    strcat(asm_code, item);
    sprintf(item, "        %s     %s%d\n", jump, WHILE_END, lp_index);
    strcat(asm_code, item);
}

void Syntax::Asm_WhileEnd()
{
    char item[MAX_LINE];
    sprintf(item, "        JMP     %s%d\n", WHILE_BEGIN, lp_index);
    strcat(asm_code, item);
    sprintf(item, "%s%d:\n", WHILE_END, lp_index);
    strcat(asm_code, item);
    lp_index++;
}

void Syntax::Asm_DoAdd()
{
    char item[MAX_LINE];
    sprintf(item, "        ADD     AX, BX\n");
    strcat(asm_code, item);
    sprintf(item, "        PUSH    AX\n");
    strcat(asm_code, item);
}

void Syntax::Asm_DoSub()
{
    char item[MAX_LINE];
    sprintf(item, "        SUB     AX, BX\n");
    strcat(asm_code, item);
    sprintf(item, "        PUSH    AX\n");
    strcat(asm_code, item);
}

void Syntax::Asm_DoMul()
{
    char item[MAX_LINE];
    sprintf(item, "        IMUL    BX\n");
    strcat(asm_code, item);
    sprintf(item, "        XOR     DX, DX\n");
    strcat(asm_code, item);
    sprintf(item, "        PUSH    AX\n");
    strcat(asm_code, item);
}

void Syntax::Asm_DoDiv()
{
    char item[MAX_LINE];
    sprintf(item, "        XOR     DX, DX\n");
    strcat(asm_code, item);
    sprintf(item, "        IDIV    BX\n");
    strcat(asm_code, item);
    sprintf(item, "        PUSH    AX\n");
    strcat(asm_code, item);
}

void Syntax::Asm_Expression(struct Word * theoptr_ptr)
{
    struct Word tmp;
cmp_pri:
    switch (GetOptrPri(&(optr.top()), theoptr_ptr))
    {
    case '<':
        optr.push(*theoptr_ptr);
        break;
    case '>':
        //操作数2
        Asm_PopToReg("BX");
        opnd.pop();
        //操作数1
        Asm_PopToReg("AX");
        opnd.pop();
        //运算符
        switch (optr.top().detail)
        {
        case P_PLUS:
            Asm_DoAdd();
            break;
        case P_SUB:
            Asm_DoSub();
            break;
        case P_STAR:
            Asm_DoMul();
            break;
        case P_SLASH:
            Asm_DoDiv();
            break;
        default:
            break;
        }
        optr.pop();
        tmp.detail = P_INTLITERAL;
        tmp.value.int_val = 0;
        opnd.push(tmp);
        goto cmp_pri;
        break;
    case '=':
        optr.pop();
        break;
    default:
        break;
    }
}

void Syntax::Asm_Comment(const char * comment)
{
    char item[MAX_LINE];
    sprintf(item, "        ;%s\n", comment);
    strcat(asm_code, item);
}

char Syntax::GetOptrPri(struct Word * word1, struct Word * word2)
{
    int i, j;
    switch (word1->detail)
    {
    case P_PLUS:
        i = 0;
        break;
    case P_SUB:
        i = 1;
        break;
    case P_STAR:
        i = 2;
        break;
    case P_SLASH:
        i = 3;
        break;
    case P_BAR:
        i = 4;
        break;
    default:
        i = 4;
        break;
    }
    switch (word2->detail)
    {
    case P_PLUS:
        j = 0;
        break;
    case P_SUB:
        j = 1;
        break;
    case P_STAR:
        j = 2;
        break;
    case P_SLASH:
        j = 3;
        break;
    case P_BAR:
        j = 4;
        break;
    default:
        j = 4;
        break;
    }
    return OPTR_PRI[i][j];
}

bool Syntax::Ready()
{
    return !(wordlist.empty());
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -