ll(1)分析器生成器
arcee的Python项目详细描述
阿西
它是一个python解析器生成器,使用类似ebnf的语法。
安装
$ pip install Arcee
示例
它真的很可读。
语法:
KEYWORDS : let, if, zero, -
NUMBER : \d+(\.\d*)?
ASSIGN : =
SUBTRACTION : -
RIGHT_BRACKET : (
COLON : ,
LETF_BRACKET : )
ID : [A-Za-z]+
SKIP : [ \\t]+
program : expression ;
expression : zeroexp
| diffexp
| ifexp
| varexp
| letexp
| constexp
;
constexp : $NUMBER ;
diffexp : '-' '(' expression ',' expression ')' ;
zeroexp : 'zero' '(' expression ')' ;
ifexp : 'if' expression 'then' expression 'else' expression ;
varexp : $ID ;
letexp : 'let' $ID '=' expression 'in' expression ;
$ arcee grammar > result.py
result.py
有三个部分:
代币
fromcollectionsimportnamedtupleToken=namedtuple('Token',['type','value','line','column'])Program=namedtuple('Program',['expression'])# ...
莱克瑟
importredeftokenize(code):pass# ...
分析器
classParser:def__init__(self,token_list):pass# ... defparse_expression(self):ifxxx:self.parse_constexp()elifyyy:self.parse_diffexp()#...defparse_constexp(self):passdefparse_diffexp(self):passdefparse_zeroexp(self):passdefparse_ifexp(self):passdefparse_varexp(self):passdefparse_letexp(self):pass
您可以分析输入,例如:
input='''let a = 0 in if zero(a) then -(a, 1) else -(a, 2)'''tokens=list(tokenize(input))parser=Parser(tokens)parser.parse_program()
结果是:
result=Program(expression=Expression(nonterminal=Letexp(ID=Token(type='ID',value='a',line=2,column=4),expression1=Expression(nonterminal=Constexp(NUMBER=Token(type='NUMBER',value='0',line=2,column=8))),expression2=Expression(nonterminal=Ifexp(expression1=Expression(nonterminal=Zeroexp(expression=Expression(nonterminal=Varexp(ID=Token(type='ID',value='a',line=2,column=21))))),expression2=Expression(nonterminal=Diffexp(expression1=Expression(nonterminal=Varexp(ID=Token(type='ID',value='a',line=2,column=31))),expression2=Expression(nonterminal=Constexp(NUMBER=Token(type='NUMBER',value='1',line=2,column=34))))),expression3=Expression(nonterminal=Diffexp(expression1=Expression(nonterminal=Varexp(ID=Token(type='ID',value='a',line=2,column=44))),expression2=Expression(nonterminal=Constexp(NUMBER=Token(type='NUMBER',value='2',line=2,column=47))))))))))
现在,你可以用这个ast做你喜欢的事情。
您还可以在python文件中使用api。
fromarceeimportgenerategrammar='''KEYWORDS : let, if, zero, -NUMBER : \d+(\.\d*)?ASSIGN : =SUBTRACTION : -RIGHT_BRACKET : (COLON : ,LETF_BRACKET : )ID : [A-Za-z]+SKIP : [ \\t]+program : expression ;expression : zeroexp | diffexp | ifexp | varexp | letexp | constexp ;constexp : $NUMBER ;diffexp : '-' '(' expression ',' expression ')' ;zeroexp : 'zero' '(' expression ')' ;ifexp : 'if' expression 'then' expression 'else' expression ;varexp : $ID ;letexp : 'let' $ID '=' expression 'in' expression ;'''print(generate(grammar))