Pyparsing: obtener la ubicación del token en el nombre de los resultados

Estoy trabajando en un progtwig que analiza una línea de comandos con pyparsing. Utiliza la biblioteca readline para proporcionar la edición y finalización del comando.

En el contexto de la aplicación, una línea de comando válida es una ruta (opcional), seguida de un nombre de comando (opcional) y algunos parámetros (también opcionales).

Para ofrecer la finalización de comandos, la aplicación analiza la línea de comandos para ver si el elemento a completar es una ruta, un comando o una finalización. Readline da los índices del elemento que necesita ser completado. Me gustaría hacer coincidir estos índices con la ubicación de la ruta de acceso, el nombre del comando o los parámetros de los resultados analizados devueltos por pyparsing.

¿Cómo puedo obtener la ubicación de los diferentes tokens y seguir usando setResultsName () para nombrar mis tokens?

from pyparsing import Optional, Regex, Word from pyparsing import alphanums class Shell(object): def __init__(self): # Simplified grammar of the command line # path command parameters command = Word(alphanums + '_').setResultsName('command') bookmark = Regex('@([A-Za-z0-9:_.]|-)+') pathstd = Regex('([A-Za-z0-9:_.]|-)*' + '/' + '([A-Za-z0-9:_./]|-)*') \ | '..' | '.' path = (bookmark | pathstd | '*')('path') parser = Optional(path) + Optional(command) # + Optional(parameters) self.parser = parser def parse_cmdline(self, line): parse_results = self.parser.parseString(line) path = parse_results.path command = parse_results.command return (parse_results, path, command) def complete(self): """Completion method called by readline""" cmdline = readline.get_line_buffer() (result_trees, path, command) = self.parse_cmdline(cmdline) beg = readline.get_begidx() end = readline.get_endidx() prefix = cmdline[beg:end] # if beg == path.location: # completion = self.get_path_completion() # elif beg == command.location: # completion = self.get_command_completion() # elif beg in parameters.location: # completion = self.get_parameter_completion() 

Intente agregar un localizador a sus comandos y expresiones de ruta:

 locator = Empty().setParseAction(lambda s,l,t: l) def locatedExpr(expr): return Group(locator("location") + expr("value")) class Shell(object): def __init__(self): # Simplified grammar of the command line # path command parameters #command = Word(alphanums + '_').setResultsName('command') command = locatedExpr(Word(alphanums + '_'))('command') bookmark = Regex('@([A-Za-z0-9:_.]|-)+') pathstd = Regex('([A-Za-z0-9:_.]|-)*' + '/' + '([A-Za-z0-9:_./]|-)*') \ | '..' | '.' #path = (bookmark | pathstd | '*')('path') path = locatedExpr(bookmark | pathstd | '*')('path') parser = Optional(path) + Optional(command) # + Optional(parameters) self.parser = parser 

Ahora debería poder acceder a path.location y path.value para obtener la ubicación y el texto coincidente para la ruta, y también para el comando.