lex / flex对C / C ++嵌套`#include“ Header”`语法的实现的解释?

问题描述 投票:-1回答:1

我正在研究lex / flex中的开始状态和嵌套输入文件

在书中[[flex and bison中,我对C / C ++ #include "Header"语法的示例实现感到困惑:

这里是示例词法的一部分:

/* Companion source code for "flex & bison", published by O'Reilly * Media, ISBN 978-0-596-15597-1 * Copyright (c) 2009, Taughannock Networks. All rights reserved. * See the README file for license conditions and contact info. * $Header: /home/johnl/flnb/code/RCS/fb2-3.l,v 2.3 2010/01/04 02:43:58 johnl Exp $ */ /* fb2-3 skeleton for include files */ %option noyywrap warn nodefault %x IFILE struct bufstack { struct bufstack *prev; /* previous entry */ YY_BUFFER_STATE bs; /* saved buffer */ int lineno; /* saved line number */ char *filename; /* name of this file */ FILE *f; /* current file */ } *curbs = 0; char *curfilename; /* name of current input file */ int newfile(char *fn); int popfile(void); %% ^"#"[ \t]*include[ \t]*[\"<] { BEGIN IFILE; } <IFILE>[^ \t\n\">]+ { { int c; while((c = input()) && c != '\n') ; } yylineno++; if(!newfile(yytext)) yyterminate(); /* no such file */ BEGIN INITIAL; } <IFILE>.|\n { fprintf(stderr, "%4d bad include line\n", yylineno); yyterminate(); } ^. { fprintf(yyout, "%4d %s", yylineno, yytext); } ^\n { fprintf(yyout, "%4d %s", yylineno++, yytext); } \n { ECHO; yylineno++; } . { ECHO; } <<EOF>> { if(!popfile()) { fprintf(yyout, "end of file, total lines: %4d %s", yylineno, yytext); yyterminate();} } %% main(int argc, char **argv) { if(argc < 2) { fprintf(stderr, "need filename\n"); return 1; } if(newfile(argv[1])) yylex(); } int newfile(char *fn) { FILE *f = fopen(fn, "r"); struct bufstack *bs = malloc(sizeof(struct bufstack)); /* die if no file or no room */ if(!f) { perror(fn); return 0; } if(!bs) { perror("malloc"); exit(1); } /* remember state */ if(curbs)curbs->lineno = yylineno; bs->prev = curbs; /* set up current entry */ bs->bs = yy_create_buffer(f, YY_BUF_SIZE); bs->f = f; bs->filename = fn; yy_switch_to_buffer(bs->bs); curbs = bs; yylineno = 1; curfilename = fn; return 1; } int popfile(void) { struct bufstack *bs = curbs; struct bufstack *prevbs; if(!bs) return 0; /* get rid of current entry */ fclose(bs->f); yy_delete_buffer(bs->bs); /* switch back to previous */ prevbs = bs->prev; free(bs); if(!prevbs) return 0; yy_switch_to_buffer(prevbs->bs); curbs = prevbs; yylineno = curbs->lineno; curfilename = curbs->filename; return 1; }

请帮助我解决以下问题:

    为什么<IFILE>[^ \t\n\">]+"的末尾>Header匹配?
  1. 为什么使用{ int c; while((c = input()) && c != '\n') ; }会吃掉所有字符,直到行\n结束? yytext是否与Header文件名完全匹配?
  2. 如何像Java import java.util.Decoder;那样实现语法?
c++ include lex
1个回答
0
投票
为什么[^ \ t \ n \“>] +与标题的结尾”或>匹配?

答案是:它

没有。

但是它的作用是匹配所有字符

直到

(和空格,制表符和换行符),并且当您到达这些字符时,匹配就会停止。因此,当您有一个匹配项并且执行了该规则的代码时,您知道匹配项之后文件中的下一个字符必须是">或空白字符。让我们举个例子:

#include <foo/bar.h>

    规则^"#"[ \t]*include[ \t]*[\"<]匹配#include <
  • 规则<IFILE>[^ \t\n\">]+匹配foo/bar.h
  • 然后运行代码时

    int c; while((c = input()) && c != '\n') ;

    它将通过读取结尾的>开始,然后继续读取并丢弃所有剩余的字符,直到该行的结尾。

    为了验证这一点,您可以在循环中添加一些字符输出。

  • © www.soinside.com 2019 - 2024. All rights reserved.