C# 在ANTLR中修改运行时终端的值

C# 在ANTLR中修改运行时终端的值,c#,parsing,antlr,C#,Parsing,Antlr,假设我有一个简单的语法,如下所示: name -> girl_name | boy_name; girl_name -> 'Matilda' | 'Vicky' | 'Alice'; boy_name -> 'Spike' | 'Athos' | 'Mike'; 我在ANTLRv3中为它建模。是否有可能,在运行时,我预测男孩和女孩的名字终端可以接受的一组值 谢谢:)在你的lexer语法中,你可以包含一个非常简单的名称定义 NAME : ('A'..'Z' | 'a'..'z'

假设我有一个简单的语法,如下所示:

name -> girl_name | boy_name;
girl_name -> 'Matilda' | 'Vicky' | 'Alice';
boy_name -> 'Spike' | 'Athos' | 'Mike';
我在ANTLRv3中为它建模。是否有可能,在运行时,我预测男孩和女孩的名字终端可以接受的一组值


谢谢:)

在你的lexer语法中,你可以包含一个非常简单的
名称定义

NAME : ('A'..'Z' | 'a'..'z')+;
@members {
    public static final Set<String> GIRL_NAMES = new HashSet<String>();
    static {
        GIRL_NAMES.add("Matilda");
        GIRL_NAMES.add("Vicky");
        GIRL_NAMES.add("Alice");
    }

    public static final Set<String> BOY_NAMES = new HashSet<String>();
    static {
        BOY_NAMES.add("Spike");
        BOY_NAMES.add("Athos");
        BOY_NAMES.add("Mike");
    }

    public static final int ClassifyName(String name) {
        if (GIRL_NAMES.contains(name)) {
            return GIRL_NAME;
        } else if (BOY_NAMES.contains(name)) {
            return BOY_NAME;
        } else {
            return NAME;
        }
    }
}
然后通过创建
fragment
规则定义
GIRL\u NAME
BOY\u NAME
标记

fragment GIRL_NAME : ;
fragment BOY_NAME : ;
然后,创建代码,将
名称
分配给
女孩姓名
男孩姓名

NAME : ('A'..'Z' | 'a'..'z')+;
@members {
    public static final Set<String> GIRL_NAMES = new HashSet<String>();
    static {
        GIRL_NAMES.add("Matilda");
        GIRL_NAMES.add("Vicky");
        GIRL_NAMES.add("Alice");
    }

    public static final Set<String> BOY_NAMES = new HashSet<String>();
    static {
        BOY_NAMES.add("Spike");
        BOY_NAMES.add("Athos");
        BOY_NAMES.add("Mike");
    }

    public static final int ClassifyName(String name) {
        if (GIRL_NAMES.contains(name)) {
            return GIRL_NAME;
        } else if (BOY_NAMES.contains(name)) {
            return BOY_NAME;
        } else {
            return NAME;
        }
    }
}

在lexer语法中,可以包含一个非常简单的
NAME
定义

NAME : ('A'..'Z' | 'a'..'z')+;
@members {
    public static final Set<String> GIRL_NAMES = new HashSet<String>();
    static {
        GIRL_NAMES.add("Matilda");
        GIRL_NAMES.add("Vicky");
        GIRL_NAMES.add("Alice");
    }

    public static final Set<String> BOY_NAMES = new HashSet<String>();
    static {
        BOY_NAMES.add("Spike");
        BOY_NAMES.add("Athos");
        BOY_NAMES.add("Mike");
    }

    public static final int ClassifyName(String name) {
        if (GIRL_NAMES.contains(name)) {
            return GIRL_NAME;
        } else if (BOY_NAMES.contains(name)) {
            return BOY_NAME;
        } else {
            return NAME;
        }
    }
}
然后通过创建
fragment
规则定义
GIRL\u NAME
BOY\u NAME
标记

fragment GIRL_NAME : ;
fragment BOY_NAME : ;
然后,创建代码,将
名称
分配给
女孩姓名
男孩姓名

NAME : ('A'..'Z' | 'a'..'z')+;
@members {
    public static final Set<String> GIRL_NAMES = new HashSet<String>();
    static {
        GIRL_NAMES.add("Matilda");
        GIRL_NAMES.add("Vicky");
        GIRL_NAMES.add("Alice");
    }

    public static final Set<String> BOY_NAMES = new HashSet<String>();
    static {
        BOY_NAMES.add("Spike");
        BOY_NAMES.add("Athos");
        BOY_NAMES.add("Mike");
    }

    public static final int ClassifyName(String name) {
        if (GIRL_NAMES.contains(name)) {
            return GIRL_NAME;
        } else if (BOY_NAMES.contains(name)) {
            return BOY_NAME;
        } else {
            return NAME;
        }
    }
}

这种方法适用于更复杂的语法吗?换句话说,是否有可能像这样返回终端,并且实际上匹配整个非终端?A->B{$type=ClassifyName($text)}C{$type=ClassifyName($text)}。这个方法适用于更复杂的语法吗?换句话说,是否有可能像这样返回终端,并且实际上匹配整个非终端?A->B{$type=ClassifyName($text)}C{$type=ClassifyName($text)}。