LEX 简单入门

news/2024/11/28 4:48:43/

youtube : https://www.youtube.com/watch?v=54bo1qaHAfk&list=PLkB3phqR3X43IRqPT0t1iBfmT5bvn198Z

参考网站 :https://www.ibm.com/developerworks/cn/linux/sdk/lex/

强烈推荐文章:如何愉快地写个小parser (大神写的真的好,和下面的处理SQL配置文件刚好是一样的思想)

这是一个youtube上介绍lex/yacc的视频,讲的超级的好,对于CS143的任务1,我又有了信心。这一篇文章是上面视频的总结和记录,我尽量写得详细点,但是强烈推荐去看看。

如果你给我说不能翻墙,那我只能说,国内搜索引擎都什么呀!有个B站UP主叫LEX,取名字之前不先搜搜吗?不过主要还是搜索引擎做的不好,加上国内对于计算机底层方面没有计算机应用方面火。所以还是推荐大家试着科学上网。

然后就是这个是linux/unix上的,双系统走一波。

还有需要就是这个不单单对编译原理有用,视频里面举例判断SQL配置文件的程序相当漂亮。

简单介绍词法分析

在这里插入图片描述

什么是LEX?

lex is a scanner generator.

  • 输入: 正则表达式和用c语言写的相关联的行为(actions)
  • 输出: a table-driven scanner (默认文件名为lex.yy.c)

flex 是原始UNIX上lex工具的一个开源实现。

lex 三个组成部分:

FRIST PART                  // 可选的
%%
pattern             action  // 模式 行为
....
%%
THIRD PART                  // 可选的

LEX如何运行?

lex 示例(文件名 ex1.l,传说中的hello world):

%%
"hello world"       printf("GOODBYE\n");    // 将匹配"hello world",并执行printf
.                   ;                       // 匹配任意字符,忽略其他情况
%%

测试上面的代码:

% lex ex1.l                 // 处理ex1.l生成lex.yy.c
% cc lex.yy.c -ll           // 编译lex.yy.c,-ll抢占main函数
% ./a.out                   // gcc/cc默认输出可执行文件为a.out
hello world
GOODBYE
%

lex 常见正则表达式

在这里插入图片描述

lex 如何处理文本配置文件以及集成到c语言?

假如我们有一个配置文件(config.in):

db_type : myset
db_name : testdate
db_table_prefix : test_
db_port : 1099

首先定义scanner.h用来为每个token进行标记

#define TYPE 1
#define NAME 2
#define TABLE_PREFIX 3
#define PORT 4
#define COLON 5         // 冒号
#define IDENTIFIER 6
#define INTEGER 7

然后定义scanner.l,这里有一个坑,%{ %}不要写成了%{ }%

%{#include "scanner.h"
%}%%:                   return COLON;
"db_type"           return TYPE;
"db_name"           return NAME;
"db_table_prefix"   return TABLE_PREFIX;
"db_port"           return PORT; [a-zA-Z][_a-zA-Z0-9]*  return IDENTIFIER;
[1-9][0-9]*            return INTEGER;
[ \t\n]                ;.                   printf("unexpected character\n");%%/*注意这一段必须包括 yywrap() 函数。Lex 有一套可供使用的函数和变量。 其中之一就是 yywrap。这一函数在文件(或输入)的末尾调用。 如果函数的返回值是1,就停止解析。
*/int yywrap(void) {return 1;
}

然后lex scanner.l生成lex.yy.c文件

然后编写scanner.c

#include <stdio.h>
#include "scanner.h"extern int yylex();     // 这一函数开始分析。 它由 Lex 自动生成。
extern int yylineno;    // 提供当前的行数信息。 (lexer不一定支持。)
extern char* yytext;    // 匹配模式的文本存储在这一变量中(char*)。char *names[] = {NULL,"db_type","db_name","db_table_prefix","db_port"};int main(void) {int ntoken, vtoken; // name & valuentoken = yylex();while(ntoken) {     // 结束时返回0printf("%d\n",ntoken);if(yylex() != COLON) { // 下一个不为分号printf("Syntax error in line %d, Except a ':' but found %s\n",yylineno,yytext);return 1;}   vtoken = yylex();switch(vtoken){case TYPE:case NAME:case TABLE_PREFIX:if(vtoken != IDENTIFIER) {printf("Syntax error in line %d, Except an identifier but found %s\n",yylineno,yytext);return 1;}printf("%s is set to %s\n",names[ntoken],yytext);break;case PORT:if(vtoken != INTEGER) {printf("Syntax error in line %d, Except an identifier but found %s\n",yylineno,yytext);return 1;}printf("%s is set to %s\n",names[ntoken],yytext);break;default:printf("Syntax error in line %d\n",yylineno);}ntoken = yylex();}return 0;
}

然后gcc scanner.c lex.yy.c -o scanner

运行代码./scanner < config.in

最终结果:

1
db_type is set to myset
2
db_name is set to testdate
3
db_table_prefix is set to test_
4
db_port is set to 1099

http://www.ppmy.cn/news/239789.html

相关文章

ElasticSearch6.x插件之IK分词器

IK分词器插件下载地址&#xff1a;git地址 1.下载并安装IK插件 首先下载es对应版本的ik分词器的zip包&#xff0c;上传到es服务器上&#xff0c;在es的安装目录下有一个plugins的目录&#xff0c;在这个目录下创建一个叫ik的目录 然后将解压好的内容&#xff0c;拷贝到ik目录…

JDBC 拾枝杂谈—入门篇(通俗易懂)

目录 一、前言 二、JDBC介绍 1.基本概述 : 2.基本原理 : 三、JDBC模拟 1.模拟接口 &#xff1a; 2.模拟实现类 : 3.模拟测试类 : 4.模拟扩展 : 四、JDBC入门 1.编写JDBC程序的核心四部曲 : &#xff08;全文背诵&#xff09; 2.准备工作 : ①导入jar包 ②创建测试表 …

Lexer(Ver. Hand)

本文介绍如何手撕词法分析器&#xff0c;整体来说难度不大&#xff0c;还是文件读取麻烦。 lexer.h #ifndef LEXER_H #define LEXER_H#include <iostream> #include <fstream> #include <vector> #include <string>using namespace std;enum token_typ…

【Pytorch】模型摘要信息获取、模型参数获取及模型保存的三种方法

目录 问题一&#xff1a;模型摘要信息的获取问题二&#xff1a;模型参数的获取问题三&#xff1a;模型的保存方式 问题1&#xff1a;我想得到模型的摘要信息&#xff0c;包括每一层的名称、输入尺寸、输出尺寸以及参数量。 PyTorch Summary是一个用于计算模型参数量和输出尺…

Databend 开源周报第 96 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 虚拟列 查询 J…

djangoo配置与运行

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

【云原生】docker-Cgroup资源限制

Docker容器的资源控制 Docker通过Cgroup 来控制容器使用的资源配额&#xff0c;包括CPU、内存、磁盘三大方面&#xff0c;基本覆盖了常见的资源配额和使用量控制。Caroup 是ControlGroups的缩写&#xff0c;是Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源…

Yolov3 模型构建和深入掌握快速搭建网络的搭积木方法

&#xff08;一&#xff09;设计Conv2dBatchLeaky 1、了解LeakyReLU激活函数 LeakyReLU 激活层&#xff0c;创建一个可调用对象以计算输入 x 的 LeakReLU 。其中&#xff0c;x为输入的 Tensor 感觉和飞桨的api有点相同&#xff0c;可以对照参考理解&#xff1a; LeakyReLU激活…