• 词法分析


    我的博客

    要求

    输入:源程序文件
    输出:二元组(syn,token或sum)构成的序列(文件),其中:syn为单词种别码,token为存放的单词自身字符串,sum为整型常量。
    已知待分析的C语言子集的词法:
    1、关键字: main if else int while char 均为小写。
    2、专用符号: = + - * / < <= > >= == != ; , { } ( )
    3、其他标记ID和NUM通过以下正则式定义:

    ID: letter(letter|digit)*
    NUM: digit digit*
    letter→a|b|c|d…|z|A|B|C…|Z
    digit →0|1|2|3|4|5|6|7|8|9

    4、空格由空白、制表符、换行符组成,用来分隔ID、NUM、专用符号与关键字,词法分析阶段常被忽略。
    各种单词符号对应的种别码如下表:

    源程序

    程序中涉及两个文件:
    input.txt 程序测试数据
    output.txt 输出测试结果

    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    
    char TOKEN[20];
    char TABLE[6][10] = {{"main"},{"int"},{"char"},{"if"},{"else"},{"while"}};
    
    int lookup(char arr[]) {
        int i;
        for (int i = 0; i < 6; ++i) {
            if (!strcmp(arr,TABLE[i]))
                return i+1;
        }
        return 0;
    }
    // 扫描器
    void scanner(FILE* fp) {
        char ch, tmp;
        int i, c;
        FILE* wfp = fopen("output.txt","w");
    
        while (ch != EOF) {	// 一次循环即扫描一个词 
            i = 0;
            ch = getc(fp);
    
            if (isalpha(ch)){   // 字母开头 
                TOKEN[i++] = ch;
                while (isalpha(ch=getc(fp))|| isdigit(ch)) {
                    TOKEN[i++] = ch;
                }
                TOKEN[i] = '';
                fseek(fp,-1,1);
                c = lookup(TOKEN);
                if (c != 0)
                	fprintf(wfp,"(%d,%s)
    ",c,TOKEN);	// 关键字 
                else
                    fprintf(wfp,"(10,%s)
    ",TOKEN);  // 标识符 
            } else if (isdigit(ch)) {   // 数字开头 
                TOKEN[i++] = ch;
                while (isdigit(ch=getc(fp))) {
                    TOKEN[i++] = ch;
                }
                TOKEN[i] = '';
                fseek(fp,-1,SEEK_CUR);
                fprintf(wfp,"(20,%s)
    ",TOKEN);    // 数字
            } else {    // 其它符号开头 
                switch (ch) {
                    case ' ': break;
                    case '
    ': break;
                    case '	': break;
                    case EOF: break;
                    case '=': ch=getc(fp);
                        if (ch == '=') {
                        	fprintf(wfp,"(36,==)
    "); break;
    					}
                        else {
                        	fprintf(wfp,"(21,=)
    "); break;
    					} 
                    case '+': fprintf(wfp,"(22,+)
    "); break;
                    case '-': fprintf(wfp,"(23,-)
    "); break;
                    case '*': fprintf(wfp,"(24,*)
    "); break;
                    case '/': fprintf(wfp,"(25,/)
    "); break;
                    case '(': fprintf(wfp,"(26,()
    "); break;
                    case ')': fprintf(wfp,"(27,))
    "); break;
                    case '{': fprintf(wfp,"(28,{)
    "); break;
                    case '}': fprintf(wfp,"(29,})
    "); break;
                    case ',': fprintf(wfp,"(30,,)
    "); break;
                    case ';': fprintf(wfp,"(31,;)
    "); break;
                    case '>': ch=fgetc(fp);
                        if (ch == '=') {
                        	fprintf(wfp,"(34,>=)
    "); break;
    					}
                        else {
                        	fprintf(wfp,"(32,>)
    "); break;
    					}
                    case '<': ch=fgetc(fp);
                        if (ch == '=') {
                        	fprintf(wfp,"(35,<=)
    "); break;
    					}
                        else {
                        	fprintf(wfp,"(33,<)
    "); break;
    					}
                    case '!': tmp = ch;
    					ch=getc(fp);
                        if(ch == '=')
    					{
    						fprintf(wfp,"(37,!=)
    "); 
    						break;
    					}
    					else 
    					{
    						fprintf(wfp,"error:(0,%c)
    ",tmp); 
    						fseek(fp,-1,1);
    						break;
    					}
                    default:
                        fprintf(wfp,"error:(0,%c)
    ",ch); break;
                }
            }
        }
    	fclose(wfp); 
    }
    
    int main(){
        FILE* fp;
        char ch;
        if ((fp=fopen("input.txt","r")) == NULL){
            printf("文件打开错误!
    ");
            return 0;
        }
        scanner(fp);
        fclose(fp);
    
        return 0;
    }
    

    运行结果截图

  • 相关阅读:
    在jQuery ajax中按钮button和submit的区别分析
    jQuery学习-打字游戏
    AndroidManifest.xml权限大全
    判断数据连接----小程序
    ADB常用的几个命令
    Android的ADB配置环境和adb指令使用
    读懂Android项目结构目录
    Android四大组件
    多态继承
    匿名内部类
  • 原文地址:https://www.cnblogs.com/godfriend/p/11811123.html
Copyright © 2020-2023  润新知