Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 如何使用Flex和YACC实现#include构造?_Parsing_Include_Yacc_Lex - Fatal编程技术网

Parsing 如何使用Flex和YACC实现#include构造?

Parsing 如何使用Flex和YACC实现#include构造?,parsing,include,yacc,lex,Parsing,Include,Yacc,Lex,在解析过程中,如果遇到include标记,我希望指示YACC打开指定为输入的文件并开始解析它。一旦解析完成,我想指示YACC返回到文件,并直接在include表达式之后继续解析。我将把include depth级别限制为1。flex手册介绍了如何使用yypush\u buffer\u state()和yypop\u buffer\u state()实现这一点 是官方手册中关于使用多输入缓冲区的章节。有一些示例代码。在处理器的词法和语法阶段之间进行通信是正常的 因此,在解析器中识别include指

在解析过程中,如果遇到include标记,我希望指示YACC打开指定为输入的文件并开始解析它。一旦解析完成,我想指示YACC返回到文件,并直接在include表达式之后继续解析。我将把include depth级别限制为1。

flex手册介绍了如何使用yypush\u buffer\u state()和yypop\u buffer\u state()实现这一点


是官方手册中关于使用多输入缓冲区的章节。有一些示例代码。

在处理器的词法和语法阶段之间进行通信是正常的

因此,在解析器中识别include指令的语法(或者,为了使事情更简单,只需在lexer中识别它),并在词法级别进行切换

例如,这里有一种简单的语言,可以识别包含
ab
cd
.file
的标准输入行。当它看到
.someString
时,它会将
someString
作为包含文件打开,然后返回到读取标准输入

%{
#include <stdio.h>
#include <stdlib.h>
void start_include(char *); int yylex(void); void yyerror(void *);
#define YYSTYPE char *
%}
%%
all:          all others | others;
others:       include_rule | rule_1 | rule_2 | 'Z' { YYACCEPT; };
include_rule: '.' '\n' { start_include($1); };
rule_1:       'a' 'b' '\n' { printf("random rule 1\n"); };
rule_2:       'c' 'd' '\n' { printf("random rule 2\n"); };
%%
FILE * f = NULL;
void start_include(char *s) {
        if ((f = fopen(s, "r")) == NULL)
                abort();
}
int yylex(void) {
        int c;
        static char s[100];
        if (f == NULL)
                f = stdin;
        c = getc(f);
        if (c == EOF) {
                f = stdin;
                c = getc(f);
        }
        if (c == '.') {
                scanf(" %s", s);
                yylval = s;
        } else if (c == EOF)
                return 'Z';
        return c;
}
%{
#包括
#包括
void start_包括(char*);int yylex(void);void yylex错误(void*);
#定义YYSTYPE字符*
%}
%%
全部:所有其他|其他;
其他:包括|规则|规则| 1 |规则|规则| 2 |'Z'{yyapt;};
include_规则:'.'\n'{start_include($1);};
规则1:'a''b'\n'{printf(“随机规则1\n”);};
规则2:'c'd'\n'{printf(“随机规则2\n”);};
%%
文件*f=NULL;
无效开始_包括(字符*s){
如果((f=fopen(s,“r”))==NULL)
中止();
}
int yylex(无效){
INTC;
静态字符s[100];
如果(f==NULL)
f=stdin;
c=getc(f);
如果(c==EOF){
f=stdin;
c=getc(f);
}
如果(c=='。){
scanf(“%s”,s);
yylval=s;
}else如果(c==EOF)
返回'Z';
返回c;
}
当我们运行它时

$ cat > toplevel
ab
.myinclude
ab
$ cat > myinclude
cd
cd
$ yacc ip.y && cc -Wall y.tab.c -ly && ./a.out < toplevel
random rule 1
random rule 2
random rule 2
random rule 1
$ 
$cat>顶级
ab
.myinclude
ab
$cat>myinclude
光盘
光盘
$yacc ip.y&&cc-Wall y.tab.c-ly&&a.out
DigitilRoss的回答彻底而准确。但最佳实践终有一天会战胜聪明。我在18分钟前看到了这个,现在我有了一个工作包。谢谢你的链接+1.