12

解析中にインクルード トークンに遭遇した場合、入力として指定されたファイルを開き、これの解析を開始するように YACC に指示したいと考えています。この解析が終了したら、YACC にファイルに戻り、インクルード式の直後に解析を続行するように指示したいと思います。インクルード深度レベルを 1 に制限します。

4

2 に答える 2

9

フレックスマニュアルでは、yypush_buffer_state()およびyypop_buffer_state()を使用してこれを行う方法について説明しています。

これは、複数の入力バッファの使用に関する公式マニュアルのセクションです。いくつかのサンプルコードがあります。

于 2010-02-16T00:49:58.710 に答える
5

プロセッサの字句フェーズと構文フェーズの間で通信するのは正常です。

したがって、パーサーでインクルード ディレクティブの構文を認識し (または、簡単にするために、レクサーでそれを認識するだけです)、字句レベルで切り替えを行います。

たとえば、 or を含む標準入力行を認識する簡単な言語を次に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;
}

そして、それを実行すると...

$ 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
$ 
于 2010-02-16T01:46:00.657 に答える