2013-06-24 5 views
2

루비가 구문 분석하는 방법을 어떻게 예측할 수 있습니까?Ruby 파서의 원리는 무엇입니까?

문자열을 연결하는 동안 Ruby에서 파싱 오류가 발생했습니다.

> "every".capitalize +"thing" 
=> NoMethodError: undefined method `[email protected]' for "thing":String 

물론 추가 공간을 넣으면 의도 한대로 작동합니다.

> "every".capitalize + "thing" 
=> "Everything" 

이 오류는 anything.any_method +"any string" 인 경우에 발생합니다. Ruby가하는 일은 우리가 괄호를 생략하고 메서드에 대한 논쟁을 시도하고 있다고 가정합니다.

"every".capitalize(+"thing") 

은 우리가 문자열에 단항 연산자 [email protected]을 정의하지 않은 것을 통지하고, 그 오류가 발생합니다.

제 질문은 루비 파서의 동작을 예측하기 위해 어떤 원칙을 사용해야합니까? 나는 단지 많은 인터넷 검색 후에이 오류를 발견했다. .capitalize은 매개 변수를 전혀 사용하지 않습니다 (C 소스 코드조차 포함하지 않음). 이전 개체에 적용되지 않는 메서드를 사용하면 undefined method 'capitalize' for "every":String 오류 대신 [email protected] 오류가 발생합니다. 따라서이 구문 분석은 분명히 상위 수준입니다. 저는 Matz의 parser.y을 읽을만큼 지식이 없습니다. 나는 비슷한 다른 놀라운 오류를 발견했습니다. 누구든지 Ruby의 파싱 우선 순위를 말해 줄 수 있습니까? 당신은 루비 코드를 구문 분석하는 방법을 보려면

+0

BNF 형식의 [Ruby grammar] (http://web.njit.edu/all_topics/Prog_Lang_Docs/html/ruby/yacc.html)도 파서보다 조금 덜 밀집되어 있습니다. .y 파일. – squiguy

답변

3

, 당신은 파스 트리를 덤프 할 수, 즉

ruby -e '"every".capitalize +"thing"' --dump parsetree

나는 내 눈에 훨씬 쉽게 원인도 가끔 explainruby를 사용하려면
# @ NODE_SCOPE (line: 1) 
# +- nd_tbl: (empty) 
# +- nd_args: 
# | (null node) 
# +- nd_body: 
#  @ NODE_CALL (line: 1) 
#  +- nd_mid: :capitalize 
#  +- nd_recv: 
#  | @ NODE_STR (line: 1) 
#  | +- nd_lit: "every" 
#  +- nd_args: 
#   @ NODE_ARRAY (line: 1) 
#   +- nd_alen: 1 
#   +- nd_head: 
#   | @ NODE_CALL (line: 1) 
#   | +- nd_mid: :[email protected] 
#   | +- nd_recv: 
#   | | @ NODE_STR (line: 1) 
#   | | +- nd_lit: "thing" 
#   | +- nd_args: 
#   |  (null node) 
#   +- nd_next: 
#    (null node) 

:)