2017-05-16 7 views
0

이 질문에 대한 답변으로 How to create AST with ANTLR4? AST 노드를 만들 수 있었지만 허용 된 대답의 예에서 설명한대로 BuildAstVisitor을 코딩 할 때 막혔습니다.AstTList 생성 방법 - AstVistor 생성 방법

나는 이런 식으로 시작하는 문법이 있습니다

mini: (constDecl | varDef | funcDecl | funcDef)* ; 

을 그리고 난 블록에 라벨을 (antlr4이 label X assigned to a block which is not a set를 말한다)를 할당 할 수 없습니다 둘, 나는 어떻게 다음 노드를 방문하는 아무 생각이 없습니다.

public Expr visitMini(MiniCppParser.MiniContext ctx) { 
    return visitConstDecl(ctx.constDecl()); 
} 

나는 위의 코드에 다음과 같은 문제가 : 나는 내가 단지 visitConstDecl 기능을위한 하나 개의 요소를 필요로하는 반면, constDecl, varDef 또는 기타 옵션 ctx.constDecl()List<ConstDeclContext>을 반환 여부를 결정하는 방법을 모른다 .

편집 :

더 많은 문법 규칙 :

mini: (constDecl | varDef | funcDecl | funcDef)* ; 

//-------------------------------------------------- 

constDecl: 'const' type ident=ID init ';' ; 
init:  '=' (value=BOOLEAN | sign=('+' | '-')? value=NUMBER) ; 
// ... 

//-------------------------------------------------- 

OP_ADD: '+'; 
OP_SUB: '-'; 
OP_MUL: '*'; 
OP_DIV: '/'; 
OP_MOD: '%'; 

BOOLEAN  : 'true' | 'false' ; 
NUMBER   : '-'? INT ; 
fragment INT : '0' | [1-9] [0-9]* ; 
ID    : [a-zA-Z]+ ; 
// ... 

나는 여전히 BuildAstVisitor을 구현하는 방법에 완전히 확실하지 않다. 그런 다음 각각의 하위 규칙을 얻을 수 (그들을 위해 visitConstDecl(), visitVarDef()을 visitXXX 기능을 구현하려면

@Override 
public Expr visitMini(MiniCppParser.MiniContext ctx) { 
    for (MiniCppParser.ConstDeclContext constDeclCtx : ctx.constDecl()) { 
    visit(constDeclCtx); 
    } 
    return null; 
} 

@Override 
public Expr visitConstDecl(MiniCppParser.ConstDeclContext ctx) { 
    visit(ctx.type()); 
    return visit(ctx.init()); 
} 
+0

당신은 당신의 표현에 주위에 Kleene 별'*'을 넣었습니다. 이것은 각 항목이 여러 번 나타날 수도 있고 전혀 사용될 수도 없다는 것을 의미합니다. 이것이 바로'ctx.constDecl()'이 모든 노드의'constDecl' 자식 노드를 포함하는리스트를 반환하는 이유입니다. 최상위 대체 요소 (예 :'rule : foo # labelA | bar # labelB;')에만 레이블을 할당 할 수 있기 때문에 ANTLR이이를 거부합니다. 정확히 무엇을하려고하는지 모르기 때문에 여기서 해결책이 무엇인지는 알지 못합니다. 그러나 정확히 하나의 가지를 얻기 위해 별을 제거하거나 각 자식 노드를 방문해야합니다. 처음 것 대신에. –

+0

각 자식 노드를 방문한다면'visitMini' 함수는 무엇을 반환할까요? 당신의 예제에서 당신은'노드들 '의리스트를 방문 할 필요가 없다. – Johannes

답변

1

... 지금은 다음의 라인을 따라 뭔가를하지만 확실히 나에게 제대로 보이지 않습니다 등) 대신 visitMini() 함수. 입력에 실제로 일치하는 경우에만 호출됩니다. 그러므로 당신은 발생을 확인하지 않아도됩니다.

+0

방문자를 구현하는 경우 노드를 직접 방문하지 않아도됩니까? 나는 이것을하기위한 이유가 CST를 스스로 통과하여 AST를 구축 할 수 있다고 생각했습니다. 그러므로'visitMini()'함수를 구현해야합니다. 왜냐하면 그것은 입력 된 첫 번째 규칙이기 때문입니다. 미안해, 내가 잘못 했어! – Johannes

+0

내 실수를 발견했다. 나는'XBaseVisitor'를 확장하기보다는'Visitor'를 구현하고 있었다. – Johannes