精华内容
下载资源
问答
  • 语言语言 语言C语言
  • Go语言之所以被称为21世纪的C语言,不仅在于它精简的语法和高效的开发,更在于它具有原生支持和易于使用的高并发的特性。而越是简单的技术就越能够生成千变万化的组合。 《Go语言编程》首先引领读者快速浏览Go 语言...
  • 编译原理实验一(C-语言词法分析器的编写C语言版本) 1.词法规则 ①语言的关键字: else if int return void while 所有的关键字都是保留字,并且必须是小写。 ②专用符号: + - * / < <= > &...

     

     

    编译原理实验一(C-语言词法分析器的编写C语言版本)

    一、tiny词法分析程序源代码阅读笔记:

    重要变量和函数:

    ①变量和函数:

    A.要计算的唯一特性是词法或是被识别的记号的串值

    变量t o k e n S t r i n g

    B.扫描程序使用3个全程变量

    文件变量s o u r c e和l i s t i n g,整型变量l i n e n o

    C.存储当前行

     char lineBuf[BUFLEN];

    C.当前单词类型

     c u r r e n t T o k e n

    D.所要计算的唯一特性——词法或是被识别的记号的串值

    t o k e n S t r i n g

    E.标志变量被用作指示是否将一个字符增加到t o k e n S t r i n g之上

    s a v e

     F.完成位于由g e t T o k e n的主要循环识别的标识符之后的保留字的查找

    TokenType reservedLookup (char* s)

    G.进行词法分析,返回下一个合法单词的类型

    TokenType getToken(void)

    D.按格式打印一个单词

    void printToken( TokenType token, const char* tokenString )

    E.从行缓冲中输入下一个非空格字符,当行缓冲为空则输入下一行字符串。

    static int getNextChar(void)

     

    F.不读取下一个字符,在行缓冲中回退一个字符。

    static void ungetNextChar(void)

     

    ②数据结构

     

    A.状态类型(枚举)

    typedef enum

    { START,INASSIGN,INCOMMENT,INNUM,INID,DONE }

       StateType;

     

     

    B.单词类型(枚举)

    typedef enum{

    ENDFILE,ERROR,

        IF,THEN,ELSE,END,REPEAT,UNTIL,READ,WRITE,    ID,NUM,

    ASSIGN,EQ,LT,PLUS,MINUS,TIMES,OVER,LPAREN,RPAREN,SEMI

       } TokenType;

     

     

     

    C.保留字的查找表(结构体类型)

     

    static struct

        { char* str;

          TokenType tok;

        } reservedWords[MAXRESERVED]

       = {{"if",IF},{"then",THEN},{"else",ELSE},{"end",END},

          {"repeat",REPEAT},{"until",UNTIL},{"read",READ},

          {"write",WRITE}};

     

    有START,INASSIGN,INCOMMENT,INNUM,INID,DONE六个状态

    其状态转换图:

    总结:

    cifa词法分析程序的主要思路是:

    ①从主函数环境变量中获取输入文件的名称,并判断其是否存在

    ②循环调用getToken函数进行词法分析,直到函数返回值位ENDFILE即到达文件末尾

    ③getToken函数中的分析思路:

    1. 初始状态位START, tokenStringIndex 为0表示从输入字符串的第一个字符开始分析
    2. 调用getNextChar()来获取下一个位置的字符
    3. 在对应的状态下,根据字符的类型和DFA中的转换关系,得到当前词法单元的类型,并更新状态。
    4. 在分析过程中将每个字符保存到tokenString中。
    5. 直到状态STATE为DONE则该词法单元分析结束。tokenString中加入一个空字符表示词法单元的尾部。并且如果该词法单元为标识符则查找相应的保留字。

    二、C-词法分析器实验报告:

    1.C-词法规则

    语言的关键字

    else if int return void while

    所有的关键字都是保留字,并且必须是小写。

     

    专用符号

    + - * / < <= > >= == != = ; , ( ) [ ] { } /* */

     

    其他标记是I D和N U M,通过下列正则表达式定义:

    ID = letter letter*

    NUM = digit digit*

    letter = a|..|z|A|..|Z

    digit = 0|..|9

    小写和大写字母是有区别的。

     

    空格由空白、换行符和制表符组成。空格通常被忽略,除了它必须分开 I D、N U M关键字。

     

    注释用通常的C语言符号/ * . . . * /围起来。注释可以放在任何空白出现的位置 (即注释

    不能放在标记内)上,且可以超过一行。注释不能嵌套。

     

     

     

     

     

    整理:

    保留字

    特殊符号

    其他

    else

    +

     

     

     

     

     

     

    ID(letter letter* )

    letter = a|..|z|A|..|Z

     

    if

    -

    int

    *

    return

    /

    void

    <

    while

    <=

    >

    >=

    ==

    !=

    =

    ;

     

     

     

     

     

    NUM(digit digit*)

    digit = 0|..|9

     

    ,

    (

    )

    [

    ]

    {

    }

    /*

    /*

     

     

    1. DFA:

    ①注释状态转换图:

    ②专用符号、ID、NUM状态转换图:

    注意

    关键字

    除了数量减少以及关键词内容有所改变以外,关键字都是由字母小写构成,其中不添加其他符号,所以我们在关键字处理方式可以使用Tiny编译器的处理方式。

    ②专用符号

    1. tiny编译器的基础上,增添了有两个符号构成的符号,例如<=、>===、!=等,这需要在构建C-词法分析状态转换图时需要注意;
    2. <=是被当做小于等于而不是小于和等于两个词素的原因是我们默认遵循最长子串原则,其中具体构建方法见下一步。

    ③其他标记ID/NUM

    NUM只包括数字、ID只包括大小写字母,且字母区分大小写。

    ④注释:

    C-语言的注释前置符号和后置符号都又两个符号构成 ’/’ ’*’ ;处理该符号时需要注意。

     

    1. 代码实现:

    工程结构

    main.cpp   C-编译器的的主程序

    scan.c 实现C-编译器的扫描功能

    scan.h C-编译器的scan接口

    ①scan.h

    定义了单词类型、状态转换图中的状态名称、输入文件路径、打印分析过程的标记,

    声明了分析方法。

    #ifndef SCAN_H_INCLUDED
    #define SCAN_H_INCLUDED
    
    #define MAXRESERVED 6
    #define BUFLEN 256
    #define MAXTOKENLEN 40
    
    /**单词类型  */
    typedef enum
    {ENDFILE, ERROR,
        /** 保留字 */
        IF,ELSE,INT,RETURN,VOID,WHILE,
        /** 多字符单词的Token */
        ID,NUM,
        /** 特殊标记符 + - * / < > <= >= = ,  ; ( ) [ ] { } 注释符号左右 */
         ASSIGN,PLUS, MINUS, MULT, DIVI, LT, GT, LTE, GTE, DH, FH, EQ, NEQ, LSP, RSP,  LMP, RMP, LLP, RLP, LCOM, RCOM
    } TokenType;
    
    /** 状态名称*/
    typedef enum    { START, INNUM, INID, INGTE, INLTE , INEQ, INNEQ, NILCOM, INCOMMENT, INLCOM, INRCOM, DONE  } StateType;
    
    
    
    FILE* source; /** 源代码文件 */
    FILE* listing; /** 输出文件 */
    FILE* code; /* code text file for TM simulator */
    
    /**************************************************/
    /***********   Flags for tracing       ************/
    /**************************************************/
    
    /* EchoSource = TRUE causes the source program to
     * be echoed to the listing file with line numbers
     * during parsing
     */
    int EchoSource;
    /* TraceScan = TRUE causes token information to be
     * printed to the listing file as each token is
     * recognized by the scanner
     */
    int TraceScan;
    
    
    /*****************词法分析函数*****************************/
    TokenType getToken(void);
    
    
    #endif // SCAN_H_INCLUDED
    

     

    scan.c

    包含数据结构:

    static struct

        { char* str;

          TokenType tok;

        } reservedWords[MAXRESERVED]

      用一个结构体类型来描述保留字,str代表保留字的值,tok代表保留字类型。

     

    包含方法:

    static TokenType reservedLookup (char* s)

    查找某标识符是否为保留字,若为保留字则返回保留字类型

    char isAlpha(char c)

    判断c是否为字符

    char isDigit(char c)

    判断c是否为数字

    static int getNextChar(void)

    从输入缓冲中得到下一个字符

    static void ungetNextChar(void)

    在输入缓冲中回退一个字符

    void printToken( TokenType token, const char* tokenString )

    打印分析后的单词

    TokenType getToken(void)

    分析输入缓冲中的源代码,返回分析后的单词类型

     

    getToken的代码:

    /****************************************/
    /** 扫描器的主要方法 */
    /****************************************/
    /** 返回缓冲行中下一要分析的字符
     */
    TokenType getToken(void)
    {  
    
       /* index for storing into tokenString */
       int tokenStringIndex = 0;
       /* holds current token to be returned */
       TokenType currentToken;
       /* current state - always begins at START */
       StateType state = START;
       /* flag to indicate save to tokenString */
       int save;
       while (state != DONE){
         int c = getNextChar();
         save = 1;
         switch (state)
         { case START:
             if (isDigit(c))
               state = INNUM;
             else if (isAlpha(c)){
               state = INID;
             }
             else if (c == '>')
               state = INGTE;
             else if (c == '<')
               state = INLTE;
             else if (c == '=')
               state = INEQ;
             else if (c == '!')
               state = INNEQ;
             else if ((c == ' ') || (c == '\t') || (c == '\n') || (c == 13) )
               save = 0;
             else if (c == '/'){ 
    	   save = 0;
               state = INLCOM;
             }
             else
             { state = DONE;
               switch (c){ 
                  case EOF:
                   save = 0;
                   currentToken = ENDFILE;
                   break;
                 case '+':
                   currentToken = PLUS;
                   break;
                 case '-':
                   currentToken = MINUS;
                   break;
                 case '*':
                   currentToken = MULT;
                   break;
                 case ',':
                   currentToken = DH;
                   break;
                 case ';':
                   currentToken = FH;
                   break;
                 case '(':
                   currentToken = LSP;
                   break;
                 case ')':
                   currentToken = RSP;
                   break;
                 case '[':
                   currentToken = LMP;
                   break;
                 case ']':
                   currentToken = RMP;
                   break;
                 case '{':
                   currentToken = LLP;
                   break;
                 case '}':
                   currentToken = RLP;
                   break;
                 default:
                   currentToken = ERROR;
                   Error = 1;
                   break;
               }
             }
             break;
           case INLCOM://!    '/'
             if (c =='*'){//!  "/*"组合出现,表示注释,此时字符串不保存
                state = INCOMMENT;
                save = 0;
             }
             else{
                state = DONE;
                ungetNextChar();//!如果没有配对成功,表示为DIVI除法运算符号,并返回上一个符号
                currentToken = DIVI;
             }
             break;
           case INCOMMENT://!注释
             if (c == '*')
               state = INRCOM;
             break;
           case INRCOM://!可能为右注释
             if (c == '/'){//!注释结束
                state = DONE;
             }
             else//!否则返回注释状态
                state = INCOMMENT;
             break;
           case INID:
             if (!isAlpha(c))
             {
               ungetNextChar();
               save = 0;//!最后一个字符不重复保存
               state = DONE;
               currentToken = ID;
             }
             break;
           case INNUM:
             if (!isDigit(c))
             {
               ungetNextChar();
               save = 0;//!最后一个字符不重复保存
               state = DONE;
               currentToken = NUM;
             }
             break;
           case INGTE:
            if (c == '='){// >=
                state = DONE;
                currentToken = GTE;
             }
             else{
                state = DONE;
                ungetNextChar();//!如果没有配对成功,则是>
                currentToken = GT;
             }
             break;
           case INLTE:
            if (c == '='){// <=
                state = DONE;
                currentToken = LTE;
             }
             else{
                state = DONE;
                ungetNextChar();//!如果没有配对成功,表示为DIVI除法,并返回上一个符号
                currentToken = LT;
             }
             break;
           case INEQ:
            if (c == '='){// ==
                state = DONE;
                currentToken = EQ;
             }
             else{
                state = DONE;
                ungetNextChar();//!如果没有配对成功则为=
                currentToken = ASSIGN;
             }
             break;
           case INNEQ:
            if (c == '='){//! !=
                state = DONE;
                currentToken = NEQ;
             }
             else{//!不合法
                fprintf(listing,"Scanner Bug: state= %d\n",state);
                state = DONE;
                save = 0;
                ungetNextChar();//!如果没有配对成功,则单个字符!不合法ERROR
                currentToken = ERROR;
                Error = 1;
             }
             break;
           case DONE:break;
           default: /* should never happen */
             fprintf(listing,"Scanner Bug: state= %d\n",state);
             state = DONE;
             currentToken = ERROR;
             Error = 1;
             break;
         }
         if ((save) && (tokenStringIndex <= MAXTOKENLEN))
           tokenString[tokenStringIndex++] = (char) c;
         if (state == DONE){
                tokenString[tokenStringIndex] = '\0';
                if (currentToken == ID)//! 如果是标识符则判断是否为保留字(查表)
                    currentToken = reservedLookup(tokenString);
         }
       }
    
      // if (TraceScan) {
         fprintf(listing,"\t%d: ",lineno);
         printToken(currentToken,tokenString);
      // }
       return currentToken;
    } /* end getToken */
    

     ③main.c主函数

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "scan.h"
    int main(int argc, char * argv[] )
    {
        char pgm[120]; /* source code file name */
        if (argc != 2)
        { fprintf(stderr,"usage: %s <filename>\n",argv[0]);
          return 0;
        }
        strcpy(pgm,argv[1]) ;
        source = fopen(pgm,"r");
        if (source==NULL){
            fprintf(stderr,"File %s not found\n",pgm);
            return 0;
        }
        listing = stdout; /**输出结果到屏幕 */
        fprintf(listing,"\nC- COMPILATION: %s\n",pgm);
        while (getToken()!=ENDFILE);
        return 0;
    }
    

     

    1. 测试

    ①正例:

    ②反例(其中!和float是没有定义的专用符号或关键字)

    • 总结与心得

    1.总结

    实现词法分析设计的主要工作:

    (1)从源程序文件中读入字符。

    (2)统计行数和列数用于错误单词的定位。

    (3)删除空格类字符,包括回车、制表符空格。

    (4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token 的机内表示)

    (5)如果发现错误则报告出错

    2.心得

    (1)本次实验最主要的是通过对源代码进行分析得到一个个的单词,通过编程实现后对词法分析这一过程更加的熟悉了。

    (2)实验过程中第一个问题是源代码的输入。解决方式:利用文本文件txt以字符串的形式存储代码,利用fgets等c语言函数进行代码的逐行读取,并分析。

    (3)实验过程分析出“注释”后,打印时打印出“Unknown token”和toekn值,后来改成了打印“Unknown token”和toeknString,也就是其值

    (4)实验中回车(13)一开始没有处理,导致识别出ERROR,但是也打印不出来,这里花费的时间比较多,后来把回车和空格,换行符,制表符在一起进行判断,并将save置为0,不保存该字符。

    (5)输入源代码样式有待进一步测试

    展开全文
  • c语言编写的C-编译器,词法分析 语法分析 语义分析 代码生成都有,也能完成对C-语言的编译
  • 经过了多年的发展,各种新兴的编程语言都在不断产生,但是,作为基础的C语言一直没有被人们遗忘。 C语言是由C语言之父–Dennis M Ritchie(丹尼斯·里奇)创造出来的。虽然从1972年到现在以及有快50年时间,但是,...

    经过了多年的发展,各种新兴的编程语言都在不断产生,但是,作为基础的C语言一直没有被人们遗忘。
    C语言是由C语言之父–Dennis M Ritchie(丹尼斯·里奇)创造出来的。虽然从1972年到现在以及有快50年时间,但是,C语言仍然活跃在各种编程软件,各种软件公司中。
    这里写图片描述
    虽然过了这么多年时间,但是还是非常受欢迎。
    为什么会这样呢。因为C语言有着很多优点。
    首先它是一种高级语言,可以将高级语言基本结构和低级语言实用性结合起来。其次,是一种可以跨平台运行的语言,C语言活跃于各种操作系统,无论是window,linux都可以看到C语言的踪影。
    另外,还有下面的一些其他的优点。

    1. 简洁紧凑,灵活方便。
    2. 运算符丰富。
    3. 数据类型丰富。
    4. 生成的代码质量高,程序执行效率较高。

    当然,C语言还有其他的一些优点,我就不一一列举了。
    经过的几十年的发展,C语言也经过了很多的标准更替。从最开始的K&R,再到ANSI通过的C89标准,再到99年ISO和IEC共同发表的ISO/IEC 9899:1999 - Programming languages – C,简称C99标准。
    最后在2011年通过了ISO/IEC 9899:2011 - Information technology – Programming languages – C 这一标准。
    这一套又一套的标准的出现,也为C语言赋予了新的生命。所以C语言仍然焕发着蓬勃的生机。

    作为任何一个编程人员,都应该首先熟悉C语言,学习了C语言之后,对我们学习其他的语言起着不可磨灭的影响。所以,C语言是编程语言的基础。

    本文共530字。

    展开全文
  • 基于Lex的-语言自动词法分析器

    热门讨论 2010-04-28 11:36:14
    基于Lex的-语言自动词法分析器是由 Parser Generator软件实现的,我所做的只是编写Lex输入文件scan.l 和Parser Generator的输入文件source.txt,然后通过Parser Generator编译生成具体的C语言的词法分析器。
  • 自制编程语言-基于c语言的源码,源代码是在linux平台下开发的,修改了一些代码,移植到windows平台下面,vs2013编译通过,算是给windows平台下的朋友提供一点福利
  • c语言---java

    2018-09-01 12:14:00
    c语言语言给java程序师的
  • C语言--视频精讲

    2021-06-08 18:17:22
    C语言作为被长期使用的编程语言,可以被运用到各种操作系统,游戏,开发中。本课程作为互联网上首家使用C99录制的C语言教程,展现了全面、专业。标准的C语言教程。可以帮助学员从基础开始一点点的深刻理解C语言
  • C语言------100-200的素数,且每5个换一行 运行结果

    C语言------100-200的素数,且每5个换一行

    在这里插入图片描述
    在这里插入图片描述
    运行结果
    在这里插入图片描述

    展开全文
  • C语言是一种低级(low-level)语言. 可不是说C语言

           C语言是一种相对于其它语言要低级(low-level)语言.偷笑 可不是说C语言的能力不强,说的是C语言写出的来东西,更接近机器真正懂的。

    计算机只懂得一种语言:机器语言。(由0,1组成的二进制流) binary stream


    几步曲:

    1.在任何一个编辑器中,写代码:

       rock.c

    2.用gcc将其编译成机器语言:

       gcc rock.c -o rock

    3.在mac或者是linux机器上面: 

       ./rock

    就会运行程序。

    后两步:(二合一)

       gcc rock.c -o rock && ./rock


    ****************

    首先编写源文件: hello.c

    预处理命令:  gcc -o hello.i  hello.c  -E   (由hello.c----> hello.i)
    编译:           gcc -o hello.s hello.i  -S    (由hello.i----->hello.s)
    汇编:           gcc -o hello.o hello.s        (由hello.s----->hello.o)
    链接:           gcc -o hello hello.c           (由hello.o------> hello可执行)




    展开全文
  • c语言--windows文件夹选择对话框--windows api--SHBrowseForFolder
  • C语言-----VS2008建立C工程

    千次阅读 2012-06-09 11:35:23
    如何在vs2008中建立C语言工程并运行。 1.新建Win32工程 2.选择空项目 3.新建--->文件---》文本文件 4.保存文件为.c文件 转载请注明出处:奔跑的蜗牛(袁方的技术博客) 5.在文件右键-...
  • C语言---打砖块源代码

    2020-11-21 12:53:44
    C打砖块源代码,适合初级C语言学习的朋友参考练习,对编写小程序有一定帮助,希望能对C语言爱好者有所帮助。
  • 1.3 C 语言学习内容;程序 ;1.4 计算机语言概述;3.常用的高级语言;4.C语言;1.5 语言的特点;1.6 简单的C程序介绍?例2? void main( ) /*求两个数的和*/ { int a,b,sum; a=123;b=456 sum=a+b; printf(sum=%d\n,sum; } ;...
  • C语言---“C语言 谁与争锋?”

    千次阅读 2012-09-08 09:18:49
    C语言现在还是第一,这是为什么,我个人感觉主要来自“冯式计算机”的主流计算机体系结构,PC、移动,电信网络,C与它们系统层0距离的现状,这样C不坚挺才怪呢。 还有部分归为开源社区的兴起。
  • C语言---编译器、编辑器

    千次阅读 2019-10-17 14:00:11
    相信很多C语言方面的书籍开篇都是先讲C语言的历史什么的,但是我觉得应该对学习C语言所使用安装的各种“软件”进行一个讲解和说明, 了解C语言的环境,这对于学习C语言也是很重要的. 1、GCC中的C语言编译器 ...
  • C语言-----有参数的main函数

    万次阅读 多人点赞 2018-04-18 19:18:25
    我们学习C语言的时候,用到的第一个函数应该就是main函数了吧,大多数情况下看到的都是没有参数的int main(void),今天我们来深入解析一下有参数并且带有三个参数的main函数。编译器为vs2013。int main(int argc,...
  • /* 计算机发展史 1,电子管计算机 2,晶体管计算机 3,中小型规模集成电路计算机 4,大规模和超大规模集成电路计算机--微型计算机 ...4,高级语言--c语言,c++,java,pythy,php脚本语言 计算机的组成--计...
  • 这个教程只是为初学或入门者准备的。使用 C 语言肯定要使用到C 编译器,以便把写好的C 程序编译为机器码,使用KEIL51 软件作为调试软件。
  • C语言----斐波那契数的n种实现方法

    万次阅读 多人点赞 2018-10-09 20:02:44
    斐波那契数列(Fibonacci):第1...第三个数为前两两个数之和,定义第三个变量cc=a+b;现在有三个数,为了避免冗余,把第二个数的值赋给a,第三个数的值赋给b,c=a+b得到第四个数,以此类推… #define _CRT_SECU...
  • C语言----取反~

    千次阅读 2014-11-29 15:00:00
    一、正数 (1)执行~0001后 为1110(内存中就是这样存储0001取反的结果的) ... printf("a=%d,b=%d,c=%d,d=%d\n",~a,~b,~c,~d); }   转载于:https://www.cnblogs.com/ZhangYuGe/p/4130962.html
  • json解析、构筑。项目语言c语言。。。。。
  • C 语言程序设计之 函数教学设计 贵州交通技师学院 张 红 C 语言程序设计之 函数教学设计 教材 教材C 语言程序设计实训教程 主编康英健出版社海军出版社 中职中专教材 教学内容分析 函数是 C 语言程序设计中非常重要...
  • 机器语言->汇编语言->高级语言->面向过程(C) / 面向对象(C++ java C#);   C语言的特点: 优点:代码量小、速度快、功能强大 所以操作系统基本上都是用C语言写的:windows 内核C语言 外核C++语言、...
  • 汉语编程、中文编程、国产C语言编译器-习语言4714(2016)版 是最新的习语言版本。 方便友好的界面, 全兼容C语言的特性, 是学习C语言的好帮手, 是提升代码可读性的好工具。 习语言界面: ...
  • 中国大学生MOOC-翁恺C语言-学习笔记(一)
  • 1. 任何表达式语句都是表达式加分号组成的。 (T) 2. 增1减1运算符的前缀运算和后缀运算的表达式值是相同的。 (F) 3. C语言程序是从源文件的第一条语句开始执行的。...C 语言中的变量名不区分大小写。 (F) ...
  • C语言--文件重命名

    千次阅读 2018-12-29 21:51:06
    函数rename()用于重命名文件、改变文件路径或更改目录名称,其原型为 int rename(char * oldname, char * newname);  【参数】oldname为旧文件名,newname为新文件名。  【返回值】修改文件名成功则返回0,否则...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,108,961
精华内容 843,584
关键字:

c-语言