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


80

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

따라서 나는 PHP로 작성된 PHP 파서를 찾고 있습니다. hnw / PhpParser 및 kumatch / 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.