首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ANTLR: Lexer规则严格接受一个字母和多个字符的标记,而不是仅接受一个(Java)

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

Stack Overflow用户
提问于 2011-01-10 01:22:21
回答 1查看 1.1K关注 0票数 1

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

代码语言:javascript
复制
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); };

树语法:

代码语言:javascript
复制
tree grammar AntlrFormulaTreeParser;

options {
    tokenVocab=AntlrFormula;
    ASTLabelType=CommonTree;
}

expr returns [Formula f]
    : ^(BICONDITIONAL f1=expr f2=expr) {
        $f = new Biconditional(f1, f2);
    }
    | ^(IMPLICATION f1=expr f2=expr) {
        $f = new Implication(f1, f2);
    }
    | ^(DISJUNCTION f1=expr f2=expr) {
        $f = new Disjunction(f1, f2);
    }
    | ^(CONJUNCTION f1=expr f2=expr) {
        $f = new Conjunction(f1, f2);
    }
    | ^(NEGATION f1=expr) {
        $f = new Negation(f1);
    }
    | CHAR {
        $f = new Atom($CHAR.getText());
    }
    | TRUTH {
        $f = Atom.TRUTH;
    }
    | FALSITY {
        $f = Atom.FALSITY;
    }
    ;

我在上述语法方面遇到的问题如下:

  1. AntlrFormulaLexer代码中的令牌、含义和BICONDITIONAL似乎只是在检查它们各自的第一个字符(即'-‘和'<')是否匹配令牌,而不是语法中指定的整个字符串。
  2. 在测试AntlrFormulaParser的java代码时,如果传递"~ab“这样的字符串,它会返回"(~ a)”(和字符串"ab&c“只返回"a")的树,而实际上应该返回错误/异常,根据上面的语法,原子只能有一个字母。对于这些示例字符串,它根本不提供任何错误/异常。

如果有人能帮我解决这几个问题,我会非常感激的。谢谢您:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-01-10 01:34:27

我将以下定义改为:

代码语言:javascript
复制
IMPLICATION: ('\u2192' | '->');
BICONDITIONAL: ('\u2194' | '<->');

注:"->“vs”>“

为了解决错误问题:

代码语言:javascript
复制
formula 
    : (
         atom
       | LEFT_PAREN! biconexpr RIGHT_PAREN! 
      ) EOF
    ;

出发地:http://www.antlr.org/wiki/pages/viewpage.action?pageId=4554943

修正了针对antlr 3.3编译的语法(除Antlrforma.g外):

代码语言:javascript
复制
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; };

链接到antlr 3.3二进制:http://www.antlr.org/download/antlr-3.3-complete.jar

您将需要尝试匹配程序规则,以匹配完整的文件。

这个类是可测试的:

代码语言:javascript
复制
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();
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4642986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档