我使用 Lepl 作为解析器,我正在解析的语言非常复杂,我只关心一小部分。我想不出办法让 Lepl 解析我关心的语法,然后只为其他所有内容返回字符串。如果我添加如下规则:
everything_else = ~newline & Regexp('.')[:]
然后它被用来代替我关心的东西。我认为它正在发生,因为它比我的其他规则更长。Lepl 中是否有配置设置或其他东西,以便我可以拥有一个不完美的解析器?
更新 按要求添加一些细节。我只想解析出等于数字的顶级变量定义。那些依赖于他人或者是我想忽略的数学表达式。我还想忽略块定义中的内容我想忽略语言中的许多其他构造。所以这里有一个例子:
from lepl import *
class Variable(List): pass
import string
def parse_it(a_string):
# Parser: TODO: incomplete
s = ~Space()[:] # zero or more spaces
s1 = ~Space()[1:] # 1 or more spaces
newline = Newline() & s
number_squote = ~Optional(Literal("'")) & s & Real() & s & ~Optional(Literal("'"))
number_dquote = ~Optional(Literal('"')) & s & Real() & s & ~Optional(Literal('"'))
number = number_squote | number_dquote | Real() >> float
var_keyword = ~newline & ~Regexp(r'(?i)variable')
var_name = Word() >> string.lower
var_assignment = s1 & var_name & s & ~Literal('=') & s & number > Variable
vars = var_keyword & var_assignment[1:]
parser = vars[1:]
return parser.parse(a_string)
input="""
VARIABLE abc=5 bbb='7' ddd='abc*bbb'
variable ccccc=7 // comment
block(1,2,3,4) of_type=cleaner abc=4 d=5 c=string('hi')
define_block block2 (3,4,5,6,7,a,b) var1=35 var2=36
variable ignore_this=5
block3(3,4,5,6) x='var1*ignore_this' y=var2
block4(4,5,6,7,a,b) x='var1*2' y="var2*3"
end_block
block2(1,2,3,4,5,6,3) abc=ccccc d=abc
create_blocks // comment: initialize memory
connect_blocks // connect blocks together
simulate //
"""
for i in parse_it(input):
print i
所以我只真正关心variable Word() = Real()
在块定义之外定义的文件中的信息。我想将其余部分保留为字符串,以便我可以构建 AST 并修改变量值,然后再次写出控制文件。