0

如果您看一下下面的语法,您会看到一个主要规则表达式,它被解析为更具体的表达式类型。

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 的解析按预期工作,但我更愿意用“@”而不是“andex”来标记表达式规则中的 and_expr 元素。我希望解析后的输出只会产生一个 CompareExpression 对象,该对象位于 Expression 对象的 not_ex 元素内。

!(a == b)

似乎在 and_expr 元素上使用“@”标签时,Expression 对象中没有显示任何属性!这是一个错误还是故意的?在使用 ModelBuilderSemantics 时,我必须用名称标记所有元素并且不使用“@”标签吗?

我一直面临的另一个问题是,如果后面的规则(例如 comp_expr)没有关联的类名,则其元素在打印时会出现在字典中,但点符号访问器会因 AttributeError 而失败,即“AttributeError : 'dict' 对象没有属性 'comp'"。即使规则没有与之关联的类名,是否有任何方法可以使用点符号访问器?

4

1 回答 1

0

我使用的一些标准:

  1. 不是每个规则都必须有一个关联的Node类。
  2. 以闭包{}作为主要表达式的规则适用于返回列表。
  3. 以 aa 选择|作为主要表达式的规则最好返回成功选项返回的任何内容,即使这通常需要将选项分解到自己的规则中。
  4. 优先级很重要。
  5. 等等。

这个想法是生成的解析模型应该易于使用,特别是对于walkers,至少具有if-elseor 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_]*/
    ;
于 2016-10-13T01:26:38.747 回答