【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
词法分析是编译原理的基础。目前来说,大部分编程语言还是以英文为主。使用英文有几个好处,这主要是因为英文的单词和单词之间是用空格分开来的,不像中文需要用词组来分割。记得读书的时候,有一个编译原理上机作业,就是编写一个词法分析器。如果是纯手工编写词法分析器,那么势必涉及到状态机的知识。然而如果使用javacc来编写,只需要描述清楚规则就可以了。
目前词法分析涉及到的分词主要有这么几种,一种是关键字,一种是标识符,剩下来的就是各种各样的符号、字符串、数字等等。通常来说,分词就是将一长串的字符串解析成一个一个token。
当然,除了分词之外,有一些字符也是要过滤的,比如换行、空格、注释等等。
代码链接:https://github.com/feixiaoxing/DIYCompiler
1、关键字
关键字比较好理解。就是某个编程语言当中被预留的一些单词。比如c语言里面if、else、for、while、switch、case、goto等等,这些都属于关键字。javacc中一般是这么安排的,
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
2、标识符
除了关键字之外,接下来就该说说标志符了。标识符通常就是各种各样变量的名字。这个名字一般用于描述全局变量、局部变量、函数名、函数参数、函数调用等等。对于标识符,javacc是这样来描述的,
TOKEN: {}
3、其他符号
在关键字和标识符之后,留下来的就是各种各样的计算符号、数字、字符串和一些特殊付好了。比如,数字一般这么描述,
TOKEN: { }
计算符号通常这么来描述,
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
特殊符号也有一些,比如这些,
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
4、待过滤的符号
在编程代码中,有一些符号是要过滤的,他们不参与最终的代码生成,
SKIP: { <[" ", "\t", "\r", "\n"]> }
这样,有了上面四种形式的符号,基本的词法分析就差不多了。这里没有描述出来所有的符号,本着用多少记录多少的想法,大家在实际开发中可以根据自己的需要灵活增减。
5、实例
之前我们谈到了四则运算,这里稍作改变,其实就可以将语法表达式全部用token来表示了,
options {STATIC = false;
}PARSER_BEGIN(Parse)
import java.io.*;
public class Parse {public static void main(String[] args) {for (String arg : args) {try {System.out.println(evaluate(arg));} catch (ParseException ex) {System.err.println(ex.getMessage());}}}public static long evaluate(String src) throws ParseException {Reader reader = new StringReader(src);return new Parse(reader).expr();}
}
PARSER_END(Parse)SKIP: { <[" ", "\t", "\r", "\n"]> }TOKEN: { }TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}TOKEN: {}TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}
TOKEN: {}long expr() throws NumberFormatException :
{long value = 0 ;
}
{value = main_expr() { return value ; }
}long main_expr() throws NumberFormatException :
{long a ;long b ;long value = 0 ;
}
{a = primary() {value = a;}( b = primary(){ value += b; }| b = primary(){ value -= b; })*{ return value ; }
}long primary() throws NumberFormatException :
{long a ;long b ;long value = 0 ;
}
{a = secondary() {value = a;}( b = secondary(){ value *= b; }| b = secondary(){ value /= b; })*{ return value ; }
}long secondary() throws NumberFormatException:
{Token a;long b = 0;long value = 0;
}
{(a = {value = Integer.parseInt( a.image );} | b =main_expr() { value = b;}){ return value;}
}
这里有一点需要注意下,如果在语法表达式中需要使用token的时候,应该用<>来表示。此外如果需要解析这个token的时候,可以直接转变为Token,获取对应的信息就可以了。
上一篇:二叉树刷题
下一篇:position有哪些属性和区别
相关内容
热门资讯
【MySQL】锁
锁 文章目录锁全局锁表级锁表锁元数据锁(MDL)意向锁AUTO-INC锁...
【内网安全】 隧道搭建穿透上线...
文章目录内网穿透-Ngrok-入门-上线1、服务端配置:2、客户端连接服务端ÿ...
GCN的几种模型复现笔记
引言 本篇笔记紧接上文,主要是上一篇看写了快2w字,再去接入代码感觉有点...
数据分页展示逻辑
import java.util.Arrays;import java.util.List;impo...
Redis为什么选择单线程?R...
目录专栏导读一、Redis版本迭代二、Redis4.0之前为什么一直采用单线程?三、R...
【已解决】ERROR: Cou...
正确指令: pip install pyyaml
关于测试,我发现了哪些新大陆
关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
Lock 接口解读
前置知识点Synchronized synchronized 是 Java 中的关键字,...
Win7 专业版安装中文包、汉...
参考资料:http://www.metsky.com/archives/350.htm...
3 ROS1通讯编程提高(1)
3 ROS1通讯编程提高3.1 使用VS Code编译ROS13.1.1 VS Code的安装和配置...
大模型未来趋势
大模型是人工智能领域的重要发展趋势之一,未来有着广阔的应用前景和发展空间。以下是大模型未来的趋势和展...
python实战应用讲解-【n...
目录 如何在Python中计算残余的平方和 方法1:使用其Base公式 方法2:使用statsmod...
学习u-boot 需要了解的m...
一、常用函数 1. origin 函数 origin 函数的返回值就是变量来源。使用格式如下...
常用python爬虫库介绍与简...
通用 urllib -网络库(stdlib)。 requests -网络库。 grab – 网络库&...
药品批准文号查询|药融云-中国...
药品批文是国家食品药品监督管理局(NMPA)对药品的审评和批准的证明文件...
【2023-03-22】SRS...
【2023-03-22】SRS推流搭配FFmpeg实现目标检测 说明: 外侧测试使用SRS播放器测...
有限元三角形单元的等效节点力
文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
初级算法-哈希表
主要记录算法和数据结构学习笔记,新的一年更上一层楼! 初级算法-哈希表...
进程间通信【Linux】
1. 进程间通信 1.1 什么是进程间通信 在 Linux 系统中,进程间通信...
【Docker】P3 Dock...
Docker数据卷、宿主机与挂载数据卷的概念及作用挂载宿主机配置数据卷挂载操作示例一个容器挂载多个目...