2011-12-27 5 views
3

저는 최근에 특수 목적 프로그래밍 언어에 대한 첫 번째 파서/컴파일러를 완성했습니다. 나는이 언어의 명세에서 약간의 자유를 가졌으며 어떤 곳에서는 구문 분석이 더 쉽도록 스펙을 수정했다. 어떤 곳에서는 언어 자체의 개선을 위해 (지금까지) 사소한 점이있었습니다. 어쩌면 나는 미래 v2에서 그것들을 고칠 것이다. 당분간 나는이 과정에서 배운 것들을 여전히 소화하고 있는데 이것에 관해 몇 가지 질문이 있습니다. 필자는 컴파일러 디자인 과정을 공식적으로 듣지 않았으므로 필자의 이해가이 분야의 최첨단 기술과 부합하는지 확인하고자한다.문법/파서 이론에 대한 질문입니다.

  • 대부분의 기사와 교과서는 구문 분석 프로세스를 토큰 화와 어휘 분석의 두 단계로 나눕니다. 일반적으로 대부분의 실제 구현에서 구현을 쉽게하기 위해 보통 두 가지가 서로 얽혀있다. 제 자신의 경험은 반대로, 그것들을 섞으면 일이 더 힘들어지고, 제 3의 패스를 추가하기까지했습니다. 나는 최소한의 토큰 화를 수행하는 첫 번째 단계를 수행하는데, 이는 내가 토큰을 가장 간단한 형태로 정의한다는 것을 의미한다. 예를 들어 생성자 전체가 '토큰'인 접근법을 실험했습니다. 나는 그 접근 방식에서 벗어나서 이제는 프로그램의 가장 기본적인 구성 요소 인 '토큰 (tokens)'만을 부릅니다. 그런 다음 어시스턴트를 작성하는 어휘 분석 과정을 거칩니다. 그렇다면 세 번째 단계는 (내가 부르는) 구조 분석입니다. 함수에 전달되는 인수의 개수가 해당 함수의 서명과 일치하는지 확인하십시오. 일반적으로 '구문 분석'의 일부가 아니거나 '어휘 분석'에 포함될 수 있습니까? 구문 분석 접근 방식을 통과합니까? (논증 할 수 있듯이, 코드 생성 인 네 번째 패스가 있지만, 이는 대부분 별도의 프로세스입니다.)

  • 내 lexer는 (내가 생각하는) recursive-descent입니다. 토큰 스트림과 일치하는 루틴을 가지고 있거나, 할 수 없을 때 false를 반환하고, 모든 토큰이 처리 될 때까지 다른 '규칙'과 완전히 일치하는 루틴을 시도합니다. 이러한 루틴은 최대 2 개의 토큰을 미리 찾습니다. 내가 이해하기에 이것은 내가 'LL (2) 문법'을 가지고 있음을 의미합니다. 내 질문은 :이 번호는 무엇이 중요할까요? 'LL (1) 문법'은 숫자가 높은 문법보다 '더 좋은'것입니까? 또한 역 추적이 바람직하지 않은 이유는 무엇입니까? (그렇지 않습니까? 오해입니까?)

  • 왜 문법의 분류가 그렇게 중요합니까? 모든 텍스트는 (일반적으로 꽤 광범위한) 설명으로 시작하지만, 이해할 수있는대로 디자인중인 언어의 작동 방식을 변경하지 않고도 문법의 속성을 실제로 변경할 수는 없습니다. 이제는 기존 언어를 구문 분석하고 구조를 분류하면 결과 구문 분석기의 복잡성 등급을 증명할 수 있습니다. 그러나 새로운 언어를 설계 할 때, 가장 중요한 것은 표현력 또는 다른 종류의 적합성이며,이를위한 파서의 성능은 부차적 인 것입니다. 이 마지막 부분은 논쟁의 여지가 있지만, 새로운 언어를 설계 할 때 문법의 유형을주의 깊게 관찰 할 수있는 실용적인 이유가 있습니까?

답변

4
  1. 난 당신이 조금 용어를 혼동 생각합니다. 파싱은 출처에서 AST로 진행되는 것을 다루며, "단계"로 나뉘며 "통과"가 아닙니다. "통과"라는 단어를 사용하는 것은 순차적으로 수행된다는 것을 의미하며 이는 일반적으로 사실이 아닙니다.

    실제 어휘 분석 (즉 토큰 화)과 실제 구문 분석이 서로 얽혀있는 이유는 대상 언어의 통어론 특성 때문입니다. 많은 실제 언어의 구문이 "상황에 민감한"토큰을 정의하여 더 잘 설명됩니다. 문자열 보간이나 사용자 정의 연산자를 사용하여 언어를 생각해보십시오.

  2. LL (k) 문법의 구문 분석 표는 최악의 경우 k와 지수 함수 적으로 커집니다. 그 이유는 나쁜 이름 (k> 1)을 가졌기 때문입니다.재귀 적 파생 구문 분석기를 수동으로 구현하는 경우에는 미리보기가 중요하지 않습니다. 그러나 역 추적은 지수 런타임을 유발할 수 있기 때문에 여전히 나쁩니다.

  3. 대상 언어에 영향을주지 않고 문법을 변경할 수 있습니다. 문법이 특정 클래스에 속하는지 확인하면 기존 도구 (예 : LALR 파서 생성기)를 사용할 수 있으며 파서의 런타임 특성에 대한 정보를 얻을 수 있습니다. 약간의 상식이 도움이된다고 할지라도, 또는 C + +와 같은 분석 할 수없는 혼란으로 끝날지라도, 언어 디자인이 파싱 고려 사항으로 인도되면 안된다는 것에 동의합니다.

+0

"약간의 상식이 도움이되거나 C + + 같은 분석 할 수없는 혼란으로 끝날지라도 - 왜 Perl이 아니겠습니까? 나는 새로운 펄이 정말로 파싱 될 수 없다는 것을 알았다. 하지만 실제로 C++ 컴파일러가 작동 중입니다 ... –

관련 문제