回 帖 发 新 帖 刷新版面

主题:急用~~C语言实现语法分析的功能

哪位哥们能帮我弄个实验`。。来实现语法分析的功能 急用。。。
先谢谢了。。。知道的请留下你宝贵的意见~~~~~~

回复列表 (共11个回复)

沙发

//这是一个C++ 写的C语言词法分析器
#include <iostream>
#include <stdio.h>
#include <string>

using namespace std;

FILE *f;
int line = 1;
struct ID{ char *name; int count;};
ID iD[100]; //用于存放ID号码  
ID id[100];
int s = 1;
int I = 0;//用于记录ID存放的数量
int Number[100];// 用于存放数字
int P = 0;//用于记录存放数字的个数
int error[100] = {0};//用于记录错误的行数
int K = 0;//记录错误次数
void Error(); //记录错误
void loginID(char *);//注册ID
void loginNumber(int &);//放入数字
void noteLine(char &);//记录光标的行数
void print(); //输出部分

    


void Error()
{ error[K++] = line; }

void loginID(char *chr)
{
    int i = 0;
    while( i < I && !strcmp(chr,id[i].name))//检测是否已经注册
    {i++;}
    if( i == I )//新的ID注册
    {
        id[i].name = chr;
        I++;
    }

}  

void loginNumber(int &nu)  
{ Number[P++] = nu; }
        
void noteLine(char &ch)
{
    if ( ch == '\n' )
    ++line;
}

void print()//////////////////////////输出部分
{
    //cout << "关键字以及变量:" << endl;
    //for(int i = 0; i < I; i++)
    //cout << i <<"  " << iD[i].name << "  " << iD[i].count << endl;
    //cout << "数字:" << endl;
    //for(int i = 1; i <= P; i++)
    //cout << i << ":  " << Number[i-1] << endl;
    if(error[0] != 0)
    {
        cout << "出现的错误!" << endl;
        for(int i = 1; i <= K; i++)
        cout << "第" <<  i << "个错误:   " << "第" << error[i-1] << "行" << endl;
    }  
    else
    cout << "没有错误!" << endl;     
}

//////////////////////////////文件处理部分
void noblank( char &ch)//跳过空格,回车
{
    noteLine(ch);
    while(ch == ' ' || ch == '\n')
    ch = fgetc(f);
}
void identifier(char name[],char &ch)//字母变量
{
    
    int i;
    for(i = 0; i < 20; i++)
    name[i] = ' ';
    i = 0;
    while (('0'<= ch && ch <= '9')||('a'<= ch&&ch <= 'z')||('A'<= ch&&ch <='Z'))
    {
        name[i] = ch;
        i++;
        ch = fgetc(f);
    }
    loginID(name);
    //for(int j = 0; j < i; j++)
    //{cout << name[j];}
   // cout << ' ';
    
}

板凳

int number(char &ch)//数字
{
    int num=0;
    while('0'<= ch && ch <= '9')
    {
        num = num* 10 + (ch-'0');
        ch = fgetc(f);
    }
    if( ('a'<= ch&&ch <= 'z')||('A'<= ch&&ch <='Z'))
    {
        Error();
    }
    else if( ch == '.')
    {;}
    loginNumber(num);
    return num;   
}
   
void test(char &ch)//符号
{
    char str[2]={'0/'};
    if(ch == '*')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '.')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == ',')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '"')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '/')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '%')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '^')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '-')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '{')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '}')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '[')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == ']')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == ';')
    {str[0] = ch; ch = fgetc(f);}
    if(ch == ':')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '?')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == '(')
    { str[0] = ch; ch = fgetc(f);}
    if(ch == ')')
    {str[0] = ch; ch = fgetc(f);}
    if(ch =='+')
    {
         
        str[0] = ch;
        if((ch = fgetc(f)) == '+' )
        {
            str[1] = ch;
            ch = fgetc(f);
            //cout << str[0] << str[1] << endl;
        }
    
        //cout << str[0]<< endl;
    }  
    if(ch == '-')
    {
         
        str[0] = ch;
        if((ch = fgetc(f)) == '-' )
        {
            str[1] = ch;
            ch = fgetc(f);
            //cout << str[0] << str[1] << endl;
        }
       
        //cout << str[0]<< endl;
    }  
    if(ch == '&')
    {
         
        str[0] = ch;
        if((ch = fgetc(f)) == '&' )
        {
            str[1] = ch;
            ch = fgetc(f);
            //cout << str[0] << str[1] << endl;
        }
      
        //cout << str[0]<< endl;
    }  
    if(ch == '|')
    {
         
        str[0] = ch;
        if((ch = fgetc(f)) == '|' )
        {
            str[1] = ch;
            ch = fgetc(f);
            //cout << str[0] << str[1] << endl;
        }
      
        //cout << str[0]<< endl;
    }
    if(ch == '!')
    {
         
        str[0] = ch;
        if((ch = fgetc(f)) == '=' )
        {
            str[1] = ch;
            ch = fgetc(f);
            //cout << str[0] << str[1] << endl;
        }

        //cout << str[0]<< endl;
    }
    if(ch == '=')
    {
         
        str[0] = ch;
        if((ch = fgetc(f)) == '=' )
        {
            str[1] = ch;
            ch = fgetc(f);
            //cout << str[0] << str[1] << endl;
        }

    }    
    if(ch == '>')
    {
         
        str[0] = ch;
        if((ch = fgetc(f)) == '=' )
        {
            str[1] = ch;
            ch = fgetc(f);
            //cout << str[0] << str[1] << endl;
        }
        else
        if(ch == '>' )
        {
            str[1] = ch;
            ch = fgetc(f);
            //cout << str[0] << str[1] << endl;
        }

    }
    if(ch == '<')
    {
        str[0] = ch;
        if((ch = fgetc(f)) == '=' )
        {
            str[1] = ch;
            ch = fgetc(f);
        }
        else
        if(ch == '<' )
        {
            str[1] = ch;
            ch = fgetc(f);
        }

    }
    
}

3 楼

int main()
{
    char ch;
    char name[30];
    f = fopen("c.txt","r");
    if (f==NULL)
    cout<<"no such file."<<endl;
    ch = fgetc(f);
    while(!feof(f))
    {
        noblank( ch );
        if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
        {identifier(name,ch);}
        if(ch >= '0'&& ch <= '9')
        {number(ch);}
        else
        {test(ch);}
    }
    print();
    fclose(f);
    system("pause");
    return 0;
}

4 楼

我编了个算符优先分析法的程序,不过现在不能公布代码,呵呵~~!

5 楼

大哥,看一下我的吧!
比较一下!
不过我没有完全。。。我的只是识别pascal的一小部分
不过很容易完善的.......
------------------------------------------------------------
#define BEGIN 1
#define END   2
#define IF    3
#define THEN  4
#define ELSE  5
#define ID    6
#define INT   7
#define LT    8
#define LE    9
#define EQ    10
#define NE    11
#define GT    12
#define GE    13
#define TOKEN_SIZE 64
#define TAB_SIZE   5
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
char TOKEN[TOKEN_SIZE];
extern int lookup(char *);
extern void  out(int ,char*);
extern void  report_error();
char ch;
//信息表
typedef struct{
int ad;
char id[6];
}info_ele;
info_ele info_tab[TAB_SIZE]={{1,"begin"},{2,"end"},{3,"if"},{4,"then"},{5,"else"}};
//扫描器函数
void scaner(FILE *fp)
{
    int i,c_id;
    ch=fgetc(fp);
    if(isalpha(ch)){
         TOKEN[0]=ch;
         i=1;
         ch=fgetc(fp);
         while(isalnum(ch))
            {TOKEN[i]=ch;
             i++;
             ch=fgetc(fp);
            }
         fseek(fp,-1,1);
         TOKEN[i]='\0';
         c_id=lookup(TOKEN);
         if (c_id==0) out(ID,TOKEN);
          else out(c_id,TOKEN);
          }
     else if(isdigit(ch)){
                TOKEN[0]=ch;
                i=1;
                ch=fgetc(fp);
                while(isdigit(ch))
                {TOKEN[i]=ch;
                  i++;
                  ch=fgetc(fp);
                }
                 fseek(fp,-1,1);
                TOKEN[i]='\0';
                out(INT,TOKEN);
          }
          else
              if(ch==' ');//遇见空格继续
              else switch(ch)
            {
                case '=':out(EQ,"=");
                           break;
                case '>':ch=fgetc(fp);
                            if(ch=='=')out(GE,">=");
                            else{ fseek(fp,-1,1);
                                     out(GT,">");
                            }
                            break;
                case'<':ch=fgetc(fp);
                          if(ch=='=') out(LE,"<=");
                          else if(ch=='>')out(NE,"<>");
                                 else{
                                       fseek(fp,-1,1);
                                       out(LT,"<");
                                 }
                            break;
                default: report_error();
                         break;
            }
}
                                 
int lookup(char p[])
{
    int i=0;
    for(i;i<TAB_SIZE;i++)
    {
        if(!strcmp(info_tab[i].id,p))return (info_tab[i].ad);
    }
     return 0;
    
}

void out(int a,char *p)
{
    
    switch(a){
    case BEGIN: printf("(BEGIN,%s)",p);break;
    case END : printf("(END,%s)",p); break;
    case IF: printf("(IF,%s)",p);break;
    case THEN: printf("(THEN,%s)",p);break;
    case ELSE: printf("(ELSE,%s)",p);break;
    case ID: printf("(ID,%s)",p);break;
    case INT:printf("(INT,%s)",p);break;
    case LT:printf("(LT,%s)",p);break;
    case LE:printf("(LE,%s)",p);break;
    case EQ:printf("(EQ,%s)",p);break;
    case NE:printf("(NE,%s)",p);break;
    case GT:printf("(GT,%s)",p);break;
    case GE:printf("(GE,%s)",p);break;
    default:   break;
    }
}

void report_error()
{
    printf("\n有错误!\n");
    exit(0);
}

6 楼

主函数如下:
#include<stdio.h>
#include<stdlib.h>
extern void scaner(FILE *);
void  main()
{
extern char ch;
char fname[20];
FILE * fp;
printf("Enter file's name:");
scanf("%s",&fname);
if((fp=fopen(fname,"r"))==NULL)
{
  printf("\nfile open error!\n");
  exit(0);
}


do{scaner(fp);}while(ch!=EOF);
}

7 楼

感觉你的太复杂!
我的 自动机的思想/

8 楼

我用的也是自动机哦!

9 楼


[em4]我借鉴了你的程序,我用while(fgetc(fp)!=EOF)
                          {scaner(fp);}
 运行结果产生死循环呢!

10 楼


[em1]都挺厉害的,不过我用的是1楼同志的程序```易懂些``呵呵``,对了,你那可以该下哦,就是"void test(char &ch)//符号 
{
    char str[2]={'0','/'};
改成这样就没warning了```

我来回复

您尚未登录,请登录后再回复。点此登录或注册