C보다 Java를 구문 분석하기가 더 쉬운 이유는 무엇입니까?


90

저는 C와 C ++의 문법이 문맥에 민감 하다는 사실을 잘 알고 있습니다. 특히 C에서 "lexer hack"이 필요하다는 사실을 알고 있습니다. 두 언어간에 상당한 유사성에도 불구하고 2 개의 미리보기 토큰.

구문 분석을 더 쉽게하기 위해 C에 대해 무엇을 변경해야합니까?

C의 컨텍스트 민감도에 대해 본 모든 예제가 기술적으로 허용되지만 끔찍하게 이상하기 때문에 묻습니다. 예를 들면

foo (a);

foo인수로 void 함수 를 호출 할 수 있습니다 a. 또는 a유형의 객체 로 선언 할 수 foo있지만 괄호를 쉽게 제거 할 수 있습니다. 부분적으로 이러한 이상 함은 C 문법에 대한 "직접 선언자"생성 규칙이 함수와 변수를 모두 선언하는 이중 목적을 충족 하기 때문에 발생 합니다.

반면에 Java 문법 에는 변수 선언과 함수 선언에 대한 별도의 생산 규칙이 있습니다. 당신이 쓰면

foo a;

그러면 그것이 변수 선언이고 foo분명하게 타입 이름으로 파싱 될 수 있다는 것을 알고 있습니다. 클래스 foo가 현재 범위의 어딘가에 정의되지 않은 경우 유효한 코드가 아닐 수 있지만 이는 나중에 컴파일러 패스에서 수행 할 수있는 의미 분석 작업입니다.

C가 typedef로 인해 구문 분석하기 어렵다고 말했지만 Java에서도 자신의 유형을 선언 할 수 있습니다. 외에 어떤 C 문법 규칙 direct_declarator이 잘못 되었습니까?


7
멋진 질문입니다. 아마도 너무 광범위하거나 주로 의견이 많을 것입니다.
asteri

37
이것은 파서에 대한 유효한 질문이며 그것에 대한 광범위한 의견이나 의견은 마지막 몇 개의 문장입니다 (아마도 삭제하거나 변경해야 함). 가까운 투표로 종료하십시오.
R .. GitHub의 STOP 돕기 ICE

1
그에 따라 질문을 편집했습니다. 피드백에 대해 @R .. 감사합니다.
korrok 2014 년

3
거의 모든 (표준) 컴퓨터 언어는 상황에 따라 다릅니다 . 한 가지 유형의 변수를 선언 할 수 없으며 대부분의 langauges . 이는 " 언어에 대한 모든 문법 "이 상황에 맞는 것과는 다릅니다 . 파서를 작성하는 대부분의 사람들은 컨텍스트없는 (또는 훨씬 더 제한적인) 파서를 만든 다음 파서 외부에서 해킹을 사용하여 컨텍스트없는 속성을 확인합니다.
Ira Baxter

1
@IraBaxter 나는 그것을 "핵"이라고 부르지 않을 것이다. 상황에 맞는 언어를 파싱하는 것은 효율적으로 수행 할 수 없기 때문에 문제를 둘로 나누는 것이 합리적으로 보입니다. . 컨텍스트 프리 구문 분석 + 정적 분석은 AST를 통해 컨텍스트에 민감한 속성 만 확인하는 것이 합리적입니다.
Bakuriu 2014 년

답변:


76

C ++ 구문 분석이 어려워지고 있습니다. 자바 구문 분석도 그만큼 어려워지고 있습니다.

C (및 C ++)가 구문 분석하기 "어려운"이유를 설명하는SO 답변을 참조하십시오 . 짧은 요약은 C 및 C ++ 문법 이 본질적으로 모호하다는 것입니다. 여러 구문 분석을 제공 하므로 모호성을 해결하려면 컨텍스트를 사용해야합니다 . 그런 다음 사람들은 구문 분석 할 때 모호성을 해결해야한다고 가정하는 실수를합니다. 그렇지 않으면 아래를 참조하십시오. 구문 분석 할 때 모호성을 해결해야한다고 주장하면 구문 분석기가 더 복잡해지고 빌드하기가 훨씬 더 어려워집니다. 하지만 그 복잡성은 자해 상처입니다.

IIRC, Java 1.4의 "명백한"LALR (1) 문법은 모호하지 않았으므로 구문 분석이 "쉬웠습니다". 나는 현대 자바가 적어도 장거리 로컬 모호성을 가지고 있지 않다고 확신하지 못한다. "... >>"가 두 개의 템플릿을 닫는 지 또는 "오른쪽 시프트 연산자"인지 여부를 결정하는 데 항상 문제가 있습니다. 현대 자바가 더 이상 LALR (1)로 구문 분석하지 않는다고 생각 합니다.

그러나 두 언어 모두에 대해 강력한 파서 (또는 현재 C 및 C ++ 프런트 엔드가 대부분 사용하는 약한 파서 및 컨텍스트 수집 해킹)를 사용하여 파싱 문제를 해결할 수 있습니다. C와 C ++는 전처리기를 갖는 추가적인 복잡성이 있습니다. 이들은보기보다 실제로 더 복잡합니다. 한 가지 주장은 C 및 C ++ 파서가 너무 어렵 기 때문에 손으로 작성해야한다는 것입니다. 사실이 아닙니다. GLR 파서 생성기를 사용하면 Java 및 C ++ 파서를 빌드 할 수 있습니다.

그러나 파싱은 실제로 문제가있는 곳이 아닙니다.

구문 분석을 마치면 AST / parse 트리를 사용하여 작업을 수행 할 수 있습니다. 실제로 모든 식별자에 대해 그 정의가 무엇이며 어디에 사용되는지 알아야합니다 ( "이름 및 유형 확인", 엉성하게 기호 테이블 작성). 이것은 상속, 인터페이스, 오버로딩 및 템플릿으로 인해 구문 분석기를 올바르게 설정하는 것보다 훨씬 더 많은 작업이며,이 모든 것에 대한 의미 체계가 수십에서 수백 페이지에 걸쳐있는 비공식적 인 자연 언어로 작성되었다는 사실로 인해 혼란스러워졌습니다. 언어 표준의. 여기서 C ++는 정말 나쁩니다. Java 7과 8은이 관점에서 꽤 끔찍해졌습니다. (심볼 테이블이 필요한 전부는 아닙니다. "파싱 이후의 삶"에 대한 더 긴 에세이는 저의 약력을 참조하십시오).

대부분의 사람들은 순수한 구문 분석 부분 (종종 절대 끝나지 않습니다. 실제 언어에 대한 작동 구문 분석기를 빌드하는 방법에 대한 많은 질문에 대해 SO 자체를 확인하십시오)에 어려움을 겪으므로 구문 분석 후 삶을 보지 못합니다. 그리고 우리는 파싱하기 어려운 것에 대한 민속 정리를 얻고 그 단계 이후에 일어나는 일에 대한 신호가 없습니다.

C ++ 구문을 수정해도 아무데도 가지 않습니다.

C ++ 구문 변경과 관련하여 : 모든 C ++ 문법에서 다양한 로컬 및 실제 모호성을 처리하기 위해 많은 부분을 패치해야합니다. 주장한다면 다음 목록이 좋은 출발점이 될 수 있습니다 . 나는 당신이 C ++ 표준위원회가 아니라면이 일을하는 데 아무런 의미가 없다고 주장한다. 당신이 그렇게하고 그것을 사용하여 컴파일러를 구축한다면, 아무도 그것을 사용하지 않을 것입니다. 파서를 구축하는 사람들의 편의를 위해 전환하기 위해 기존 C ++ 애플리케이션에 너무 많은 투자가 이루어졌습니다. 게다가 그들의 고통은 끝났고 기존 파서는 잘 작동합니다.

자신의 파서를 작성하는 것이 좋습니다. 좋아요, 괜찮습니다. 커뮤니티의 나머지 부분이 여러분이 더 쉽게 사용할 수 있도록 사용해야하는 언어를 변경할 수 있다고 기대하지 마십시오. 그들은 모두 그들이 더 쉽게하기를 원하며 그것은 문서화되고 구현 된대로 언어를 사용하는 것입니다.


좋은 대답입니다. 이러한 문제 중 일부를 해결하려는 D 및 C +도 참조하십시오. s / content / contend /
david.pfx

3
나는 이전에 Life After Parsing을 읽었고 그것이 진짜 눈을 뜨게했다는 것을 알았습니다. 그것은 구문 분석보다 의미 론적 분석 (이름 / 유형 확인, ...)에서 훨씬 더 많은 작업이 있다는 것을 나에게 분명히 보여주었습니다. 나는 어떤 언어의 구문도 바꾸려고 하지 않습니다 . 내가 않는 속성이 먼저 구문 분석을 할 수있는 언어와 그 의미 분석의 무엇인지 이해하고 싶다. C는 그런 언어가 아닙니다 (렉서 해킹이 필요합니다). 저는 항상 Java가 있다고 생각했고 그 이유를 알고 싶습니다.
korrok

1
@Korrok : GLR 파서를 사용하여 Java / C ++ 빌드에 대한 내 대답을 읽으십시오. 렉서 해킹이 필요하지 않습니다 . 따라서 구분은 잘못된 구문 분석 기술을 사용하는 사람들의 마음에 있습니다. ... 물론, 완전한 C ++ 프론트 엔드 (특히 우리가해온 C ++ 14)를 구축하는 것은 Java8을 수행하는 것보다 어렵지만 (노력과 세부 사항에주의를 기울이는면에서) 어렵고 파싱입니다. 가장 쉬운 부분입니다.
Ira Baxter

1
귀하의 "파싱 후 수명"에 동의합니다. 예를 들어 C #의 과부하 해결은 모든 3-SAT 문제를 인코딩 할 수 있으므로 NP가 어렵습니다.
Jörg W Mittag 2014 년

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.