ROST情感分析的语法规则_从词法分析角度聊 Go 代码组成
之前的 Go 笔记系列,已经完成到了开发环境搭建,原本接下来的计划就是到语法部分了,但后来一直没有前进。主要是因为当时的工作比较忙,分散了精力,于是就暂时放下了。
最近,准备重新把之前计划捡起来。
第一步,肯定是了解 Go 基础语法部分。原本计划是写 Go 编码的一些基础知识,但纯粹聊什么是关键字、标识符、字面量、操作符实在有点无聊。
突然想到,词法分析这块知识还没仔细研究过,那就从这个角度出发吧。通过逐步地拆解,将各个 token 进行归类。
概述
我们知道,编译型语言(比如 Go)的源码要经过编译和链接才能转化为计算机可以执行的程序,这个过程的第一步就是词法分析。
什么是词法分析呢?
它就是将源代码转化为一个个预先定义的 token。为了便于理解,我们将词法分析分为两个阶段。
第一阶段,对源码串进行扫描,按预先定义的 token 规则进行匹配并切分为一个个有语法含义、最小单元的字符串,即词素(lexme),并在此基础上将其划归为某一类 token。这个阶段,一些字符可能会被过滤掉,比如,空白符、注释等。
第二阶段,通过评估器 Evaluator 评估扫描出来的词素,并确定它字面值,生成最终的 Token。
是不是有点不好理解呢?
如果之前从未接触过这块内容,可能没有直观感受。其实,看着很复杂,但的确非常简单。
一个简单的示例
先看一段代码,经典的 hello world,如下:
package main
我们可以通过这个例子的源码逐步拆解词法分析的整个流程。
什么是词素
理论性的概念就不说了,直接看效果吧。
首先,将这段示例代码通过词法分析的第一阶段,我们将会得到如下内容:
packagemain\nimport"fmt"\nfuncmain(){\nfmt.Println("Hello World")\n}
输出的这一个个独立的字符序列就是词素。
词素的切分规划和语言的语法规则有关。此处的输出中除了一些可见的字符,换行符同样也具有语法含义,因为 Go 不像 C/C++ 必须是分号分隔语句,也可以通过换行符分隔。
源码分割为一个个词素的过程是有一定的规则的,这和具体的语言有关。但虽有差异,其实规则都差不多,无非两种,一是通过无语法含义的字符(空格符、制表符等)切分,还有是每个词素可以用作为分隔符。
什么是 token
token,也称为词法单元、记号等,它由名称和字面值两部分组成。从词素到 token 有固定的对应关系,而且并非所有的 token 都有字面值。
将 hello world 的源码转化为 token,我们将会得到如下的一张对应表格。
lexme | name | value |
---|---|---|
package | PACKAGE | "package" |
main | IDENT | "main" |
\n | SEMICOLON | "\n" |
import | IMPORT | "import" |
"fmt" | STRING | "\"fmt\"" |
\n | SEMICOLON | "\n" |
func | FUNC | "func" |
main | IDENT | "main" |
( | LPAREN | "" |
) | RPAREN | "" |
{ | LBRACE | "" |
fmt | IDENT | "fmt" |
. | PERIOD | "" |
Println | IDENT | "Println" |
( | LPAREN | "" |
"Hello World" | STRING | ""Hello World"" |
) | RPAREN | "" |
\n | SEMICOLON | "\n" |
} | LBRACE | "" |
\n | SEMICOLON | "\n" |
稍微有点长,因为这里没有省略。表格中的第一列是原始内容,第二列对应的 token 的名称,最后一列是 token 的字面值。
从表格中可以观察出,其中有一些 token 并没有值,比如,括号、点,名称本身已经表示了它们的内容。
token 的分类
token 一般可以分为关键字、标识符、字面量、操作符这四个大类。这个分类其实在 Go 的源码中有非常明显的体现。
查看源码文件 src/go/token/token.go[1],将会找到 Token
类型如下的几个方法。
// 是否是字面常量
代码非常简单,通过比较确定 Token
是否位于指定范围确定它的类型。上面的这三个方法分别对应于判断 Token
是字面常量、操作符还是关键字。
额?怎么没有标识符呢?
当然也有啦,只不过它不是 Token
的方法,而是单独的一个函数。如下:
func IsIdentifier(name string) bool {
我们常说的变量、常量、函数、方法的名称不能为关键字,且必须是由字母、下划线或数字组成,且名称的开头不能为数字的规则,看到这个函数是不是一些就明白了。
到这里,其实已经写的差不多了。但想想还是拿其中一个类型再简单说说吧。
关键字
就以关键字为例吧,Go 中的关键字有哪些呢?
继续看源码。将之前那段如何判断一个 token
是关键字的代码再看一遍。如下:
func (tok Token) IsKeyword() bool {
只要 Token
大于 keyword_beg
且小于 keyword_end
即为关键字,看起来还挺好理解的。那在 keyword_beg
和 keyword_end
之间有哪些关键字呢?代码如下:
const (
总共梳理出了 25 个关键字。如下:
break
关键字的确挺少的。可见。。。
嗯?!
是不是猜到我要说,Go 语言就是简洁,关键字的都这么少。你看 Java,足足有 53 个关键字,其中有两个是保留字,而 Go 并没有保留字,自信!
既然你猜到了,那我还是先不说了吧。
其他
操作符和字面常量就不追了,思路都是一样的。
Go 中的操作符有 47 个,比如赋值运算符、位运算符、算术运算符,比较运算符,还有其他的操作符。相信我吧,都是从源码中数出来的,没有看任何资料。[此处应该放个捂脸笑]。
字面常量呢?有 5 种类型,分别是 INT(整型)、FLOAT(浮点型)、IMG(复数类型)、CHAR(字符型)、STRING(字符串型),
总结
文章写完了,前面扯了那么一堆废话,其实就只是为了介绍 Go 语法中用到的关键字、标识符、运算符、字面量从哪里找。并且,最终它们如何使用也没有怎么说明。
纯粹为了好玩吗?当然不是(是)。因为。。。,先不剧透了,避免后面尴尬。
阅读资料
Go 程序是怎么跑起来的[2]
go-lexer 词法分析[3]
Lexical analysis[4]
词法分析[5]
喜欢本文的朋友,欢迎关注“Go语言中文网”:
参考资料
[1]
src/go/token/token.go: https://github.com/golang/go/blob/master/src/go/token/token.go
[2]
Go 程序是怎么跑起来的: https://zhuanlan.zhihu.com/p/71993748
[3]
go-lexer 词法分析: https://studygolang.com/articles/6708
[4]
Lexical analysis: https://en.wikipedia.org/wiki/Lexical_analysis#Evaluator
[5]
词法分析: https://cs.nju.edu.cn/changxu/2_compiler/slides/Chapter_3.pdf
ROST情感分析的语法规则_从词法分析角度聊 Go 代码组成相关推荐
- go string 换行_从词法分析角度聊 Go 代码组成
之前的 Go 笔记系列,已经完成到了开发环境搭建,原本接下来的计划就是到语法部分了,但后来一直没有前进.主要是因为当时的工作比较忙,分散了精力,于是就暂时放下了. 最近,准备重新把之前计划捡起来. 第 ...
- 情感分析朴素贝叶斯_朴素贝叶斯推文的情感分析
情感分析朴素贝叶斯 Millions of tweets are posted every second. It helps us know how the public is responding ...
- python评论情感分析计算分数值_使用python对淘宝评论进行情感分析并绘制词云
淘宝商品评论分析系统简介 截至2018年12月,我国网络购物用户规模达6.10亿,网购已经慢慢占据了我们生活的方方面面,所以一份透明的网购指南就显得尤为重要. 大部分网购消费群体只能依赖于其他人在商品 ...
- mysql 名次语法规则_基于sql语句的一些常用语法积累总结
1.当某一字段的值希望通过其它字值显示出来时(记录转换),可通过下面的语句实现:case Type when '1' then '普通通道' when '2' then '高端通道' end as T ...
- matlab的基本语法规则_【经验交流】matlab自定义回调函数语法规则
给出我今天学到的两个例子来说明两种用法: (1)set(h, 'StartFcn', @myfile)型 function [varargout] = XIE_bwmorphfig(Size, var ...
- 正则表达式变量名命名的规则_如何简单有效地提高代码质量?修改变量名即可...
全文共6633字,预计学习时长13分钟 图片来源:pexels.com/@digitalbuggu 请快速说出以下代码的功能: for i in range(n): for j in range(m) ...
- python中有哪些重要的书写规则_一文读懂Python代码的书写规范
Python代码的书写规范 1. 一致性的建议 打破一条既定规则的两个好理由 当应用这个规则将导致代码可读性下降,即使对于某人来说他已经习惯于按照这条规则来阅读代码了 为了和周围的代码保持一致而打破规 ...
- java qq号码生成规则_只需亿小串代码,教你用java仿制qq
只需亿小串代码,教你用java仿制qq 直奔主题,代码如下: import java.awt.Color; import java.awt.Container; import java.awt.Ima ...
- 开平方_复数有效值+角度的verilog代码
1.逐位比较法-二进制 < FPGA篇(一) 基于verilog的定点开方运算(1)-逐次逼近算法 >该篇文章中有详细描述 假设被开方数rad_i[7:0],则结果qout[3:0]位宽为 ...
- [Python人工智能] 三十四.Bert模型 (3)keras-bert库构建Bert模型实现微博情感分析
从本专栏开始,作者正式研究Python深度学习.神经网络及人工智能相关知识.前一篇文章开启了新的内容--Bert,首先介绍Keras-bert库安装及基础用法及文本分类工作.这篇文章将通过keras- ...
最新文章
- python【力扣LeetCode算法题库】面试题 01.07- 旋转矩阵
- 根据xml生成相应的对象类
- CAS单点登录 - 创建用户会话、全局门票、临时票据
- 【超级鼠标键盘锁】之远线程注入winlogon.exe进程屏蔽Ctrl+Alt+Del、Win+L
- mongo数据库插入数据_深入研究Mongo数据库
- 如何让DIV模块随着页面固定和不固定
- 介绍个好点的,JAVA技术群
- C# 很基础的那些东西
- 《Orange'S:一个操作系统的实现》与上一版之比较
- 完全卸载NI系列软件的方法
- 中国麻将:世界上最早的区块链项目
- 机器学习基石 之 三大学习原则(Three Learning Principles)
- 圆柱体积怎么算立方公式_圆柱体积公式怎么算
- Android 百度地图定位显示当前位置
- input输入框提示语
- 机器学习 交叉验证与网格搜索调参
- Java中的七种设计原则
- 神经网络图用什么软件做,神经网络输入图片大小
- [iOS]阿里云人脸身份证校验
- 服务器基线加固脚本_一种基于WebLogic的安全基线加固方法与流程
热门文章
- Fiddler 抓包工具2 - 全网最全最细教程,没有之一
- Dev C++调试程序方法详解
- python简明教程电子书下载_python简明教程中文pdf下载-Python入门级电子书完整免费版-东坡下载...
- C语言程序设计:图书管理系统(附代码)
- mysql主从中断原因_mysql主从中断
- 罗技Lua脚本-CF神圣爆裂者自动开枪
- python必背100源代码-python 100例 (持续更新)
- c语言程序中所有语句都将被转换成二进制的机器指令,c语言练习试题
- vivo手机点击android,了解Vivo手机几个小技巧,让您的手机变得更好用
- matlab画图点形状,matlab画图点的形状