初学者:L1解析表语法错误

时间:2014-07-22 18:54:43

标签: c++ parsing

我是一名CS学生正致力于实施代码,但很难运行它。

请帮我解决这个L1解析表的问题。

可能是我在做一些愚蠢的语法错误。

我非常感谢你的回复。

干杯!

    #include <iostream.h>
    #include <conio.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    void main()
    {
        clrscr();
        int i=0,j=0,k=0,m=0,n=0,o=0,o1=0,var=0,l=0,f=0,c=0,f1=0;
        char     str[30],str1[40]="E",temp[20],temp1[20],temp2[20],tt[20],t3[20];
        strcpy(temp1,'\0');
        strcpy(temp2,'\0');
        char t[10];
        char array[6][5][10] = {
                     "NT", "<id>","+","*",";",
                     "E", "Te","Error","Error","Error",
                     "e", "Error","+Te","Error","\0",
                     "T", "Vt","Error","Error","Error",
                     "t", "Error","\0","*Vt","\0",
                     "V", "<id>","Error","Error","Error"
                      };
        cout << "\n\tLL(1)  PARSER  TABLE \n";
        for(i=0;i<6;i++)
        {
            for(j=0;j<5;j++)
            {
                cout.setf(ios::right);
                cout.width(10);
                cout<<array[i][j];
            }
            cout<<endl;
        }
        cout << endl;
        cout << "\n\tENTER THE STRING :";
        gets(str);
        if(str[strlen(str)-1] != ';')
        {
              cout << "END OF STRING MARKER SHOULD BE ';'";
              getch();
              exit(1);
        }
        cout << "\n\tCHECKING VALIDATION OF THE STRING ";
        cout <<"\n\t" << str1;
        i=0;

    while(i<strlen(str))
        {
         again:
              if(str[i] == ' ' && i<strlen(str))
              {
                   cout << "\n\tSPACES IS NOT ALLOWED IN SOURSE STRING ";
                   getch();
                   exit(1);
              }
              temp[k]=str[i];
              temp[k+1]='\0';
              f1=0;
         again1:
              if(i>=strlen(str))
              {
                   getch();
                   exit(1);
              }
              for(int l=1;l<=4;l++)
              {
                if(strcmp(temp,array[0][l])==0)
                {
                    f1=1;
                    m=0,o=0,var=0,o1=0;
                    strcpy(temp1,'\0');
                    strcpy(temp2,'\0');
                    int len=strlen(str1);
                    while(m<strlen(str1) && m<strlen(str))
                    {
                          if(str1[m]==str[m])
                          {
                               var=m+1;
                               temp2[o1]=str1[m];
                               m++;
                               o1++;
                          }
                          else
                          {
                               if((m+1)<strlen(str1))
                               {
                                   m++;
                                   temp1[o]=str1[m];
                                   o++;
                               }
                               else
                                   m++;
                          }

                    }
                    temp2[o1] = '\0';
                    temp1[o] = '\0';
                    t[0] = str1[var];
                    t[1] = '\0';
                    for(n=1;n<=5;n++)
                    {
                        if(strcmp(array[n][0],t)==0)
                            break;
                    }
                    strcpy(str1,temp2);
                    strcat(str1,array[n][l]);
                    strcat(str1,temp1);
                    cout << "\n\t" <<str1;
                    getch();

                    if(strcmp(array[n][l],'\0')==0)
                    {
                        if(i==(strlen(str)-1))
                        {
                              int len=strlen(str1);
                              str1[len-1]='\0';
                              cout << "\n\t"<<str1;
                              cout << "\n\n\tENTERED STRING IS                             VALID";
                              getch();
                              exit(1);
                          }
                          strcpy(temp1,'\0');
                          strcpy(temp2,'\0');
                          strcpy(t,'\0');
                          goto again1;
                    }
                    if(strcmp(array[n][l],"Error")==0)
                    {
                          cout << "\n\tERROR IN YOUR SOURCE STRING";
                          getch();
                          exit(1);
                    }
                    strcpy(tt,'\0');
                    strcpy(tt,array[n][l]);
                    strcpy(t3,'\0');
                    f=0;
                    for(c=0;c<strlen(tt);c++)
                    {
                         t3[c]=tt[c];
                         t3[c+1]='\0';
                         if(strcmp(t3,temp)==0)
                         {
                               f=0;
                               break;
                         }
                         else
                               f=1;
                     }

                     if(f==0)
                     {
                        strcpy(temp,'\0');
                        strcpy(temp1,'\0');
                        strcpy(temp2,'\0');
                        strcpy(t,'\0');
                        i++;
                        k=0;
                        goto again;
                     }
                     else
                     {
                        strcpy(temp1,'\0');
                        strcpy(temp2,'\0');
                        strcpy(t,'\0');
                        goto again1;
                    }
                }
              }
              i++;
              k++;
        }
        if(f1==0)
               cout << "\nENTERED STRING IS INVALID";
        else
              cout << "\n\n\tENTERED STRING IS VALID";
        getch();
    }

输出


        LL(1)  PARSER  TABLE

        NT      <id>         +         *         ;
        E        Te     Error     Error     Error
        e     Error       +Te     Error
        T        Vt     Error     Error     Error
        t     Error                 *Vt
        V      <id>     Error     Error     Error

        ENTER THE STRING :<id>+<id>*<id>;

    CHECKING VALIDATION OF THE STRING
                E
                Te
                Vte
                <id>te
                <id>e
                <id>+Te
                <id>+Vte
                <id>+<id>te
                <id>+<id>*Vte
                <id>+<id>*<id>te
                <id>+<id>*<id>e
                <id>+<id>*<id>
                ENTERED STRING IS VALID
    [/Code]

1 个答案:

答案 0 :(得分:4)

因此,您需要进行代码检查/代码审查。在这里:

C ++与C
你的程序看起来像是C,但你的问题标签是C ++。所以,我将从C ++的角度来看它。

将头文件切换为C ++:

#include <iostream>
#include <string>
#include <cstdlib>

请注意标题名称中没有“.h”后缀。

控制台I / O
conio.h头文件是特定于编译器的。您没有提到您正在使用的编译器,因此我们很多人无法加载您的源代码并为您提供帮助。

clrscr()功能不是必需的,通常,清除屏幕会删除以后可能需要的信息。顺便说一句,它不便携,因为并非所有平台都有屏幕。

void main
main函数始终返回int

变量名称
C ++语言规范允许标识符中至少包含32个字符。允许使用更多字符,但只有前32个字符用于确定重复字符。

所以使用它们。单个字母只会减少您的打字时间。描述性名称允许其他人和您轻松了解代码的工作方式。你知道所有这些变量用于什么,而不阅读任何其他文档?

样式 - 每行一个声明
每行声明一个变量。易于维护,更易于阅读。

<强>空间吗
空间花费很少的构建时间并且不会影响执行速度。它们增加了清晰度,使用它们。 一般规则是变量和运算符之间的一个空间;逗号后面的一个空格。

角色阵列
不要使用它们,引起问题。由于您的问题标记为C ++,请改用std::string

一个字符的strcpy
不要将strcpy用于一个字符,只需直接指定:

  temp1[0] = '\0';

顺便说一句,strcpy很危险,请改用strncpy;注意字母'n'。

<强> CONST
用它。应该将未更改的内容声明为const以防止错误并允许编译器发现此错误。此外,字符常量(a.k.a. literals)是常量,不能更改。

映射表
三个维度?真? 如何更容易理解,例如结构表:

struct Token_Entry
{
  const char * token_text;
  unsigned int token_ID;
};

const Token_Entry token_table[] =
{
  {TOKEN_NT, "NT"},
  {TOKEN_ID, "<id>"},
  {TOKEN_PLUS, "+"},
  // ...
};
const unsigned int Number_Of_Token_Entries =
    sizeof(token_table) / sizeof(token_table[0]);

避免获取,这很危险。
无论数量多少,gets都会读取输入。如果您分配5个插槽并且用户键入10个字母,您将超出缓冲区。很糟糕。
如果必须,请使用fgets或切换到C ++并使用getline(std::string)

避免exit功能
正确的方法是在return函数中使用main。这样可以正确清理变量。 exit函数更危险一点。

没有Gotos和标签
阅读您喜欢的,正确的C ++文本中的循环。特别是breakcontinue个关键字。

每行一个作业
回车,换行和换行是免费的,使用它们。每行一个分配。它会使编译过程减慢微秒或纳秒;换句话说,处理行结束字符所需的时间可以忽略不计。

使用括号
如果您已经记住优先级表,则可能没有必要使用括号对逻辑语句进行分组,但它们使代码更具可读性:

  while ((m < strlen(str1)) && (m < strlen(str)))

一次计算常数
例如,在分析循环期间,字符串的长度不会更改。所以将它存储到一个常量变量中:

const unsigned int length_str1 = str1.length(); // Since you will be using std::string.
const unsigned int length_str  = strlen(str);   // Or if you insist on C-style strings.
while ((m < length_str1) && (m < length_str))

无符号与有符号整数
我的一个小小的烦恼。如果值为负数,请使用int(a.k.a。signed int);否则使用unsigned int。例如,文本长度不能为负数。长度为-5的字符串是什么样的?

评论您的代码
告诉读者你在做什么以及为什么。不要谈论分配变量。例如,为什么k在循环结束时递增?为什么在一个部分中将temp设置为null而不是另一个部分。 f1变量用于什么?设置verbosity = maximum。

使用调试器
由于您没有对代码进行注释,因此使用单字母变量名称,您的代码将花费大量时间来理解。您可以通过使用调试程序来提供帮助。调试器允许您一次执行一行(a.k.a。单步执行),并打印或显示变量中的值。比在代码中的不同位置为变量添加print语句的古老艺术要快得多。

另外,使用调试器测试和评估程序比在网上发布更快,特别是在这里。