문제

저는 Lex와 YACC(실제로는 Flex와 Bison)를 사용하여 컴파일러를 만들고 있습니다.이 언어에서는 모든 기호(예: C#)에 대한 무제한 전방 참조를 허용합니다.문제는 식별자가 무엇인지 모르면 언어를 구문 분석하는 것이 불가능하다는 것입니다.

내가 아는 유일한 해결책은 전체 소스를 렉싱한 다음 "폭 우선" 구문 분석을 수행하여 클래스 선언 및 함수 선언과 같은 상위 수준 항목이 이를 사용하는 함수보다 먼저 구문 분석되도록 하는 것입니다.그러나 이는 큰 파일의 경우 많은 양의 메모리를 차지하며 YACC로 처리하기 어려울 것입니다(선언/본문 유형마다 별도의 문법을 만들어야 합니다).나는 또한 어휘분석기를 손으로 작성해야 할 것이다(이것은 그다지 문제가 되지 않는다).

효율성에 대해서는 크게 신경 쓰지 않습니다(여전히 중요하지만). 일단 컴파일러를 완성하면 자체적으로 다시 작성할 것이기 때문입니다. 하지만 해당 버전이 빠르기를 원합니다. Lex/YACC에서는 할 수 없지만 손으로 ​​할 수 있는 기술도 제안해 주세요.그래서 지금은 개발의 용이성이 가장 중요한 요소입니다.

이 문제에 대한 좋은 해결책이 있습니까?C#이나 Java와 같은 언어용 컴파일러에서는 일반적으로 이 작업이 어떻게 수행되나요?

도움이 되었습니까?

해결책

그것을 분석하는 것은 전적으로 가능합니다.식별자와 키워드 사이에는 모호함이 있지만 lex는 키워드에 우선순위를 부여하여 이에 대처합니다.

다른 문제가 있는지 모르겠습니다.구문 분석 단계에서는 식별자가 유효한지 확인할 필요가 없습니다.구문 분석을 하면서 구문 분석 트리 또는 추상 구문 트리(차이는 미묘하지만 이 논의의 목적과 관련 없음)를 구성하게 됩니다.그런 다음 구문 분석 중에 생성한 AST에 대한 전달을 수행하여 중첩된 기호 테이블 구조를 구축합니다.그런 다음 AST를 통해 또 다른 전달을 수행하여 사용된 식별자가 유효한지 확인합니다.AST에 대한 하나 이상의 추가 구문 분석을 수행하여 출력 코드 또는 기타 중간 데이터 구조를 생성하면 완료됩니다!

편집하다:수행 방법을 보려면 Mono C# 컴파일러의 소스 코드를 확인하세요.이것은 실제로 C나 C++가 아닌 C#으로 작성되었지만 yacc와 매우 유사한 Jay의 .NET 포트를 사용합니다.

다른 팁

한 가지 옵션은 실제 처리 방법을 알 수 있는 항목에 도달할 때까지(일종의 "패닉 모드" 오류 복구와 같은) 토큰을 스캔하고 캐싱하여 전방 참조를 처리하는 것입니다.전체 파일을 생각한 후에는 돌아가서 이전에 구문 분석하지 않은 비트를 다시 구문 분석해 보십시오.

어휘 분석기를 직접 작성해야 하는 경우;그렇지 마십시오. lex를 사용하여 일반 파서를 생성하고 손으로 작성한 shim을 통해 읽으십시오. 그러면 다시 돌아가서 캐시와 lex가 만드는 것에서 파서에 공급할 수 있습니다.

여러 문법을 만드는 것과 관련하여 yacc 파일의 전처리기를 사용하면 약간 재미있고 동일한 원본 소스에서 모두 만들 수 있어야 합니다.

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