2012-06-28 2 views
1

필자는 ANTLR 3.4에서 PHP5 파서를 작성했으나 거의 준비가되었지만 PHP의 까다로운 기능 중 하나는 처리 할 수 ​​없습니다. 내 문제는 할당 연산자의 우선 순위입니다. PHP 매뉴얼 says처럼 할당의 우선 순위는 거의 목록의 끝에 있습니다. and, xor, or, 만 목록에 있습니다.PHP 파서에서 대입 연산자의 우선 순위를 처리하는 방법은 무엇입니까?

그러나 말한다 매뉴얼 페이지이에 메모가 :

=하지만 대부분의 다른 사업자보다 낮은 우선 순위를 가지고는, PHP는 여전히 다음과 같은 식을 수 있습니다 : 에, if (!$a = foo())을하는 반환 값이 foo() 인 경우 $a에 넣습니다.

노트의 작은 예제는 내 파서에는 문제가 아니며,이를 assigment 규칙에서 특별한 경우로 처리 할 수 ​​있습니다.

그러나 더 복잡한 코드가이 예 : 그것은 $a && $b 먼저 인식하고 conditioin의 나머지 부분을 처리 할 수 ​​없기 때문에

if ($a && $b = func()) {}

내 파서 여기에 실패합니다. 이는 &&=보다 우선 순위가 높기 때문입니다. 내가 &&의 오른쪽 대괄호를 넣으면 :

if ($a && ($b = func())) {}

을 이런 식으로 파서 잘 구조를 인식합니다.

연산자는 ANTLR 서적에서 권장하는 방식으로 작성됩니다. 첫 번째 단계에서 기본 표현이 있으며 각 수준의 연산자가 서로 뒤 따르고 있습니다.

이 우선 순위 점핑을 처리 할 방법이 있습니까?

답변

0

과제로 보지 말고 할당 표현으로 지정하겠습니다. 단항 표현 "아래에"이 할당 식을 착용 할 것 (그래서 그들은 단항 것보다 더 높은 우선 순위가) :

grammar T; 

options { 
    output=AST; 
} 

tokens { 
    BLOCK; 
    FUNC_CALL; 
    EXPR_LIST; 
} 

parse 
: stat* EOF! 
; 

stat 
: assignment ';'! 
| if_stat 
; 

assignment 
: Var '='^ expr 
; 

if_stat 
: If '(' expr ')' block -> ^(If expr block) 
; 

block 
: '{' stat* '}' -> ^(BLOCK stat*) 
; 

expr 
: or_expr 
; 

or_expr 
: and_expr ('||'^ and_expr)* 
; 

and_expr 
: unary_expr ('&&'^ unary_expr)* 
; 

unary_expr 
: '!'^ assign_expr 
| '-'^ assign_expr 
| assign_expr 
; 

assign_expr 
: Var ('='^ atom)* 
| atom 
; 

atom 
: Num 
| func_call 
; 

func_call 
: Id '(' expr_list ')' -> ^(FUNC_CALL Id expr_list) 
; 

expr_list 
: (expr (',' expr)*)? -> ^(EXPR_LIST expr*) 
; 

If : 'if'; 
Num : '0'..'9'+; 
Var : '$' Id; 
Id : ('a'..'z')+; 
Space : (' ' | '\t' | '\r' | '\n')+ {skip();}; 

을 지금 소스 분석하려는 경우 :

if (!$a = foo()) { $a = 1 && 2; } 
if ($a && $b = func()) { $b = 2 && 3; } 
if ($a = baz() && $b) { $c = 3 && 4; } 

을 다음 AST는 건설받을 것이다 :

enter image description here

+0

감사를 당신의 응 답에 대한 이자형. 나는 그 진술을 진술로서 별도의 규칙을 만들지 않았다. 나는 이것이 누락 된 조각이라고 생각한다. – dtengeri

+0

@ dtengeri도 환영합니다. –

관련 문제