Pyparsing: get token location in results name

拈花ヽ惹草 提交于 2020-01-11 03:57:06

问题


I am working on a program that parses a command line with pyparsing. It uses the readline library to provide command edition and completion.

In the context of the application, a valid command line is a path (optional), followed by a command name (optional) and some parameters (also optional).

To offer command completion, the application parses the command line to see if the element to complete is a path, a command or a completion. Readline gives the indexes of the element that needs completion. I would like to match these indexes with the location of the path, the command name or the parameters of the parsed results returned by pyparsing.

How can I get the location of the different tokens and keep using setResultsName() to name my 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()

回答1:


Try adding a locator to your command and path expressions:

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

Now you should be able to access path.location and path.value to get the location and matched text for the path, and likewise for command.



来源:https://stackoverflow.com/questions/18706631/pyparsing-get-token-location-in-results-name

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!