답변:
파서의 출력은 트리 일 필요는 없습니다. 실제로 추상 구문 트리에 겹쳐진 변수의 USE에서 DEFinition까지의 참조와 같은 것을 고려할 때 즉시 그래프가 나타납니다.
문제는 일반적으로 구문 분석은 단일 패스에서 수행되도록 설계 되었기 때문입니다. 이는 공간 부족 및 프로세서 속도와 같은 역사적 이유로뿐만 아니라 추론하기가 더 간단하기 때문입니다. 그런 다음 후속 단계에서는 추가 정보를 사용하여 구문 분석 트리를 장식합니다.
프로그래밍 문법을 파싱하는 데 사용되는지는 모르겠지만 그래프 문법과 같은 것들이 있습니다.
OP의 질문은 약간 거꾸로 언급되었습니다. 물론 파싱 알고리즘은 원하는 것을 출력 할 수 있습니다. 문제는 구문 분석의 목적과 구문 분석기가이 목표에 맞는 결과를 출력하는지 여부를 이해하는 것입니다. 그런 다음 트리 또는 그래프와 같이 적절한 표현이 무엇인지 궁금 할 수 있습니다.
글쎄, 파서는 언어의 구문에 대한 공식적인 정의에 따라 입력으로 주어진 문장의 구문 구조를 제공하는 알고리즘이라고 생각합니다.
사람들은 언어의 구문을 구성하는 요소에 동의하지 않을 수 있습니다. 일부는 순수한 공식 언어 백본으로 제한하는 반면 다른 유형은 유형, 장르, 숫자 또는 기타 더 복잡한 것들과 같은 약간 더 의미 론적 고려 사항을 도입 할 수 있습니다 (NLP 또는 프로그래밍 언어를 구별하지 않습니다). 대부분의 언어에는 그래프를 표시해야하는 기능이 있지만 구문에 포함할지 여부를 결정하는 것은 "구현 자"(더 나은 단어가 없음)에 달려 있습니다.
따라서 구문을 정의한 내용에 따라 다른 종류의 공식 구조를 출력해야 할 수도 있습니다.
단순한 Context-Free 구문 분석의 간단한 경우, 아래에 설명 된 모호성 문제 또는 AST를 얻기 위해 비트를 약간 수정하려는 경우를 제외하고 구문 분석 트리가 수행 할 수 있습니다 (아래 참조).
그러나 더 복잡한 경우에는 종종 트리에서 링크로 표시되는 다른 구조가 필요할 수 있으므로 그래프 구조로 이어집니다. 이것은 언어 구문의 정의에 크게 좌우됩니다.
또한 어떤 트리를 출력해야하는지 명확하지 않습니다. 트리 인접 문법 (TAG)의 경우 구문 트리가 파생 트리와 동일하지 않은 방식으로 작동하지만 전자는 후자에서 파생 될 수 있습니다. 출력하려는 것은 관련 질문 일 수 있습니다.
모호성과 관련하여 또 다른 문제가 있습니다. 주어진 문장은 귀하의 언어에 속하면서 여러 가지 방식으로 수행 될 수 있지만 여러 가지 방식으로 구문 구조가 지정 될 수 있습니다.
그런 다음 무작위로 또는 잘 정의 된 기준 (예 : 가능성)에 따라 이러한 구조 중 하나만 출력하도록 선택할 수 있습니다. 여러 개 또는 모두를 출력하도록 선택할 수도 있습니다. 여러 개를 출력하려면 일반적으로 공통 구조를 공유하는 고유 한 구조로 포장하는 것이 좋습니다. 따라서 공간과 컴퓨팅 시간이 절약되며 복잡성이 실제로 문제가 될 수 있습니다.
모든 출력을 선택하면 가능한 수의 구문 분석이있을 수 있으므로 공유 할 수밖에 없습니다. 그리고 어떻게 든 그래프에 사이클을 가짐으로써 만 무한히 유한하게 표현 될 수 있습니다. 따라서 일반적으로 그래프 구조를 만들어야합니다. 그러나이 그래프 구조의 속성은 선택한 공식 구문의 종류와 관련이 있습니다.
이제 질문은 추상 구문 트리에 관한 것이 었습니다. 혼란을 가져 오기 때문에 "추상적 인"부분을 건너 뛰었습니다. 실제로 그 문제는 다양한 재개에서 이미 혼동되고 있습니다.
역사적 관점에서 AST와 관련하여 1960-1970 년의 언어 리스프 및 프로그램 조작 시스템에서 유래합니다. 이 아이디어는 조작 목적을 위해 수학 공식처럼 큰 표현으로 프로그램을 고려하고 공식적인 방식으로 속성을 분석하거나 의미를 정의하는 것으로 수학자는 공식에서 수행하는 방법을 알고있었습니다. 공식적으로, 그것들은 자연적으로 나무 구조로되어 있었지만,이 나무들을 그래프로 바꾸는 다양한 정보로 장식 될 수있었습니다. 이것은 공식적으로나 실용적으로 편리했으며 컴파일러와 프로그래밍 시스템에서 더 많이 사용되었습니다.
따라서 기본적으로 AST는 이름에서 알 수 있듯이 나무이지만 추가 정보를 전달할 수 있습니다. 나머지는 구현 자의 선택과 보는 사람의 눈에 있습니다. 그래프입니까, 장식 된 나무입니까? 그러나 기본 AS 트리는 이론과 프로그래밍 모두에서 구축 한 스캐 폴딩이기 때문에 중요합니다.
AST는 형식 언어 이론에서 연구 된 파싱 알고리즘에 의해 생성 된 구문 분석 트리 (구문은 문맥에 기초하지 않음)와 구별되었다. 그 이유는 구문의 설계가 당시의 구문 분석 기술에 의해 제약을 받았으며, 그 자체가 이용 가능한 낮은 컴퓨팅 능력에 의해 제약을 받기 때문이었다. 그 결과 구문 트리는 자연스럽게 프로그램의 구조를 고려한 것의 고문 변형 일 뿐이며, 기본 공식 파싱 프로세스의 일부가 아닌 추가 처리는 AST라는 더 깨끗하고 간단한 버전을 얻기 위해 수행되어야했습니다.
그러나 컴퓨터의 트리 표현은 추상적이든 아니든 모호한 문장의 모든 구조를 나타내려고 할 때 다소 제한적입니다. 특히 이것은 복잡성 문제를 숨 깁니다. 구문 분석 트리에서 AS 트리로 변환하는 동안 그래프 구조의 모호성을 보존하는 것도 문제가 될 수 있습니다. 그러나 걱정이되는 경우 구문 분석 트리가 AST로 제공 될 수있는 방식으로 구체적인 구문을 정의하는 것이 종종 가능합니다. 이는 모호성을 처리하는 매우 일반적인 알고리즘과 현재 컴퓨터의 성능에 의해 허용됩니다.
GLR 구문 분석 (일반화 된 LR)을 사용하여 구문 분석하고 입력 구문 분석이 모호한 경우 (입력 구문 분석에 가능한 여러 방법이 있음) 구문 분석 결과는 구문 분석 DAG가 아닌 구문 분석 DAG로 간주 될 수 있습니다. 트리를 구문 분석하십시오. 구문 분석 DAG는 여러 가지 구문 분석 트리 (작은 가능한 구문 분석 트리)를 간결하게 인코딩합니다.
그러나 결론은 문맥이없는 문법이 있고 입력 문자열을 명확하게 구문 분석 할 수있는 경우 (이 입력 문자열을 생성하는 문법에는 단일 파생 만 있음) 구문 분석 작업이 생성되는 경우입니다. 이러한 조건 하에서 구문 분석 결과는 항상 구문 분석 트리 일 것입니다. 문맥없는 문법은 기본적으로 트리 구조를 갖기 때문입니다.
예를 들어 + = 연산자의 "AST"(예 :)가 트리가 아닌 C에 대한 인터프리터를 작성했습니다. 고려 a[i++] += d
곳 a[i++]
이다 int
하고 d
있다 double
. 암시 적 변환 및 페치 조작은 트리에서 명시 적이므로 문제는 페치 a[i++]
및 변환을 두 배로 둘 위치에 있습니다. 우리의 해결책은 나무를 버리는 것이었다. 결과 "ASG"는 다음과 같습니다
+=
/ | \
/ | \
/ | \
/ convert \
| | \
| fetch fetch
| / |
index d
/ \
a postinc
|
i