回 帖 发 新 帖 刷新版面

主题:[原创]C语言词法分析器

/*////////////////////
题目:C语言词法分析器
作者:liuanggh
时间:2005.9.20 
*/////////////////////
#include<iostream>
#include<stdio.h>
#include<string>

using namespace std;
  
FILE *f;                      //定义一个文件变量 
static int line = 1;          //表示光标所在的行数 
struct ID{ char *name; int count;}id[100];//用于存放ID号码
static int I = 0;             //用于记录ID存放的数量 
int Number[100];              //用于存放数字 
static int P = 0;             //用于记录存放数字的个数 
int error[100] = {0};         //用于记录错误所在的行数
static int K = 0;             //记录错误次数 
void Error();                 //记录错误
void loginID(char *);         //注册ID号 
void loginNumber(int &);      //记录数字 
void noteLine(char &);        //记录光标所在的行数 
void print();                 //输出分析结果
int same(char *chr);         //判断单词是否已经存在


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

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

*/
/*
void loginID(char *chr)
{
    if( same(chr) )                   //单词不存在,就注册新的ID号
         id[I++].count++;             
}    

int same(char *chr)
{
    for(int i = 0; i < I; i++)
        if( !strcmp(chr,id[i].name) )     //单词已经存在 
        {id[i].count++;                  //该ID号的count+1 
        return 0;}
     return 1;           

*/ 

void loginID(char *chr)                 //注册ID号 
{
    int k = 0;
    int h = 0;
    for(int i = 0; i < I; i++)
    {
        if(!strcmp(chr,id[i].name))    //如果单词已经存在 
        {
            id[i].count++; 
            k = 1;
        }
    }
    //这一段一直有错误 ! 
    if(k == 0)                        //该单词不存在 
    {    
        h = I + 1;   
        //I = h;   
        id[h].count++;
        id[h].name = chr;            
        //strcpy(id[h].name ,chr);
    }
        
}          
            
    
void loginNumber(int &nu)  
{ Number[P++] = nu; }
        
void noteLine(char &ch)
{
    if ( ch == '\n' )
    ++line;


void print()//////////////////////////输出部分 
{
    //cout << "关键字以及变量:" << endl;
    //for(int i = 0; i < 100; 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] = '\0';
    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 << ' ';
    
}

回复列表 (共6个回复)

沙发

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;
        }

    }

3 楼

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);
        }

    }
    
}  
 
int main()
{
    char ch;
    char name[30];
    for(int i = 0; i < 30; i++)
    name[i] = '/0';
    f = fopen("c.txt","r");               //打开指定输入文件 
    if (f == NULL)
    cout<<"文件不存在!"<<endl;
    ch = fgetc(f);
    while(!feof(f)) 
    {
        noblank( ch );                   //跳过回车,空格 
        if( ( ch >= 'a' && ch <= 'z' )||( ch >= 'A' && ch <= 'Z' ))
        { identifier(name,ch); }         //处理字母 
        else if( ch >= '0'&& ch <= '9')
        { number(ch); }                  //处理数字 
        else
        { test(ch); }                    //处理符号 
    }
    print();                             //打印词法分析结果 
    fclose(f);                           //关闭文件 
    system("pause");
    return 0;
}

4 楼

void loginID(char *chr)                 //注册ID号 
{
    int k = 0;
    int h = 0;
    for(int i = 0; i < I; i++)
    {
        if(!strcmp(chr,id[i].name))    //如果单词已经存在 
        {
            id[i].count++; 
            k = 1;
        }
    }
  其实这个词法分析器我看不懂,不过这里的 k = 1;后面加一个i=I;可能效率高一点吧;

5 楼

if(k == 0)                        //该单词不存在 
    {    
        h = I + 1;   
        //I = h;   
        id[h].count++;
        id[h].name = chr;            
        //strcpy(id[h].name ,chr);
    }
这里的  h = I + 1;改为h=++I好吧;

6 楼

这个程序还有很多不完善的地方,希望大家可以给点意见

我来回复

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