实验二

#include <iostream>
#include <cstring>

#define MAX 100
#define DIGIT 0
#define OPER 1
#define ERROR -1

struct node
{
    char charType;
    union {
        /* data */
        char valChar;
        int valInt;
    };
};

char in[MAX]; // input String
int eft[MAX]; // error table
struct node stable[MAX];

bool isFrontDigit = false;
bool isError = false;
int stableIndex = 0;
int analysisIndex = 0;

void A();
void B();
void F();
void E();
void T();
void match(char);

void init()
{
    memset(eft, 0, sizeof(eft));
    memset(in, 0, sizeof(in));
    memset(stable, 0, sizeof(stable));
}

int decideType(char c)
{
    if (c >= '0' && c <= '9')
        return DIGIT;
    else if (c == '+' || c == '-' || c == '*' || c == '/')
        return OPER;
    else
        return ERROR;
}

void errorLexical(char in[], int eft[], int index)
{
    int lexicalError = 0;
    while (in[index] != '\0')
    {
        if (decideType(in[index]) == ERROR)
        {
            eft[index] = 1;
            lexicalError++;
        }
        ++index;
    }
    printf("Lexical %d error(s):\n", lexicalError);
    // output error position
    int i;
    for (i = 0; i < index; ++i)
    {
        if (eft[i] == 1)
            printf("    index:%d -> %c\n", i + 1, in[i]);
    }
}

/**
 * 0   error
 * 1    true
 */
int buildStable()
{
    int i = 0;
    while (in[i] != '\0')
    {
        // ignore spacebar
        if (in[i] == ' ')
        {
            ++i;
            continue;
        }
        else
        {
            // lexical error break
            if (decideType(in[i]) == ERROR)
            {
                errorLexical(in, eft, i);
                isError = true;
                return 0;
            }
            // is character
            else if (decideType(in[i]) == OPER)
            {
                stable[stableIndex].charType = 'o';
                stable[stableIndex].valChar = in[i];
                ++stableIndex;
                isFrontDigit = false;
            }
            // is digit
            else if (decideType(in[i]) == DIGIT)
            {
                if (isFrontDigit)
                {
                    --stableIndex;
                    stable[stableIndex].valInt = stable[stableIndex].valInt * 10 + in[i] - '0';
                    ++stableIndex;
                }
                else
                {
                    stable[stableIndex].charType = 'n';
                    stable[stableIndex].valInt = in[i] - '0';
                    ++stableIndex;
                    isFrontDigit = true;
                }
            }
        }
        ++i;
    }
    return 1;
}

void errorSyntax()
{
    printf("Syntax error:\n");
    printf("    index:%d -> ", analysisIndex + 1);
    if (stable[analysisIndex].charType == 'o')
        printf("%c\n", stable[analysisIndex].valChar);
    else
        printf("%d\n", stable[analysisIndex].valInt);
    exit(0);
}

void SyntaxAnalysis()
{
    analysisIndex = 0;
    E();
}

void E()
{
    if (stable[analysisIndex].charType == 'n')
    {
        T();
        A();
    }
    else
        errorSyntax();
}

void A()
{
    if (stable[analysisIndex].charType == 'o' && stable[analysisIndex].valChar == '+')
    {
        match('+');
        T();
        A();
    }
    else if (stable[analysisIndex].charType == 'o' && stable[analysisIndex].valChar == '-')
    {
        match('-');
        T();
        A();
    }
    else if (stable[analysisIndex].charType == 'o' && stable[analysisIndex].valChar == '#')
    {
        analysisIndex++;
        return;
    }
    else
        errorSyntax();
}

void T()
{
    if (stable[analysisIndex].charType == 'n')
    {
        F();
        B();
    }
    else
        errorSyntax();
}

void B()
{
    if (stable[analysisIndex].charType == 'o' && stable[analysisIndex].valChar == '*')
    {
        match('*');
        F();
        B();
    }
    else if (stable[analysisIndex].charType == 'o' && stable[analysisIndex].valChar == '/')
    {
        match('/');
        F();
        B();
    }
    else if (stable[analysisIndex].charType == 'o' && (stable[analysisIndex].valChar == '+' || stable[analysisIndex].valChar == '-' || stable[analysisIndex].valInt == '#'))
    {
        return;
    }
    else
        errorSyntax();
}

void F()
{
    if (stable[analysisIndex].charType == 'n')
    {
        analysisIndex++;
        return;
    }
    else
        errorSyntax();
}

void match(char ch)
{
    if (analysisIndex < stableIndex && stable[analysisIndex].valChar == ch)
        analysisIndex++;
    else
        errorSyntax();
}

int main()
{
    init();
    std::cin.getline(in, MAX);
    if (buildStable() == true)
    {
        // add end flag
        stable[stableIndex].charType = 'o';
        stable[stableIndex].valChar = '#';
        stableIndex++;
        // output result
        printf("Lexical Complete!\n");
        printf("result: ");
        for (int i = 0; i < stableIndex; ++i)
        {
            if (stable[i].charType == 'o')
                printf("%c", stable[i].valChar);
            else if (stable[i].charType == 'n')
                printf("%d", stable[i].valInt);
            else
            {
                printf("Program error!");
                exit(0);
            }
        }
        printf("\n");
        SyntaxAnalysis();
    }
    return 0;
}



扫一扫在手机打开当前页