문제

들소 매뉴얼에서 :

각 입력이 한 줄인 간단한 대화식 명령 파서에서 Yyparse가 오류에서 1을 반환하고 발신자가 발생할 때 나머지 입력 줄을 무시하게하는 것으로 충분할 수 있습니다 (그리고 Yyparse를 다시 호출하십시오).

이것은 내가 원하는 것과 거의 비슷하지만 일하는 데 어려움을 겪고 있습니다. 기본적으로 Flex의 감지 및 오류를 원하고 오류가 감지되면 Bison이 전체 라인을 폐기하도록합니다. 내가 지금 가지고있는 것은 내 명령이 여전히 실행되기 때문에 제대로 작동하지 않습니다.

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

내 들소 파일에서 :

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

그리고 내 플렉스에서 :

'   {BEGIN inQuote; }

<inQuote>\n {printf("Error: Unterminated Single Quote\n"); BEGIN(0); return(ERROR);}
도움이 되었습니까?

해결책

Lexer에서 이러한 유형의 구문 분석 오류를 처리하는 간단한 솔루션을 찾을 수 없다고 생각합니다.

Lexer (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쪽으로 전환하여 사용자가 명령으로 언제 수행되었는지 확인할 수있게되면 사물을 정리하고 다시 시작할 수 있습니다 (가지고 있다고 가정합니다.int yywrap() {return 1;}"어딘가). Flex에서 너무 일찍 감지하려고한다면 언제 오류를 제기하는 것을 알고 있습니까?
  2. CHDIR은 하나의 명령이 아닙니다 (하위 지배가 지배되지 않았고 당신이 그것을 보여주지 않는 한), 이제 chdir_command 문자열 (chdir에 대한 인수)이 있습니다. 이로 인해 파서가 무엇이 잘못되었는지 알아낼 수 있도록 해당 디렉토리가 존재하지 않으면 yyerror가 될 수 있습니다.

이렇게하면 (CHDIR이 어떻게 생겼는지 추측) : :

cd 'some_directory
구문 오류
cd 'some_directory'
당신은 some_directory 친구에 있습니다!

그리고 그것은 모두 Tokenizer가 아니라 YACC Grammer가 처리합니다.

나는 Flex를 가능한 한 간단하게 유지하면 가장 *** Flex *** I Cality를 제공한다는 것을 알았습니다. :)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top