初识 lex

一、背景

从零开始学习下lex和yacc

     1. 基础

lex只有状态和状态转换,没有栈,善于模式匹配;yacc能处理带栈的FSA(有限状态机),更适合更复杂的任务。

模式匹配原语

元字符 匹配说明
. 任意字符( 除了换行)
\n 换行
* 0次或者多次重复前面的表达式
+ 1次或者多次重复前面的表达式
? 0次或者1次重复前面的表达式
^ 行的开始
$ 行的结尾
a|b a or b
(ab)+
1次或者多次重复组ab

[...] 任意一个出现的字符

一些匹配的例子

表达式 匹配说明
abc abc
abc* ab, abc, abcc, abccc,.....
abc+ abc, abcc, baccc,......
a(bc)+ abc, abcbc, abcbcbc,......
a(bc)? a, abc
[abc] a, b, c
[a-z] a到z的任意字符
[a\-z] a, -, z
[-az] -, a, z
[a-zA-Z0-9]+ 一个或者多个任何数字字母
[ \t\n] witespace
[^ab] 除了a,b的任何字符
[a^b] a, ^, b
[a|b] a, |, b
a|b a or b

匹配规则:

1. 贪心: 两个模式去匹同一个字符串,匹配上最长的模式

2. 顺序优先: 两个相同长度的模式, 匹配上先定义的模式

.l文件内容的格式被%%分成了三部分,如下:

....definitions.....

%%

.....rules....

%%

...subroutines...

其中rules是必须的,其他部分可选

一些内置函数以及变量

int yylex(void) 调用分析器,返回 token
char *yytext 指定匹配的字符串
yyleng 匹配上的字符串的长度
int yywrap(void) 返回1 则结束了
FILE *yyout 输出文件,默认 stdout
FILE *yyin 输入文件, 默认stdin
INITIAL initial start condition
BEGIN condition switch start condition
ECHO  write mached string

#define ECHO fwrite(yytext, yyleng, 1, yyout)

二、开始第一个例子

   环境说明:

          VMware Workstation 12 Pro, ubuntu17.04 ,lex2.6.1

输出文件的内容并且在前面增加行号

lineno.l

%{ 
    int yylineno;
%}
%%
^(.*)\n printf("%4d\t%s",  ++yylineno, yytext);
%%
int main(int argc, char *argv[])
{ 
    FILE *fp = NULL;
    if (argc == 2) {
      fp = fopen(argv[1], "r");
      if (NULL != fp) {
         yyin = fp;  
      } 
    }  
     
    yylex();
    
    if (NULL != fp) { 
       fclose(fp); 
    }
    
    return 0;
}

使用lex将lineno.l文件转换为.c文件

  $ lex lineno.l
  $ls
  lex.yy.c lineno.l

使用gcc 将lex.yy.c编译成可执行文件

   $ gcc lex.yy.c -o lineno

/tmp/ccNgesbZ.o:在函数‘yylex’中:
    lex.yy.c:(.text+0x55c):对‘yywrap’未定义的引用
    /tmp/ccNgesbZ.o:在函数‘input’中:
    lex.yy.c:(.text+0x116c):对‘yywrap’未定义的引用
    collect2: error: ld returned 1 exit status

网上查询说是要在.l文件中实现yywrap函数

修改后:

%{   
  int yylineno;
%}
%%
^(.*)\n printf("%4d\t%s",  ++yylineno, yytext);
%%
int main(int argc, char *argv[])
{    
     FILE *fp = NULL;
     yylineno = 0; 
     
     if (argc == 2) {    
         fp = fopen(argv[1], "r");    
         if (NULL != fp) {   
            yyin = fp;   
          }   
      }   
        
      yylex();  
      
      if (NULL != fp) {    
          fclose(fp);  
      }   
      
     return 0;
}

int yywrap()
{ 
    return 1;
}

再次编译成功

$gcc lex.yy.c -o lineno
$lineno lineno.l

1    %{
   2            int yylineno;
   3    %}
   4
   5    %%
   6    ^(.*)\n printf("%4d\t%s",  ++yylineno, yytext);
   7    %%
   8
   9    int main(int argc, char *argv[])
  10    {
  11            FILE *fp = NULL;
  12            yylineno = 0;
  13
  14            if (argc == 2) {
  15                    fp = fopen(argv[1], "r");
  16                    if (NULL != fp) {
  17                            yyin = fp;
  18                    }
  19            }
  20
  21            yylex();
  22
  23            if (NULL != fp) {
  24                    fclose(fp);
  25            }
  26
  27            return 0;
  28    }
  29
  30    int yywrap()
  31    {
  32            return 1;

33    }

时间: 2024-11-09 10:00:17

初识 lex的相关文章

初识Python,望君多多关照

在学习Python之前,我们接触过数据结构和网页制作.前者让我们学习如何把C语言运用的更加整齐规范,而后者让我们亲身学习如何运用所学,制作一个静态网页.通过这些课程的学习,让我对C语言产生了比较大的压力,以至于对编程.对这学期的Python课程都有一种如临大敌的感觉. 但是真的学习了这门课程,体会了编码过程中的一些固定运用方法和套路之后,也许过程中对这门课程隐隐约约产生了一点点朦胧的感觉,仿佛他也并没有想象中的那么困难,起码现在的学习让我认为,他可能没有C语言那么繁琐和麻烦.当然,以一个初学者的

初识数组排序!!!!

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>初识数组排序</title> <!--调试成功--> <style type="text/css"> *{ padding:0; margin: 0; } li,ul{ list-style: none; } #p

初识操作系统和linux

初识操作系统和linux 1.计算机系统由硬件系统和软件系统两大部分组成:是一种能接收和存储信息,并按照存储在其内部的程序对海量数据进行自动.高速地处理,然后把处理结果输出的现代化智能电子设备. 2.世界上第一台计算机是1946年诞生在美国宾州大学. 3.冯·诺依曼体系结构:1946年数学家冯·诺依曼于提出计算机硬件系统由运算器.控制器.存储器.输入设备.输出设备.摩根定律:当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能也将提升一倍.现在计算机技术进本很难遵

JAVA 初识类加载机制 第13节

JAVA 初识类加载机制 第13节 从这章开始,我们就进入虚拟机类加载机制的学习了.那么什么是类加载呢?当我们写完一个Java类的时候,并不是直接就可以运行的,它还要编译成.class文件,再由虚拟机解释给当前的操作系统去执行.这些过程都是我们看不见的,我们能看见的也就是一个.class文件.既然虚拟机要解释这些.class文件给当前的操作系统听,那么他怎么获得这些.class文件呢?虚拟机获得这些.class文件的过程就是类加载了. 所以,总结来说就是:虚拟机将.class文件从磁盘或者其他地

初识React

原文地址:北云软件-初识React 专注于UI 在MVC分层设计模式中,react常被拿来实现视图层(V).React不依赖于技术栈的其他部分,因此可以方便的在现有项目中尝试用它来实现一个小特性. 虚拟DOM React从DOM中抽象出来,给出一种更简洁的编程模型,且性能表现更好.能够通过NodeJS实现服务端渲染,通过React Native开发原生app. 数据流React实现单向.响应式数据流,减少boilerplate且比传统数据绑定更容易理解. 简洁的组件React的组件都实现了一个r

泛型的几种类型以及初识webform

今天学习的可以分为两类吧,但是学习的都是比较抽象的,不太容易掌握吧.首先我们大部分时间学习了泛型,泛型的委托,泛型接口以及枚举器,迭代器,扩展方法:最后简单的认识了webform,实现了一个简单的功能. 一.泛型 定义:泛型(generic)可以软糖多个类型共享一组代码,泛型允许我们声明类型参数化.可以用不同的类型进行实例化,说白了,就是可以用类型占位符,创建具体类型致命的真实概念.C#中提供了五种泛型,类,结构,接口,委托和方法.下面举例说明可能更容易理解, class MyStack<T>

最新计算机技术与管理科学应用专家——初识ERB

ERB管理系统:英文全称Enterprise Resource and Behavior,英文简称:ERB,中文名全称:企业资源与行为管理系统.ERB是由理文企业管理顾问有限公司首席管理师,现任商翼ERB企业管理系统项目总监吴志华先生,于2010年9月首先提出的.ERB不再单以供应链管理作为系统应用的基础,而是以企业行为与企业资源规划的最佳结合作为系统应用设计的核心基础,强调企业行为的规划.执行.监督与追溯,强调企业管理水平与员工素养的持续提升:提供企业行为与企业资源管理最佳结合的整体应用解决方

[OpenGL]环境搭建以及OpenGL初识

想往游戏行业发展的话,经常被提及到的就是OpenGL和DirectX,这两者听起来感觉是一门挺高深的技术,今天我也开始摸索学习OpenGL,那么OpenGL到底是什么?它和DirectX有什么区别和联系? OpenGL初识 OpenGL只是一套图形函数库 DirectX包含图形.声音.输入.网络等模块. 但就图形而论,DirectX的图形库性能不如OpenGL,OpenGL稳定,可以跨平台使用,DirectX只支持Windows平台,所以OpenGL还是有它的优势!OpenGL ES是OpenG

初识git

初识git 1 安装git 最早Git是在Linux上开发的,很长一段时间内,Git也只能在Linux和Unix系统上跑.不过,慢慢地有人把它移植到了Windows上.现在,Git可以在Linux.Unix.Mac和Windows这几大平台上正常运行了. 要使用Git,第一步当然是安装Git了.根据你当前使用的平台来阅读下面的文字: 1.1 在Linux上安装Git 首先,你可以试着输入git,看看系统有没有安装Git: ``` $ git The program 'git' is curren