pyparsing: игнорировать любой токен, который не совпадает - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть файл из игры, который я пытаюсь проанализировать.Вот выдержка:

    <stage> id: 50  #Survival Stage
            <phase> bound: 1500  # phase 0   bandit
                    music: bgm\stage4.wma
                    id: 122  x: 100  #milk  ratio: 1
                    id: 30 hp: 50  times: 1
                    id: 30 hp: 50  times: 1  ratio: 0.7
                    id: 30 hp: 50  times: 1  ratio: 0.3
            <phase_end>
    <stage_end>

# обозначает комментарий, но только для читателей-людей, а не для парсера игры.Первые два комментария находятся в конце строки, но ratio: 1 после #milk не является частью комментария, он фактически считается.Я думаю, что парсер игры игнорирует все токены, которые он не может понять.Есть ли способ сделать это в pyparsing?

Я пытался использовать parser.ignore(pp.Word(pp.printables)), но это заставляет его пропустить все .Вот мой код:

import pyparsing as pp

txt = """
<stage> id: 50  #Survival Stage
        <phase> bound: 1500  # phase 0   bandit
                music: bgm\stage4.wma
                id: 122  x: 100  #milk  ratio: 1
                id: 30 hp: 50  times: 1
                id: 30 hp: 50  times: 1  ratio: 0.7
                id: 30 hp: 50  times: 1  ratio: 0.3
        <phase_end>
<stage_end>
"""

phase = pp.Literal('<phase>')
stage = pp.Literal('<stage>') + pp.Literal('id:') + pp.Word(pp.nums)('id') + pp.OneOrMore(phase)
parser = stage

parser.ignore(pp.Word(pp.printables))

print(parser.parseString(txt).dump())

1 Ответ

0 голосов
/ 14 ноября 2018

Оказывается, в файле стоковой игры после # появляется только ключевое слово ratio:, поэтому я использовал это для определения конца комментария, например:

parser.ignore(Suppress('#') + SkipTo(MatchFirst([FollowedBy('ratio:'), LineEnd()])))
...