编译技术实验2:递归下降语法分析

源代码

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
const char* keyword[8] = { "if","for","else","while","do","float","int",
                              "break" };
char keywordtable[20][20], re_keywordtable[20][20];
char digittable[20][20], re_digittable[20][20];
char otherchartable[20][20], re_otherchartable[20][20];
char idtable[20][20], re_idtable[20][20];
char notetable[20][20];
char finaltable[100][20];
int finaltableint[100];
char word[20];
void initialize();
void alpha();
void digit();
void error();
void otherchar();
void note();
void print();
void program();
void block();
void stmt();
void stmts();
void _bool();
void bool1();
void expr();
void expr1();
void term();
void term1();
void factor();
void match(const char* t);
int digit_num = 0, keyword_num = 0, otherchar_num = 0, id_num = 0, note_num = 0;
int redigit_num = 1, rekeyword_num = 1, reotherchar_num = 1, reid_num = 1; 
int final_num = 0, finalnum = 0;
int flag_error = 0, flagerror = 0;
char lookahead;
void main()
{
    cout << "请输入要分析的语句:" << endl;
    initialize();
    while (1)
    {
        lookahead = cin.get();
        if (isalpha(lookahead))
        {
            alpha();
            initialize();
        }
        else if (isdigit(lookahead))
        {
            digit();
            initialize();
        }
        else if (lookahead == '\t' || lookahead == ' ')
        {
            continue;
        }
        else if (lookahead == '\n')
            break;
        else if (lookahead == '/')
        {
            lookahead = cin.get();
            if (lookahead == '/' || lookahead == '*')
            {
                note();
                initialize();
            }
            else
            {
                cin.putback(lookahead);
                strcpy(finaltable[final_num], "/");
                strcpy(otherchartable[otherchar_num++], "/");
                finaltableint[final_num++] = 2;
                initialize();
            }
        }
        else
        {
            otherchar();
            initialize();
        }
    }
    if (flag_error == 0)
    {
        print();
        program();
        if (finalnum == final_num&&flagerror==0)
            cout << "语法分析完成!" << endl;
    }
}
void initialize()
{
    for (int i = 0; i < 20; i++)
    {
        word[i] = '\0';
    }
}
void alpha()
{
    int i = 1, flag;
    char ch = lookahead;
    word[0] = ch;
    ch = cin.get();
    while (isalpha(ch) || isdigit(ch) || ch == '_')
    {
        word[i++] = ch;
        ch = cin.get();
    }
    cin.putback(ch);
    flag = 0;
    for (i = 0; i < 8; i++)
    {
        if (strcmp(word, keyword[i]) == 0)
            flag = 1;
    }
    if (flag == 1)
    {
        strcpy(keywordtable[keyword_num++], word);
        strcpy(finaltable[final_num], word);
        for (int k = 1; k <= 8; k++)
        {
            if (strcmp(word, keyword[k]) == 0)
            {
                finaltableint[final_num++] = k * 100;
            }
        }
    }
    else
    {
        strcpy(idtable[id_num++], word);
        strcpy(finaltable[final_num], "id");
        finaltableint[final_num++] = 1;
    }
}
void digit()
{
    int i = 1;
    int flag;
    char ch = lookahead;
    word[0] = ch;
    ch = cin.get();
    while (isalpha(ch) || isdigit(ch))
    {
        word[i++] = ch;
        ch = cin.get();
    }
    cin.putback(ch);
    flag = 0;
    for (i = 0; word[i] != '\0'; i++)
    {
        if (word[i] < '0' || word[i]>'9')
            flag = 1;
    }
    if (flag == 1)
    {
        strcpy(idtable[id_num++], word);
        strcpy(finaltable[final_num], "id");
        finaltableint[final_num++] = 1;
    }
    else
    {
        strcpy(digittable[digit_num++], word);
        strcpy(finaltable[final_num], "num");
        finaltableint[final_num++] = 99;
    }
}
void note()
{
    char ch;
    int i = 0;
    ch = cin.get();
    while (1)
    {
        if (ch == '*')
        {
            ch = cin.get();
            if (ch == '/')
                break;
            else
            {
                word[i++] = '*';
                word[i++] = ch;
            }
        }
        else
        {
            word[i++] = ch;
        }
        ch = cin.get();
    }
    strcpy(notetable[note_num++], word);
}
void otherchar()
{
    char ch;
    ch = lookahead;
    switch (ch)
    {
        case'!':
        {
            ch = cin.get();
            if (ch == '=')
            {
                strcpy(otherchartable[otherchar_num++], "!=");
                strcpy(finaltable[final_num], "!=");
                finaltableint[final_num++] = 3;
            }
            else
            {
                cin.putback(ch);
                error();
            }
        }
        break;
        case'=':
        {
            ch = cin.get();
            if (ch == '=')
            {
                strcpy(otherchartable[otherchar_num++], "==");
                strcpy(finaltable[final_num], "==");
                finaltableint[final_num++] = 4;
            }
            else
            {
                strcpy(otherchartable[otherchar_num++], "=");
                strcpy(finaltable[final_num], "=");
                finaltableint[final_num++] = 5;
                cin.putback(ch);
            }
        }
        break;
        case'(':
        {
            strcpy(otherchartable[otherchar_num++], "(");
            strcpy(finaltable[final_num], "(");
            finaltableint[final_num++] = 6;
        }
        break;
        case')':
        {
            strcpy(otherchartable[otherchar_num++], ")");
            strcpy(finaltable[final_num], ")");
            finaltableint[final_num++] = 7;
        }
        break;
        case';':
        {
            strcpy(otherchartable[otherchar_num++], ";");
            strcpy(finaltable[final_num], ";");
            finaltableint[final_num++] = 8;
        }
        break;
        case'{':
        {
            strcpy(otherchartable[otherchar_num++], "{");
            strcpy(finaltable[final_num], "{");
            finaltableint[final_num++] = 9;
        }
        break;
        case'}':
        {
            strcpy(otherchartable[otherchar_num++], "}");
            strcpy(finaltable[final_num], "}");
            finaltableint[final_num++] = 10;
        }
        break;
        case'+':
        {
            strcpy(otherchartable[otherchar_num++], "+");
            strcpy(finaltable[final_num], "+");
            finaltableint[final_num++] = 13;
        }
        break;
        case'-':
        {
            strcpy(otherchartable[otherchar_num++], "-");
            strcpy(finaltable[final_num], "-");
            finaltableint[final_num++] = 19;
        }
        break;
        case'>':
        {
            ch = cin.get();
            if (ch == '=')
            {
                strcpy(otherchartable[otherchar_num++], ">=");
                strcpy(finaltable[final_num], ">=");
                finaltableint[final_num++] = 14;
            }
            else
            {
                strcpy(otherchartable[otherchar_num++], ">");
                strcpy(finaltable[final_num], ">");
                finaltableint[final_num++] = 15;
                cin.putback(ch);
            }
        }
        break;
        case'<':
        {
            ch = cin.get();
            if (ch == '=')
            {
                strcpy(otherchartable[otherchar_num++], "<=");
                strcpy(finaltable[final_num], "<=");
                finaltableint[final_num++] = 16;
            }
            else
            {
                strcpy(otherchartable[otherchar_num++], "<");
                strcpy(finaltable[final_num], "<");
                finaltableint[final_num++] = 17;
            }
        }
        break;
        case'*':
        {
            strcpy(otherchartable[otherchar_num++], "*");
            strcpy(finaltable[final_num], "*");
            finaltableint[final_num++] = 18;
        }
        break;
        default:
            error();
            break;
    }
}
void error()
{
    flag_error = 1;
    cout << "出现错误,终止分析!" << endl;
}
void print()
{
    finaltableint[final_num] = '\0';
    cout << "词法分析结果如下:" << endl;
    for (int i = 0; i < final_num; i++)
        cout << finaltable[i];
    cout << endl;
    cout << "语法分析过程如下:" << endl;
}
void program()
{
    cout << "program-->block" << endl;
    block();
    if (flagerror == 1)
    {
        error();
        return;
    }
}
void block()
{
    if (flagerror == 1)return;
    cout << "block-->{stmts}" << endl;
    match("{");
    stmts();
    match("}");
}
void stmts()
{
    if (flagerror == 1)return;
    if (finaltableint[finalnum] == 10)
    {
        cout << "stmts-->NULL" << endl;
        return;
    }
    cout << "stmts-->stmt stmts" << endl;
    stmt();
    stmts();
}
void stmt()
{
    if (flagerror == 1)return;
    switch (finaltableint[finalnum])
    {
    case 1:
        cout << "stmt-->id=expr;" << endl;
        match("id");
        match("=");
        expr();
        match(";");
        break;
    case 100:
        match("if");
        match("(");
        _bool();
        match(")");
        stmt();
        if (strcmp(finaltable[finalnum], "else") == 0)
        {
            cout << "stmt-->if(_bool)stmt else stmt" << endl;
            match("else");
            stmt();
            break;
        }
        else
        {
            cout << "stmt-->{if(_bool)stmts" << endl;
            break;
        }
    case 400:
        cout << "stmt-->while(bool)stmts" << endl;
        match("while");
        match("(");
        _bool();
        match(")");
        stmt();
        break;
    case 500:
        cout << "stmt-->do stmt while(bool)" << endl;
        match("do");
        stmt();
        match("while");
        match("(");
        _bool();
        match(")");
        break;
    case 800:
        cout << "stmt-->break" << endl;
        match("break");
        break;
    default:
        cout << "stmt-->block" << endl;
        block();
        break;
    }
}
void _bool()
{
    if (flagerror == 1)
        return;
    expr();
    switch (finaltableint[finalnum])
    {
    case 17:
        cout << "_bool-->expr<expr" << endl;
        match("<");
        expr();
        break;
    case 16:
        cout << "_bool-->expr<=expr" << endl;
        match("<=");
        expr();
        break;
    case 15:
        cout << "_bool-->expr>expr" << endl;
        match(">");
        expr();
        break;
    case 14:
        cout << "_bool-->expr>=expr" << endl;
        match(">=");
        expr();
        break;
    default:
        cout << "_bool-->expr" << endl;
        expr();
        break;
    }
}
void expr()
{
    if (flagerror == 1)return;
    cout << "expr-->term expr1" << endl;
    term();
    expr1();
}
void expr1()
{
    if (flagerror == 1)return;
    switch (finaltableint[finalnum])
    {
    case 13:
        cout << "expr1-->+ term expr1" << endl;
        match("+");
        term();
        expr1();
        break;
    case 19:
        cout << "expr1-->- term expr1" << endl;
        match("-");
        term();
        expr1();
        break;
    default:
        cout << "expr1-->NULL" << endl;
        return;
    }
}
void term()
{
    if (flagerror == 1)return;
    cout << "term-->factor term1" << endl;
    factor();
    term1();
}
void term1()
{
    if (flagerror == 1)return;
    switch (finaltableint[finalnum])
    {
    case 18:
        cout << "term1-->* factor term1" << endl;
        match("*");
        factor();
        term1();
        break;
    case 2:
        cout << "term1-->/factor term1" << endl;
        match("/");
        factor();
        term1();
        break;
    default:
        cout << "term1-->NULL" << endl;
        return;
    }
}
void factor()
{
    if (flagerror == 1)
        return;
    switch (finaltableint[finalnum])
    {
    case 6:
        cout << "factor-->(expr)" << endl;
        match("(");
        expr();
        match(")");
        break;
    case 1:
        cout << "factor-->id" << endl;
        match("id");
        break;
    case 99:
        cout << "factor-->num" << endl;
        match("num");
        break;
    default:
        flagerror == 1;
        break;
    }
}
void match(const char* t)
{
    if (strcmp(finaltable[finalnum], t) != 0)
    {
        flagerror = 1;
        return;
    }
    finalnum++;
}

上一篇:C语言 全排列


下一篇:数据结构(C语言)--链表