私は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を作成して変数値を変更してから、制御ファイルを再度書き出すことができるように、残りを文字列として保持したいと思います。