语法分析

#include <iostream>
using namespace std;
#include <string.h>
char str[1000];
int num, k = 0, f = 0, now, ago;        //f记录:=的个数,k记录;的个数,出现关键字begin和多字节id时借用now移动指针
int T = 0, Go = 1, L = 0, R = 0, Z = 1; //T来判断检索方向 T=0正向检索,T=1反向检索 Go 出现报错后终止程序
void Check_begin_end();                 //判断是否包含begin end
void Check_assignment();                //检查赋值符号前后字符
void Check_id(int i);                   //检查id后面的字符
void Check_Leftparenthesis(int i);      //检查( 后的字符
void Check_Operation(int i);            //检查运算符后的字符
void Check_Rightparenthesis(int i);     //检查右括号后的字符
int scaner(int i);                      //检索字符数组str的值
int scaner(int i)
{
    char t[6], Gjz[2][10] = {"begin", "end"};
    int j, j1;
    switch (str[i])
    {
    case 'b':
        for (j = 0, j1 = i; j <= 4; j++, j1++)
            t[j] = str[j1];
        if (strcmp(t, Gjz[0]) == 0)
        {
            now = j1; //指向begin的后一个字符上
            return 1;
        }
        else
            goto loop;
        break;
    case 'e':
        for (j = 0, j1 = i; j <= 2; j++, j1++)
            t[j] = str[j1];
        t[j] = '\0';
        if (strcmp(t, Gjz[1]) == 0)
            return 6;
        else
            goto loop;
    case '+':
        return 13;
    case '-':
        return 14;
    case '*':
        return 15;
    case '/':
        return 16;
    case ':':
        if (str[i + 1] == '=')
            return 18;
    case '(':
        return 27;
    case ')':
        return 28;
    case '#':
        return 0;
    case ';':
        return 26;
    }
loop:
    if (((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= '0' && str[i] <= '9')) && T == 1)
    {
        while ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= '0' && str[i] <= '9'))
            i--;
        return 10;
    }
    else if (((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')) && T == 0)
    {
        while ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= '0' && str[i] <= '9'))
            i++;
        now = i; //指向id后一个字符;
        return 10;
    }
    else if (str[i] >= '0' && str[i] <= '9')
    {
        while (str[i] >= '0' && str[i] <= '9') //和上一步判断id10一样,让while浪费一步,保证指针的正常移动
            i++;
        now = i;
        return 11;
    }
    else
        return 155; //避免在出现不是以上字符时返回任意值;
}
void Check_Rightparenthesis(int i) //此时i指向 ) 后的第一个字符
{
    R++;
    int r;
    r = scaner(i);
    switch (r)
    {
    case 13:
    case 14:
    case 15:
    case 16:
        Check_Operation(i + 1); // )后出现运算符
        break;
    case 28: // )后出现 )
        Check_Rightparenthesis(i + 1);
        break;
    case 26: // )后出现;
        k++;
        break;
    case 6: // )后出现end
        if (k == f - 1 && L == R)
            cout << "sucess" << endl;
        else if (k == f - 1 && L != R)
            cout << "error(括号不匹配)" << endl;
        else
            cout << "error(缺少:=或;)" << endl;
        Go = 0;
        break;
    default:
        cout << "error(  )后出现非法字符)" << endl;
        Go = 0;
    }
}
void Check_Operation(int i) //此时i指向运算符后的第一个字符
{
    int r;
    r = scaner(i);
    switch (r)
    {
    case 10:
    case 11:
        Check_id(now);
        break;
    case 27:
        Check_Leftparenthesis(i + 1);
        break;
    default:
        Go = 0;
        cout << "error(运算符后出现非法字符)" << endl;
    }
}
void Check_id(int i) //此时i在id后面的第一个字符上
{
    int r;
    r = scaner(i);
    switch (r)
    {
    case 13:
    case 14:
    case 15:
    case 16:
        Check_Operation(i + 1);
        break; //id后面出现运算符
    case 28:   //id后面出现 )
        Check_Rightparenthesis(i + 1);
        break;
    case 26: //id后面出现 ;
        k++;
        break;
    case 6:
    case 0: //id后面出现end,由于end在检索时会被并到id中,但是遇到#时一定能遇到end
        if (k == f - 1 && L == R)
            cout << "sucess" << endl;
        else if (k == f - 1 && L != R)
            cout << "error(括号不匹配)" << endl;
        else if (k != f - 1 && L == R)
        {
            cout << "error(缺少;或者缺少:=)" << endl;
            Go = 0;
        }

        break;
    default:
        cout << "error(id后出现非法字符)" << endl;
        Go = 0;
    }
}
void Check_Leftparenthesis(int i) //此时i是在 ( 后的第一个字符上
{
    L++;
    int r;
    r = scaner(i);
    switch (r)
    {
    case 10:
    case 11:
        Check_id(now);
        break;
    case 27:
        Check_Leftparenthesis(i + 1);
        break;
    default:
        cout << "error(左括号后出现非法字符)" << endl;
        Go = 0;
    }
}
void Check_assignment()
{
    int i = now, r, j, j1; //now此时是在begin后一个的字符上
    char o[6], p[6] = {"nigeb"};
    r = scaner(i);
    while (r != 6 && Go == 1)
    {
        if (r == 18) //出现赋值号 此时i指向的是赋值号中的 :
        {
            f++; //记录赋值符号的个数
            T = 1;
            r = scaner(i - 1); //检查赋值符号前面的字符
            T = 0;
            if (r != 10)
            {
                cout << "error( No." << f << ":= without id)" << endl; //赋值号前面不是 id 报错
                Go = 0;
            }
            else
            {
                if (f == 1)
                {
                    for (j = i - 1, j1 = 0; j1 <= 4; j--, j1++)
                        o[j1] = str[j];
                    o[j1] = '\0';
                    if (strcmp(o, p) == 0 && (str[0] == o[j1 - 1]))
                    {
                        cout << "error( No." << f << ":= without id)" << endl; //赋值号前面是 begin 报错
                        Go = 0;
                    }
                    else
                    {
                        r = scaner(i + 2); //i在这时候指向的是:需要往后加2才能指到赋值号后的东西
                        if (r == 27)       // 赋值号后面出现 (
                            Check_Leftparenthesis(i + 3);
                        else if (r == 10 || r == 11) // 赋值号后面出现 id
                            Check_id(now);
                        else
                        {
                            cout << "error(No." << f << " :=后出现非法字符 )" << endl;
                            Go = 0;
                        }
                    }
                }
                else
                {
                    r = scaner(i + 2); //i在这时候指向的是:需要往后加2才能指到赋值号后的东西
                    if (r == 27)       // 赋值号后面出现 (
                        Check_Leftparenthesis(i + 3);
                    else if (r == 10 || r == 11) // 赋值号后面出现 id
                        Check_id(now);
                    else
                    {
                        cout << "error(No." << f << " :=后出现非法字符 )" << endl;
                        Go = 0;
                    }
                }
            }
        }
        i++;
        r = scaner(i);
    }
    if (f == 0 || k != f - 1)
        cout << "error(缺少:=或者缺少;)" << endl; //缺少:=或者:=与;在数量上不匹配;
}
void Check_begin_end() //判断第一个字符是不是关键字begin,以及end,#
{
    int i = 0, r = 0;
    r = scaner(i);
    if (r != 1)
        cout << "error(without begin)" << endl;
    else
    {
        i = num;
        r = scaner(i - 3);
        if (r != 6)
            cout << "error(without end)" << endl;
        else
            Check_assignment();
    }
}
int main()
{
loop1:
    int i = 0, C;
    k = f = L = R = 0;
    Go = 1;
    cout << "__________________________________" << endl;
    cout << "__________________________________" << endl;
    cout << "Input end with #" << endl;
    cin >> str[i];
    while (str[i] != '#')
    {
        i++;
        cin >> str[i];
    }
    num = i;
    Check_begin_end();
    cout << "If continue,input 1: ";
    cin >> C;
    cout << endl;
    if (C == 1)
        goto loop1;
    else
        return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值