저는 최근에 특수 목적 프로그래밍 언어에 대한 첫 번째 파서/컴파일러를 완성했습니다. 나는이 언어의 명세에서 약간의 자유를 가졌으며 어떤 곳에서는 구문 분석이 더 쉽도록 스펙을 수정했다. 어떤 곳에서는 언어 자체의 개선을 위해 (지금까지) 사소한 점이있었습니다. 어쩌면 나는 미래 v2에서 그것들을 고칠 것이다. 당분간 나는이 과정에서 배운 것들을 여전히 소화하고 있는데 이것에 관해 몇 가지 질문이 있습니다. 필자는 컴파일러 디자인 과정을 공식적으로 듣지 않았으므로 필자의 이해가이 분야의 최첨단 기술과 부합하는지 확인하고자한다.문법/파서 이론에 대한 질문입니다.
대부분의 기사와 교과서는 구문 분석 프로세스를 토큰 화와 어휘 분석의 두 단계로 나눕니다. 일반적으로 대부분의 실제 구현에서 구현을 쉽게하기 위해 보통 두 가지가 서로 얽혀있다. 제 자신의 경험은 반대로, 그것들을 섞으면 일이 더 힘들어지고, 제 3의 패스를 추가하기까지했습니다. 나는 최소한의 토큰 화를 수행하는 첫 번째 단계를 수행하는데, 이는 내가 토큰을 가장 간단한 형태로 정의한다는 것을 의미한다. 예를 들어 생성자 전체가 '토큰'인 접근법을 실험했습니다. 나는 그 접근 방식에서 벗어나서 이제는 프로그램의 가장 기본적인 구성 요소 인 '토큰 (tokens)'만을 부릅니다. 그런 다음 어시스턴트를 작성하는 어휘 분석 과정을 거칩니다. 그렇다면 세 번째 단계는 (내가 부르는) 구조 분석입니다. 함수에 전달되는 인수의 개수가 해당 함수의 서명과 일치하는지 확인하십시오. 일반적으로 '구문 분석'의 일부가 아니거나 '어휘 분석'에 포함될 수 있습니까? 구문 분석 접근 방식을 통과합니까? (논증 할 수 있듯이, 코드 생성 인 네 번째 패스가 있지만, 이는 대부분 별도의 프로세스입니다.)
내 lexer는 (내가 생각하는) recursive-descent입니다. 토큰 스트림과 일치하는 루틴을 가지고 있거나, 할 수 없을 때 false를 반환하고, 모든 토큰이 처리 될 때까지 다른 '규칙'과 완전히 일치하는 루틴을 시도합니다. 이러한 루틴은 최대 2 개의 토큰을 미리 찾습니다. 내가 이해하기에 이것은 내가 'LL (2) 문법'을 가지고 있음을 의미합니다. 내 질문은 :이 번호는 무엇이 중요할까요? 'LL (1) 문법'은 숫자가 높은 문법보다 '더 좋은'것입니까? 또한 역 추적이 바람직하지 않은 이유는 무엇입니까? (그렇지 않습니까? 오해입니까?)
왜 문법의 분류가 그렇게 중요합니까? 모든 텍스트는 (일반적으로 꽤 광범위한) 설명으로 시작하지만, 이해할 수있는대로 디자인중인 언어의 작동 방식을 변경하지 않고도 문법의 속성을 실제로 변경할 수는 없습니다. 이제는 기존 언어를 구문 분석하고 구조를 분류하면 결과 구문 분석기의 복잡성 등급을 증명할 수 있습니다. 그러나 새로운 언어를 설계 할 때, 가장 중요한 것은 표현력 또는 다른 종류의 적합성이며,이를위한 파서의 성능은 부차적 인 것입니다. 이 마지막 부분은 논쟁의 여지가 있지만, 새로운 언어를 설계 할 때 문법의 유형을주의 깊게 관찰 할 수있는 실용적인 이유가 있습니까?
"약간의 상식이 도움이되거나 C + + 같은 분석 할 수없는 혼란으로 끝날지라도 - 왜 Perl이 아니겠습니까? 나는 새로운 펄이 정말로 파싱 될 수 없다는 것을 알았다. 하지만 실제로 C++ 컴파일러가 작동 중입니다 ... –