| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 831 人关注过本帖
标题:C语言做的词法分析器。。。请教高手
只看楼主 加入收藏
imissmylove
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2009-11-12
收藏
 问题点数:0 回复次数:0 
C语言做的词法分析器。。。请教高手
用C语言做的词法分析器,如果要识别浮点数,怎么修改程序啊?请教高手


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <assert.h>
#include "lex.h"

char strToken[30];  //字符数组,存放构成单词符号的字符串。
int lvalue;         //单词的内码值
keyword keywords[]={
    "switch",$SWITCH,
    "case",$CASE,
    "if",$IF,
    "else",$ELSE,
    "do",$DO,
    "while",$WHILE,
    "stop",$STOP,
    "end",$END,
    "var",$VAR,
    "dim",$DIM,
    0,0,
};                          //关键字表
symbol ctable[200];         //常数表
symbol vtable[200];         //符号表(标识符)
char inbuf[300];            //扫描缓冲区
int sp;                     //起点指示器
int ep;                     //扫描指示器
int lineno;                 //行计数器
FILE *fsrc;

char GetChar()
{
    //从扫描缓冲区中读一个字符,实现双输入缓冲。
    //第一个缓冲区从inbuf[0]到inbuf[149],第二个缓冲区从inbuf[150]到inbuf[299],
    //每次从源文件读一个缓冲区大小的内容,分析完当前工作缓冲区内容时把源文件读入
    //另一个缓冲区,另一个缓冲区成为工作缓冲区
    int i = 0;
    char ch;
    if ((ep == 150)||(ep == 300))
    {
        ep = ep%300;
        while (((inbuf[i+ep]=fgetc(fsrc))!=NULL) && (i<150))
            i++;
    }
    ch = inbuf[ep];
    ep++;
    return ch;
}
char GetBC()
{
    //从扫描缓冲区读字符,过滤空格、制表和回车符号
    char ch = GetChar();
    while ((ch==' ') || (ch=='\n') || (ch=='\t'))
    {
        if (ch=='\n')
            lineno++;
        ch = GetChar();
    }
    return ch;
}
void Concat(char str[], char ch)
{
    //将字符ch添加到符号串str的尾部
    str[strlen(str)] = ch;
}
bool isLetter(char ch)
{
    //判断ch是否字母
    if (((ch>='A')&&(ch<='Z')) || ((ch>='a')&&(ch<='z')))
        return true;
    return false;
}
bool isDigit(char ch)
{
    //判断ch是否数字
    if ((ch>='0')&&(ch<='9'))
        return true;
    return false;
}
int Reserve(char* str)
{
    //如str是保留字,返回保留字种别号
    //否则返回0
    int i = 0;
    while (keywords[i].code != 0)
    {
        if (strcmp(str,keywords[i].name) == 0)
            return keywords[i].code;
        i++;
    }
    return 0;
}
void  Retract()
{
    //从扫描输入缓冲区回退一个字符
    if (ep==0)
        ep = 299;
    else
        ep--;
}

int InsertID(char *str)
{
    //如符号表中已有str标识符,返回记录号,
    //否则将str加到符号表中,返回记录号
    int i = 0;
    while ((vtable[i].number!=0) && (i<200))
    {
        if (strcmp(str,vtable[i].name) == 0)
            return vtable[i].number;        
        i++;
    }
    if (i<200)
    {
        vtable[i].number = i+1;
        strcpy(vtable[i].name, str);
        return vtable[i].number;
    }
    return 0;
}
int InsertConst(char *str)
{
    //如常数表中已有str常数,返回记录号,
    //否则将str加到常数表中,返回记录号
    int i = 0;
    while ((ctable[i].number!=0) && (i<200))
    {
        if (strcmp(str,ctable[i].name) == 0)
            return ctable[i].number;        
        i++;
    }
    if (i<200)
    {
        ctable[i].number = i+1;
        strcpy(ctable[i].name, str);
        return ctable[i].number;
    }
    return 0;
}
void ProcError()
{
    printf("%i 行有错误\n", lineno);
}
int Lex()
{
    //从扫描缓冲区中识别出一个单词,返回单词种别号,
    //构成的单词的符号串保留在strToken中,
    //单词的值保留在lvalue中。strToken和lvalue为全局变量。
    int code;
    char ch;

    memset(strToken, 0, 30);
    ch = GetBC();
    sp = ep-1;
    lvalue = 0;
    if (isLetter(ch))
    {
        while (isLetter(ch) || isDigit(ch))
        {
            Concat(strToken, ch);
            ch = GetChar();
        }
        Retract();
        code = Reserve(strToken);
        if (code == 0)
        {
            lvalue = InsertID(strToken);
            return $ID;
        }
        return code;
    }
    else if (isDigit(ch))
    {
        while (isDigit(ch))
        {
            Concat(strToken, ch);ch = GetChar();
        }
        Retract();
        lvalue = InsertConst(strToken);
        return $INT;
    }
    else if (ch == '=')
    {
        ch = GetChar();
        if (ch == '=')
            return $EQ;
        Retract();
        return $ASSIGN;
    }
    else if (ch == '+') return $PLUS;
    else if (ch == ';') return $SEMICOLON;
    else if (ch == '(') return $LPAR;
    else if (ch == ')') return $RPAR;
    else if (ch == '{') return $LBRACE;
    else if (ch == '}') return $RBRACE;
    else if (ch == '*')
    {
        ch = GetChar();
        if (ch == '*')
            return $POWER;
        Retract();
        return $STAR;
    }
    else if (ch == EOF) return $END;
    else
    {
        ProcError();
        return $END;
    }
}
void main()
{
    token aToken;
    int i = 0;
    char strName[256];
    FILE *fcon = fopen("const.txt","w+");
    FILE *ftoken = fopen("token.txt","w+");
    FILE *fsym = fopen("symbol.txt","w+");
    printf("请输入源文件名(enter结束):\n");
    scanf("%s",strName);
    fsrc = fopen(strName,"r");
    if (fsrc == NULL)
    {
        printf("找不到源文件src.txt\n");
        exit(1);
    }
    if ((ftoken == NULL) || (fcon == NULL) || \
        (fsym == NULL))
    {
        printf("不能创建输出文件const.txt,token.txt,symbol.txt\n");
        exit(1);   
    }
    /*读源文件入缓冲区*/
    while ((i<150) && ((inbuf[i]=fgetc(fsrc)) != EOF))
        i++;

    /*词法分析开始*/
    ep = 0;
    lineno = 1;
    aToken.label = 0;
    aToken.code = Lex();
    aToken.addr = lvalue;
    printf("单词序列:\n");
    while (aToken.code != $END)
    {
        //单词输出到文件
        fprintf(ftoken, "(%3d,%3d)", aToken.code, aToken.addr);
        //单词输出到屏幕
        printf("(%3d,%3d) ", aToken.code, aToken.addr);
        aToken.label++;
        aToken.code = Lex();
        aToken.addr = lvalue;
    }
   
    /*词法分析结束,输出符号表和常数表到symbol.txt、const.txt文件并显示在屏幕*/
    i = 0;
    printf("\n符号表:\n");
    while (vtable[i].number != 0)
    {
        fprintf(fsym, "(%3d,%s)", vtable[i].number, vtable[i].name);
        printf("(%3d,%s)", vtable[i].number, vtable[i].name);
        i++;
    }
    i = 0;
    printf("\n常数表:\n");
    while (ctable[i].number != 0)
    {
        fprintf(fcon, "(%3d,%s)", ctable[i].number, ctable[i].name);
        printf("(%3d,%s)", ctable[i].number, ctable[i].name);
        i++;
    }
    fclose(fsrc);
    fclose(fsym);
    fclose(fcon);
    fclose(ftoken);
    printf("\n词法分析结束,按任意键\n");
    getch();
}
搜索更多相关主题的帖子: 分析器 C语言 词法 
2009-11-12 13:33
快速回复:C语言做的词法分析器。。。请教高手
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025499 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved