2016-04-18 17 views
0

私はyacc/lexの絶対初心者です。私は単純なように思えますが、理解できません。私は以下の2つの規則を持っています:S : E;E : STR;(そしてレクサーでは[a-z]+STRにマップされます)。私の推測では、入力を "ヒーティング"にすると、入力が消費され、パーサが終了するはずです。YACCの文法規則の終わり

パーザはまだ入力を待っていますので、なんとかS : Eは消費されません。入力を続けていると、構文エラーが発生します(これは予想されます)。

私の質問は、パーサーが入力を求めないのですか?より正確には、具体的な例として、規則S : E;が満足していないのはなぜですか?

test1.l

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

%option noyywrap 

%% 
[a-z]+     {yylval.str = yytext; return (STR);} 
.      { ; } 
%% 

test1.y

私はここに私.Lと私.Yファイルを添付

%{ 
#include <stdio.h> 
#include <stdlib.h> 
extern int yylex(); 
%} 

%union { 
    char *str; 
} 

%token <str> STR 
%type <str> E 

%% 

S : E     {printf("%s\n", $1);} 
    ; 

E : STR     {$$ = $1;} 
    ; 

%% 

int yyerror(char *msg) { 
    printf("%s\n", msg); 
    return (0); 
} 

int main() { 
    yyparse(); 
    return (0); 
} 
私には本当に奇妙なようだ

事がある、もしI入力が "ヒット"、 "ヒット"が端末に印刷されているので、実際にはと認識されていることがわかりますが実行されました。

答えて

0

バイソン/ yaccの(そして多くの、すべてではないけれども、誘導体)は、実際に効果的である新たなスタートの生産を追加することによって、文法を「増補」を構築します指定しない場合は文法上の最初の非終端記号)、ENDは入力の終わりを表すトークンです。 (これは実際のトークンであり、その値は0です。(f)lexスキャナはファイルの終わりを取得すると0を返します。したがって、パーサーにはENDトークンが与えられているように見えます)。

パーサーはENDトークンが見つかるまで戻りません。つまり、スキャナでファイルの終わりが検出されました。あなたの入力が端末からのものである場合は、EOFを入力する必要があります。通常、EOF文字を入力する必要があります:ほとんどのUnixライクなシステムではcontrol-D、Windows/DOSではcontrol-Zです。

多くのパーサジェネレータとは異なり、bisonは、先読みシンボルが削減を実行する必要があると判断する必要がない場合、先読みシンボルを読み取らずに縮小を実行します。文法の場合は、S: Eのプロダクションで可能ですが、シフトはありません。 (次のトークンがENDの場合)、または入力が構文的に有効でない場合(次のトークンが他の場合)したがって、文字列の意味値が出力されます。さらに少し複雑な文法については、(EOFが認識されるまで)それは起こりません。

0

さらに入力を待っているので、生産を減らすことができますS : E ;。システムによっては、ctrl/dまたはctrl/zを入力する必要があります。

$start: S END 
Sがあなたの開始記号である

(または:

関連する問題