使用lex&yacc实现一个xml解析器

本文详细介绍了如何使用lex和yacc来实现一个XML解析器。首先介绍了lex,包括其定义部分、规则部分和用户子程序部分,然后讲解了yacc的基本用法和步骤。接着讨论了yacc的细节,如嵌入式动作、符号类型和错误处理。最后,给出了一个使用lex和yacc解析XML结构体的示例,包括词法分析文件和语法分析文件的编写,以及如何将解析的XML转换为C结构体。
摘要由CSDN通过智能技术生成

在开始编写xml解析器之前我们先来简单介绍一下lex ,yacc。

 

Lex:

Lex工具是一种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识
别程序,由该程序识别出输入文本中的各个单词。一般可以分为<定义部分><规则部
分><用户子程序部分>。其中规则部分是必须的,定义和用户子程序部分是任选的。 


(1)定义部分


定义部分起始于 %{ 符号,终止于 %} 符号,其间可以是包括include语句、声明语句
在内的C语句。这部分跟普通C程序开头没什么区别。
%{
#include "stdio.h"
int linenum;
%}
(2) 规则部分
规则部分起始于"%%"符号,终止于"%%"符号,其间则是词法规则。词法规则由模式和
动作两部分组成。模式部分可以由任意的正则表达式组成,动作部分是由C语言语句组
成,这些语句用来对所匹配的模式进行相应处理。需要注意的是,lex将识别出来的单
词存放在yytext[]字符数据中,因此该数组的内容就代表了所识别出来的单词的内容。
类似yytext这些预定义的变量函数会随着后面内容展开一一介绍。动作部分如果有多
行执行语句,也可以用{}括起来。
%%
title                 showtitle();
[\n]                  linenum++;
[0-9]+                printf("Int     : %s\n",yytext);
[0-9]*\.[0-9]+        printf("Float   : %s\n",yytext);
[a-zA-Z][a-zA-Z0-9]*  printf("Var     : %s\n",yytext);
[\+\-\*\/\%]          printf("Op      : %s\n",yytext);
.                     printf("Unknown : %c\n",yytext[0]);
%%


lex规则部分具有优先级的概念:
1  Lex会选择最长的字符匹配规则。
2  当存在多个规则同事满足时,这时Lex只会选择第一个规则


(3) 用户子程序部分
最后一个%%后面的内容是用户子程序部分,可以包含用C语言编写的子程序,而这些子
程序可以用在前面的动作中,这样就可以达到简化编程的目的。


Lex(Lexical Analyzar) 一些的内部变量和函数
内部预定义变量:
yytext   char *  当前匹配的字符串
yyleng   int     当前匹配的字符串长度
yyin     FILE *  lex当前的解析文件,默认为标准输出
yyout    FILE *  lex解析后的输出文件,默认为标准输入
yylineno int     当前的行数信息
内部预定义宏:
ECHO     #define ECHO fwrite(yytext, yyleng, 1, yyout)  也是未匹配字符的默认动作
内部预定义的函数:
int yylex(void)    调用Lex进行词法分析
int yywrap(void)   在文件(或输入)的末尾调用。如果函数的返回值是1,就停止解析。因此它可以用来解析多个文件。


注意lex库提供一些默认的函数,例如main,yywrap函数等。 当编译时不带-ll选项时,必须自行实现main函数和yywrap等函数。


在linux中假设现在有lex规则文件a.l。运行lex a.l  便自动生成lex.yy.c
 cc -o test lex.yy.c -ll 便生成了可执行程序。注意当编译时不带-ll选项时,必须自行实现main函数和yywrap等函数。

 

Yacc


如同 Lex 一样, 一个 Yacc 程序也用双百分号分为三段。 它们是:声明、语法规则和 C 代码
用 Yacc 来创建一个编译器包括四个步骤:


1 编写一个 .y 的语法文件(同时说明 C 在这里要进行的动作)。
2 编写一个词法分析器来处理输入并将标记传递给解析器。 这可以使用 Lex 来完成。
3 编写一个函数,通过调用 yyparse() 来开始解析。
4 编写错误处理例程(如 yyerror())。
5 通过yacc工具对.y生代码并编译它。


yacc 必须与lex一起使用,而lex可以单独使用。因为yacc需要使用lex来返回标记。

在linux中假设现在有lex规则文件a.l, a.y。

运行lex a.l  便自动生成lex.yy.c

运行 yacc -d a.y  便自动生成了y.tab.c  y.tab.h   -d表示生成头文件
 cc -o test lex.yy.c y.tab.c -ll -ld 便生成了可执行程序 

同样 yacc库也提供了一些默认的函数 例如main,yyerror

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值