2

我几乎完成了我与 ANTLR 的第一次冒险,这是一次相当愉快的旅行。不幸的是,总是只计算马蹄铁、手榴弹和核武器,对吧?

无论如何,我正在尝试解析如下所示的输入:

; IF AGE IS LESS THAN 21, STILL RETURN TRUE FOR OVERSEAS LOCATION \r\n
SHOW "AGE REQUIREMENTS FAILED" FOR \r\n
IF AGE < 21 THEN \r\n
LOCATION = "OVERSEAS" \r\n
ENDIF \r\n
\r\n
; NEED  SOMEONE WHO HAS WORKED FOR US FOR > 1 YEAR EXCEPT FOR CEO \r\n
SHOW "MINIMUM TIME REQUIREMENT NOT MET" FOR \r\n
IF STARTDATE > TODAY - 1 YEAR THEN \r\n
EMPLID=001 \r\n
ENDIF \r\n

通常,如果测试失败,则会显示该消息。

无论如何,一个集合可以包含 1 个或多个 SHOW 规则。处理单个 SHOW 规则有效,但当输入流包含 > 1 个 SHOW 规则时,它不会“拆分”。

以下是语法中的相关规则:

showGroup returns [List<PolicyEvaluation> value]
  @init {List<PolicyEvaluation> peList = new ArrayList<PolicyEvaluation>();}
  : (expr1=show)* {peList.add($expr1.value);}
  {
    System.out.println("Entered policyGroup rule");
    $value = peList;
  }
  ;

// evaluate a single SHOW statement
show returns [PolicyEvaluation value]
  : ('SHOW' expr1=STRING 'FOR')? expr2=ifStatement EOL*
  {
    System.out.println("Entered show rule");
    Boolean expr2Value = (Boolean) $expr2.value;
    PolicyEvaluation pe = new PolicyEvaluation();
    if (expr1 == null) {
      pe.setValue(expr2Value);
      pe.setMessage(null);
    } else {
        if (expr2Value == false) {
          pe.setValue(false);
          pe.setMessage(expr1.getText());
        } else {
          pe.setValue(true);
          pe.setMessage(null);
        }   
    }
    $value = pe;
  }
  ;
// rules leading up to the show rule
// domain-specific grammar rules
STRING: '"' ID  (' ' ID)* '"'
  {
    System.out.println("Entered STRING lexer rule");
    // strip the quotes once we match this token
    setText(getText().substring(1, getText().length()-1));
  }
  ;
COMMENT: ';' (ID|' ')* EOL {$channel = HIDDEN;};
EOL: ('\r'|'\n'|'\r\n') {$channel = HIDDEN;};
SPACE: ' ' {$channel = HIDDEN;};

也许这很简单。任何帮助表示赞赏。

杰森

4

1 回答 1

3

尝试改变这个:(expr1=show)* {peList.add($expr1.value);}

对此:(expr1=show {peList.add($expr1.value);})*

该动作仅在所有匹配完成后才会触发show,让您在最后一个操作expr1

于 2012-11-27T17:26:48.157 回答