ANTLR4没有访问访客

时间:2016-03-08 09:10:01

标签: antlr antlr4

我正在尝试为我的语法创建访问者,遵循不同的帮助和建议。然而,即使我似乎做了每个人都告诉我的事情,我的访客似乎也不会被访问?这是我的ANTLR语法:

grammar Minecraft;

/* LEXER RULES */
SINGLE_COMMENT      : '//' ~('\r' | '\n')* -> skip ;
MULTILINE_COMMENT   : '/*' .*? '*/' -> skip ;
WS                  : [ \t\n\r]+ -> skip ;
fragment LETTER     : ('a' .. 'z') | ('A' .. 'Z') ;
IDENTIFIER          : LETTER+ ;
fragment NUMBER     : ('0' .. '9') ;
BOOL                : 'true' | 'false' ;
NUM                 : NUMBER+ | NUMBER+ '.' NUMBER+ ;
STR                 : '"' (LETTER | NUMBER)* '"' | '\'' (LETTER | NUMBER)* '\'' ;
COORDS              : NUM ',' NUM ',' NUM ;
ITEM_ID             : NUMBER+ | NUMBER+ ':' NUMBER+ ;
MULDIVMODOP         : '*' | '/' | '%' ;
ADDSUBOP            : '+' | '-' ;
NEGOP               : '!' ;
EQOP                : '==' | '!=' | '<' | '<=' | '>' | '>=' ;
LOGOP               : '&&' | '||' ;

/* PROGRAM GRAMMAR */

prog                : 'begin' 'bot' body 'end' 'bot' ;
body                : glob_var* initiate main function* ;
initiate            : 'initiate' stmt* 'end' 'initiate' ;
main                : 'loop' stmt* 'end' 'loop' ;
type                : 'num' | 'bool' | 'string' | 'block' | 'item' | 'coords' ;

function
    : 'function' IDENTIFIER '(' args ')' stmt* 'end' 'function'                                 #function_func
    | 'activity' IDENTIFIER '(' args ')' stmt* 'end' 'activity'                                 #activity_func
    ;

arg
    : (type | type '[' ']') IDENTIFIER                                                          #type_arg
    | dcl                                                                                       #dcl_arg
    ;

args                : arg ',' args | arg ;
i_args              : IDENTIFIER ',' i_args | /* epsilon */ ;

cond
    : '(' cond ')'                                                                              #paren_cond
    | left=cond MULDIVMODOP right=cond                                                          #multdiv_cond
    | left=cond ADDSUBOP right=cond                                                             #addsub_cond
    | NEGOP cond                                                                                #neg_cond
    | left=cond EQOP right=cond                                                                 #eq_cond
    | left=cond LOGOP right=cond                                                                #log_cond
    | tpe=(NUM | STR | BOOL | ITEM_ID | COORDS | IDENTIFIER)                                    #var_cond
    ;

stnd_stmt
    : dcl                                                                                       #dcl_stmt
    | 'for' IDENTIFIER '=' init=NUM way=('to' | 'downto') target=NUM 'do' stmt* 'end' 'for'     #for_stmt
    | rpt=('while' | 'until') cond 'repeat' stmt* 'end' 'repeat'                                #repeat_stmt
    | IDENTIFIER '(' i_args ')'                                                                 #func_call_stmt
    | IDENTIFIER '=' cond                                                                       #assign_stmt
    | 'return' (IDENTIFIER | cond)                                                              #return_stmt
    | 'break'                                                                                   #break_stmt
    ;

stmt                : stnd_stmt | if_stmt ;
else_stmt           : stnd_stmt | ifelse_stmt ;

if_stmt
    : 'if' cond 'then' stmt* 'end' 'if'
    | 'if' cond 'then' stmt* 'else' else_stmt* 'end' 'if'
    ;

ifelse_stmt
    : 'if' cond 'then' else_stmt*
    | 'if' cond 'then' else_stmt* 'else' else_stmt*
    ;

glob_var            : 'global' dcl ;

str_arr_items       : val=(STR | IDENTIFIER) ',' str_arr_items | val=(STR | IDENTIFIER) ;
num_arr_items       : val=(NUM | IDENTIFIER) ',' num_arr_items | val=(NUM | IDENTIFIER) ;
bool_arr_items      : val=(BOOL | IDENTIFIER) ',' bool_arr_items | val=(BOOL | IDENTIFIER) ;
blck_arr_items      : val=(ITEM_ID | IDENTIFIER) ',' blck_arr_items | val=(ITEM_ID | IDENTIFIER) ;

dcl
    : 'num' id=IDENTIFIER '=' (val=(NUM | IDENTIFIER) | accessing | cond)                       #num_dcl
    | 'bool' id=IDENTIFIER '=' (val=(BOOL | IDENTIFIER) | accessing | cond)                     #bool_dcl
    | 'string' id=IDENTIFIER '=' (val=(STR | IDENTIFIER) | accessing)                           #str_dcl
    | 'block' id=IDENTIFIER '=' (val=(ITEM_ID | IDENTIFIER) | accessing)                        #block_dcl
    | 'item' id=IDENTIFIER '=' (val=(ITEM_ID | IDENTIFIER) | accessing)                         #item_dcl
    | 'coords' id=IDENTIFIER '=' (val=(COORDS | IDENTIFIER) | accessing)                        #coords_dcl
    | 'string' '[' ']' id=IDENTIFIER '=' ('{' str_arr_items '}' | vid=IDENTIFIER)               #str_arr_dcl
    | 'num' '[' ']' id=IDENTIFIER '=' ('{' num_arr_items '}' | vid=IDENTIFIER)                  #num_arr_dcl
    | 'bool' '[' ']' id=IDENTIFIER '=' ('{' bool_arr_items '}' | vid=IDENTIFIER)                #bool_arr_dcl
    | tpe=('block' | 'item') '[' ']' id=IDENTIFIER '=' ('{' blck_arr_items '}' | vid=IDENTIFIER)#blck_item_arr_dcl
    ;

accessing
    : IDENTIFIER '[' val=('X' | 'Y' | 'Z') ']'                                                  #coords_accessing
    | IDENTIFIER '[' val=NUM+ ']'                                                               #arr_accessing
    ;

我的主要人物:

package Minecraft;
import org.antlr.runtime.RuleReturnScope;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.v4.runtime.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.*;

public class Minecraft {
    public static void main(String[] args) throws IOException {
        File f = new File("input");
        FileInputStream fis = new FileInputStream(f);

        ANTLRInputStream in = new ANTLRInputStream(fis);
        MinecraftLexer lexer = new MinecraftLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        MinecraftParser parser = new MinecraftParser(tokens);
        ParseTree tree = parser.prog();
        ReadBaseVisitor visitor = new ReadBaseVisitor();
        visitor.visit(tree);
    }
}

ReadBaseVisitor类:

package Minecraft;

public class ReadBaseVisitor extends MinecraftBaseVisitor<Symbol> {

    @Override
    public Symbol visitProg(MinecraftParser.ProgContext ctx){
        Symbol s = new Symbol();
        System.out.println("kk");
        return s;
    }
}

现在,问题是,它从不打印&#34; kk&#34; line,所以它永远不会进入visitProg方法,即使它来自prog方法,我首先创建了解析树。有人可以帮我吗?

修改

这是由ANTLR创建的MinecraftBaseVisitor:

package Minecraft;// Generated from E:/Dropbox/Dropbox/P4/ANTLRGrammar\Minecraft.g4 by ANTLR 4.5.1
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;

/**
 * This class provides an empty implementation of {@link MinecraftVisitor},
 * which can be extended to create a visitor which only needs to handle a subset
 * of the available methods.
 *
 * @param <T> The return type of the visit operation. Use {@link Void} for
 * operations with no return type.
 */
public class MinecraftBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements MinecraftVisitor<T> {
    /**
     * {@inheritDoc}
     *
     * <p>The default implementation returns the result of calling
     * {@link #visitChildren} on {@code ctx}.</p>
     */
    @Override public T visitProg(MinecraftParser.ProgContext ctx) {
        return visitChildren(ctx); }
}

编辑2

这是我的测试输入(这是正确的,它可以正确解析,当我使用测试装备时,我可以看到解析树就好了):

begin bot
    global string Test = "hi"
    global num TestA = 21

    initiate
    end initiate

    loop
    end loop
end bot

0 个答案:

没有答案