如果你看一下下面的语法,你可以看到一个主要的规则,表达式,它被解析成更具体的表达式类型。
expression::Expression
=
or_ex:and_expr {'||' or_ex:and_expr}+
| andex:and_expr
;
and_expr::AndExpression
=
and_ex:sub_expr {'&&' and_ex:sub_expr}+
| subex:sub_expr
;
sub_expr::SubExpression
=
{'!!'}* '!(' not_ex:expression ')'
| {'!!'}* '(' sub_ex:expression ')'
| compex:comp_expr
;
comp_expr::CompareExpression
=
comp:identifier operator:('>=' | '<=' | '==' | '!=' | '>' | '<') comp:identifier
;
identifier::str
=
?/[a-zA-Z][A-Za-z0-9_]*/?
;如下所示,test_input的解析工作正常,但我更喜欢在表达式规则中使用“@”而不是“and_expr”来标记andex元素。我希望解析后的输出只会产生一个CompareExpression对象,该对象位于Expression对象的not_ex元素中。
!(a == b)似乎在and_expr元素上使用'@‘标签时,表达式对象中没有显示任何属性!这是一个bug还是故意的?在使用ModelBuilderSemantics时,我必须用名称标记所有元素,并且不使用'@‘标签吗?
我一直面临的另一个问题是,如果后面的规则(如comp_expr )没有关联的类名,则其元素将在打印时出现在字典中,但点符号访问器将失败,并显示AttributeError,即"AttributeError:'dict‘对象没有’comp‘属性“。有没有办法使用点符号访问器,即使规则没有关联的类名?
发布于 2016-10-13 09:26:39
我使用的一些标准:
Node类。使用闭包{}作为主表达式的|作为主表达式的我们的想法是,生成的解析模型应该易于使用,特别是与walkers一起使用,具有最少的if-else或isinstance()。
这就是我如何做你的例子:
start
=
expression $
;
expression
=
| or_expre
| and_expre
| sub_expre
;
or_expre::OrExpression
=
operands:'||'.{and_expre}+
;
and_expr::AndExpression
=
operands:'&&'.{sub_expre}+
;
sub_expr
=
| not_expr
| comp_expre
| atomic
;
not_expre::NotExpression
=
'!!' ~ sub_expr
;
comp_expr::CompareExpression
=
lef:atomic operator:('>=' | '<=' | '==' | '!=' | '>' | '<') ~ right:atomic
;
atomic
=
| group_expre
| identifier
;
group_expr::GroupExpression
=
'(' ~ expre:expression ')'
;
identifier::str
=
/[a-zA-Z][A-Za-z0-9_]*/
;https://stackoverflow.com/questions/39967579
复制相似问题