2015-01-18 21 views
0

필자는 yacc.My 언어를 사용하여 내 자신의 문법을 정의했다. 내 컴파일러를 사용하여 컴파일 할 각 파일에 적용 할 컴파일러를 호출하는 동안 사용자에게 추가 헤더를 명시 적으로 제공 할 수있는 유연성을 제공한다.Lex/yacc를 사용하여 특정 헤더가있는 파일 수를 검사하는 가장 좋은 방법은 무엇입니까?

이 시나리오에서는 두 가지 해결책을 생각해 볼 수 있습니다.

1. 각 파일에 헤더를 첨부하고 각각의 파일을 개별적으로 컴파일하십시오. 이는 파일의 시작 부분에 추가해야하는 특정 소스 파일을 편집하는 것과 관련하여 바람직하지 않습니다.

2. yywrap을 사용하여 컴파일 할 파일 목록을 반복하고 새 파일을 찾을 때마다 헤더를 처리하십시오. 동일한 파일을 반복해서 파싱해야하기 때문에 좋지 않습니다.

헤더를 처리하지 않으면 파일이 문법을 충족하지 못합니다.

가장 좋은 방법으로 생각을 공유하십시오.

답변

3

컴파일러가 여러 파일을 개별적으로 컴파일하고 단일 단위로 컴파일하는 대신 헤더 파일이 각 입력 파일에 필요하면 컴파일하는 동안 선택할 수있는 옵션이 거의 없지만 각 입력 파일의 처리 yywrap 메커니즘을 사용하거나 yy_create_bufferyy_switch_to_buffer을 사용하여 버퍼를 명시 적으로 전환하여이 작업을 수행 할 수 있습니다. 자세한 내용과 샘플 코드는 flex manual을 참조하십시오.

이 솔루션은 모든 입력 파일의 헤더 파일을 다시 구문 분석하는 데 시간이 많이 걸릴 수 있습니다.

파스가 나중에 컴파일 된 출력 또는 기타 분석을 생성하기 위해 처리되는 AST를 만드는 것 외에 다른 효과가 없다면 헤더 파일에 대한 AST를 한 번만 작성하여이 프로세스를보다 효율적으로 만들 수 있습니다. 헤더 파일의 AST 복사본으로 시작하여 각 입력 파일에 대한 AST를 작성합니다.

헤더 파일의 AST를 직렬화 한 다음 다시 파싱하는 대신 직렬화 된 버전을 읽을 수도 있지만 직렬화 된 AST가 가장 최신 버전의 헤더와 일치하는지 확인하는 데 약간의 논리가 필요합니다 파일. 이 메커니즘 ()은 많은 C/C++ 컴파일러 (예 : gcc, clang, Visual Studio)에 의해 다른 형태로 구현됩니다.

+0

주셔서 감사합니다. 나는 yy_scan_string (char *)을 사용하여 수행 할 수 있음을 알고 있습니다. 어떻게 의심하는지 여전히 알 수 있습니다. 먼저 문자열을 스캔 한 다음 파일을 검사해야합니다. yy_buffer_state 스택을 유지해야합니다. 목적? char *에 의해 생성 된 버퍼 스캔이 yywrap 또는 <>으로 끝나는 파일의 경우와 같이 종료하는 방법은 무엇입니까? –

+0

EOF로 끝납니다. 원하는 경우가 아니면 버퍼 스택이 필요 없습니다. EOF 작업에서 버퍼를 바꿀 수 있습니다. 동일한 문자열을 두 번 이상 검사하려는 경우 yy_scan_buffer를 사용하고 사본을 피할 수 있도록 두 개의 NUL 터미네이터가있는 문자열 버전을 만드는 것이 약간 효율적입니다. – rici

+0

고마워. 새 문제가 생겼어. 이제 파일 두 개와 char *로 두 개의 버퍼 상태를 만들어야 해. 문제는, 어떻게 yy_create_buffer (FILE *, size_t)를 사용할 때 크기를 사용할 수 있는지입니다. 만약 내가 YY_BUF_SIZE를 사용하여 정의 된 16k 또는 덮어 쓸 수도 있지만 그것은 제한된 수의 character.Do 가지고 내 파일을 제한 할 것이라고 또한 yyin 메커니즘이 YY_BUF_SIZE 제한도 있습니까? –