天天看点

编译原理学习(一)词法分析器

一. 实验目的

  1. 理解词法分析器的工作原理。
  2. 掌握利用状态转换图设计词法分析器的基本方法。
  3. 实现Micro语言的词法分析程序

二. 实验内容

根据给出的Micro语言的定义,设计并实现它的的词法分析器,实现源程序的输入、 预处理和词法分析,最后以编译程序需要的内部表示形式(二元组)将识别的 单词符号输出。 利用状态转换图设计Micro语言的词法规则。 用C语言实现该语言词法分析程序

三. 实验步骤

  1. Micro语言的定义

     仅有的数据类型是整型INT。

     所有的标识符采用显式声明,且长度不超过32个字符。标识符必须以字母开头并由字母、数字和下划线组成。

     整型常量由一串数字组成。

     注释由“–”开始,并在当前行尾结束。

     语句类型为:

     赋值语句:

    ID := Expression;

    Expression是由标识符、文字常量、+ - * / 运算符组成的中缀表达式结构,其中允许含有括号。

     输入输出语句:

    read( List of IDs);

    write(List of Expressions);

     begin、end、read、write、INT都是保留字。

     每条语句以分号(;)结束。程序体由begin和end界定。

     词法记号不能跨行。

    编译原理学习(一)词法分析器
    编译原理学习(一)词法分析器

四、代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char    *key_word[] = { "int", "begin", "end", "read", "write" };
int i = , j = , k = , t = ; // 搜索指示器
#define BUFFERSIZE  1000


char    ch;         // 存放最新读入的源程序字符
char    str_token[];      // 存放构成单词符号的字符
char    *char_form[];    // 字符表
char    *int_form[];     // 常数表
char    form[BUFFERSIZE];
int     q = ;
int     temp;
FILE    *fp;

// 常用语句的宏定义
#define GET_CHAR    ch = form[k]; k++;          // 将下一个字符读到ch,搜索指示器 前移一个字符位置
#define GET_BC      while(ch == ""){    GET_CHAR;}  // 检查ch字符是否为空白。是的话调用get_char
#define CONCAT      str_token[i] = ch;  i++;        // 链接字符


//判断是否为字母 
int isLetter()
{
    if (((ch <= 'z') && (ch >= 'a')) || ((ch <= 'Z') && (ch >= 'A')))
        return ();
    else
        return ();
}

//判断是否为数字 
int isDigit()
{
    if ((ch >= '0') && (ch <= '9'))
        return ();
    else
        return ();
}

//判断是否为关键字
int reserve()
{
    int q = ;
    for (q = ; q<; q++){
        if (strcmp(str_token, key_word[q]) == )
            return q;
    }
    return -;
}

//函数回调  
void retract() //将搜索指示器回调一个字符位置,将ch置为空白字符 
{
    k--;
    ch = NULL;
}

//将strToken中的标识符插入符号表,返回符号表指针 
char *insertId()
{
    char_form[j] = str_token;
    j++;
    return char_form[];
}

//将strToken中的常数插入常数表,返回常数表指针 
char *inserConst()
{
    int_form[t] = str_token;
    t++;
    return int_form[];
}

//词法分析器的构造 
int code;
void scanner()
{
    for (i = ; i<; i++)
        str_token[i] = NULL;
    i = ;
    GET_CHAR;
    GET_BC;
    printf("这是一个 ");
    if (isLetter()){
        while (isLetter() || isDigit()){
            concat();
            GET_CHAR;
        }
        retract();
        code = reserve();
        switch (code){
        case -:
            printf("字符串 %s\n", &str_token);
            break;
        default:
            printf("关键字 %s\n", &str_token);
            break;
        }
    }

    else if (isDigit()){
        while (isDigit()){
            concat();
            GET_CHAR;
        }
        retract();
        printf("运算符 %s\n", &str_token);
    }
    else if (ch == '='){
        printf("运算符 =%s\n", &str_token);
    }
    else if (ch == '+'){
        printf("运算符 +%s\n", &str_token);
    }
    else if (ch == '-'){
        printf("运算符 -%s\n", &str_token);
    }
    else if (ch == ';'){
        printf("界符 ;%s\n", &str_token);
    }
    else if (ch == '('){
        printf("界符 (%s\n", &str_token);
    }
    else if (ch == ')'){
        printf("界符 )%s\n", &str_token);
    }
}

void main() {
    int n = ;
    fp = fopen("C:\\Users\\MySHworks\\Desktop\\test.txt", "r");
    while(fgets(form, , fp) != NULL){
        k = ;
        while (form[k] != '\0')
            scanner();
    }
    system("pause");
    fclose(fp);
}
           

五、心得

  词法分析的主要任 务是:根据构造的状态转换图,从左到右逐个字符地対源程序进行扫描,识别的最小语法单位——符号或单词,如变量标识符,关键字,常量,运算符,界符等。然后将提取出的标识符以内码的形式表示,即用int类型的数字来表示其类型和在display表中的位置,而无须保留原来标识符本身的字符串,这不仅节省了内存空间,也有利于下一阶段的分析工作。通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,使用某种高级语言(例如C++语言)直接编写此法分析程序。另外,也让我重新熟悉了C++语言的相关内容,加深了对C++语言的用途的理解。

继续阅读