繁体   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