javalang包的源码简析

总体说明

javalang是一个解析java8语法的python三方库,采用的是自顶向下的解析方法,提前看1~2个字符+回溯。

tree.py 放ast的各种Node结构

parser.py 解析java8语法的核心类。

tokenizer.py lexer

parser详解

lookahead函数

next: 从lookahead表里取出一个token消费
look:看lookahead表的下一个token,不取出

accept函数

would_accept: 只判断是否指定token,不实际消费token
try_accept: 判断+成功则消费token+失败无动作
accept: 必须消费指定token,失败则抛JavaSyntaxError异常

accept既能接受指定值,也能接受指定类型,且可一次消费多个值或类型。其底层调用lookahead接口。

表达式解析

parse_expression: 表达式解析总入口,解析赋值语句,因赋值优先级最低
parse_expressionl: 解析赋值语句的左值,包括:三元操作符(?:),lambda和方法引用(method reference)
parse_expression_2: 解析二元操作符(如+-*/ instanceof等)
parse_expression_3: 解析一元操作符(!~等)及强制类型转换表达式
parse_primary: 解析优先级最高的表达式,如:括号表达式、this构造器调用、new表达式、变量id、成员引用、方法调用、基本类型、class引用等

若要新增表达式解析,放在哪个级别的函数里,需要仔细验证。不然,容易造成歧义。

语句解析

parse_statement: 解析各种语句,比如条件、循环、return、switch-case等
parse_block: 解析{}括起来的代码块

类型解析

parse_type: 解析基本类型和class类型(支持xx.xx.xx全路径名)

语句和表达式

语句与表达式的区别在于,前者没有结果值而后者有结果值,从汇报或字节码的层面来看,表达式必定有一个变量(可能是临时变量)承接,语句则只有一条条指令,无变量承接。

一些很好区别的例子,像变量名、四则运算就是表达式,条件(if)和循环(while/for)则是语句。

也有一些不那么好区别的例子,比如赋值语句,java和C/C++里是表达式,有结果值,所以能写链式赋值a=b=2;而在scala里是语句,无结果值,链式赋值会报编译错。另外,在java里,switch既能作为语句(switch-case+冒号),也能作为表达式(switch-case+箭头),而且还是优先级最高的原子表达式(primary)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值