#if YYDEBUG yydebug =1: #endif//YYDEBUG yyparse():/∥进行语法分析,这个函数是Yacc自动生成的 /∥下面的这行代码仅仅使用了STL的输出算法到标准输出 std:copy(g_Includes.begin(),g_Includes.end(,std::ostream_iterator<I nclude>(std::cout,"\n")) return 0; 4.main.hpp文件 #pragma once #include<iostream>.》 #include〈string> #include <vector> #include〈algorithm> #include <iterator> /川对于每一个项目最好都用一个独立的数据结构来保存相应的信息 struct Include void clear0:/∥设置Include的初始值 std:string headerfile:/记录头文件全名(包括路径) bool is_.quotation:/是否是双引号"“括起来的头文件 bool is_angle:/∥是否是尖括号<◇括起来的头文件 /∥下面的这个函数仅仅是用来输出到C+流而准备的 friend std::ostreamkoperator<<(std::ostream&s,const Include&I):
#if YYDEBUG yydebug = 1; #endif//YYDEBUG yyparse();// 进行语法分析,这个函数是Yacc自动生成的 // 下面的这行代码仅仅使用了STL的输出算法到标准输出 std::copy(g_Includes.begin(),g_Includes.end(),std::ostream_iterator<I nclude>(std::cout,"\n")); return 0; } 4. main.hpp 文件 #pragma once #include <iostream> #include <string> #include <vector> #include <algorithm> #include <iterator> // 对于每一个项目最好都用一个独立的数据结构来保存相应的信息 struct Include { void clear();// 设置Include的初始值 std::string headerfile;// 记录头文件全名(包括路径) bool is_quotation;// 是否是双引号""括起来的头文件 bool is_angle;// 是否是尖括号<>括起来的头文件 // 下面的这个函数仅仅是用来输出到 C++流而准备的 friend std::ostream&operator<<(std::ostream&s,const Include&I);
std:ostreamoperator<<(std::ostream&s,const Include&I) /∥下面的这个宏定义用来取消Lex和Yacc默认的YYSTYPE定义,因为默认的 YYSTYPE定义 /仅仅只能够记录整数信息,因此要保存额外的信息必须这样定义宏,可以参 见Yacc /自动生成的标记头文件frame..tab.h。 #define YYSTYPE Include 5.main.cpp文件 #include "main.hpp" /初始化所有的Include信息,避免前后关联 void Include::clear() headerfile.clear(: is_quotation false; is_angle false; ∥为了能够方便输出,在这里直接淮备好了一个流输出函数 std::ostreamkoperator<<(std::ostream&s,const Include&I) if(I.is_angle) s〈《“采用尖括号的”:
}; std::ostream&operator<<(std::ostream&s,const Include&I); // 下面的这个宏定义用来取消 Lex 和 Yacc 默认的 YYSTYPE 定义,因为默认的 YYSTYPE 定义 // 仅仅只能够记录整数信息,因此要保存额外的信息必须这样定义宏,可以参 见 Yacc // 自动生成的标记头文件 frame.tab.h。 #define YYSTYPE Include 5. main.cpp 文件 #include "main.hpp" // 初始化所有的 Include 信息,避免前后关联 void Include::clear() { headerfile.clear(); is_quotation = false; is_angle = false; } // 为了能够方便输出,在这里直接准备好了一个流输出函数 std::ostream&operator<<(std::ostream&s,const Include&I) { if(I.is_angle) s << "采用尖括号的" ;
if(I.is_quotation) s〈《“采用双引号的”: s<《"头文件:[”<I.headerfile<《"门”: return s: 6.Makefile文件 LEX=flex YACC=bison CC=g++ a.exe:lex.yy.o frame.tab.o main.o $(CC)lex.yy.o frame.tab.o main.oo a.exe lex.yy.o:lex.yy.c frame.tab.h main.hpp $(CC)-c lex.yy.c frame.tab.o:frame.tab.c main.hpp $(CC)-c frame.tab.c main.o:main.hpp main.cpp $(CC)-c main.cpp frame.tab.c frame.tab.h:frame.y $(YACC)-d frame.y lex.yy.c:frame.1 $(LEX)frame.1
if(I.is_quotation) s << "采用双引号的" ; s << "头文件:[" << I.headerfile << "]" ; return s; } 6. Makefile 文件 LEX=flex YACC=bison CC=g++ a.exe:lex.yy.o frame.tab.o main.o $(CC) lex.yy.o frame.tab.o main.o -o a.exe lex.yy.o:lex.yy.c frame.tab.h main.hpp $(CC) -c lex.yy.c frame.tab.o:frame.tab.c main.hpp $(CC) -c frame.tab.c main.o:main.hpp main.cpp $(CC) -c main.cpp frame.tab.c frame.tab.h:frame.y $(YACC) -d frame.y lex.yy.c:frame.l $(LEX) frame.l
clean m-f米,0来ch 7.sample..cpp文件 #include <iostream> #include <string> #include <ffmpeg/avformat.h> #include <ffmpeg/avcodec.h> #include <ffmpeg/avutils.h> #include〈stdio..h> #include <stdlib.h> #include "hello.h" #include "../hello.h" include"space.h" 8.运行结果 pandaxcl@PANDAXCL-F78E7D /d/work/lex_yacc/chapter06 make flex frame.1 bison-d frame.y g++-c lex.yy.c g++-c frame.tab.c g++-c main.cpp
clean: rm -f *.o *.c *.h 7. sample.cpp 文件 #include <iostream> #include <string> #include <ffmpeg/avformat.h> #include <ffmpeg/avcodec.h> #include <ffmpeg/avutils.h> #include <stdio.h> #include <stdlib.h> #include "hello.h" #include "../hello.h" # include "space.h" 8. 运行结果 pandaxcl@PANDAXCL-F78E7D /d/work/lex_yacc/chapter06 $ make flex frame.l bison -d frame.y g++ -c lex.yy.c g++ -c frame.tab.c g++ -c main.cpp
g++lex.yy.o frame.tab.o main.o-o a.exe pandaxcl10PANDAXCL-F78E7D /d/work/lex yacc/chapter06 s./a.exe sample.cpo 采用尖括号的头文件:[iostream] 采用尖括号的头文件:[string] 采用尖括号的头文件:[ffmpeg/avformat.h] 采用尖括号的头文件:[ffmpeg/avcodec..h] 采用尖括号的头文件:[ffmpeg/avutils..h] 采用尖括号的头文件:[stdio..h] 采用尖括号的头文件:[stdlib.h] 采用双引号的头文件:[hello..h] 采用双引号的头文件:[.hel1o.h] 采用双引号的头文件:[space.h] pandaxcl@PANDAXCL-F78E7D /d/work/lex_yacc/chapter06 9.总结 总的来说,上面的解析C/C+包含预处理信息的时候需要了解如下的概念 词法状态 所谓的词法状态就是指对文本进行词法分析的时候,词法分析器当前所处 的状态,默认情况下,词法分析器都处于INITIAL状态,这个INITIAL 状态是Lx内置的状态。用户可以通过x来重新定义各种各样的状态
g++ lex.yy.o frame.tab.o main.o -o a.exe pandaxcl@PANDAXCL-F78E7D /d/work/lex_yacc/chapter06 $ ./a.exe < sample.cpp 采用尖括号的头文件:[iostream] 采用尖括号的头文件:[string] 采用尖括号的头文件:[ffmpeg/avformat.h] 采用尖括号的头文件:[ffmpeg/avcodec.h] 采用尖括号的头文件:[ffmpeg/avutils.h] 采用尖括号的头文件:[stdio.h] 采用尖括号的头文件:[stdlib.h] 采用双引号的头文件:[hello.h] 采用双引号的头文件:[../hello.h] 采用双引号的头文件:[space.h] pandaxcl@PANDAXCL-F78E7D /d/work/lex_yacc/chapter06 $ 9. 总结 总的来说,上面的解析 C/C++包含预处理信息的时候需要了解如下的概念: 词法状态 所谓的词法状态就是指对文本进行词法分析的时候,词法分析器当前所处 的状态,默认情况下,词法分析器都处于 INITIAL 状态,这个 INITIAL 状态 是 Lex 内置的状态。用户可以通过%x 来重新定义各种各样的状态