2017-01-11 10 views
1

例6を実行したときに予期しない/欠落している出力が、this howto(§4.3)で、cygwin環境でlex/yaccの代わりにflex/bisonを使用しています。bison:空の疑似変数

ダウンロードセクションからexample filesをダウンロードして解凍します。ファイルexample6.compileでは、 'lex'を 'flex'と置き換えます。それ以外の場合は元の状態に保ちます(コマンドyaccはcygwinでexec '/usr/bin/bison' -y "[email protected]"を実行します)。次にexample6.compileを実行します。これはエラーなしで実行されますが、いくつかの警告が付いています(付録を参照)。 I次いでexample6を実行し、入力例のテキスト:

zone "." { 
     type hint; 
     file "/etc/bind/db.root"; 
     type hint; 
}; 

が期待出力である:

A zonefile name '/etc/bind/db.root' was encountered 
Complete zone for '.' found 

実際の出力である:

A zonefile name '' was encountered 
Complete zone for '' found 

なぜ擬似の値であります変数がありませんか?

付録

example6.compile:

flex example6.l 
yacc --verbose --debug -d example6.y 
cc lex.yy.c y.tab.c -o example6 

example6.l:

%{ 
#include <stdio.h> 
#include "y.tab.h" 
%} 

%% 

zone     return ZONETOK; 
file     return FILETOK; 
[a-zA-Z][a-zA-Z0-9]* yylval=strdup(yytext); return WORD; 
[a-zA-Z0-9\/.-]+  yylval=strdup(yytext); return FILENAME; 
\"      return QUOTE; 
\{      return OBRACE; 
\}      return EBRACE; 
;      return SEMICOLON; 
\n      /* ignore EOL */; 
[ \t]+     /* ignore whitespace */; 
%% 

example6.y:

%{ 
#include <stdio.h> 
#include <string.h> 

#define YYSTYPE char * 

int yydebug=0; 

void yyerror(const char *str) 
{ 
     fprintf(stderr,"error: %s\n",str); 
} 

int yywrap() 
{ 
     return 1; 
} 

main() 
{ 
     yyparse(); 
} 

%} 

%token WORD FILENAME QUOTE OBRACE EBRACE SEMICOLON ZONETOK FILETOK 

%% 

commands: 
     | 
     commands command SEMICOLON 
     ; 


command: 
     zone_set 
     ; 

zone_set: 
     ZONETOK quotedname zonecontent 
     { 
       printf("Complete zone for '%s' found\n",$2); 
     } 
     ; 

zonecontent: 
     OBRACE zonestatements EBRACE 

quotedname: 
     QUOTE FILENAME QUOTE 
     { 
       $$=$2; 
     } 
     ; 

zonestatements: 
     | 
     zonestatements zonestatement SEMICOLON 
     ; 

zonestatement: 
     statements 
     | 
     FILETOK quotedname 
     { 
       printf("A zonefile name '%s' was encountered\n", $2); 
     } 
     ; 

block: 
     OBRACE zonestatements EBRACE SEMICOLON 
     ; 

statements: 
     | statements statement 
     ; 

statement: WORD | block | quotedname 

の警告コンパイル:

example6.l: In function ‘yylex’: 
example6.l:10:7: warning: assignment makes integer from pointer without a cast [-Wint-conversion] 
[a-zA-Z][a-zA-Z0-9]* yylval=strdup(yytext); return WORD; 
    ^
example6.l:11:7: warning: assignment makes integer from pointer without a cast [-Wint-conversion] 
[a-zA-Z0-9\/.-]+  yylval=strdup(yytext); return FILENAME; 
    ^
example6.y:19:1: warning: return type defaults to ‘int’ [-Wimplicit-int] 
main() 
^ 
example6.y: In function ‘main’: 
example6.y:21:2: warning: implicit declaration of function ‘yyparse’ [-Wimplicit-function-declaration] 
    yyparse(); 
^
y.tab.c: In function ‘yyparse’: 
y.tab.c:1164:16: warning: implicit declaration of function ‘yylex’ [-Wimplicit-function-declaration] 
     yychar = yylex(); 

答えて

2

それが(ほぼ)常にあるので、「警告」assignment makes integer from pointer without a castは常に、エラーを考慮すべきです。

この場合、ポインター(戻り値strdup、つまりchar*)を整数(yylval)に格納しようとしているというエラーが表示されます。

もちろん、yylvalは整数であってはなりません。あなたのyacc/bisonのファイルのプロローグでCのコードでは、

#define YYSTYPE char * 

を含むが、その行はyaccの/バイソンによって生成されたヘッダファイルで終わるものではありません。もしそうであれば、ヘッダファイルには例えば、yyerrorの定義も含まれます。これは、実行可能ファイルが関数の単一の定義しか持てないため、リンケージの問題につながります)。

したがって、 bisonヘッダーファイルをインクルードする前に(YYSTYPEがそのファイルで使用されている、たとえばyylvalと宣言している)、あなたの(f)lex入力ファイルのプロローグに#defineを挿入してください。 lexとyaccのためのHOW-TOであると主張するものがこれを正しくしていないことは少し驚きです。バグ修正を提出することを検討することをお勧めします。

+0

はい、それは動作します!注意! '#define YYSTYPE char *'は正しく動作するためには、(f)lexファイルの '#include" y.tab.h "'の上に置く必要があります。 – matthiash

+0

@matthiash:はい、私はそれを言及すべきでした。私は今それを追加しました。 – rici