당신은 (테스트되지 않은) 같은 것을 원하는 :
'def' space? identifier space? '(' space? (expression (space? ',' expression)*)? space? ')'
(NB이 인수가없는 경우 루비 스타일 def
다음 괄호는 경우에 선택 사항 인 경우)
편집 입증 구문 분석 트리에서 인수를 추출 - 나는 여기 각 인수 (FunctionArg
) 구문 노드의 text_value
을 뱉어하지만 물론 아무것도 할 수 :
foo.rb :
# Prepend current directory to load path
$:.push('.')
# Load treetop grammar directly without compilation
require 'polyglot'
require 'treetop'
require 'def'
# Classes for bespoke nodes
class FunctionDefinition < Treetop::Runtime::SyntaxNode ; end
class FunctionArg < Treetop::Runtime::SyntaxNode ; end
# Some tests
[
'def foo() block end',
'def foo(arg1) block end',
'def foo(arg1, arg2) block end',
'def foo(arg1, arg2, arg3) block end',
].each do |test|
parser = DefParser.new
tree = parser.parse(test)
raise RuntimeError, "Parsing failed on line:\n#{test}" unless tree
puts test
puts "identifier=#{tree.function_identifier}"
puts "args=#{tree.function_args.inspect}"
puts
end
def.tt :
grammar Def
# Top level rule: a function
rule function_definition
'def' space identifier space? '(' space? arg0 more_args space? ')' space block space 'end' <FunctionDefinition>
{
def function_identifier
identifier.text_value
end
def function_args
arg0.is_a?(FunctionArg) ? [ arg0.text_value ] + more_args.args : []
end
}
end
# First function argument
rule arg0
argument?
end
# Second and further function arguments
rule more_args
(space? ',' space? argument)*
{
def args
elements.map { |e| e.elements.last.text_value }
end
}
end
# Function identifier
rule identifier
[a-zA-Z_] [a-zA-Z0-9_]*
end
# TODO Dummy rule for function block
rule block
'block'
end
# Function argument
rule argument
[a-zA-Z_] [a-zA-Z0-9_]* <FunctionArg>
end
# Horizontal whitespace (htab or space character).
rule space
[ \t]
end
end
출력 :
def foo() block end
identifier=foo
args=[]
def foo(arg1) block end
identifier=foo
args=["arg1"]
def foo(arg1, arg2) block end
identifier=foo
args=["arg1", "arg2"]
def foo(arg1, arg2, arg3) block end
identifier=foo
args=["arg1", "arg2", "arg3"]
의견을 보내 주셔서 감사합니다. 그러나 인수는 Treetop 트리의 노드가되고 싶습니다. 귀하의 솔루션은 작동하지만 내 주장은 나무에 나타나지 않습니다. 어쨌든 고맙습니다. –
성취하고자하는 목표에 더 가까워 지도록 편집되었습니다. –