Lex教程

1. Lex: 一种词法生成器

lex全称lexical analyzar 英文描述是 a scanner generator简单的来说,他讲一串字符串,拆分成单独的单词,并根据指定的正则来调用相应的宏,换句话说就是我们常说的保留字,lex就是去扫描里面有没有符合保留字的词,所以说是scanner,这个最中生成的c程序.

  • 根据正则规则,将输入的语法进行分割

  • yylex():

    • 将输入的流文件和正则规则进行匹配
    • 如果发现有匹配成功的,触发相关的动作
  • lex文件的结构

    • # 第一部分
      definition 初始化定义相关参数  选填
      # 第二部分
      %%
      Rules 必填
      
      #第三部分
      %%
      user subroutines 用户定义的子程序 选填
      
      
    • rule的规则: <reg.exp>

      • reg.exp: 从这一行开始到出现第一个未转义的空格结束
      • action: 当行c命令,多行的命令使用{}包起来
      • 未被匹配到字符串会被复制一份输出出去
  • lex的正则表达式:

    • 运算符:\ [ ] ˆ - ? . * | ( ) $ / { } % < >
    • 字母和数字匹配他们本身
    • .点匹配所有字符串,除了换行
    • [] 中括号里包含一些列的字符
      • 里面可以是任意字符串
      • -表示一个范围
    • ^ 表示否定,[^0-9]表示开始不能以数字开头
    • 使用引号字符时需要使用在转义字符\
    • \n, \t 代表换行, 缩进
    • () 表示一组数据
    • | 表示或关系
    • * 表示0个或更多
    • + 表示一个或者更多
    • ? 表示0个或一个
  • 在匹配的结果中有多个结果符合筛选条件时,lex会优先选择匹配字符最长的

  • 在匹配结果有多个并且字符数量一致的情况下,第一个出现的优先

  • 与自定义程序间进行通讯:

    • yytext 这是一个字符串数组,里面装着匹配好的数据

      [a-z][a-z0-9_]* printf("ident: %s\n", yytext);
      
    • yyleng 匹配到的字符长度

      //Counting the number of words in a file and their total size:
      [a-zA-Z]+ {nwords += 1; size += yyleng;}
      
  • lex中关于资源的处理:

    • 未被lex匹配到的资源,都会复制一份到编译后的c程序里面
    • 任何不适定格写的,并且不是在%{ ... %}包裹的,都会被赋值进编译好的c程序中(lex.yy.c).
  • lex中内置的变量和函数:

    • 变量

      yyin FILE* 类型。 它指向 lexer 正在解析的当前文件。
      yyout FILE* 类型。 它指向记录 lexer 输出的位置。 缺省情况下,yyin 和 yyout 都指向标准输入和输出。
      yytext 匹配模式的文本存储在这一变量中(char*)。
      yyleng 给出匹配模式的长度。
      yylineno 提供当前的行数信息。 (lexer不一定支持。)
    • 函数:

      yylex() 这一函数开始分析。 它由 Lex 自动生成。
      yywrap() 这一函数在文件(或输入)的末尾调用。 如果函数的返回值是1,就停止解析。 因此它可以用来解析多个文件。 代码可以写在第三段,这就能够解析多个文件。 方法是使用 yyin 文件指针(见上表)指向不同的文件,直到所有的文件都被解析。 最后,yywrap() 可以返回 1 来表示解析的结束。
      yyless(int n) 这一函数可以用来送回除了前n? 个字符外的所有读出标记。
      yymore() 这一函数告诉 Lexer 将下一个标记附加到当前标记后。
posted @ 2020-11-27 23:38  callmelx  阅读(972)  评论(0编辑  收藏  举报