递归规则中的ANTLR4顺序

时间:2014-05-23 12:34:47

标签: antlr4

我想描述DELPHI的BEGIN / END集团。

我使用以下源代码作为输入:

begin
  ModalResult         := mrCancel;
  FGradient.Free;
  if FMemorizeDimensions then
  begin
    if ERROR_SUCCESS = RegCreateKey(HKEY_CURRENT_USER,
                   PChar(gcsREG_KEYBASE),
                   hkResult) then
    try
      dwValueType := REG_DWORD;
      dwValue := Ord(WindowState);
      dwValueSize := SizeOf(dwValue);

    finally
      RegCloseKey(hkResult);
    end;
  end;
  inherited;
end;

这是我语法的一部分:

bloc
:BEGIN
     statement
    |conditionalBloc
    |bloc
 END SEMI
;

我在生成解析器,词法分析器等方面没有问题......

但是当我尝试使用其他语法时(切换'conditionalBloc'和'bloc'):

bloc
:BEGIN

    statement
    |bloc
    |conditionalBloc
 END SEMI
;

我得到了这个例外:

    java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
    java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
    sorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.antlr.v4.parse.GrammarTreeVisitor.visit(GrammarTreeVisitor.java:2
    07)
    at org.antlr.v4.parse.GrammarTreeVisitor.visitGrammar(GrammarTreeVisitor
    .java:201)
    at org.antlr.v4.semantics.SymbolCollector.process(SymbolCollector.java:7
    6)
    at org.antlr.v4.semantics.SemanticPipeline.process(SemanticPipeline.java
    :103)
    at org.antlr.v4.Tool.processNonCombinedGrammar(Tool.java:397)
    at org.antlr.v4.Tool.process(Tool.java:384)
    at org.antlr.v4.Tool.processGrammarsOnCommandLine(Tool.java:343)
    at org.antlr.v4.Tool.main(Tool.java:190)
    Caused by: java.lang.ArrayIndexOutOfBoundsException: 2
    at org.antlr.v4.semantics.SymbolCollector.discoverOuterAlt(SymbolCollect
    or.java:111)
    at org.antlr.v4.parse.GrammarTreeVisitor.outerAlternative(GrammarTreeVis
    itor.java:2285)
    at org.antlr.v4.parse.GrammarTreeVisitor.ruleBlock(GrammarTreeVisitor.ja
    va:2198)
    at org.antlr.v4.parse.GrammarTreeVisitor.rule(GrammarTreeVisitor.java:16
    64)
    at org.antlr.v4.parse.GrammarTreeVisitor.rules(GrammarTreeVisitor.java:1
    242)
    at org.antlr.v4.parse.GrammarTreeVisitor.grammarSpec(GrammarTreeVisitor.
    java:481)
    ... 12 more
    Exception in thread "main" java.lang.NullPointerException
    at org.antlr.v4.tool.Rule.getAltLabels(Rule.java:212)
    at org.antlr.v4.tool.Rule.hasAltSpecificContexts(Rule.java:200)
    at org.antlr.v4.semantics.SymbolChecks.checkForLabelConflicts(SymbolChec
    ks.java:151)
    at org.antlr.v4.semantics.SymbolChecks.process(SymbolChecks.java:99)
    at org.antlr.v4.semantics.SemanticPipeline.process(SemanticPipeline.java
    :107)
    at org.antlr.v4.Tool.processNonCombinedGrammar(Tool.java:397)
    at org.antlr.v4.Tool.process(Tool.java:384)
    at org.antlr.v4.Tool.processGrammarsOnCommandLine(Tool.java:343)
    at org.antlr.v4.Tool.main(Tool.java:190)

有人可以帮我理解这种情况吗?

1 个答案:

答案 0 :(得分:0)

以下是使用ANTLR 4操作顺序的bloc规则的重新格式化副本:

bloc
  : BEGIN statement
  | bloc
  | conditionalBloc END SEMI
  ;

我相信这就是你的意思:

bloc
  : BEGIN
    ( statement
    | bloc
    | conditionalBloc
    )
    END SEMI
  ;

异常是无法处理递归bloc替代,该替代在左递归引用之后不包含任何内容。您可以在此处打开项目问题跟踪器上的问题:

https://github.com/antlr/antlr4/issues