many ways to skin a cat.
require 'parslet'
require 'parslet/convenience'
require 'pp'
class MyParser < Parslet::Parser
alias_method :`, :str
rule(:word) { match['\w'].repeat(1).as(:word) }
rule(:call) { (`()`).as(:call) }
rule(:expression) {
word >> call.repeat(1) ||
word }
root(:expression)
end
pp MyParser.new.parse_with_debug("f()()()")
repeat(1) is not equal to repeat and eliminates depth-searching where no
solution exists. Think about your parser as though you were writing a
top-down parser engine by hand, that helps usually. Longer parse rules
must come before shorter ones, otherwise they wont get selected. And no,
this wont be the killer argument for left recursion.
kaspar