hive源码解析(2)之编译前序

时间:2023-02-11 11:44:10

Antlr(ANother Tool for LanguageRecognition)

ü     一种语言识别工具

ü     Antlr提供了一种语言工具框架

ü     定义标示符,关键字(词法分析)

ü     定义表达式(语法分析)

ü     可以将文本转换成抽象语法树(AST)

ü     树的解析(树分析器)

 

(1)词法分析器Lexer

ü  词法分析识别的是字符流

ü  通过词法规则,依次读入字符,并转换成记号(Token)

例如,s e l e ct--->select 关键字的过程就是一个词法分析的过程

ü  词法分析过程是一个ASCII分类整理的过程,哪些地方可以跳过(空格、换行、注释) ,哪些记号属于标识符,哪些记号属于字符串、整数、浮点数等。

ü  词法部分的定义以大写字母开头

词法分析器常见定义:

ID  :        ('a'..'z'|'A'..'Z'|'_')('a'..'z'|'A'..'Z'|'0'..'9'|'_')*

    ;//定义一个字符

 

INT :          '0'..'9'+

    ;//定义一个正整数

 

FLOAT

   :   ('0'..'9')+ '.' ('0'..'9')*EXPONENT?

   |   '.' ('0'..'9')+ EXPONENT?

   |   ('0'..'9')+ EXPONENT

    ;//定义一个浮点数

COMMENT

   :   '//' ~('\n'|'\r')* '\r'? '\n'{$channel=HIDDEN;}

   |   '/*' ( options {greedy=false;}: . )* '*/' {$channel=HIDDEN;}

    ;//定义一个多行注释

 

WS :   ( ' '

       | '\t'

       | '\r'

       | '\n'

       ) {$channel=HIDDEN;}

    ;//定义一个可以忽略的字符

 

STRING

   :  '"' ( ESC_SEQ |~('\\'|'"') )* '"'

    ;//定义一个字符串

 

CHAR: '\'' ( ESC_SEQ | ~('\''|'\\') ) '\''

    ;

 

fragment

EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+;

 

fragment

HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

 

fragment

ESC_SEQ

   :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')

   |   UNICODE_ESC

   |   OCTAL_ESC

    ;

 

fragment

OCTAL_ESC

   :   '\\' ('0'..'3') ('0'..'7')('0'..'7')

   |   '\\' ('0'..'7') ('0'..'7')

   |   '\\' ('0'..'7')

    ;

 

fragment

UNICODE_ESC

   :   '\\' 'u' HEX_DIGIT HEX_DIGITHEX_DIGIT HEX_DIGIT

;

 

(2)语法分析器(Parser)

ü  根据词法分析输出的记号流,分析语法结构,并添加代表语法结构的抽象单词(如:表达式、类、方法等),按照语法结构生成语法树的过程

ü    语法分析定义了输入字符串的合法性

ü    语法分析将词与词之间的关系用一个语法树表达出来

ü    语法部分的定义由小写字母开头、

ü    语法分析可以生成抽象语法树(AST)

 

(3)树分析器(TreeParser)

ü  树分析器可以用于对语法分析生成的抽象语法树进行遍历,并能执行一些相关的操作。

 

grammar Expr;

 

@header {

package test;

importjava.util.HashMap;

}

 

@lexer::header{package test;}

 

@members {

/** Mapvariable name to Integer object holding value */

HashMap memory= new HashMap();

}

 

prog:   stat+ ;

               

stat:   expr NEWLINE{System.out.println($expr.value);}

    |  ID '=' expr NEWLINE

        {memory.put($ID.text, newInteger($expr.value));}

    |  NEWLINE

    ;

 

expr returns[int value]

    :  e=multExpr {$value = $e.value;}

        (  '+' e=multExpr {$value += $e.value;}

        |  '-' e=multExpr {$value -= $e.value;}

        )*

    ;

   

multExprreturns [int value]

    :  e=atom {$value = $e.value;} ('*' e=atom {$value *= $e.value;})*

    ;

 

atom returns[int value]

    :  INT {$value = Integer.parseInt($INT.text);}

    |  ID

        {

        Integer v =(Integer)memory.get($ID.text);

        if ( v!=null ) $value = v.intValue();

        else System.err.println("#ff0000variable "+$ID.text);

        }

    |  '(' e=expr ')' {$value = $e.value;}

    ;

 

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

INT :   '0'..'9'+ ;

NEWLINE:'"r'?'"n' ;

WS  :   (''|'"t')+ {skip();} ;

 hive源码解析(2)之编译前序