2015-01-28 7 views
0

flex/bison 프로그램을 실행할 때 "디버그 어설 션이 실패했습니다. 식 스트림! = NULL"오류가 발생합니다. 여기에 관련 코드는 렉스 파일의 상단에 있습니다 :"포함"기능을 프로그래밍하려고 할 때 flex/bison 프로그램에서 어설 션 오류가 발생했습니다.

%x include_state 

%{ 
    #define MAX_INCLUDE_DEPTH 10 
    YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; 
    int include_stack_ptr = 0; 
%} 

... 나중에 렉스 파일 :

include[ \t]*\" { BEGIN(include_state); } 
<include_state>[a-zA-Z0-9 ]+ { 
    if (include_stack_ptr >= MAX_INCLUDE_DEPTH) 
    { 
     fprintf(stderr, "Includes nested too deeply"); 
     exit(1); 
    } 
    include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; 
    yyin = fopen(yytext, "r"); 
    if (!yyin) 
     sprintf(err_str, "Error opening include file: %s", yytext); 
    yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner), 
     yyscanner); 
} 
<include_state>\"; { BEGIN(INITIAL); } 

... 이렇게 되었하려고하는 텍스트는 다음과 같습니다

include "hello.txt"; 

내 프로그램에 "포함"기능을 추가하려고합니다. 나는 flex flex와 win bison을 사용하고 있습니다. (A면 문제 : 어떻게 내가 렉스 파일의 코드 라인을 분할합니까?)

+1

답변을 수락하지 않으셨습니까? 당신에게 충분한 대답이 아니십니까? –

+0

나는 지금 어떤 것을 가지고있다. – tyebillion

+1

'lex' 파일 내용을 포맷 할 수 있습니까? –

답변

2

디버그 어설 당신이 읽거나 암시 것이다 NULL하는 FILE*, 쓰기 시도 사실을 말하는 윈도우 런타임의 방법입니다 fopen가 실패했습니다. fopen이 실패하면

yyin = fopen(yytext, "r"); 
if (!yyin) 
    sprintf(err_str, "Error opening include file: %s", yytext); 
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner), 
    yyscanner); 

, 당신은 좋은 오류 메시지를 생성하지만, 그것으로 아무것도하지 않는 것 : 당신은 어느 쪽을 인쇄하지 않고 당신이로 전환되지 않도록 않는 코드에서

새 버퍼는 yyin의 값이 NULL입니다.

따라서 fopen이 (가) 실패하여 NULL에서 읽는 것으로 보입니다.

그러나 코드에 또 다른 문제가 있습니다.

flex 시작 조건은 버퍼의 일부가 아닙니다. 그것은 세계적입니다. 새 버퍼 으로 전환하면 시작 조건을 저장하지 않습니다 (어딘가에 저장하지 않는 한). 마찬가지로 시작 조건을 저장하지 않으면 원래 버퍼로 다시 전환 할 때 복원 할 수 없습니다. 즉, 버퍼를 전환 할 때 시작 상태가 include_state이므로 포함 된 파일을 토큰 화하기 시작하면 해당 시작 조건에 계속 남아 있습니다. 즉, 해당 파일의 시작 부분에있는 문자열 (시작 문자가 [[:alnum:] ])은 포함 할 파일 이름으로 사용하십시오. 그게 너의 fopen이 실패하는 이유일지도 모른다.

다른 명백한 문제는 잘라 붙이기 문제라고 생각됩니다. 당신은 다음을 가지고 있습니다 :

<include_state>[a-zA-Z0-9 ]+ 
{ 

빈 행동으로 이어지는 패턴이며 자유 행동 (결코 실행되지 않을 것입니다)이 뒤따라야합니다. 작업은 이어야합니다.은 패턴과 같은 줄에 있어야합니다. flex는 일치하는 }을 찾을 때까지 작업을 계속 읽어, 그래서 당신은 단지 패턴으로 같은 줄에 {을 둘 필요가 : 코드 분할 "에 의해 당신이 무슨 뜻 밖의 무엇 확실하지 않다

<include_state>[a-zA-Z0-9 ]+  { 

다른 줄에 "그 질문에 대한 답변이되기를 바랍니다.

+0

오른쪽! 파일 이름이 잘못 되었기 때문에 fopen이 실패했습니다. 나는 "."을 확인하는 것을 잊었다. 이름으로. 렉스 패턴/동작에서 괄호/행에 대한 논리를 명확히 해 주셔서 감사합니다. – tyebillion