Flex (Lex) 및 Bison (YACC)으로 오류가 발생합니다.
-
07-07-2019 - |
문제
들소 매뉴얼에서 :
각 입력이 한 줄인 간단한 대화식 명령 파서에서 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 ...
여기에는 두 가지 사항이 있습니다.
- Newline과 같은 것들이 YACC쪽으로 전환하여 사용자가 명령으로 언제 수행되었는지 확인할 수있게되면 사물을 정리하고 다시 시작할 수 있습니다 (가지고 있다고 가정합니다.
int yywrap() {return 1;}
"어딘가). Flex에서 너무 일찍 감지하려고한다면 언제 오류를 제기하는 것을 알고 있습니까? - CHDIR은 하나의 명령이 아닙니다 (하위 지배가 지배되지 않았고 당신이 그것을 보여주지 않는 한), 이제 chdir_command 문자열 (chdir에 대한 인수)이 있습니다. 이로 인해 파서가 무엇이 잘못되었는지 알아낼 수 있도록 해당 디렉토리가 존재하지 않으면 yyerror가 될 수 있습니다.
이렇게하면 (CHDIR이 어떻게 생겼는지 추측) : :
cd 'some_directory
구문 오류
cd 'some_directory'
당신은 some_directory 친구에 있습니다!
그리고 그것은 모두 Tokenizer가 아니라 YACC Grammer가 처리합니다.
나는 Flex를 가능한 한 간단하게 유지하면 가장 *** Flex *** I Cality를 제공한다는 것을 알았습니다. :)