`
庄表伟
  • 浏览: 1150846 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

ANTLR学习心得——第二个例子

阅读更多

  废话不说了,我们直接开始:

 

1、请在Eclipse中建立一个新的项目,名叫Simple2,在classpath中,要加入antlr.jar

2、再下载一个文件:simple2.g,放在这个项目的路径下

3、在DOS窗口下,输入antlr simple2.g

4、回到eclispe,按F5刷新,会看到多出不少文件来。

5、再新建一个类Main,输入以下代码:

import java.io.*;
public class Main {
    public static void main(String args[]) {
        FileInputStream f = null;
        try {
            f = new FileInputStream("......\\test.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        DataInputStream input = new DataInputStream(f);
        SimpleLexer lexer = new SimpleLexer(input);
        SimpleParser parser = new SimpleParser(lexer);
        try {
            parser.entry();
        } catch(Exception e) {}
    }
}

6、新建一个文本文件test.txt,输入内容:

06/06/82 Peter 20;
03/04/83 Rosie 19;
04/05/81 Mikey 21;

7、运行Mainm,就能看到输出结果:

Name: Peter, Age: 20, DOB: 06/06/82
Name: Rosie, Age: 19, DOB: 03/04/83
Name: Mikey, Age: 21, DOB: 04/05/81

 

下面来解释一下,这里面的原理。先来看simple2.g的内容:

class SimpleParser extends Parser;

entry : (d:DOB n:NAME a:AGE(SEMI)
      {
        System.out.println(
          "Name: "    +
          n.getText() +
          ", Age: "   +
          a.getText() +
          ", DOB: "   +
          d.getText()
        );
      })*
      ;

class SimpleLexer extends Lexer;

NAME : ('a'..'z'|'A'..'Z')+;

DOB  : ('0'..'9' '0'..'9' '/')=>
       (('0'..'9')('0'..'9')'/')(('0'..'9')('0'..'9')'/')('0'..'9')('0'..'9') //{ $setType(DOB); }
     | ('0'..'9')+  { $setType(AGE); } ;

WS     :
    (' '
    | '\t'
    | '\r' '\n' { newline(); }
    | '\n'      { newline(); }
    )
    { $setType(Token.SKIP); }
  ;

SEMI : ';' ;

 

要理解这个文件,我们得从下往上读,才能渐入佳境

 

最简单的是: 

SEMI : ';';

SEMI是一种符号,对于词法分析器来说,只要它读到一个字符是“;”,它就认为自己是读到了一个SEMI

 

第二简单的是:

NAME : ('a'..'z'|'A'..'Z')+;

当词法分析器读取一个一个的字符的时候,当他读到一个以上的字母(无论大小写),它都把它们连在一起,作为一个NAME。()+,就是出现一次以上的意思。()*,就是出现0次以上的意思。

 

第三简单的是:

WS  :
    (' '
    | '\t'
    | '\r' '\n' { newline(); }
    | '\n'      { newline(); }
    )
    { $setType(Token.SKIP); }
  ;

任何一个词法分析中定义的词,都有这样的格式:

[名称] : [定义] ;

定义的格式,又可以是一个或多个定义,';'就是一个定义,' '|'\t'就是两个定义。

每个定义之后,都可以跟一段代码,在

其中处理程序部分是可以省略的。

对于WS的定义,就是(' '|'\t'|'\r''\n'|'\n') 。但是,我们在这个定义之中,发现了三个嵌有代码的地方:'\r''\n'和'\n'后面,都有一句话,newline(),这是告诉词法分析器,行号计数器加一。这样在出现词法、语法错误时,就能报告一个准确的行号了。

在整个定义完成之后,还有一行代码$setType(Token.SKIP);,这是代码调用一个antlr的内置函数,告诉词法分析器,以上遇到的这四种字符情况,都请一律跳过。

 

最难的一种:

DOB  : ('0'..'9' '0'..'9' '/')=>
       (('0'..'9')('0'..'9')'/')(('0'..'9')('0'..'9')'/')('0'..'9')('0'..'9') //{ $setType(DOB); }
     | ('0'..'9')+  { $setType(AGE); } ;

为什么说这个是最难的一种,因为这篇blog我本来按照每天一篇的进度,是该在昨天发出来的,结果我想了一天,才终于想通这个语法的意义。

DOB,是一种单词,但是这个单词不是一次分析出来的,而是有一个试错的过程。

DOB的格式是00/00/00,而AGE的格式是00。这样要区分两个单词,就相当困难。

而现在的这个定义,则分为三个部分 (...)=>(...)|(...)。这相当于一般语言中的三元表达式:

(1)?(2):(3)。如果式1为真,则返回式2的值,否则返回式3的值。

DOB与AGE的区别在于第三个字符,如果('0'..'9' '0'..'9' '/')的尝试判断无误,则进一步分析这剩下的字符,是否符合DOB的格式。那//注释后面的代码,之所以被注释起来,就是因为他其实不用执行,也是DOB类型了。而如果('0'..'9' '0'..'9' '/')的尝试判断出错,则只能按照 ('0'..'9')+的判断来分析试一试,如果成立,就手工赋予一个类型AGE。

 

把这Lexer讲完以后,Parser其实是极为简单的,大家自己看吧。下一次我们讲讲表达式的ANTLR描述。

 

(未完待续)

分享到:
评论

相关推荐

    antlr4入门例子

    在这个“antlr4入门例子”中,我们将会探讨如何使用ANTLR4创建一个简单的解析器来处理“hello world”这样的语句。"hello-antlr4"可能是项目或者示例代码的名称,它可能包含以下组件: 1. **ANTLR4 Grammar**:首先...

    antlr 例子集 v3版

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架,包括SQL、Java、C#、Python、JavaScript等。...

    用Antlr 分析布尔表达式的例子

    用antlr分析处理布尔表达式的例子,包括:语法定义.g文件;生成的词法分析和语法分析器;带有图形界面的分析器调用代码。 其中带有GUI的分析器ParserFrame,可以用于任何.g文件生成的词法、语法分析器,只要通过改变...

    ANTLR和Soot的完整例子

    在实验的第二步,你需要实现一个自定义的ASTVisitor,遍历ANTLR生成的语法树。ASTVisitor模式允许你对每个节点执行特定操作,比如在访问到某个语句或表达式时,可以转换为Jimple三地址代码。Jimple是Soot使用的内部...

    antlr3.12--工具+JAR+例子

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于各种语言和系统的开发,包括编程语言、配置文件、协议、查询语言...

    antlr4应用例子

    基于antlr4的语义action和属性的编译器前端例子

    the Definitive ANTLR Reference 源代码 包含所有例子

    这本书深入浅出地介绍了ANTLR的工作原理和使用方法,包括语法定义、解析树构造、错误处理、访问语法树以及自定义语义动作等多个方面,是学习ANTLR的必备资料。 源代码部分包含了书中所有的示例,这对于理解ANTLR的...

    antlr-2.7.7.jar.zip

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于各种编程语言的编译器和解释器的构建,它能生成Java、C#、Python...

    antlr.jar.zip

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于构建语言、工具和框架,如SQL解析器、XML解析器以及各种编程语言...

    The Definitive ANTLR4Reference 学习笔记

    ANTLR(Another Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它被广泛应用于编程语言、协议、表达式、脚本和其他语言的定义。ANTLR 4是ANTLR系列...

    Antlr4 C++ 计算器

    ANTLR4 是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架,包括SQL、Java、C#、JavaScript、Python等。在本项目中,"Antlr4 C++ 计算器"是一个基于...

    编译原理学习框架antlr4

    ANTLR4(ANTLR Version 4)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架,包括SQL解析器、Java代码分析器以及各种语法权限控制系统。ANTLR4支持...

    ANTLR

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架,包括SQL解析器、XML处理器以及各类编程语言的...

    antlr-2.7 (3个)

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于各种编程语言的编译器和解释器的开发,它能生成Java、C#、Python...

    antlr 五分钟入门

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛用于构建语言、工具和框架,包括SQL、JavaScript、Python、Java、C++等。...

    antlr入门 编译领域

    为了更好地理解ANTLR的工作原理和使用方式,下面通过一个简单的例子来介绍ANTLR的基本语法结构: ```antlr grammar MyGrammar; options { language = Java; } // 定义词法规则 tokens { ID; } // 字母数字串...

    开源项目-antlr-antlr4.zip

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于构建语言、工具和框架,如SQL处理器、Java源码分析器、XML解析器...

    antlr-2.7.6.jar

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于构建语言、工具和框架,如SQL处理器、Java序列化器、XML解析器等...

    antlr4-master 源码

    ANTLR4(ANTLR Version 4)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架,包括SQL解析器、配置文件解析器、DSL(领域特定语言)以及各种编程...

Global site tag (gtag.js) - Google Analytics