【问题标题】:Regular Expressions - tree grammar Antlr Java正则表达式 - 树语法 Antlr Java
【发布时间】:2012-12-01 05:19:00
【问题描述】:

我正在尝试用 ANTLR (Java) 编写一个关于简化正则表达式的程序。我已经写了一些代码(语法下面的文件内容)

grammar Regexp_v7;
options{
    language = Java;
    output = AST;
    ASTLabelType = CommonTree;
    backtrack = true;
}

tokens{
    DOT;
    REPEAT;
    RANGE;
    NULL;
} 

fragment
    ZERO
            :    '0'
            ;

fragment
    DIGIT
            :    '1'..'9'
            ;

fragment
    EPSILON
            :    '@'
            ;

fragment
    FI
            :    '%'
            ;

    ID
            :    EPSILON
            |    FI
            |    'a'..'z'
            |    'A'..'Z'
            ;

 NUMBER
            :    ZERO
            |    DIGIT (ZERO | DIGIT)*
            ;

 WHITESPACE
            :    ('\r' | '\n' | ' ' | '\t' ) + {$channel = HIDDEN;}
            ;

list
            :    (reg_exp ';'!)*
            ;

term
            :        ID -> ID
            |    '('! reg_exp ')'!
            ;

repeat_exp
            :    term ('{' range_exp '}')+ -> ^(REPEAT term (range_exp)+)
            |    term -> term
            ;

range_exp
            :    NUMBER ',' NUMBER -> ^(RANGE NUMBER NUMBER)
            |    NUMBER (',') -> ^(RANGE NUMBER NULL)
            |    ',' NUMBER -> ^(RANGE NULL NUMBER)
            |    NUMBER -> ^(RANGE NUMBER NUMBER)
            ;
kleene_exp
            :    repeat_exp ('*'^)*
            ;
concat_exp
            :    kleene_exp (kleene_exp)+ -> ^(DOT kleene_exp (kleene_exp)+)
            |    kleene_exp -> kleene_exp
            ;

reg_exp
            :    concat_exp ('|'^ concat_exp)*
            ;

我的下一个目标是写下树语法代码,它能够简化正则表达式(例如 a|a -> a 等)。我已经完成了一些编码(见下文),但我在定义将节点视为子树的规则时遇到了麻烦(为了简化以下类型的表达式,例如:(a|a)|(a|a) to a 等。 )

tree grammar Regexp_v7Walker;

options{
    language = Java;
    tokenVocab = Regexp_v7;
    ASTLabelType = CommonTree;
    output=AST;
    backtrack = true;
}

tokens{
    NULL;
}

bottomup
            : ^('*' ^('*' e=.)) -> ^('*' $e)    //a** -> a*
            | ^('|' i=.* j=.* {$i.tree.toStringTree() == $j.tree.toStringTree()} ) 
            -> $i // There are 3 errors while this line is up and running: 
                  // 1. CommonTree cannot be resolved, 
                  // 2. i.tree cannot be resolved or is not a field,
                  // 3. i cannot be resolved.
;

小驱动类:

public class Regexp_Test_v7 {
    public static void main(String[] args) throws RecognitionException {
        CharStream stream = new ANTLRStringStream("a***;a|a;(ab)****;ab|ab;ab|aa;");
        Regexp_v7Lexer lexer = new Regexp_v7Lexer(stream);
        CommonTokenStream tokenStream = new CommonTokenStream(lexer);
        Regexp_v7Parser parser = new Regexp_v7Parser(tokenStream);
        list_return list = parser.list();
        CommonTree t = (CommonTree) list.getTree();
        System.out.println("Original tree: " + t.toStringTree());
        CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
        Regexp_v7Walker s = new Regexp_v7Walker(nodes);
        t = (CommonTree)s.downup(t);
        System.out.println("Simplified tree: " + t.toStringTree());

谁能帮我解决这个问题? 提前致谢和问候。

【问题讨论】:

  • 我正在解析以下一组正则表达式:“a***;a|a;(ab)****;ab|ab;ab|aa;”有3个错误:1. CommonTree 无法解析,2. i.tree 无法解析或不是字段,3. i 无法解析。
  • 我用 kleene_exp 更新了语法并添加了小的测试驱动类
  • 浏览tree-pattern docs,我发现缺少一些东西:filter=true,这是强制性的,AFAIK。也许你应该再读一遍?
  • 还是一样...:/ 我特别感兴趣的是下面的代码 sn-p: "(...) ^('|' x=.* y=.*) {用 $x 和 $y} 做一些事情;"。是否有可能替换“。”与子树匹配的东西? {在花括号中,我想比较两个子树以简化表达式,例如:(a|a)|(a|a)}

标签: java antlr tree-grammar


【解决方案1】:

现在,我不是专家,但在你的树语法方面:

  1. 添加filter=true
  2. bottomup规则的第二行更改为:
    ^('|' i=. j=. {i.toStringTree().equals(j.toStringTree()) }? ) -> $i }

如果使用 i=.* 没有记错的话,您将允许 i 不存在,并且您将在转换为 String 时获得 NullPointerException

ij 都是 CommonTree 类型,因为你已经这样设置了:ASTLabelType = CommonTree,所以你应该调用i.toStringTree()

由于它是 Java 并且您正在比较字符串,请使用 equals()

还要使大括号中的表达式成为谓词,您需要在结束后加一个问号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    相关资源
    最近更新 更多