Python 使用arpeggio处理空白或逗号分隔的标记列表

Python 使用arpeggio处理空白或逗号分隔的标记列表,python,parsing,peg,Python,Parsing,Peg,我正在尝试编写一个琶音语法,它将提取可以用逗号或空格分隔的标记。也就是说,令牌可以用逗号分隔,如下所示: a,b,c a b c a, b c def token(): return RegExMatch('[^\s,]*') def sep(): return RegExMatch('\s*[\s,]\s*') def token_list(): return token, ZeroOrMore(sep, token) def tokens(): return OneOrMore(to

我正在尝试编写一个琶音语法,它将提取可以用逗号或空格分隔的标记。也就是说,令牌可以用逗号分隔,如下所示:

a,b,c
a b  c
a, b c
def token(): return RegExMatch('[^\s,]*')
def sep(): return RegExMatch('\s*[\s,]\s*')
def token_list(): return token, ZeroOrMore(sep, token)
def tokens(): return OneOrMore(token_list), EOF
parser = ParserPython(tokens)
class TokenVisitor(PTNodeVisitor):
    def visit_token_list(self, node, children):
        return list(take_nth(2, children))
def tokenize(string):
    tree = parser.parse(string)
    return visit_parse_tree(tree, TokenVisitor())
空白,如下所示:

a,b,c
a b  c
a, b c
def token(): return RegExMatch('[^\s,]*')
def sep(): return RegExMatch('\s*[\s,]\s*')
def token_list(): return token, ZeroOrMore(sep, token)
def tokens(): return OneOrMore(token_list), EOF
parser = ParserPython(tokens)
class TokenVisitor(PTNodeVisitor):
    def visit_token_list(self, node, children):
        return list(take_nth(2, children))
def tokenize(string):
    tree = parser.parse(string)
    return visit_parse_tree(tree, TokenVisitor())
或者一个组合,像这样:

a,b,c
a b  c
a, b c
def token(): return RegExMatch('[^\s,]*')
def sep(): return RegExMatch('\s*[\s,]\s*')
def token_list(): return token, ZeroOrMore(sep, token)
def tokens(): return OneOrMore(token_list), EOF
parser = ParserPython(tokens)
class TokenVisitor(PTNodeVisitor):
    def visit_token_list(self, node, children):
        return list(take_nth(2, children))
def tokenize(string):
    tree = parser.parse(string)
    return visit_parse_tree(tree, TokenVisitor())
上述所有操作都将产生三个令牌
“a”
“b”
,和
“c”
。我还希望允许使用空令牌,这样两个逗号之间只有空格,将生成一个空令牌:

"a,b,, c" -> ["a", "b", "", "c"]
我对我的琶音语法的定义如下:

a,b,c
a b  c
a, b c
def token(): return RegExMatch('[^\s,]*')
def sep(): return RegExMatch('\s*[\s,]\s*')
def token_list(): return token, ZeroOrMore(sep, token)
def tokens(): return OneOrMore(token_list), EOF
parser = ParserPython(tokens)
class TokenVisitor(PTNodeVisitor):
    def visit_token_list(self, node, children):
        return list(take_nth(2, children))
def tokenize(string):
    tree = parser.parse(string)
    return visit_parse_tree(tree, TokenVisitor())
实现了一个非常简单的访问者,如下所示:

a,b,c
a b  c
a, b c
def token(): return RegExMatch('[^\s,]*')
def sep(): return RegExMatch('\s*[\s,]\s*')
def token_list(): return token, ZeroOrMore(sep, token)
def tokens(): return OneOrMore(token_list), EOF
parser = ParserPython(tokens)
class TokenVisitor(PTNodeVisitor):
    def visit_token_list(self, node, children):
        return list(take_nth(2, children))
def tokenize(string):
    tree = parser.parse(string)
    return visit_parse_tree(tree, TokenVisitor())
还有一个顶级函数,如下所示:

a,b,c
a b  c
a, b c
def token(): return RegExMatch('[^\s,]*')
def sep(): return RegExMatch('\s*[\s,]\s*')
def token_list(): return token, ZeroOrMore(sep, token)
def tokens(): return OneOrMore(token_list), EOF
parser = ParserPython(tokens)
class TokenVisitor(PTNodeVisitor):
    def visit_token_list(self, node, children):
        return list(take_nth(2, children))
def tokenize(string):
    tree = parser.parse(string)
    return visit_parse_tree(tree, TokenVisitor())
这在以下示例中都很有效:

tokenize('a,b,c') # [u'a', u'b', u'c']
tokenize('a, b ,c') # [u'a', u'b', u'c']
但是,以下示例给出了奇怪的输出:

tokenize('a,b c') # u'a | , | b | c | '
tokenize('a,b c') # u'a | b | c | '
tokenize('a,b,,c') # [u'a', u'b', u',']

也许有一些关于琶音如何处理空白和空字符串的东西我不明白。如何修复语法以正确解析所有这些示例?

默认情况下,Arpeggio的解析器跳过空白。要覆盖此行为,请将
skipws=False
传递给
ParserPython
构造函数:

parser = ParserPython(tokens, skipws=False)