0916 编程实验一 词法分析程序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define _KEY_WOED_END "waiting for your expanding"
 
typedef struct
{
    int typenum;
    char * word;
}WORD;

char input[255];  
char token[255] = ""; 
int p_input;      
int p_token;     
char ch;        
 
char * rwtab[] = {"begin", "if", "then", "while", "do", "end", _KEY_WOED_END};        
WORD * scaner();
 
int main()
{
    int over = 1;
    WORD *oneword;
    oneword=(WORD *)malloc(sizeof(WORD));

    printf("input words:");
    scanf("%[^#]s",input);                    
    p_input=0;
    printf("您输入的字符串是:%s\n\n",input);
    while(over < 1000 && over != -1)
    {
        oneword = scaner();
        printf("(%d,%s)\n",oneword->typenum,oneword->word);
        over = oneword->typenum;
    }
}
 
char m_getch(){
    ch=input[p_input];
    p_input=p_input+1;
    return (ch);
}

void getbc()
{
    while(ch==' '||ch==10){
    ch=input[p_input];
    p_input=p_input+1;
    }
}

void concat()
{
    token[p_token]=ch;
    p_token=p_token+1;
    token[p_token]='\0';
}

int letter()
{
    if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')return 1;
    else return 0;
}
 
int digit()
{
    if(ch>='0'&&ch<='9')
        return 1;
    else
        return 0;
}

int reserve()
{
    int i=0;
    for(i=0;i<7;i++)
    {
        if(!strcmp(rwtab[i],token))
        {
            return i+1;
        }
        i=i+1;
    }
    return 10;
}
 
void retract()
{
    p_input=p_input-1;
}
 
WORD * scaner()
{
    WORD * myword;
    myword = (WORD *)malloc(sizeof(WORD));
    myword->typenum = 10;
    myword->word = "";
    p_token=0;
    m_getch();
    getbc();
    if(letter())
    {
        while(letter()||digit())
        {
           concat();
           m_getch();
         
        }
        retract();
        myword->typenum=reserve();
        myword->word=token;
        return(myword);
    }
    else if(digit())
    {
        while(digit())
        {
            concat();
            m_getch();
        }
        retract();
        myword->typenum=20;
        myword->word=token;
        return(myword);
    }
    else
    {
        switch(ch)
        {
        case '=':m_getch();
            if(ch=='=')
            {
                myword->typenum=39;
                myword->word="==";
                return(myword);
            }
            retract();
            myword->typenum=21;
            myword->word="=";
            return(myword);
            break;
        case '+':
            myword->typenum=22;
                myword->word="+";
                return(myword);
                break;
        case '-':
            myword->typenum=23;
                myword->word="-";
                return(myword);
                break;
        case '*':
            myword->typenum=24;
            myword->word="*";
            return(myword);
            break;
        case '/':
            myword->typenum=25;
            myword->word="/";
            return(myword);
            break;
        case '(':
            myword->typenum=26;
            myword->word="(";
            return(myword);
            break;
        case ')':
            myword->typenum=27;
            myword->word=")";
            return(myword);
            break;
        case '[':
            myword->typenum=28;
            myword->word="[";
            return(myword);
            break;
        case ']':
            myword->typenum=29;
            myword->word="]";
            return(myword);
            break;
        case '{':
            myword->typenum=30;
            myword->word="{";
            return(myword);
            break;
        case '}':
            myword->typenum=31;
            myword->word="}";
            return(myword);
            break;
        case ',':
            myword->typenum=32;
            myword->word=",";
            return(myword);
            break;
        case ':':
            myword->typenum=33;
            myword->word=":";
            return(myword);
            break;
        case ';':
            myword->typenum=34;
            myword->word=";";
            return(myword);
            break;
        case '>':
            myword->typenum=35;
            myword->word=">";
            return(myword);
            break;
        case '<':
            myword->typenum=36;
            myword->word="<";
            return(myword);
            break;
        case '!':
            m_getch();
            if(ch=='=')
            {
                myword->typenum=40;
                myword->word="!=";
                return(myword);
            }
            retract();
            myword->typenum=-1;
            myword->word="ERROR";
            return(myword);
            break;
        case '\0':
            myword->typenum=1000;
            myword->word="OVER";
            return(myword);
            break;
        default:
            myword->typenum=-1;
            myword->word="ERROR";
            return(myword);
            }
        }
    }

 

转载于:https://www.cnblogs.com/shuaibi/p/4827013.html

⒈ 题目 编写前述PASCAL子集的词法分析程序。 1)主程序设计考虑,(参阅后面给出的程序框架) 主程序说明部分为各种表格和变量安排空间。 数组k为关键字表,每个数组元素存放一个关键字。采用定长的方式,较短的关键字后面补空格。 P 数组存放分界符。为了简单起见,分界符、算术运算符和关系运算符都放在p表中(学生编程时,应建立算术运算符表和关系运算符表,并且各有类号),合并成一类。 id 和ci 数组分别存放标识符和常数。 instring 数组为输入源程序的单词缓存。 outtoken 记录为输出内部表示缓存。 还有一些为造表填表设置的变量。 主程序开始后,先以人工方式输入关键字,造 k 表;再输入分界符等造 p 表。 主程序的工作部分设计成便于调试的循环结构。每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。 2)词法分析过程考虑 该过程取名为 lexical,它根据输入单词的第一个字符(有时还需读第二个字符),判断单词类,产生类号:以字符k表示关键字;i表示标识符;c 表示常数;p 表示分界符;s 表示运算符(学生编程时类号分别为1,2,3,4,5)。 对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组 id 中,将常数变为二进制形式存入数组中 ci 中,并记录其在表中的位置。 lexical 过程中嵌有两个小过程:一个名为 getchar,其功能为从 instring 中按顺序取出一个字符,并将其指针 pint 加 1 ;另一个名为 error,当出现错误时,调用这个过程,输出错误编号。 将词法分析程序设计成独(入口)立一遍扫描源程序的结构。其流程图见图5-1。 图5-1 词法分析程序流程图 ⒉ 要求 ⑴ 所有识别出的单词都用两个字节的等长表示,称为内部码。第一个字节为 t ,第二个字节为 i 。 t 为单词的种类。关键字的 t=1;分界符的 t=2;算术运算符的 t=3;关系运算符的 t=4;无符号数的 t=5;标识符的 t=6。i 为该单词在各自表中的指针或内部码值。表 5-1 为关键字表;表 5-2 为分界符表;表 5-3 为算术运算符的 i 值;表 5-4 为关系运算符的 i 值。 表5-1 关键字表 表5-2 分界符表 指针1 关键字 指针1 分界符 0 BEGIN 0 , 1 DO 1 ; 2 ELSE 2 . 3 END 3 := 4 IF 4 ( 5 THEN 5 ) 6 VAR 7 WHILE 表5-3 算术运算符 表5-4 关系运算符 i 值 算术运算符 i 值 关系运算符 00H < 10H + 01H 21H / 04H >= 05H 常数表和标识符表是在编译过程中建立起来的。其 i 值是根据它们在源程序中出现的顺序确定的。 ⑵ 常数分析程序、关键字和标识符分析程序、其他单词分析程序请参阅范例自行设计。 ⑶ 本实践题可通过扩充下面给出的程序框架完成。 PROGRAM plexical(input,output); LABEL l; CONST keylen=10; identlen=10; TYPE //定义的类型 tstring=ARRAY[1..identlen] OF char; outreco=RECORD//记录为输出内部表示缓存。 ty: char; point: integer; END; {outreco} VAR cip,ip,pint,i,j,l,m,errorx:integer; charl:CHAR; ci:ARRAY[1..10] OF integer; k,id:ARRAY[1..keylen] OF tstring; token:tstring; //标志符 outtoken:outreco; instring:ARRAY[1..10]OF char; p:ARRAY[1..16] OF ARRAY [1..2] OF char; PROCEDURE lexical; VAR l,m,num:integer; b: boolean; PROCEDURE
实验一  手工构造简单词法分析程序(必修) 一、实验目的 了解词法分析程序的基本构造原理,掌握简单词法分析程序手工构造方法。 二、实验内容 对从键盘输入或从文件读入的形如: “const count=10,sum=81.5,char1=’f’,string1=”hj”, max=169;”的常量说明进行处理,分析常量说明串中各常量名、常量类型及常量值,并统计各种类型常量个数。 三、实验要求 1、输入的常量说明串,要求最后以分号作结束标志; 2、根据输入串或读入的文本文件中第一个单词是否为“const”判断输入串或文本文件是否为常量说明内容; 3、识别输入串或打开的文本文件中的常量名。常量名必须是标识符,定义为字母开头,后跟若干个字母,数字或下划线; 4、根据各常量名紧跟等号“=”后面的内容判断常量的类型。其中:字符型常量定义为放在单引号内的一个字符;字符串常量定义为放在双引号内所有内容;整型常量定义为带或不带+、- 号,不以0开头的若干数字的组合;实型常量定义为带或不带+、- 号,不以0开头的若干数字加上小数点再后跟若干数字的组合; 5、统计并输出串或文件中包含的各种类型的常量个数; 6、以二元组(类型,值)的形式输出各常量的类型和值; 7、根据常量说明串置于高级语言程序中时可能出现的错误情况,模仿高级语言编译器对不同错误情况做出相应处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值