#include"stdio.h"
#include"string.h"#define R  30
#define C  20typedef struct elem
{
    char e[4];
}Elem;   //ACTION表与GoTo表中的元素类型Elem LR[R][C];              //存放ACTION表与GoTo表中的内容typedef struct out
{
    int  order;         //序号
    int  state[10];     //状态栈
    char sign[30];      //符号栈
    char grasen[20];    //产生式
    char input[30];     //输入串
    char explen[50];    //解释说明
}OutNode;   //输出结果中每一行的类型OutNode out[20];            //存放输出结果char Sentence[20];          //存放文法的一个句子
char GramSent[10][20];      //存放文法的一组产生式
int row,colno;              //row为状态个数数,colno为ACTION表与GoTo表列总数
int stateTop=0,signTop=0;       //状态栈与符号栈的栈顶位置(值与栈中元素的个数相等)void input_GramSent()
{
    int i,num;
    printf("请输入文法中产生式的个数\n");
    scanf("%d",&num);
    for(i=1;i<=num;i++)
    {
       printf("请输入文法的第%d个产生式\n",i);
       scanf("%s",GramSent+i-1);
    }
    printf("请输入文法的一个句子\n");
    scanf("%s",Sentence);
    
    printf("**********************************************************\n");
    printf("*  文法的产生式如下:                                    *\n");
    printf("**********************************************************\n");
    for(i=0;i<num;i++)
        printf("%s\n",GramSent+i);
    printf("**********************************************************\n");
    printf("*  文法的句子如下:                                      *\n");
    printf("**********************************************************\n");
      printf("%s\n",Sentence);
}
void input_LR(int row,int colno)                //row为行总数,colno为列总数
{
  int i,j;
  char mid[4];
  printf("**********************************************************\n");
  printf("*  提示:每输入一个元素后就回车                          *\n");
  printf("**********************************************************\n");  printf("请输入LR分析表的终结符(包括#)与非终结符\n");
  for(j=0;j<colno;j++)
     scanf("%s",LR[0][j].e);  for(i=0;i<row;i++)
  {
      printf("请输入%d号状态所对应的各列的元素,空白的地方用s代替\n",i);
      for(j=0;j<colno;j++)
      {
          scanf("%s",mid);
          if(strcmp(mid,"s")==0||strcmp(mid,"S")==0)
              strcpy(LR[i+1][j].e," ");
          else
              strcpy(LR[i+1][j].e,mid);
      }
  }  
}
void output_LR(int row,int colno)
{
  int i,j;
  printf("**********************************************************\n");
  printf("*  LR分析表如下:                                        *\n");
  printf("**********************************************************\n");
  printf("\n");  printf("    ");
  for(j=0;j<colno;j++)
          printf("%s   ",LR[0][j].e);
  printf("\n");  for(i=1;i<=row;i++)
  {   
      printf("%d   ",i-1);
      for(j=0;j<colno;j++)
          printf("%s   ",LR[i][j].e);
      printf("\n");
  }
  printf("\n");
}int SignNum(char ch)//给定一个终结符或非终结符,返回其在ACTION表与GoTo表中的列位置
{
  int i;
  char c[2]="0";
  c[0]=ch;
  for(i=0;i<colno;i++)
      if(strcmp(c,LR[0][i].e)==0)
          return i;
  return -1;
}int CharChangeNum(char* ch)//给定一数字字符串,返回其所对应的数字
{
    int result=0;
    while(*ch!='\0')
    {
        result=result*10+(*ch-'0');
        ch++;
    }
    return result;
}
int OutResult(int s,int c,int i)//输出结果的第i+1行处理函数,(s为状态,c为列)
{
    char mid[4],gra[20];
    int s_num,r_num;
    int n,len,j;    strcpy(mid,LR[s+1][c].e);
    if(strcmp(mid," ")==0)
    {  printf("不能规约\n");   return -2;  }    if(strcmp(mid,"acc")==0||strcmp(mid,"ACC")==0)
    {  printf("规约成功\n");   return -1;  }    out[i+1].order=i+2;    if(mid[0]=='s'||mid[0]=='S')
    {
        s_num=CharChangeNum(mid+1);//s_num为S后的数字
        for(j=0;j<stateTop;j++)
            out[i+1].state[j]=out[i].state[j];
        out[i+1].state[stateTop]=s_num; 
        out[i+1].state[++stateTop]=-1;   //完成第i+1行的状态栈赋值        strcpy(out[i+1].sign,out[i].sign);
        out[i+1].sign[signTop]=out[i].input[0];
        out[i+1].sign[++signTop]='\0';  //完成第i+1行的符号栈的赋值        strcpy(out[i+1].grasen," ");                //完成第i+1行的产生式的赋值        strcpy(out[i+1].input,out[i].input+1);    //完成第i+1行的输入符号串的赋值        //说明暂时不写
    }
    else if(mid[0]=='r'||mid[0]=='R')
    {
        r_num=CharChangeNum(mid+1);//r_num为r后的数字
        strcpy(gra,*(GramSent+r_num-1));
        len=strlen(gra);
        for(j=0;j<len;j++)
            if(gra[j]=='-' && gra[j+1]=='>')
             break;
        n=strlen(gra+j+2);
    
        stateTop-=n;  signTop-=n;        for(j=0;j<stateTop;j++)
            out[i+1].state[j]=out[i].state[j];
        j=SignNum(gra[0]);
        out[i+1].state[stateTop]=CharChangeNum(LR[out[i+1].state[stateTop-1]+1][j].e); 
        out[i+1].state[++stateTop]=-1;   //完成第i+1行的状态栈赋值        strcpy(out[i+1].sign,out[i].sign);
        out[i+1].sign[signTop]=gra[0];
        out[i+1].sign[++signTop]='\0';  //完成第i+1行的符号栈的赋值        strcpy(out[i+1].grasen,gra);                //完成第i+1行的产生式的赋值        strcpy(out[i+1].input,out[i].input);    //完成第i+1行的输入符号串的赋值        //说明暂时不写
    }
    return 1;
}void OutputResult(int r)

    int i,j;
    printf("**********************************************************\n");
    printf("*  句子:%s 用LR分析表 规约过程如下:                  *\n",Sentence);
    printf("**********************************************************\n");
    for(i=0;i<=r;i++)
    {
        j=0;
        printf("%2d  ",out[i].order);
        while(out[i].state[j]!=-1)
            printf("%d",out[i].state[j++]);
        printf("  %s  %s  %s\n",out[i].sign,out[i].grasen,out[i].input);
    }
}int OutControl()//输出结果的总控函数
{
    int s_num,i=0;
    out[0].order=1;                  //序号赋值
    out[0].state[0]=0;  stateTop=1;  out[0].state[stateTop]=-1;     //状态栈赋值,置栈顶位
    strcpy(out[0].sign,"#");   signTop=1;   //符号栈赋值,置栈顶位
    strcpy(out[0].grasen," ");              //产生式为空
    strcpy(out[0].input,Sentence);          //以下两行为输入串赋值
    strcat(out[0].input,"#");
    strcpy(out[0].explen,"0和#进栈");       //解释说明
    //初使化输出结果的第一行
    
    while(1)
    {
        s_num=SignNum(out[i].input[0]);
        //if(s_num!=-1)
        if(OutResult(out[i].state[stateTop-1],s_num,i)!=1)
            break;
        i++;
    }
    return i;
}main()
{
    int r;
    printf("**********************************************************\n");
    printf("*  函数的输入: 文法的产生式,文法句型的一个句子,LR分析表  *\n");
    printf("*  函数的输出: LR分析器的工作过程与说明                  *\n");
    printf("**********************************************************\n");
    printf("请输入LR分析表中终结符与非终结符的总个数\n");
    scanf("%d",&colno);
    printf("请输入LR分析表中状态的总个数\n");
    scanf("%d",&row);
    input_LR(row,colno);
    output_LR(row,colno);
    input_GramSent();
    r=OutControl();  //r为输出结果的行数
    OutputResult(r);
}
这个C程序实现的功能是:1,输入LR分析表。2:输入一个句子(字符串)。
3:对这个输入的句子,输出这个LR分析的过程表格。

解决方案 »

  1.   

    关于那个
    要调用它的JAVA程序是:
    import java.io.*;
    import java.awt.*;
    import java.awt.event.*;
    public class Lr extends WindowAdapter implements ActionListener
    {
          Frame f;
          Button b1,b2,b3;
          TextArea ta1,ta2;
          TextField tf;
          String s1,s2;//s1数组是分析表的输入存储数组,s2数组是输入串的数组
          
     public Lr()
     {      f = new Frame("Lr分析窗口");
          f.setSize(500,500);
          ta1 = new TextArea();
          ta2 = new TextArea();
          tf = new TextField(20);
          Label l1,l2,l3;
          l1 = new Label("Lr分析表:");
          l2 = new Label("Lr分析输入串:");
          Panel p1 = new Panel();
          Panel p2 = new Panel();
          b1 = new Button("输入");
          b2 = new Button("执行");
          b3 = new Button("取消");
          b1.addActionListener(this);
          b2.addActionListener(this);
          b3.addActionListener(this);
          p1.add(l2);
          p1.add(tf);
          p1.add(b1);
          p1.add(b2);
          p1.add(b3);
          p2.add(l1);
          p2.add(ta1);
          f.add(ta2);
          f.add(p1,"South");
          f.add(p2,"North");
          f.setVisible(true);
          f.addWindowListener(this);
      }
      public  void DealIn()
      {
        try           {
                                       FileInputStream inFile1 = new FileInputStream("LrTable.txt");
                                       byte inPut1[] = new byte[512];
                                          while(inFile1.read(inPut1) != -1)//分析表的输入
                                       {                                       s1 = new String(inPut1); //分析表数组
                                           ta1.append(s1);                                     
                                       }
                                       inFile1.close();                                   FileInputStream inFile2 = new FileInputStream("LrInString.txt");
                                       byte inPut2[] = new byte[512];
                                       while (inFile2.read(inPut2) != -1)//输入字符串输入
                                       {
                                         
                                         s2 = new String(inPut2);//输入串数组
                                         tf.setText(s2);
                                       }
                                       inFile2.close();           }
               catch(IOException e)
                       {
                                       System.out.println("I/O error");
                   }
      }
      public void DealDo()
      {
          System.exit(0);
      }
      public void actionPerformed(ActionEvent e)
      {      if(e.getSource()==b1)//如果点击按钮1,所以激发的事件
          {
           DealIn();//激发输入函数
          }
          if(e.getSource()==b2)//点击按钮2时,激发的事件
          {
           DealDo();//激发执行函数         执行函数,我已经用C语言写出来了。但是在修改为JAVA的时候,出了很多问题
          }
          if(e.getSource()==b3)//点击按钮3时,激发的事件
          System.exit(0);
      }
      public void windowClosing(WindowEvent e)
      {
          System.exit(0);
      }
      public static void main(String args[])
      {
           new Lr();
      }
    }
    上面的JAVA程序就是我已经定义好的,一个窗口化的程序,
    现在希望用下面一个C语言的程序来实现上面按钮2中的事件激发程序。。
      

  2.   

    急问另外一个#include <iostream>
    #include <windows.h>
    #include <time.h>
    using namespace std;
    //15a,c3i
    int *init_pair[2];
    //num+R^Z8J
    int num;
    //max_b?fVi
    int max_b;
    void RandGene();
    void DynamicSolve();
    void main()
    {
    srand((unsigned)time(NULL));
    cout<<"LUN^Z8J>n3i";
    cin>>num;
    cout<<endl;
    init_pair[0] = new int[num];
    init_pair[1] = new int[num];
    //Y>-O56Gl,B_gX
    for(int i=0;i<5;i++)
    {
    //Y=O./QWC
    RandGene();
    //DQgX
    DWORD _tstart,_tend;
    _tstart = ::GetTickCount();
    DynamicSolve();
    _tend = ::GetTickCount();
    3
    cout<<":?g_P "<<_tend-_tstart<<endl;
    }
    //T5K1F
    delete []init_pair[0];
    delete []init_pair[1];
    }
    void RandGene()
    {
    int a,b;
    for(int i=0;i<num;i++)
    {
    a = rand()%100;
    b = rand()%100;
    while(a==0 || b==0)
    {
    a = rand()%100;
    b = rand()%100;
    }
    init_pair[0][i] = a;
    init_pair[1][i] = b;
    }
    max_b = rand()%1000 + 1000;
    }
    void DynamicSolve()
    {
    //k*7pWm,EpSnum_max_b+1H3Wm
    int *workplace = new int[num*(max_b+1)];
    //goal[0]15i-1goal15i,o\;
    [1][<[0]
    int *goal[2];
    goal[0] = new int[max_b+1];
    goal[1] = new int[max_b+1];
    for(int i=0;i<max_b+1;i++)
    goal[0][i] = 0;
    4
    for(int i=0;i<num;i++) //4eIb6(a,c)4
    {
    for(int j=0;j<max_b+1;j++)//4Ib6bi
    {
    int pmax=0;
    int pnum=0;
    int bound = min(2,j/init_pair[0][i]);
    //ahndi
    for(int p=0;p<=bound;p++)
    {
    if(init_pair[1][i]*p + goal[0][(j-init_pair[0][i]*p)] > pmax)
    {
    pmax = init_pair[1][i]*p + goal[0][(j-init_pair[0][i]*p)];
    pnum = p;
    }
    }
    goal[1][j] = pmax;
    workplace[i*(max_b+1)+j] = pnum;
    }
    //)goal[1]copy2goal[0]jM
    for(int j=0;j<max_b+1;j++)
    {
    goal[0][j] = goal[1][j];
    }
    }
    //U0A9
    int base = max_b;
    int *result = new int[num];
    for(int i=num-1;i>=0;i--)
    {
    int pnum = workplace[i*(max_b+1)+base];
    result[i] = pnum;
    base = base - init_pair[0][i] * pnum;
    }
    cout<<"nd`H?"<<endl;
    for(int i=0;i<num;i++)
    cout<<result[i]<<" ";
    5
    cout<<endl;
    cout<<"^Z3ndi?"<<goal[0][max_b]<<endl;
    //T5K1F
    delete []workplace;
    delete []goal[0];
    delete []goal[1];
    }
    6
      

  3.   

    还有一个哦#include "fstream.h"struct point
    {
    int x,y;
    };
    struct node
    {
    int len,cost;
    };const int max=100000000;ifstream in("input.txt");
    ofstream out("output.txt");
    int n,k,a,b,c;
    int **p;
    point *newp;
    int **e;
    node **pt2;
    int sn;void newgraph();
    void edgecost();
    void cost(int &result);
    bool place(point d);void main()
    {
        in>>n;
    in>>k;
    in>>a;
    in>>b;
    in>>c;
        p=new int*[n+1];
        int i,j;
        for(i=0;i<=n;i++)
    p[i]=new int[n+1];
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    in>>p[j][i];
    p[1][1]=2;
    p[n][n]=2; int result;
    newgraph();
    edgecost();
    cost(result);
    out<<result;
    }void newgraph()
    {
    newp=new point[n*n+1];
    newp[1].x=1;
    newp[1].y=1;
    sn=1;
    int i,j;
        for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    if(p[i][j]==1) 
    {
    sn++;
    newp[sn].x=i;
    newp[sn].y=j;
    }
    sn++;
    newp[sn].x=n;
    newp[sn].y=n;
    }void edgecost()
    {
    int i,j,r,s;
    pt2=new node*[n+1];
    for(i=0;i<=n;i++)
    pt2[i]=new node[n+1];
    e=new int*[sn+1];
    for(i=0;i<=sn;i++)
    e[i]=new int[sn+1];point *pmid,*pmid2;
    pmid=new point[4*n+1];
    pmid2=new point[4*n+1];
    point pf[5];
    int xt,yt,midn,midn2;

    for(i=1;i<=sn-1;i++)
    {
    for(j=1;j<=n;j++)
    for(r=1;r<=n;r++)
    {
    if(p[j][r]==0) pt2[j][r].len=0;
    else pt2[j][r].len=-2;
    pt2[j][r].cost=max;
    }
    xt=newp[i].x;
    yt=newp[i].y;
    pt2[xt][yt].len=-1;
    pt2[xt][yt].cost=0;
    midn2=1;
    pmid2[1].x=newp[i].x;
    pmid2[1].y=newp[i].y;

    for(j=1;j<=n*n;j++)
    {
    if(midn2==0) break; midn=midn2;
    for(r=1;r<=midn2;r++)
    {
    pmid[r].x=pmid2[r].x;
    pmid[r].y=pmid2[r].y;
    }
    midn2=0;
    for(r=1;r<=midn;r++)
    {
    for(s=1;s<=4;s++)
    {
    pf[s].x=pmid[r].x;
    pf[s].y=pmid[r].y;
    }
    pf[1].x--;
    pf[2].x++;
    pf[3].y--;
    pf[4].y++;
    for(s=1;s<=4;s++)
    if(place(pf[s]))
    if(pt2[pf[s].x][pf[s].y].len==0 
    || pt2[pf[s].x][pf[s].y].len==-2)
    {

    pt2[pf[s].x][pf[s].y].cost
    =pt2[pmid[r].x][pmid[r].y].cost;
    if(s==1 || s==3)
    pt2[pf[s].x][pf[s].y].cost+=b;
    if(pt2[pf[s].x][pf[s].y].len==0)
    {
    pt2[pf[s].x][pf[s].y].len=j;
    midn2++;
    pmid2[midn2].x=pf[s].x;
    pmid2[midn2].y=pf[s].y;
    if(j % k==0)
    pt2[pf[s].x][pf[s].y].cost+=(a+c);
    }
    else if(pt2[pf[s].x][pf[s].y].len==-2)
    {
    pt2[pf[s].x][pf[s].y].len=j;
    if((pf[s].x!=1 || pf[s].y!=1) 
    && (pf[s].x!=n || pf[s].y!=n) )
    pt2[pf[s].x][pf[s].y].cost+=a;
    }
    }
    }
    }
    for(j=1;j<=sn;j++)
    e[i][j]=pt2[newp[j].x][newp[j].y].cost; }
    }void cost(int &result)
    {
    int i=1,j=sn-1,last=1,r,maxt;
    int *q=new int[sn+1];
    int *t=new int[sn+1];
    for(r=2;r<=sn;r++)
    t[r]=e[1][r];
    bool *la=new bool[sn+1];
    for(r=2;r<=sn;r++)
    la[r]=false;
    q[1]=0;
    la[r]=true;
    while(i<sn)
    {
    for(r=1;r<=sn;r++)
    if((!la[r]) && (q[last]+e[last][r]<t[r]))
    t[r]=q[last]+e[last][r];
    maxt=max;
    for(r=1;r<=sn;r++)
    if((!la[r]) && (t[r]<maxt))
    {
    maxt=t[r];
    last=r;
    }
    la[last]=true;
    q[last]=t[last];
    i++;
    }
    result=q[sn];
    //out>>result>>endl;
    }bool place(point d)
    {
    if(d.x>=1 && d.x<=n && d.y>=1 && d.y<=n)
    return true;
    return false;
    }
      

  4.   

    具体的
    整个JAVA程序+C程序(即将修改成JAVA程序的那个)
    这JAVA程序,功能为:从各个文件中读入 需要的各种数据。
    同时在JAVA窗口的ta1编辑框和tf编辑框中,显示,输入的LR分析表和输入的字符串
    同时在ta2中,输出,对上面输入的字符串进行LR分析过程的过程表格。
    谢谢大家了,本来,我可以自己修改的,但是我对JAVA中这样表示C程序中的指针如何在JAVA中表示,感到很困惑
      

  5.   

    楼住很强啊,自己写LR分析器?你可以使用JNI ,先生成DLL,然后直接在java中就可以调用C语言的函数了
      

  6.   

    不过,你的题目,好像是说 C中访问java,这样的话就更简单了
    直接LoadLibary()虚拟机就可以用来了,查查看吧。
      

  7.   

    大家有没有,
    好点的,在JAVA中,使用指针的方法哦?
      

  8.   

    UP~~~~
    这个确实就是LR分析器的程序
    因为,我们的课程是学C程序的,
    JAVA我是自学的,,
    所以,我想做,窗口化LR分析器的时候,
    现在我已经完成了,LR分析器的,窗口化的设计,
    同时,也完成了,输入,句子(字符串)和分析表的功能(从文件中读取的)
    但是,当我想把我已经用C语言完成的LR分析的程序转化成JAVA的时候,遇到了极大的困难,
    因为,好象JAVA中,没有结构体和指针数据类型(这里,我已经搞顶把结构体转化成一个类的形式来调用,但是当转化指针的时候,遇到了,极大的困难,,,,,)
    希望,大虾们能,抽点时间,看下我上面的程序......