【问题标题】:Parsing unstructured text with ANTLR使用 ANTLR 解析非结构化文本
【发布时间】:2011-10-12 20:09:03
【问题描述】:

例如,假设我想使用单个标记元素(双星 **)解析大部分非结构化文本。这是我的 ANTLR 语法:

text : (plain | tag)+ ;
plain : ~(TAG) ;

tag : TAG tag_inner TAG ;
tag_inner : ~(TAG) ;

TAG : '**' ;
TEXT : ('a'..'z' | ' ' | '.')+ ;

如果我正在解析的文本在语法上是正确的,那么这个语法就可以正常工作,也就是说,对于每个开头**,都有一个结尾**。如果**s 的数量是奇数,ANTLR 会报错,并输出错误。

如何解决这个问题,以便 ANTLR 会提前寻找关闭的双星,如果没有人将那颗孤立的双星视为纯文本?我很确定 ANTLR 可以做到这一点,而句法/语义谓词就是答案,但是在我们阅读文档之后,我仍然无法解决。

【问题讨论】:

    标签: parsing antlr


    【解决方案1】:

    当你扩展你的语法时,这会变得一团糟! :)

    但是,当然,可以使用谓词。这是一个演示:

    T.g

    grammar T;
    
    options {
      output=AST;
    }
    
    tokens {
      ROOT;
      PROPER_TAG;
    }
    
    parse
      :  text+ EOF -> ^(ROOT text+)
      ;
    
    text
      :  (tag)=> tag // syntactic predicate here! (the `(...)=>`)
      |  plain
      |  TAG
      ;
    
    plain
      :  ~TAG 
      ;
    
    tag
      :  TAG plain TAG -> ^(PROPER_TAG plain)
      ;
    
    TAG  : '**' ;
    TEXT : ('a'..'z' | ' ' | '.')+ ;
    

    Main.java

    import org.antlr.runtime.*;
    import org.antlr.runtime.tree.*;
    import org.antlr.stringtemplate.*;
    
    public class Main {
      public static void main(String[] args) throws Exception {
        TLexer lexer = new TLexer(new ANTLRStringStream("this **is** just **a simple** demo **."));
        TParser parser = new TParser(new CommonTokenStream(lexer));
        CommonTree tree = (CommonTree)parser.parse().getTree();
        DOTTreeGenerator gen = new DOTTreeGenerator();
        StringTemplate st = gen.toDOT(tree);
        System.out.println(st);
      }
    }
    

    运行演示

    java -cp antlr-3.3.jar org.antlr.Tool T.g
    javac -cp antlr-3.3.jar *.java
    java -cp .:antlr-3.3.jar Main
    

    这将产生一些DOT-output 对应于以下AST:

    (使用graphviz-dev.appspot.com 创建的图像)

    【讨论】:

      猜你喜欢
      • 2015-08-26
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      相关资源
      最近更新 更多