手工编程实现词法分析器java_自制操作系统Antz(14)——实现内置编程语言(词法解析器)...

AntzScript

🎓 The language executed in the Antz system.

基于以实现的内置vim,接下来需要实现Antz系统中内置语言AntzScript。

vim

46042150e6b3369c7ddc7dcc3346e782.png

一、概述

1. 解释器与编译器

1.1 解释器

解释器根据程序中的算法执行运算。简单地说,它是一种用于执行程序的软件。

1.2 编译器

编译器能将某种语言写成的程序转换为另一种语言的程序。通常它会将源程序转换为机器语言程序。编译器转换程序的行为称为编译,转换前的程序称为源程序。

Java虚拟机为了提高性能,会在执行过程中通过编译器将一部分Java二进制代码直接转换为机器语言使用。

过去的编译器编译过程非常费时,不过由于编译后实际执行的是机器语言,因此执行速度很快。而解释器,会在程序输入的同时立即执行,执行速度较慢。这就是两者的基本区别。

在为Antz制作内置脚本语言时,因为是直接执行,处理器属于解释器,不过,为了提高性能,该解释器内部将采用编译器。

基本流程如下

9e42bd9ce96c1d3a92af5e72edd0d628.png

b79f8b76ed23f97ef947ac09697d493c.png

2. Token

语言处理器的第一个组成部分是词法分析器(lexer)。程序的源代码最初只是一长串字符串,这样的字符串很难处理,语言处理器通常会首先将字符串中的字符以解析单元分组,切割成多个Token,这就是词法分析。

解析结果

025529a7473a712911ad4298f2dbb09c.png

f8c048add949c3d236d3e516d7d14d11.png

Token类中需要对源代码分割成最小单元,并解析出变量类型,数值量,符号,标识符等

Token

ec4dc8d09d2ceb97f1ae50a67ee1b172.png

Token中k代表单元含义,lexeme代表其在代码中的内容。kindMap是一个提前预置关系转换符表。在需要添加其他关键字时可以直接在KindMap中添加。

fbfa174b9049b9dd517cf95a82b9b12c.png

词法解析器的实现方法有手工构造法和正则表达式的方法。

手工构造法-状态图

991efe367fbee638bead9a6b737dd3ec.png

这种方法较为复杂,需要大量的代码,而正则表达式的方法较为便捷。

二、实现词法解析

借助正则表达式库能简单地实现词法分析器。下表列出的记号在大多数情况下都能使用。例如,.*\.java指的是以.java结束的任意长度的字符串模式。.*\.由两部分组成,.*表示由任意字符组成的任意长度的字符串模式,\.表示与句点字符相匹配的字符串模式。(java|javax)\..*则表示由java.或javax.起始的任意长度的字符串模式。

元字符

含义

.

与任意字符匹配

[0-9]

与0至9中的某个数字匹配

[^0-9]

与0至9这些数字之外的的某个字符匹配

pattern*

模式pattern至少重复出现0次

pattern+

模式pattern至少重复出现1次

pattern?

模式pattern出现0次或1次

pattern1

pattern2

()

将括号内视为一个完整的模式

\c

与单个字符c(元字符*或.等)匹配

整型字面量的匹配

[0-9]+

标识符的匹配

[A-Z_a-z][A-Z_a-z0-9]*

以字母、下划线开头,之后仅包含有字母、数字、下划线的就是标识符的定义规则。

[A-Z_a-z][A-Z_a-z0-9]*|==|<=|>=|&&|\|\||\p{Punct}

最后的\p{Punct}表示与任意一个符号字符匹配。模式\|\|将会匹配||。由于|是正则表达式的元字符,因此在使用时必须添加反斜线转义。

最后需要定义的是字符串字面量。由于不得不处理各种转义字符,字符串字面量的定义略微复杂。

"(\\"|\\\\|\\n|[^"])*"

首先,从整体上看,这是一个"(pattern)*"形式的模式,即双引号内是一个与pattern重复出现至少0次的结果匹配的字符串。其中,模式pattern与\"、\\、\n匹配,同时也与除"之外任意一个字符匹配。

所以我们可以得到一个下图的匹配规则regexPat。

99cd380dbfbaed5e984b8eb6bb503378.png

ArrayList tokens是词法解析器Lexer中已解析的Token。

源码source作为参数传入Lexer的add方法中。

7397a180ed234c6c63c50aee82993606.png

在创建Token时,单元作为构造函数的参数。同时变量,数字值等单元我们无法通过KindMap类来判断k值,所以需要在这里判断。

3696731b2af0ee5d5a57a04a78449e13.png

3faa4d9c85a9535f807219139600c25f.png

判断是否是变量类型

6eb021a6a0f31c8d5f885f0aca234878.png

判断是否是数值类型

9728e1f57ca3c32a72ab0c5aa2c6bc8f.png

判断是否是字符串类型

4de64ca42a0624f049ac2ac59d201d93.png

三、效果

测试代码

fabf5ac94e7cc3cebd1fbafdc185a92f.png

Token解析

1fd991f6f86ba03679d12cf7112c3a85.png

a9d8dd2309738bee2791cb17e093714d.png

将源代码转换为了相应的Token单元,这就是词法解析的主要工作了。

接下来按照源代码获得转换后的直译代码。

效果图

be2ed036499596322e1e1d0bc2715ce6.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值