Skip to content

Instantly share code, notes, and snippets.

@ZenLiuCN
Created April 16, 2020 15:36
Show Gist options
  • Save ZenLiuCN/dafaf635412274a8bf367f1f72824a59 to your computer and use it in GitHub Desktop.
Save ZenLiuCN/dafaf635412274a8bf367f1f72824a59 to your computer and use it in GitHub Desktop.
ANLTR4

ANTLR

ANTLR是什么

ANTLR (ANother Tool for Language Recognition)是一项开源的java编写的语法/词法分析器套件.

通过ANTLR可以生成语法处理器来对进行文本或二进制文件进行解析处理.

ANTLR由定义语法,编译工具和运行时库组成.

使用ANTLR需要先依据其定义语法编写语法解析文件(.g4),然后通过java编译器输出对应平台的解析器源代码

解析器源代码结合运行库即可进行语法树解析.

解析之后

解析之后,通过读取语法树即可将你的语法转换为对应平台的真实执行.

限制

只支持LR语法

ANTLR4支持的输出平台

  • Java
  • C#
  • Python2 Python3
  • javascript
  • Go
  • C++
  • Swift
  • Php

ANTLR 生成的对应平台解析器都需要对应平台的运行时进行支持!

语法解析文件

  • .g4 作为扩展名 (grammar 4 的缩写)

  • 语法文件定义语法中的模式

  • 解析文件定义语法解析的规则

  • 上两者可以合并为 语法解析文件 就是写一起完事儿

  • 基本格式

    //单行注释
    /*
     多行注释
    */
    /**
    * java 文档型注释
    */
    lexer grammar NameLexer;//定于语法文件和语法名称
    import OtherG4;//导入文件
    Token //定义一个语法标记
    	: Param //语法标记的模式
    	;//结束
    //--------这是同文件夹的另外一个g4
    parser grammar NameParser;//某个语法的解析规则
    options { tokenVocab = NameLexer; }//上面定义的语法
    Statement
    	: Pattern //语句的模式
    	;//结束
    //-------这是一个独立的g4	
    grammar NameLanguage;
    
    
  • 注释: 同Java就一毛一样

  • 语句: 最终由分号结束

  • Token: 标记,代表你的语法中的一个元素,Token名字必须是大写字母开头

  • Rule: 规则,规则名字必须是小写字母开头

  • Label: 标签,是规则一条匹配项后面以# 开始的标注,对不同的标签会生成对应的visitor方法

  • Identifier: Token和Statement的统称,可以包含Unicode的字面值(中文编程不是梦)

  • Literals:字面值,由单引号'包围起来的一个或多个字符

  • Actions: 目标平台的代码片段

  • EmbeddedCode: 嵌入的目标平台代码行,包括@header @member

  • Keywords: 关键词,这个是ANTLR定义语法的关键词

    关键词 说明
    import 导入另外一个语法规则文件
    fragment 定义一个语法片段
    lexer 定义语法,一般同grammar联用
    parser 定义解析规则,一般同grammar联用
    returns 定义返回值
    locals 定义局部变量
    throws 定义异常
    catch 定义异常捕获
    finally 不想注释了,同java一样一样嘚
    mode 定义模式
    options 定义选项值(后面细说)
    tokens 就是Token加s

    rule : 不是关键字,但是不要用,其他目标平台的关键字也不能用..so.中文考虑下🤔

  • 具体格式(🙂又是格式)

    /** 可选的像java一样的备注 */
    /**
    * lexer grammar  开头的文件只能有语法规则
    * parser grammar 开头的文件只能有解析规则
    * grammar 文件是上两者其一或同时兼具(懒就用这个)
    */
    grammar Name; //语法名字必须同文件名一样,比如这个文件就应该是Name.g4
    options {...}//这些操作是顺序无关的
    import ... ; //导入另外一个文件,必须是同类文件(语法或者解析规则或者又是语法又是解析规则)
     	
    tokens {...} //定义一堆没有语法规则的Token
    channels {...} // 只有语法文件可以有
    @actionName {...}
     	 
    rule1 // parser and lexer rules, possibly intermingled
    ...
    ruleN
    
  • import: 导入,引入另外一个同类 文件.相当于就写在一起了,

    • 被导入文件中已经有的规则会被当前文件所覆盖
    • 对于复合导入的文件,除了当前文件中的规则优先之外,最深的规则优先
      • A[r:'1';] B:[<-A;c'1';] C:[r:'2';] D[<-A,B;e:'3';] ==>D[r:'1';c:'1';e:'3';]

特殊用例

  • 流转: ->

    • -> skip 忽略 常用于注释等 WS:[\t\r\n]+ -> skip;

    • -> channel(NAME) 发送到通道

      WS  : [ \r\t\n]+    -> channel(HIDDEN) //等同 -> skip
          ;
      

参考资源

官方的开源语法库

官方文档(英文)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment