Lors de l'analyse, si je rencontre un jeton d'inclusion, je souhaite que YACC ouvre le fichier spécifié comme entrée et commence à l'analyser. Une fois cette analyse terminée, je souhaite que YACC retourne au fichier et continue l'analyse directement après l'expression include. Je vais restreindre le niveau de profondeur d'inclusion à un.Comment puis-je implémenter des constructions #include avec Flex et YACC?
Répondre
Le manuel flexible explique comment procéder en utilisant yypush_buffer_state() et yypop_buffer_state(). Here est la section du manuel sur l'utilisation de plusieurs tampons d'entrée. Il y a un exemple de code.
Il est normal de communiquer entre les phases lexicale et syntaxique de votre processeur. Donc, reconnaissez la syntaxe d'une directive include dans votre analyseur (ou, pour simplifier les choses, reconnaissez-la simplement dans le lexeur) et faites la commutation au niveau lexical. Par exemple, voici un langage simple reconnaissant les lignes d'entrée standard contenant ab
ou cd
ou .file
. Lorsqu'il voit .someString
, il ouvre someString
en tant que fichier d'inclusion, puis revient à la lecture de l'entrée standard.
%{
#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;
}
Et quand nous courons ...
$ 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
$
DigitilRoss de réponse était complète et assez précis. Mais les meilleures pratiques l'emportent sur l'intelligence chaque jour. J'ai vu ça il y a 18 minutes et maintenant j'ai travaillé. Merci pour le lien. +1 – Jamie