2013-10-15 2 views
14

일반적으로 ANTLR4에서 대체 레이블을 액세스하는 동안 구문 분석 트리를 탐색 할 수 있습니까? 또는, ANTLR3의 ^ 운영자의 기능을 복제하는 방법이 있습니다. 트릭을 수행하는 것입니다.일반적으로 ANTLR4에서 대체 레이블을 액세스하는 동안 구문 분석 트리를 탐색 할 수 있습니까?

간단한 방법론 (예 : 대체 레이블이있는 프로덕션 이름 지정)을 따르는 ANTLR4 문법에 대해 AST 예쁜 프린터를 작성하려고합니다. 때문에, 나는 효과적으로 plusminus 제작에 이름을 부여 드릴 수 없습니다

int_expression 
    : int_expression '+' int_expression # plus 
    | int_expression '-' int_expression # minus 
    | raw_int       # int_literal 
    ; 
raw_int 
    : Int 
    ; 
Int : [0-9]+ ; 

: 나는 다음과 같은 문법 주어진 꽤 (int_expression (plus (int_literal 3) (int_literal 5))), 또는 이와 유사한 같은 3 + 5 같은 용어를 인쇄 할 수 있도록하고 싶습니다 그것들을 자신의 프로덕션으로 끌어 내면 툴은 규칙들이 상호 왼쪽 - 재귀 적이라는 불평을하게됩니다. 내가 그걸 빼낼 수 없다면 어떻게이 작품 이름을 줄 수 있니?

주 1 : 나는 방법 론적으로 (예를 들어, 위의 Int) 특수 제작에서 (제작이 raw_ 같은 특정 접두어로 시작) "좋은"단자를 바꾸어 + 인수를 제거 할 수 있었다. 그런 다음 부모 작품의 이름이 "raw_ ..."이고 나머지는 모두 삭제하는 터미널 만 인쇄 할 수 있습니다. 이것은 을 없애고 출력에 35을 유지하는 데 효과적입니다. ANTLR3에서 !으로이 작업을 수행 할 수 있습니다.

참고 2 : 특정 전문 프린터를 작성하거나 주어진 언어의 각 제작 작업을 사용할 수 있지만 ANTLR4를 사용하여 다양한 언어의 구문 분석 및 AST를 생성하고 싶습니다. 이처럼 단순하고 예쁜 프린터를 일반적으로 작성할 수 있어야합니다. 다른 말로하면, 나는 AST를 얻는 것에 만 신경을 쓴다. AST를 얻기 위해 각기 다른 문법을 귀여운 프린터로 만들어 놓을 필요가 없다. 아마도 ANTLR3으로 돌아 가야할까요?

답변

1

중첩 된 방문자 클래스를 사용하여 예쁜 프린터를 구현하여 다양한 컨텍스트 개체의 이름을 가져 오는 것이 좋습니다.

private MyParser parser; // you'll have to assign this field 
private StringBuilder builder = new StringBuilder(); 

@Override 
public void enterEveryRule(@NotNull ParserRuleContext ctx) { 
    if (!builder.isEmpty()) { 
     builder.append(' '); 
    } 

    builder.append('('); 
} 

@Override 
public void visitTerminalNode(@NotNull TerminalNode node) { 
    // TODO: print node text to builder 
} 

@Override 
public void visitErrorNode(@NotNull TerminalNode node) { 
    // TODO: print node text to builder 
} 

@Override 
public void exitEveryRule(@NotNull ParserRuleContext ctx) { 
    builder.append(')'); 
} 

protected String getContextName(@NotNull ParserRuleContext ctx) { 
    return new ContextNameVisitor().visit(ctx); 
} 

protected class ContextNameVisitor extends MyParserBaseVisitor<String> { 
    @Override 
    public String visitChildren() { 
     return parser.getRuleNames()[ctx.getRuleIndex()]; 
    } 

    @Override 
    public String visitPlus(@NotNull PlusContext ctx) { 
     return "plus"; 
    } 

    @Override 
    public String visitMinus(@NotNull MinusContext ctx) { 
     return "minus"; 
    } 

    @Override 
    public String visitInt_literal(@NotNull MinusContext ctx) { 
     return "int_literal"; 
    } 
} 
+0

각 언어에 대해 전문적인 예쁜 프린터를 작성하지 않고이를 수행하는 일반적인 방법을 찾고 있습니다. 이것을 할 방법이 없습니까? 사용자의 관점에서 나는 대체 레이블이 바로 있기 때문에 왜 존재하지 않는지 이해하지 못합니다. –