修改后的基于LL(1)文法的语法分析程序

原创 2004年07月25日 20:21:00

       对前一个程序做了修改,使用了C++标准库,去掉了自己编写的类,简洁了一点。

/*
 * 文件名称: 语法分析.h
 * 摘    要: 对任意输入LL(1)文法的分析表及字符串,本程序能自动判断所给字符串是
 *           否为该文法的句子,并能给出分析过程。
 * 当前版本: 1.2
 * 作    者: happyjyr
 * 完成日期: 2004.6.8
 * 修改日期: 2004.7.24
 *
*/

#include<iostream>
#include<stdio.h>
#include <string>
#include <stack>

using namespace std;

void showstack(stack< char > st)
{
 int i,j;
 char ch[100];
 j=st.size();
 for(i=0;i<j;i++)
 {
        ch[i]=st.top();
  st.pop();
 }
    for(i=j-1;i>=0;i--)
 {
  cout<<ch[i];
  st.push(ch[i]);
 }
}
bool find(char c,char array[])                     //查找函数,返回布尔值
{
 int i;
    bool flag=false;
 for(i=0;i<100;i++)
 {
  if(c==array[i])
   flag=true;
 }
 return flag;
}
int location(char c,char array[])                  //定位函数,指出字符所在位置
{
 int i;
 for(i=0;i<100;i++)
 {
  if(c==array[i])
   return i;
 }
}
void error()
{
   cout<<"                    出错!"<<endl;
}
void analyse(char Vn[],char Vt[],string M[100][100])
{
   int i,j,m,p,q,length,t,h;
   char w,X;
   string str;
opt0:
   cin>>str;
   for(i=0;i<str.size();i++)
   {
    if(!find(str[i],Vt))
    {  cout<<"输入字符串有误!请重新输入!"<<endl;
    goto opt0;
    break;}
   }
   stack <char> st;
   st.push('#');                                 
   st.push(Vn[0]);                  //#与识别符号入栈
   j=0;
   h=1;
   w=str[0];
   cout<<"步骤            "<<"分析栈                "<<"剩余输入串           "<<" 所用产生式"<<endl;
opt1:
   cout<<h<<"                ";                    //显示步骤
   h++;
   showstack(st);                                   //显示分析栈中内容
   cout<<"                      ";
    for(t=j;t<str.size();t++)
 {
  cout<<str[t];                              //显示剩余字符串
 }
   X=st.top();                             //上托栈顶符号放入X
   st.pop();
    if(find(X,Vt)&& X!='#')
   {
    if(X==w)                                    //分析栈的栈顶元素和剩余输入串的第一个元素相比较
    {    
     cout<<"                   "<<X<<"匹配"<<endl;
    j++;
     w=str[j];
     goto opt1;
    }
    else
     error();
 }
   else
   {
    if(X=='#')
    {
         if(X==w)
   {
    cout<<"                    "<<"接受!"<<endl<<endl;      
   }
       else
    error();
    }
       else 
    {
       p=location(X,Vn);
          q=location(w,Vt);
    string S1("NULL"),S2("null");
         if(M[p][q]==S1 || M[p][q]==S2)                                             //查找二维数组中的产生式
          error();
          else
    {  
          string str0=M[p][q]; 
        cout<<"                  "<<X<<"-->"<<str0<<endl;       //显示对应的产生式
    if(str0=="$")
     goto opt1;
    else
    {length=str0.size();                                //逆序进栈
            for(m=length-1;m>=0;m--)
      {
           st.push(str0[m]);
      }
           goto opt1;
    }
    }
    }
   }
}
main()
{  
 int i,k,n,r;
    char Vn[100],Vt[100],select;
    string M[100][100];
    cout<<"* 文件名称: 语法分析"<<endl;
    cout<<"* 摘    要: 对任意输入LL(1)文法的分析表及字符串,本程序能自动判断所给字符串是"<<endl;
    cout<<"*           否为该文法的句子,并能给出分析过程。"<<endl;
    cout<<"*--------------------------------------------------------------------*"<<endl;
    cout<<endl<<endl;
 opt2: 
 cout<<"请输入非终结符个数:";
 cin>>n;
 cout<<"请输入各终结符(#号表示结束)Vt[i]:";
 for(i=0;i<100;i++)
 {
  cin>>Vt[i];
  if(Vt[i]=='#')
  {
   r=i;
   break;
  }
 }
    for (i=0;i<n;i++)
 {
  cout<<"请输入非终结符Vn["<<i<<"]:";
  cin>>Vn[i];
        cout<<"请输入此非终结符对应各终结符的产生式右部(null或NULL表示出错;$表示空串):";
  for(k=0;k<=r;k++)
  {
   cin>>M[i][k];
  }
 }
opt3:
    cout<<"请输入要分析的字符串,且以#结束:";
    analyse(Vn, Vt, M);
    cout<<"             ************************请选择***********************"<<endl;
    cout<<"                                  1: 输入字符串"                  <<endl;
    cout<<"                                  2: 输入新分析表"                <<endl;
    cout<<"                                  0: 退  出"                      <<endl;
opt4:
    cin>>select;
    switch(select)
 {
        case '1': {goto opt3;break;}
        case '2': {goto opt2;}
        case '0': {break;}
        default:  {cout<<"输入错误!请重新选择:"<<endl;
             goto opt4;
          break;}
 }
    return 0;
}

 

LL(1)文法分析器简单实现

文法: E->E+T | T T->T*F | F F->(E)|i 消除左递归: E->TH H->+TH|e(空,一普赛肋) ...
  • IT_DREAM_ER
  • IT_DREAM_ER
  • 2016年12月06日 12:11
  • 2007

编译原理:LL(1)文法 语法分析器(预测分析表法)

设计要求:对于任意输入的一个LL(1)文法,构造其预测分析表,并对指定输入串分析其是否为该文法的句子。 思路:首先实现集合FIRST(X)构造算法和集合FOLLOW(A)构造算法,再根据FIRST和F...
  • NK_test
  • NK_test
  • 2016年05月22日 20:54
  • 21602

【编译原理】LL1文法语法分析器

上篇文章 【编译原理】语法分析——自上向下分析 分析了LL1语法,文章最后说给出栗子,现在补上去。说明: 这个语法分析器是利用LL1分析方法实现的。 预测分析表和终结符以及非终结符都是针对一个特定文法...
  • yangbodong22011
  • yangbodong22011
  • 2016年11月30日 23:23
  • 5040

LL语法分析器和LR语法分析器的比较

最近正在读久负盛名的“龙书”,
  • Miss_kanagi
  • Miss_kanagi
  • 2014年06月10日 18:14
  • 3524

用JAVA实现LL(1)文法语法分析程序

一个简单语法分析器的设计与实现 实验目的: 1.掌握语法分析的基本任务; 2.掌握语法分析器的工作流程; 3.能设计一个简单的语法分析器,并完成对指定句子的分析。 实验内容:         给定一...
  • puhaiyang
  • puhaiyang
  • 2016年06月30日 23:36
  • 8002

编译原理(六) LL(1)文法分析法(分析过程的C++实现)

前情了解快速通道算法分析预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输入符号a行事的。如下图所示,对于任何(X,a),总控程序每次都执行下述三种可能的动作之一: 若X = a =...
  • qq_24451605
  • qq_24451605
  • 2015年11月28日 21:38
  • 4064

LL(1)文法代码(有一定的纠错能力)

#include #include #include using namespace std; /* 产生式为: E -> TE` E` -> + TE` T -> FT` T` -> *FT`...
  • shl_shl
  • shl_shl
  • 2016年11月28日 20:51
  • 378

LL(1)语法分析器 //c++实现

#include #include #include #include #include #include #include using namespace std; mapgetnum; char ...
  • u011498819
  • u011498819
  • 2014年06月28日 10:53
  • 3964

C++:基于LL(1)方法的语法分析程序-3

前面两次我们完成了对于固定的文法进行分析和从txt文件中生成预测分析表。下面我们改动第一次文件中本来应该可变的部分。首先,我们修改关于分析表的一些函数,例如寻找产生式、寻找终结符的索引……然后我们进行...
  • hengbao4
  • hengbao4
  • 2015年12月05日 21:16
  • 1099

编译原理上机作业2——LL(1)语法分析

#include #include #include #include char grammer[200][200]; char terSymbol[200]; char nterSymbo...
  • sambrown123
  • sambrown123
  • 2013年11月03日 20:55
  • 2182
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:修改后的基于LL(1)文法的语法分析程序
举报原因:
原因补充:

(最多只允许输入30个字)