Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Pyparsing:尝试非贪婪导致无限循环_Python_Pyparsing - Fatal编程技术网

Python Pyparsing:尝试非贪婪导致无限循环

Python Pyparsing:尝试非贪婪导致无限循环,python,pyparsing,Python,Pyparsing,我试图为创建一个解析器,但是,当试图在RCSadmin上下文中解析RCSid时,它会经历一个无限循环。删除违规行 Group(ZeroOrMore(RCSid)).setResultsName('access') + \ 使挂起不会发生。其上的RCSid成功解析字符串。有什么建议吗 以下是我所拥有的: from pyparsing import * import string # Special characters in the RCS file format spec

我试图为创建一个解析器,但是,当试图在RCSadmin上下文中解析RCSid时,它会经历一个无限循环。删除违规行

        Group(ZeroOrMore(RCSid)).setResultsName('access') + \
使挂起不会发生。其上的RCSid成功解析字符串。有什么建议吗

以下是我所拥有的:

from   pyparsing import *
import string

# Special characters in the RCS file format
special = '$,.:;@'

RCSdigit = Word(nums, min=1, max=1).setName('RCSdigit')
RCSnum = Word(nums + '.').setName('RCSnum')
RCSidchar = CharsNotIn(special + string.whitespace).setName('RCSidchar')
RCSid = Combine(Optional(RCSnum) + ZeroOrMore(RCSidchar +
        ZeroOrMore(RCSidchar | RCSnum))).setName('RCSid')
RCSadmin = \
    Keyword('head').suppress() + \
        Optional(RCSnum).setResultsName('head') + \
        Suppress(';') + \
    Optional(Keyword('branch').suppress() +
        Optional(RCSnum).setResultsName('branch') +
        Suppress(';')
    ) + \
    Keyword('access').suppress() + \
        Group(ZeroOrMore(RCSid)).setResultsName('access') + \
        Suppress(';')

ids = ['.111abc111', '1111abc111', '1.11', '1', '1abc', 'abc',
        'abc1', 'abc1.11', 'abc.1111', '']
for i in ids:
    try:
        print i, RCSid.parseString(i)
    except ParseException, pe:
        print pe.markInputline()
for i in ids:
    line = 'head 3; branch 1; access ' + i + ';'
    try:
        print line, RCSadmin.parseString(line)
    except ParseException, pe:
        print pe.markInputline()
具有输出(^C处于挂起状态):

.111abc111['.111abc111']
1111abc111['1111abc111']
1.11 ['1.11']
1 ['1']
1abc['1abc']
abc[‘abc’]
abc1['abc1']
abc1.11['abc1.11']
abc.1111['abc.1111']
['']
^Chead 3;分支机构1;获取111abc111;
回溯(最近一次呼叫最后一次):
文件“sample.py”,第35行,在
打印行,RCSadmin.parseString(行)
parseString格式的文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第1070行
loc,标记=self.\u解析(instring,0)
文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第945行,在parseNoCache中
loc,tokens=self.parseImpl(指令、预指令、动作)
parseImpl中的文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第2352行
loc,exprtokens=e.(指令,loc,动作)
文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第945行,在parseNoCache中
loc,tokens=self.parseImpl(指令、预指令、动作)
parseImpl中的文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第2604行
返回self.expr.\u parse(instring、loc、doActions、callPreParse=False)
文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第945行,在parseNoCache中
loc,tokens=self.parseImpl(指令、预指令、动作)
parseImpl中的文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第2724行
loc,tmptokens=self.expr.\u解析(指令、预指令、动作)
文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第945行,在parseNoCache中
loc,tokens=self.parseImpl(指令、预指令、动作)
parseImpl中的文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第2604行
返回self.expr.\u parse(instring、loc、doActions、callPreParse=False)
文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第945行,在parseNoCache中
loc,tokens=self.parseImpl(指令、预指令、动作)
parseImpl中的文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第2336行
loc,resultlist=self.exprs[0]。\u解析(instring,loc,doActions,callPreParse=False)
文件“/usr/lib/pymodules/python2.6/pyparsing.py”,第943行,在parseNoCache中
如果self.mayindexer或loc>=len(安装):
键盘中断

空字符串真的是有效的RCSid吗?我想不是。现在,可以在admin语句的access子句中省略RCSid,但您已经在使用ZeroOrMore来处理它了。按照指定的原语定义原语,然后在更高级别的构造中考虑可选、ZeroOrMore等

将RCSid更改为:

RCSid = Combine(RCSnum + ZeroOrMore(RCSidchar + ZeroOrMore(RCSidchar | RCSnum))
                |
                OneOrMore(RCSidchar + ZeroOrMore(RCSidchar | RCSnum))).setName('RCSid')
给我一个仍然匹配所有测试用例的结果(除了匹配“”),并正确解析完整的RCSAdmin字符串

编辑 这是我的完整解析器,与pyparsing 1.5.6一起使用:

# Special characters in the RCS file format
special = '$,.:;@'

RCSdigit = Word(nums, min=1, max=1).setName('RCSdigit')
RCSnum = Word(nums + '.').setName('RCSnum')
RCSidchar = CharsNotIn(special + string.whitespace).setName('RCSidchar')
#~ RCSid = Combine(Optional(RCSnum) + ZeroOrMore(RCSidchar +
        #~ ZeroOrMore(RCSidchar | RCSnum))).setName('RCSid')
RCSid = Combine(RCSnum + ZeroOrMore(RCSidchar + ZeroOrMore(RCSidchar | RCSnum))
                |
                OneOrMore(RCSidchar + ZeroOrMore(RCSidchar | RCSnum))).setName('RCSid')
RCSadmin = \
    Keyword('head').suppress() + \
        Optional(RCSnum).setResultsName('head') + \
        Suppress(';') + \
    Optional(Keyword('branch').suppress() +
        Optional(RCSnum).setResultsName('branch') + 
        Suppress(';')
    ) + \
    Keyword('access').suppress() + \
        Group(ZeroOrMore(RCSid)).setResultsName('access') + \
        Suppress(';') 

感谢@Paul的回复,但是,通过您的更改,我仍然无法解析上面包含的RCSadmin字符串,它无法提取RCSid组件,例如:
head3;分支机构1;访问1111abc111;总目3;分支机构1;访问>!嗨@Paul,我想我应该让你知道我已经完成了RCS的PyParassing解析器,见。
# Special characters in the RCS file format
special = '$,.:;@'

RCSdigit = Word(nums, min=1, max=1).setName('RCSdigit')
RCSnum = Word(nums + '.').setName('RCSnum')
RCSidchar = CharsNotIn(special + string.whitespace).setName('RCSidchar')
#~ RCSid = Combine(Optional(RCSnum) + ZeroOrMore(RCSidchar +
        #~ ZeroOrMore(RCSidchar | RCSnum))).setName('RCSid')
RCSid = Combine(RCSnum + ZeroOrMore(RCSidchar + ZeroOrMore(RCSidchar | RCSnum))
                |
                OneOrMore(RCSidchar + ZeroOrMore(RCSidchar | RCSnum))).setName('RCSid')
RCSadmin = \
    Keyword('head').suppress() + \
        Optional(RCSnum).setResultsName('head') + \
        Suppress(';') + \
    Optional(Keyword('branch').suppress() +
        Optional(RCSnum).setResultsName('branch') + 
        Suppress(';')
    ) + \
    Keyword('access').suppress() + \
        Group(ZeroOrMore(RCSid)).setResultsName('access') + \
        Suppress(';')