如何在Python中为用户输入命令编写简单的词法分析器/解析器?

时间:2012-07-09 12:01:15

标签: python parsing lexer

对于个人项目,我需要编写一个简单的词法分析器来处理用户输入命令。它们可以包含四种模式和括号:

  • 运营商:.+-%
  • 姓名([a-zA-Z0-9]):例如foobarfooZbar2
  • 过滤器([a-z] {1}“[some text]”):例如a"hello world"p"escaped \"string\""
  • 其他过滤器([a-z] {1}〜“[some text]”):例如a~"hello world"p~"escaped \"string\""

我想拆分命令,以便有一个分层列表(基于括号),其中包含每个运算符的条目,每个名称的条目(单个字符串),以及每个过滤器的条目(a字典,例如{'a': 'hello world'}{'p~': 'escaped "string"'})。

所以这里是我想用这个输入得到的一个例子(运算符周围的空格是可选的):

foo . bar - (a"hello \"world\"" % (b~"foo" + bar) . (fooZ.(bar2+(c"foo bar".d"bar foo"))))

[
  'foo',
  '.',
  'bar',
  '-',
  [
    {'a': 'hello "world"'},
    '%',
    [
      {'b~': 'foo'},
      '+',
      'bar'
    ]
    '.',
    [
      'fooZ',
      '.',
      [
        'bar2',
        '+',
        [
          {'c': 'foo bar'},
          '.',
          {'d': 'bar foo'}
        ]
      ]
    ]
  ]
]

我看过pyparsing,PLY,pyPEG,Yapps等,但它们似乎都很难使用,我不知道我是否需要这种工具,因为我需要的语法不是很复杂。提前感谢您的建议!

1 个答案:

答案 0 :(得分:3)

了解此pyparsing解决方案如何解决您所声明的语法:

from pyparsing import *
ParserElement.enablePackrat()
import string

name = Word(alphanums)

filter = (Combine(oneOf(list(string.ascii_lowercase)) + Optional('~')) +
          dblQuotedString.setParseAction(removeQuotes))
# convert parsed filter to dict
filter.setParseAction(lambda t:{t[0]:t[1]})

expr = operatorPrecedence(filter | name, 
            [
            (oneOf('. % -'), 2, opAssoc.LEFT),
            ('+', 2, opAssoc.LEFT),
            ])

test = r'foo . bar - (a"hello \"world\"" % (b~"foo" + bar) . (fooZ.(bar2+(c"foo bar".d"bar foo"))))'

print expr.parseString(test, parseAll=True).asList()

打印:

[['foo',
  '.',
  'bar',
  '-',
  [{'a': 'hello \\"world\\"'},
   '%',
   [{'b~': 'foo'}, '+', 'bar'],
   '.',
   ['fooZ', '.', ['bar2', '+', [{'c': 'foo bar'}, '.', {'d': 'bar foo'}]]]]]]