ANTLR:Lexer规则严格接受一个字母和多个字符的标记,而不是一个(Java)

ANTLR:Lexer规则严格接受一个字母和多个字符的标记,而不是一个(Java),java,antlr,token,chars,Java,Antlr,Token,Chars,我已经为ANTLR解析器和lexer编写了以下语法,用于为逻辑公式构建树,如果有人能帮忙,我有几个问题: class AntlrFormulaParser extends Parser; options { buildAST = true; } biconexpr : impexpr (BICONDITIONAL^ impexpr)*; impexpr : orexpr (IMPLICATION^ orexpr)*; orexpr : andexpr (DISJUNCTION^

我已经为ANTLR解析器和lexer编写了以下语法,用于为逻辑公式构建树,如果有人能帮忙,我有几个问题:

class AntlrFormulaParser extends Parser;

options {
    buildAST = true;
}

biconexpr : impexpr (BICONDITIONAL^ impexpr)*;

impexpr : orexpr (IMPLICATION^ orexpr)*;

orexpr : andexpr (DISJUNCTION^ andexpr)*;

andexpr : notexpr (CONJUNCTION^ notexpr)*;

notexpr : (NEGATION^)? formula;

formula 
    : atom
    | LEFT_PAREN! biconexpr RIGHT_PAREN!
    ;

atom
    : CHAR
    | TRUTH
    | FALSITY
    ;


class AntlrFormulaLexer extends Lexer;

// Atoms
CHAR: 'a'..'z';
TRUTH: ('\u22A4' | 'T');
FALSITY: ('\u22A5' | 'F');

// Grouping
LEFT_PAREN: '(';
RIGHT_PAREN: ')';
NEGATION: ('\u00AC' | '~' | '!');
CONJUNCTION: ('\u2227' | '&' | '^');
DISJUNCTION: ('\u2228' | '|' | 'V');
IMPLICATION: ('\u2192' | "->");
BICONDITIONAL: ('\u2194' | "<->");

WHITESPACE : (' ' | '\t' | '\r' | '\n') { $setType(Token.SKIP); };
我在上述语法中遇到的问题如下:


  • AntlFormulaLexer的java代码中的标记、蕴涵和双条件似乎只检查它们各自的第一个字符(即“-”和“i将更改以下定义:

    IMPLICATION: ('\u2192' | '->');
    BICONDITIONAL: ('\u2194' | '<->');
    
    从这里开始:

    修复了根据antlr 3.3编译的语法(另存为AntlrFormula.g):


    我将以下定义更改为:

    IMPLICATION: ('\u2192' | '->');
    BICONDITIONAL: ('\u2194' | '<->');
    
    从这里开始:

    修复了根据antlr 3.3编译的语法(另存为AntlrFormula.g):


    我通过上面的定义得到这个错误:错误:令牌流错误读取语法:Formula.g:41:28:应为“”,找到“>”TokenStreamException:应为“”,找到“>”我想我最初尝试了您的定义,但出现了错误并决定切换到双引号。奇怪..在他们的示例中,他们允许这样做:ASSERT:“ASSERT”;。请参阅他们网站上的java.g语法。闭包语法相同..什么antlr版本d你用什么?我想我用的是最新的版本,v3.3。我怀疑:)。我刚刚用3.3编译了您的示例,失败了很多:)。我将发布一个合适的文件(可使用3.3编译)和一个到antlr 3.3发行版的链接,并要求您测试它。我通过上面的定义得到此错误:错误:令牌流错误读取语法:公式。g:41:28:应为“”,发现“>”令牌流异常:应为“”,发现“>”,我想我最初尝试了您的定义,但是得到了错误,决定切换到双引号。奇怪。。在他们的样本中,他们允许这样做:断言:“断言”;。有关闭包语法,请参见他们网站上的java.g语法。你用的是什么antlr版本?我想我用的是最新版本,v3.3。我怀疑:)。我刚刚用3.3编译了您的示例,失败了很多:)。我将发布一个合适的文件(可使用3.3进行编译)和一个到antlr 3.3发行版的链接,我将要求您对其进行测试。
    formula 
        : (
             atom
           | LEFT_PAREN! biconexpr RIGHT_PAREN! 
          ) EOF
        ;
    
    grammar AntlrFormula;
    
    options {
        output = AST; 
    }
    
    
    program : formula ;
    
    formula : atom | LEFT_PAREN! biconexpr RIGHT_PAREN! ;
    
    biconexpr : impexpr (BICONDITIONAL^ impexpr)*;
    
    impexpr : orexpr (IMPLICATION^ orexpr)*;
    
    orexpr : andexpr (DISJUNCTION^ andexpr)*;
    
    andexpr : notexpr (CONJUNCTION^ notexpr)*;
    
    notexpr : (NEGATION^)? formula;
    
    
    atom
        : CHAR
        | TRUTH
        | FALSITY
        ;
    
    
    // Atoms
    CHAR: 'a'..'z';
    TRUTH: ('\u22A4' | 'T');
    FALSITY: ('\u22A5' | 'F');
    
    // Grouping
    LEFT_PAREN: '(';
    RIGHT_PAREN: ')';
    NEGATION: ('\u00AC' | '~' | '!');
    CONJUNCTION: ('\u2227' | '&' | '^');
    DISJUNCTION: ('\u2228' | '|' | 'V');
    IMPLICATION: ('\u2192' | '->');
    BICONDITIONAL: ('\u2194' | '<->');
    
    WHITESPACE : (' ' | '\t' | '\r' | '\n') { $channel = HIDDEN; };
    
    import org.antlr.runtime.*;
    
    public class Main {
        public static void main(String[] args) {
            AntlrFormulaLexer lexer = new AntlrFormulaLexer(new ANTLRStringStream("(~ab)"));
            AntlrFormulaParser p = new AntlrFormulaParser(new CommonTokenStream(lexer));
    
            try {
                p.program();
                if ( p.failed() || p.getNumberOfSyntaxErrors() != 0) {
                    System.out.println("failed");
                }
            } catch (RecognitionException e) {
                e.printStackTrace();
            }
        }
    }