PHP로 작성된 괜찮은 PHP 파서? [닫은]


80

저는 PHP 코드를 조작하고 분석하는 작업을 많이합니다. 일반적으로 저는이를 위해 Tokenizer 를 사용합니다 . 대부분의 응용 프로그램에서는 이것으로 충분합니다. 그러나 때로는 어휘 분석기를 사용하여 구문 분석하는 것이 (분명히) 충분히 신뢰할 수 없습니다.

따라서 나는 PHP로 작성된 PHP 파서를 찾고 있습니다. hnw / PhpParserkumatch / stagehand-php-parser를 찾았 습니다 . 둘 다 zend_language_parser.y 를 C 대신 PHP를 사용하여 .y 파일로 자동 변환 한 다음 LALR (1) 파서로 컴파일합니다. 그러나이 자동 변환은 작동 할 수 없습니다.

그렇다면 PHP로 작성된 괜찮은 PHP 파서가 있습니까? (PHP 5.2 용과 5.3 용이 필요합니다.하지만 그중 하나만 좋은 출발점이 될 것입니다.)


1
당신의 목표는 무엇입니까? 여기서 무엇을 성취하려고하십니까?
Charles

3
@Charles : 내가 이것을 사용할 많은 것들이 있습니다. AST 표현의 PHP 소스 코드가 필요한 모든 것;)
NikiC 2011

1
@mario : 그 사람은 많은 정보를 떨어 뜨립니다. 실제로 파일에 대한 일부 정보를 추출하는 작업을 위해서만 설계되었습니다. 따라서 클래스 문, 메서드 문 또는 반환 문과 같은 것만 유지하지만 실제로 가장 관심이있는 코드는 모두 무시합니다.
NikiC 2011

2
PHP로 코딩 된 강력한 대규모 언어 파서를 찾을 수 없을 것 같습니다. 그것에 대한 전화가 없습니다.
Ira Baxter

4
지난주에 필자는 파서의 초기 버전을 직접 작성했습니다. github.com/nikic/PHP-Parser 제 코드베이스에 대해 테스트했고 잘 작동했습니다. 인터페이스를 개선하여 실제로 사용할 수 있도록 노력하겠습니다.
NikiC 2011

답변:


128

여기에서 완전하고 안정적인 파서를 찾지 못한 후 직접 작성하기로 결정했습니다. 결과는 다음과 같습니다.

PHP-Parser : PHP로 작성된 PHP 파서

이 프로젝트는 PHP 5.2와 PHP 7.1 사이의 모든 PHP 버전 용으로 작성된 구문 분석 코드를 지원합니다.

파서 자체 외에도 라이브러리는 몇 가지 관련 구성 요소를 제공합니다.

  • AST를 PHP로 다시 컴파일 ( "예쁜 인쇄")
  • AST 순회 및 변경을위한 인프라
  • XML과의 직렬화 (사람이 읽을 수있는 형식으로 덤프 포함)
  • 네임 스페이스 이름 (별칭 등) 확인

사용 개요 는 설명서의 "기본 구성 요소 사용" 섹션을 참조하십시오 .


2
굉장합니다! 그것을 유지할 계획이 있습니까?
MikeSchinkel 2015

1
@NikiC 감사합니다! 즉 :-) 좋은 도서관
BVengerov

1
2011 년 12 월 초 PHP 7.1 지원!
dotancohen

9

이것은 순수 PHP 제약을 위반하기 때문에 당신에게 좋은 선택이되지는 않을 것입니다.

얼마 전 php-internals 사람들은 파싱 ​​기술 로 Lemon 으로 전환하기로 결정했습니다 . 있다 PHP는 svn의 환매 특약에 지점 필요한 변경 사항이 포함되어 있습니다.

그들은 레몬 용액이 약 10-15 % 더 느리다는 것을 알았 기 때문에 이것을 계속하지 않기로 결정했습니다 . 그러나 지점은 여전히 ​​있습니다.

있다 오래된 레몬 파서 PHP 확장으로 작성가. 당신은 그것으로 작업 할 수 있습니다. 도 있습니다 이 PEAR 패키지 . 도 있는데 이 다른 레몬 패키지 (통해 에 대한 블로그 게시물 PGN ).

물론 제대로 작동하더라도 데이터로 무엇을할지 또는 데이터가 어떻게 보이는지 잘 모르겠습니다.

또 다른 이상한 옵션은 Java로 구현 된 PHP 인 Quercus를 엿보는 것 입니다. 그들은 파서를 작성해야했고, 조사해볼 가치가 있을지도 모릅니다.


우선 : 광범위한 연구를 위해 +1. 주된 문제는 PHP에서 파서를 빌드 할 방법이 없다는 것이 아닙니다. 레몬 PHP 문법을 사용하고 컴파일하는 것에 대해 이미 언급했습니다. "실제"yacc / bison 문법을 사용하는 것이 더 쉬울 것입니다 (컴파일러도 있습니다). 문제는 opcode를 생성하기위한 yacc C 코드를 AST를 생성하기위한 yacc PHP 코드로 변환하는 것이 정말 많은 작업이라는 것입니다. 그래서 저는 누군가 이미 그 일을했는지를 찾고있었습니다.
NikiC 2011

@nikic 아직 아무도이 작업을 수행하지 않은 이유 중 하나는 PHP가 실제로 무엇인지, 그리고 그것을 구문 분석하는 방법에 대한 사양이 없기 때문입니다. php-internals는 이전에 전체 개념을 완전히 거부했습니다. 결과적으로 PHP 소스 코드 자체 외에는 실제로 구문 분석을 수행하는 방법에 대한 신뢰할 수있는 소스 가 없습니다 . 신뢰할 수있는 참조 소스가 없으면 올바른 파서를 빌드하는 것은 진정한 모험이 될 것입니다. 이것은 불행히도 yacc 또는 Lemon 데이터로 시작하는 것이 최선의 선택 일 수 있음을 의미합니다.
Charles

@nikic, Charles : PHP 파서의 진정한 모험이었습니다. 접근 방식 : 어휘 분석기 / 문법을 제안하고, 수천 개의 파일을 시도하고, 잘못되고, 조정하고, 다시 시도하십시오. 제대로 문서화되지 않은 언어에 대한 강력한 구문 분석기를 얻으려면 약 1 년이 걸립니다. 적어도 우리에게는 그랬습니다. YMMV이지만 그다지 많지는 않습니다.
Ira Baxter

7

메트릭 도구 인 PHP Depend 에는 완전히 PHP로 작성된 PHP 소스에서 AST를 생성하는 코드가 포함되어 있습니다. 그러나 토큰 화를 위해 PHP의 자체 token_get_all을 사용합니다.

소스 코드는 github에서 사용할 수 있습니다 : https://github.com/manuelpichler/pdepend/tree/master/src/main/php/PHP/Depend

수학적 표현과 같은 일부 부분에 대한 AST 구현은 내가 마지막으로 확인한 것이 아직 완료되지 않았지만 저자에 따르면 그것이 목표입니다.


AST가 있지만 "수학적 연산"을위한 것은 아닙니다 ( "표현식"을 의미한다고 가정합니까? 이는 언어의 핵심 부분입니다. 특히 큰 따옴표로 묶인 "문자열 리터럴"(표현식 포함))가 정말 복잡하다고 생각할 때 문자열 표현.
Ira Baxter

2
이 질문에 가장 가까운 답변이기 때문에 현상금을 받았습니다. 하지만 PHP 문법의 절반이 부족하기 때문에 실제로 사용할 수 없습니다.
NikiC 2011-04-18

이 게시물의 내용이 오래되었습니다. 그 이후로 활발한 개발이 있었지만 PHP 문법을 얼마나 잘 지원하는지 모르겠습니다.
nhahtdh

4

글쎄, 이것은 PHP가 아닙니다. 미안하지만 이런 종류의 기계를 만드는 것은 어렵고 PHP는 언어 처리 작업에 특히 적합하지 않습니다.

우리의 PHP 프런트 엔드는 하는 AST에서 컴파일 가능한 소스 텍스트를 생성 할 수 있습니다, 자동 파싱 (이제 PHP 7을 처리 EDIT 2,016분의 9) 전체 PHP 문법의 모든 세부 사항과 함께하는 AST를 구축 그것은 전체 PHP 4.x 및 5.x를 제공합니다. 이상한 문자열 리터럴, 캡처 된 주석, 기수 포함 숫자 등을 포함한 모든 세부 사항을 고려할 때 들리는 것보다 어렵습니다.

그러나 AST는 충분하지 않습니다 (토큰이 거의 충분하지 않다는 것을 이미 관찰했습니다).

구축 된 기반 인 DMS 소프트웨어 리엔지니어링 툴킷 은 AST의 분석 및 임의 변환을 지원합니다. 또한 분석 및 변환을 가능하게 한 번에 대량의 파일 세트를 읽 통해 PHP 파일.


1
첫 번째 문장에 대한 응답처럼 : yacc grammer (예 : kmyacc)에서 파서를 생성 할 수있는 파서 생성기가 이미 있습니다. 즉, PHP로 빌드하는 것과 다른 언어로 빌드하는 것 사이에는 큰 차이가 없습니다. 여러분이해야 할 일은 zend_language_parser.y의 C 코드를 노드 트리를 구축하는 PHP 코드로 "그냥"(아이러니) 바꾸는 것입니다.
NikiC 2011

나머지에 관해서는 PHP 솔루션을 갖고 싶습니다. 그러나 (그리고 이것은 아마도 아마도) 그런 것이 없다면 아마도 다른 것을 사용할 것입니다. 나는 이미 DMS에 대해 여기에서 여러 번 들었으므로 살펴볼 것입니다.
NikiC 2011

@ninkic : 모든 Turing 머신 (PHP 포함)은 다른 모든 Turing 머신을 시뮬레이션 할 수 있습니다. 물론 PHP로 빌드하는 것도 가능합니다. 그러나 a) 파서 구축 하고 있습니다. 나는 PHP 파서가 트리를 구축하도록 설계되지 않았고 오히려 PHP p- 코드 생성기에 공급하도록 설계되었다고 생각합니다. 그리고 여러분이 필요로하는 것이 다르다는 것을 알게 될 것이라고 생각합니다. 그리고 b) 사람들 은 그들이 가지고 있다고 가정하는 실수를 반복적 으로합니다. AST, 다른 모든 것은 쉽습니다. 그들은 AST로 복잡한 일을 해본 경험이 없기 때문에 이러한 실수를 저지 릅니다. 이 가정이 거짓이기 때문에 DMS를 구축했습니다.
Ira Baxter 2011

1
a) 예, PHP 파서는 구문 분석 트리를 구축하도록 설계되지 않았으며 opcode 스트림을 구축하도록 설계되었습니다. 그렇기 때문에 zend 언어 파서를 PHP로 자동으로 변환하는 것이 거의 불가능합니다. b) 나는 아마도이 실수를 저지르는 사람들 중 하나 일 것이다.) 순수한 토큰 스트림으로 복잡한 조작을 이미 할 수 있다는 사실로부터 나는 AST를 사용하면 이것이 더 쉬울 것이라고 결론을 내렸다. 더 안정적입니다.
NikiC 2011

@nikic : 50 년의 컴파일러 기술에서 얻은 교훈은 각 프로그램 표현이 특정 작업을 쉽게한다는 것입니다. 텍스트에 대해서만 프로그램 조작을 있습니다 . 토큰에 대해 더 많은 것을 할 수 있습니다. AST에서 더 많은 것을 할 수 있습니다. 심볼 테이블, 제어 및 데이터 흐름 정보 (그래프), 변수 앨리어싱 데이터 (포인트 투 분석)가 있으면 정말 흥미로운 일을 할 수 있습니다. 정교한 코드 생성을 시도 할 때이 모든 것이 정말 정말 유용한 것임을 알게됩니다.
Ira Baxter

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