编译原理 - 词法分析实验

实验要求:
借助flex工具实现一个词法分析器,识别出SysY代码中的所有终结符,然后按照单词符号出现顺序依次输出: 原始单词符号、该符号出现的行数、该符号出现的列数起始与终止位置。

实验方法:
主要采用了穷举标识符的方式进行识别,其他数字类内容采用了正则表达式进行识别,通过检测换行符维护当前行数,通过全局变量判断当前识别内容是否位于注释范围内,如果被注释掉了则输出fake标记

flex代码如下:

%option noyywrap
%{

#include <stdio.h>
#include <stdlib.h>
long long line_num=1;
long long col_num=1;
long long My_yylineno=1;
long long old_My_yylineno=1;
int isLineAnno=0;
int isPartAnno=0;

%}



%%
     /*快乐标识符*/
auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno || isPartAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
        printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    col_num += strlen(yytext);
    }


     /*快乐变量名*/
[a-zA-Z_][a-zA-Z0-9_]* {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno || isPartAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
        printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    col_num += strlen(yytext); 
    }


     /*快乐整数常量*/
[-+]?[1-9][0-9]* {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno || isPartAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
        printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    col_num += strlen(yytext);
    }

     /*不快乐的八进制数*/
0[0-7]+ {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno || isPartAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
        printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    col_num += strlen(yytext);
    }

     /*不快乐的十六进制数*/
0x[0-9a-fA-F]+ {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno || isPartAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
        printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    col_num += strlen(yytext);
    }

     /*快乐小数常量*/
[-+]?[0-9]+\.[0-9]*|\.[0-9]+ {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    } 
    if(isLineAnno || isPartAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
        printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    col_num += strlen(yytext);
    }


     /*快乐科学计数法*/
[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)? {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno || isPartAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
        printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    col_num += strlen(yytext);
    }


     /*快乐字符串*/
\"(\\.|[^\\"])*\" {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno || isPartAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
        printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    col_num += strlen(yytext);
    }


     /*快乐运算符*/
"=="|"+"|"-"|"*"|"/"|"="|"<"|">"|"!"|"&&"|\|\||","|";"|"("|")"|"{"|"}"|"["|"]" {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno || isPartAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
        printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    col_num += strlen(yytext);
    }

     /*行注释*/
\/\/ {
    {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
    {
        if(isPartAnno)
        {
            isPartAnno = 1;
            printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
        }
        else
        {
            isLineAnno =1;
            printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
        }
    }
    col_num += strlen(yytext);
    }
    }

     /*开始注释*/
\/\* {
    {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
    {
        if(!isPartAnno)
        {
            isPartAnno = 1;
            printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
        }
        else
        {
            printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
        }
    }
    
    col_num += strlen(yytext);
    }
    }

     /*结束注释*/
\*\/ {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno)
        printf("%s \t\t %d \t %d \t %d - Fake\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
    else
    {
        if(isPartAnno)
        {
            isPartAnno = 0;
            printf("%s \t\t %d \t %d \t %d\n", yytext, My_yylineno, col_num,col_num + strlen(yytext));
        }
        else
        {
            printf("Part Annotation error-No start but finish\n");
            exit(1);
        }
    }
    
    col_num += strlen(yytext);
    }


     /*换行*/
[\n] {
    isLineAnno = 0;
    printf("n");
    My_yylineno++;
    }

     /*制表符*/
[\t] {
    printf("%s \t %d \t %d - t\n", yytext, My_yylineno, col_num);
    My_yylineno++;
    }

    

    /*不认识你*/
. {
    if(My_yylineno>old_My_yylineno)
    {
        col_num=1;
        old_My_yylineno=My_yylineno;
    }
    if(isLineAnno || isPartAnno)
        printf("%s(Fake)\n", yytext);
    else
        printf("%s", yytext);
    col_num += strlen(yytext);
    }

%%

int main(int argc, char *argv[]) {
    
    while(1)
    {
        int ijk=-1;
        printf("Please input which one do you want, 0 for example.sy, i for i.sy\n");
        scanf("%d",&ijk);

        FILE *file = NULL;
        switch(ijk)
        {
            case 0:
                file = fopen("example.sy", "r");
                break;

            case 1:
                file = fopen("test-cases\\1.sy", "r");
                break;

            case 2:
                file = fopen("test-cases\\2.sy", "r");
                break;

            case 3:
                file = fopen("test-cases\\3.sy", "r");
                break;

            case 4:
                file = fopen("test-cases\\4.sy", "r");
                break;

            case 5:
                file = fopen("test-cases\\5.sy", "r");
                break;

            case 6:
                file = fopen("test-cases\\6.sy", "r");
                break;

            default:
                printf("swtich file error");
                exit(1);
        }


        
        printf("\n------------------Now Starting case %d-------------------\n\n",ijk);
        printf("What \t\t Line \t Col_Start \t Col_Finish\n");
        line_num=1;
        col_num=1;
        My_yylineno=1;
        old_My_yylineno=1;
        isLineAnno=0;
        isPartAnno=0;

        if (file == NULL) 
        {
            printf("Failed to open the file in %d.\n",ijk);
            exit(1);
        }

        yyin = file;
        yylex();
    }

    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值