簡體   English   中英

正則表達式-樹語法Antlr Java

[英]Regular Expressions - tree grammar Antlr Java

我正在嘗試使用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)到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());

誰能幫我解決這個問題? 在此先感謝和問候。

現在,我不是專家,但是在您的樹語法中:

  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()

另外,要使大括號中的表達式成為謂詞,在結束括號后需要一個問號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM