来自Bison手册:

  

在一个简单的交互式命令解析器中   每个输入是一行,它可以   足以让yyparse到   错误时返回1并拥有调用者   忽略输入行的其余部分   发生了(然后调用yyparse   再次)。

这几乎是我想要的,但我无法上班。基本上,我想在flex中检测和出错,如果检测到错误,让Bison丢弃整行。我现在所拥有的,是不正常的,因为我的命令仍然执行:

kbsh: ls '/home
Error: Unterminated Single Quote
admin  kbrandt  tempuser
syntax error
kbsh: 

在我的Bison文件中:

commands:
     /*Empty*/ { prompt(); } |
     command { prompt(); }
    ;

command:
    error {return 1; } |
    chdir_command |
    pwd_command |
    exit_command |
    WORD arg_list {
        execute_command($1, $2);
        //printf("%s, %s\n", $1, $2); 
    } |
    WORD { execute_command($1, NULL); }
    ;

在我的Flex中:

'   {BEGIN inQuote; }

<inQuote>\n {printf("Error: Unterminated Single Quote\n"); BEGIN(0); return(ERROR);}
有帮助吗?

解决方案

我认为你找不到一个简单的解决方案来处理词法分析器中的这些类型的解析错误。

我会保持词法分析器(flex / lex)尽可能笨,它应该只提供一个基本标记流(标识符,关键字等等)并让解析器(yacc / bison)进行错误检测。实际上,只需对您的方法进行一些重组,它就可以根据您的需要进行设置......

在lexer(parser.l)中,保持简单(没有eol / newline处理),类似(不是完整的东西):

}%

/* I don't recall if the backslashify is required below */
SINGLE_QUOTE_STRING \'.*\'
DOUBLE_QUOTE_STRING \".*\"

%%
{SINGLE_QUOTE_STRING} {
    yylval.charstr = copy_to_tmp_buffer(yytext);  // implies a %union
    return STRING;
}
{DOUBLE_QUOTE_STRING} {
    yylval.charstr = copy_to_tmp_buffer(yytext);  // implies a %union
    return STRING;
}
\n   return NEWLINE;

然后在你的parser.y文件中做所有真正的处理(不是完整的东西):

command:
    error NEWLINE
        { yyclearin; yyerrorok; print_the_next_command_prompt(); }
    | chdir_command STRING NEWLINE
        { do_the_chdir($<charstr>2); print_the_next_command_prompt(); }
    | ... and so on ...

这里有两点需要注意:

  1. 将NEWLINE等内容转移到yacc端,以便您可以确定用户何时完成该命令,然后您可以清除并重新开始(假设您有<!> quot; int yywrap() {return 1;} <!> “某处)。如果你试图在flex中过早发现它,你何时知道引发错误?
  2. chdir不是一个命令(除非它是子规则,你只是没有显示它),它现在有chdir_command STRING(chdir的参数)。这使得解析器可以找出出错的地方,然后如果该目录不存在则可以yyerror等等......
  3. 这样你应该得到类似的东西(猜测chdir可能是什么样子):

      
        

    cd'some_directory
        语法错误
        cd'some_directory'
        你在some_directory dude!

      

    它全部由yacc语法处理,而不是由标记器处理。

    我发现尽可能简单地保持弯曲会给你最大的灵活性。 :)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top