簡體   English   中英

flex/bison 如何讓它識別一個模式,不管最后一個字符是不是一個點?

[英]flex/bison How can I make it recognize a pattern, whether the final character is a dot or not?

我嘗試對 prolog 的代碼進行分析器/解析器,這是一個事實示例:“dadof(arturo,armando)”。 它以點 (.) 結尾,我的解析器識別它然后打印 ("hecho") 但我有另一個選擇,如果輸入是 "dadof(arturo,armando)",它無法識別它。 唯一的區別是沒有點。 但它假設它也應該識別它,然后也打印“(hecho”)。 但它沒有成功。

這是我的代碼

法典代碼:

%{
    #include <stdio.h>
    #include <string.h>
    #include "que.tab.h"

    void showError();

%}

%option noyywrap


LETTER [a-zA-Z]
WORD    {LETTER}+


%%

[[:blank:]] {}
[ \t\r] {} 
{WORD}  { sscanf(yytext, "%s",yylval.cad); return CADENA; }
"%"     { return PERCENT; }
"("     { return OPENB; }
")"     { return CLOSEB; }
","     { return COMA; }
"."     { return POINT; }
":-"    { return POINTSLASH; }
"[papa]"  { return NOFACT; }

.   { showError(); return OTROS; }
%%

void showError(char *OTROS){
    printf("  <<Error lexico: \"%s\">>  ", OTROS);

}

野牛代碼:

%{
    #include <stdio.h>

    int yylex(void);
    void yyerror(char *s);
%}

%token CADENA PERCENT OTROS 
%token OPENB CLOSEB COMA POINT POINTSLASH

%type <cad> CADENA

%union{
    char cad[20];

}

%start INPUT


%%

INPUT
    : INICIO
    | INPUT INICIO
;
    INICIO:
        HECHOS
        {
            printf("(Hecho)");
        }
       
    ;

    HECHOS
        : HECHO POINT
        | HECHO
        
        
    ; 




    HECHO
        :INSTRUCCION OPENB INSTRUCCION COMA INSTRUCCION CLOSEB 
        | INSTRUCCION OPENB INSTRUCCION COMA INSTRUCCION CLOSEB COMA HECHO
        
          
    ;
   
    INSTRUCCION:
        | CADENA
        | OTROS
    ;

%%

int main(){

    return(yyparse());
    return 0;
}

void yyerror(char *s){
    printf("%s", s);
}

正如我之前所說,無論輸入是否以點結尾,它都應該打印“(Hecho)”。

盡管您的代碼存在許多問題,但它與您問題中的測試輸入完美配合。 所以我假設你所做的是這樣的:

$ bison -d -o que.tab.c que.y
$ flex -o que.lex.c que.l
$ gcc -o que que.tab.c que.lex.c
$ ./que
dadof(arturo,armando)

然后你等着看發生了什么。 但是什么也沒發生,因為您的程序仍在等待您輸入更多輸入。

或者您可能通過鍵入 Ctrl-C 終止了您的程序。 和以前一樣,您的程序仍在等待輸入,因此它還沒有嘗試打印任何內容。 Control-C 立即終止正在運行的程序。 砰,死了。 沒有機會清理,打印任何最終結果,什么都沒有。 戲劇性,是的,但有時你需要這樣做。 在這種情況下不是。

如果您將dadof(arturo,armando)行放入一個文件並使用該文件作為輸入運行程序,您將獲得或多或少預期的 output:

$ echo "dadof(arturo,armando)" > test.txt
$ ./que < test.txt

(Hecho)$

如果要從控制台鍵入輸入,則需要通過鍵入 Ctrl-Z Enter(在 Windows 上)或 Ctrl-D(在 Linux/Mac 上)來告訴程序輸入已完成。 (順便說一句,您必須在行首輸入。)然后您將看到與上面相同的 output。

output 確實顯示了您的代碼的幾個問題:

  1. 由於您的所有模式都不能識別換行符 ( \n ),因此 Flex 掃描程序會使用默認規則處理這種情況。 默認規則是將無法識別的字符寫入標准 output 然后繼續尋找令牌。 這就是為什么在“(Hecho)”之前有一個意想不到的換行符。 在解析器中,您幾乎不想觸發默認的 lex 操作; 我建議使用option nodefault禁用默認值,如果您錯過了某些字符,這將導致 flex 打印警告。 為避免這種情況發生,請使用模式.|\n而不是. 作為您的最終后備規則,和/或確保您明確處理換行符。 (例如,您可以使用[[:space:]]而不是[[:blank:]] 。)

  2. 你用printf("(Hecho)");打印(Hecho) ); . 這不會打印換行符,然后您的程序會將控制權返回給 shell。 因此 shell 提示符會在您的消息之后立即打印,這很難閱讀。 您應該始終記住以\n結束所有 output 行。

暫無
暫無

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

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