簡體   English   中英

YACC中的語法規則結束

[英]End of grammar rule in YACC

我是yacc / lex的初學者,我偶然發現了一些對我來說似乎很簡單的東西,但我無法理解。 我有以下兩個規則: S : E; E : STR; (在詞法分析器中, [az]+映射到STR )。 我的猜測是,例如,當我給輸入“ hithere”時,將消耗該輸入,並且解析器應退出,不是嗎?

問題是,解析器仍在等待輸入,因此不使用S : E (或者我猜是這樣)。 如果我繼續輸入,則會引發語法錯誤(這是預期的)。

我的問題是,在哪種情況下解析器會停止請求輸入? 也許更確切地說,為什么規則S : E; 對我的具體示例不滿意?

我在這里附加我的.l和.y文件:

test1.l

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

%option noyywrap

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

test1.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);
}

對我來說似乎很奇怪的事情是,如果我在終端上打印回“ hithere”的輸入,那么“ hithere”將被打印回我,這很明顯表明S : E; 實際上已經被識別並執行printf()

它正在等待更多輸入,因此可以減少產量S : E ; 您需要根據系統輸入ctrl / d或ctrl / z。

實際上,Bison / yacc(以及許多(盡管不是全部)派生詞)通過添加一個新的初始產生式實際上構成了“增強”語法:

$start: S END

其中S是您的起始符號(如果未指定,則為語法中的第一個非END符),而END是表示輸入結束的標記。 (這是一個真實的令牌,其值為0。(f)lex掃描程序在收到文件結束符時將返回0,因此對於解析器而言,它看起來像是被賦予了END令牌。)

因此,解析器在看到END令牌之前不會返回,這意味着掃描程序已看到文件結尾。 如果您的輸入來自終端,則需要發送EOF,通常是通過鍵入EOF字符:在大多數類Unix系統上輸入control-D,在Windows / DOS上輸入control-Z。

與許多解析器生成器不同,如果不必使用先行符號來確定必須執行縮減,則野牛將執行精簡操作而不讀取先行符號。 在您的語法情況下, S: E產生是可能的,因為沒有可能的轉移。 減少是正確的(如果下一個標記是END ),或者輸入在語法上無效(如果下一個標記是其他任何東西)。 因此,將打印字符串的語義值。 對於一個稍微復雜一點的語法,就不會發生(直到EOF被識別)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM