Token的设计(2)
词法分析
Token的几个种类
前端的第一步就是词法分析, 这个过程通俗来讲就是将源代码转化为一串Tokens
. 所以首先应该想到的是, 到底该有哪几种类型的Token
? 关于这个问题我已经想过了, 该语言将会有如下几种Token
.
enum Token_Type{
INT, // 0|([1-9][0-9]*)
FLOAT, // (0|([1-9][0-9]*)\.[0-9]+)
STRING,
IDENTIFIER, // [a-zA-Z_][0-9a-zA-Z_]*
KEYWORD,
OPERATOR, // + - * / += -= *= /= = == ! - && ||
BRACKET, // () {} []
};
你可以看到, 该语言其实只有三种基本类型, 我个人不打算支持bool
因为我感觉bool
底层实现就是整形, 所以并没有支持的必要. 另一方面这里面的int
和float
如果过长的话可能会导致编译出错, 我个人只打算使用C++中的long
和double
来解析这两个类型, 所以其实他们的长度也是有限制的. 另外KEYWORD
在分析阶段会归入IDENTIFIER
中, 等到真正构造Token的时候才会划分开来, 这样可以降低词法分析的难度.暂时的话我就想到这几种, 如果不够的话再临时加上吧.
Token的属性以及构造函数
接下来我们可以整体看一下Token
这个类 :
#ifndef FRED_TOKEN_H
#define FRED_TOKEN_H
#include <string>
class Token{
public:
enum Token_Type{
INT, // 0|([1-9][0-9]*)
FLOAT, // (0|([1-9][0-9]*)\.?[0-9]+)
STRING,
IDENTIFIER, // [a-zA-Z_][0-9a-zA-Z_]*
KEYWORD,
OPERATOR, // + - * / += -= *= /= = == ! - && ||
BRACKET, // () {} []
};
private:
Token_Type type;
union Value{
long l;
double d;
std::string s;
};
Value value;
public:
Token(Token_Type type, const std::string string): type(type) {
switch (type){
case INT:{
value.l = parseInt(string);
break;
}
case FLOAT:{
value.d = parseFloat(string);
break;
}
case IDENTIFIER:{
if(isKeyword(string)){
type = IDENTIFIER;
}
//no break here, auto jump into default
}
default:{
value.s = string;
}
}
}
Token(const Token&) = delete;
Token(const Token&&) = delete;
Token& operator=(const Token& rhs) = delete;
Token& operator=(const Token&& rhs) = delete;
virtual ~Token() = default;
Token_Type getType() const { return type; }
const Value& getValue() const { return value; }
private:
long parseInt(const std::string&);
long parseFloat(const std::string&);
bool isKeyword(const std::string&);
};
#endif //FRED_TOKEN_H
- 存
Token
的值之所以使用了union
类型, 是因为对于int
和float
, 这里实际上只需要关注他们的真实值
这里使用的是long
和double
来表示, 但是对于其他类型则仍然选择用字符串表示. 我也考虑过在Token
上衍生出两个子类的做法, 但是考虑到子类getValue
返回值不统一的情况, 所以这里只能选择用union
, 这里我 自己也感觉有点别扭, 所以如果有更好的设计方式或者想法欢迎留言. - 另外你可以看到, 正如我前面所说的我是在构造函数中将
KEYWORD
从IDENTIFIER
中分离出来的思路, 这样可以简化分析.
完成了这些之后另外三个工具函数很简单 :
#include "Token.h"
#include <cmath>
long Token::parseHelper(const std::string& str, size_t& idx){
long sum = 0;
for(size_t i = 0; i != idx; ++i){
if(str[i] == '.'){
idx = i;
return sum;
}
sum = sum * 10 + (str[i] - '0');
}
return sum;
}
long Token::parseInt(const std::string& str){
size_t len = str.length();
return parseHelper(str, len);
}
double Token::parseFloat(const std::string& str){
double sum = 0;
size_t len = str.length(), idx = len;
sum += parseHelper(str, idx);
len -= ++idx;
sum += parseHelper(str.substr(idx), len) / pow(10, len);
return sum;
}
inline bool Token::isKeyword(const std::string& str) {
return str == "int" ||
str == "float" ||
str == "string" ||
str == "print" ||
str == "while" ||
str == "for" ||
str == "class" ||
str == "return";
}
Token的设计(2)的更多相关文章
- PHP Token(令牌)设计 避免重复提交
设计目标: 避免重复提交数据. 检查来路,是否是外部提交 匹配要执行的动作(如果有多个逻辑在同一个页面实现,比如新增,删除,修改放到一个PHP文件里操作) 这里所说的token是在页面显示的时候,写到 ...
- jmeter从获取token开始设计接口
用自己实习时候的一个项目来实现一下获取token的接口测试 以登录dmp的学科列表为例子: 从登录开始,打开开发者选项 点击登录 在开发者窗口中network xhr Fildder中,看登录时的请求 ...
- PHP Token(令牌)设计应用
转自:http://my.oschina.net/u/912810/blog/358973 <?php class GEncrypt { protected static function ke ...
- 八幅漫画理解使用JSON Web Token设计单点登录系统
用jwt这种token的验证方式,是不是必须用https协议保证token不被其他人拦截? 是的.因为其实只是Base64编码而已,所以很容易就被解码了.如果你的JWT被嗅探到,那么别人就可以相应地解 ...
- 八幅漫画理解使用 JSON Web Token 设计单点登录系统
原文出处: John Wu 上次在<JSON Web Token – 在Web应用间安全地传递信息>中我提到了JSON Web Token可以用来设计单点登录系统.我尝试用八幅漫画先让大家 ...
- [转]八幅漫画理解使用JSON Web Token设计单点登录系统
上次在<JSON Web Token - 在Web应用间安全地传递信息>中我提到了JSON Web Token可以用来设计单点登录系统.我尝试用八幅漫画先让大家理解如何设计正常的用户认证系 ...
- API 接口设计中 Token 类型的分类与设计
在实际的网站设计中我们经常会遇到用户数据的验证和加密的问题,如果实现单点,如果保证数据准确,如何放着重放,如何防止CSRF等等 其中,在所有的服务设计中,都不可避免的涉及到Token的设计. 目前,基 ...
- 如何设计相对安全的cookie自动登录系统
很多网站登录的时候,都会有一个"记住我"功能,用户可以在限定时间段内免登录, 比如豆瓣.人人.新浪微博等都有这种设计.这种技术其实就是基于 cookie的自动登录, 用户登录的时候 ...
- ABP从入门到精通(5):使用基于JWT标准的Token访问WebApi
项目:asp.net zero 4.2.0 .net core(1.1) 版本 我们做项目的时候可能会遇到需要提供api给app调用,ABP动态生成的WebApi提供了方便的基于JWT标准的Token ...
随机推荐
- 【心情】bjdldrz
如果我对勇士的记忆停留在73胜10负,
- 《编程导论(Java)·3.2.4 循环语句》
本文全然复制<编程导论(Java)·3.2.4 循环语句>的内容.除[]中的说明文字.请阅读和比較其它编程教材. 我知道.假设我是一个刚開始学习的人,<编程导论(Java)>非 ...
- POJ1659Frogs' Neighborhood(lavel定理)
Frogs' Neighborhood Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 7260 Accepted: 31 ...
- Apache DataFu: LinkedIn开源的Pig UDF库
介绍 Apache DataFu分两部分,本文介绍的是其Pig UDF的部分.代码在Github上开源(除了代码外.也有一些slides介绍链接). DataFu里面是一些Pig的UDF.主要包含这些 ...
- Objective-C编码规范[译]
原文链接 : The official raywenderlich.com Objective-C style guide 原文作者 : raywenderlich.com Team 译文出自 : r ...
- [Postgre] Insert Data into Postgre Tables
// Insert one row INSERT INTO movies (title, release_date, count_stars, director_id) VALUES ( 'Kill ...
- 王立平--TableLayout
效果: <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android= ...
- MKNetworkKit的断点续传SIDownloader下载
comefrom:http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f73d6f8b9042238fce098 ...
- erlang OTP gen_server 图解分析
http://www.hoterran.info/otp-gen_server-sourcecode 在阅读erlang的otp源码gen_server.erl的时候,一直想写点什么,用一种最好的方式 ...
- 小强的HTML5移动开发之路(21)—— PhoneGap
一.PhoneGap是什么 PhoneGap 是一个用基于 HTML,CSS 和 JavaScript 的,创建移动跨平台移动应用程序的快速开发框架.它使开发者能够利用 iPhone,Android, ...