词法分析

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底层实现就是整形, 所以并没有支持的必要. 另一方面这里面的intfloat如果过长的话可能会导致编译出错, 我个人只打算使用C++中的longdouble来解析这两个类型, 所以其实他们的长度也是有限制的. 另外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
  1. Token的值之所以使用了union类型, 是因为对于intfloat, 这里实际上只需要关注他们的真实值这里使用的是longdouble来表示, 但是对于其他类型则仍然选择用字符串表示. 我也考虑过在Token上衍生出两个子类的做法, 但是考虑到子类getValue返回值不统一的情况, 所以这里只能选择用union, 这里我 自己也感觉有点别扭, 所以如果有更好的设计方式或者想法欢迎留言.
  2. 另外你可以看到, 正如我前面所说的我是在构造函数中将KEYWORDIDENTIFIER中分离出来的思路, 这样可以简化分析.

完成了这些之后另外三个工具函数很简单 :

#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)的更多相关文章

  1. PHP Token(令牌)设计 避免重复提交

    设计目标: 避免重复提交数据. 检查来路,是否是外部提交 匹配要执行的动作(如果有多个逻辑在同一个页面实现,比如新增,删除,修改放到一个PHP文件里操作) 这里所说的token是在页面显示的时候,写到 ...

  2. jmeter从获取token开始设计接口

    用自己实习时候的一个项目来实现一下获取token的接口测试 以登录dmp的学科列表为例子: 从登录开始,打开开发者选项 点击登录 在开发者窗口中network xhr Fildder中,看登录时的请求 ...

  3. PHP Token(令牌)设计应用

    转自:http://my.oschina.net/u/912810/blog/358973 <?php class GEncrypt { protected static function ke ...

  4. 八幅漫画理解使用JSON Web Token设计单点登录系统

    用jwt这种token的验证方式,是不是必须用https协议保证token不被其他人拦截? 是的.因为其实只是Base64编码而已,所以很容易就被解码了.如果你的JWT被嗅探到,那么别人就可以相应地解 ...

  5. 八幅漫画理解使用 JSON Web Token 设计单点登录系统

    原文出处: John Wu 上次在<JSON Web Token – 在Web应用间安全地传递信息>中我提到了JSON Web Token可以用来设计单点登录系统.我尝试用八幅漫画先让大家 ...

  6. [转]八幅漫画理解使用JSON Web Token设计单点登录系统

    上次在<JSON Web Token - 在Web应用间安全地传递信息>中我提到了JSON Web Token可以用来设计单点登录系统.我尝试用八幅漫画先让大家理解如何设计正常的用户认证系 ...

  7. API 接口设计中 Token 类型的分类与设计

    在实际的网站设计中我们经常会遇到用户数据的验证和加密的问题,如果实现单点,如果保证数据准确,如何放着重放,如何防止CSRF等等 其中,在所有的服务设计中,都不可避免的涉及到Token的设计. 目前,基 ...

  8. 如何设计相对安全的cookie自动登录系统

    很多网站登录的时候,都会有一个"记住我"功能,用户可以在限定时间段内免登录, 比如豆瓣.人人.新浪微博等都有这种设计.这种技术其实就是基于 cookie的自动登录, 用户登录的时候 ...

  9. ABP从入门到精通(5):使用基于JWT标准的Token访问WebApi

    项目:asp.net zero 4.2.0 .net core(1.1) 版本 我们做项目的时候可能会遇到需要提供api给app调用,ABP动态生成的WebApi提供了方便的基于JWT标准的Token ...

随机推荐

  1. Qt 学习: 视图选择 (QItemSelectionModel)

    博主QQ:1356438802 选择是视图中经常使用的一个操作.在列表.树或者表格中,通过鼠标点击能够选中某一项,被选中项会变成高亮或者反色.在 Qt 中,选择也是使用了一种模型.在 model/vi ...

  2. Codeforces Round #313 (Div. 2) 560C Gerald&#39;s Hexagon(脑洞)

    C. Gerald's Hexagon time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  3. 【codeforces 765D】Artsem and Saunders

    [题目链接]:http://codeforces.com/contest/765/problem/D [题意] 给你一个函数f(x); 要让你求2个函数g[x]和h[x],使得g[h[x]] = x对 ...

  4. javaScript显示实时时间输出

    实时时间输出 <script> function getDateTime(){ var a = new Date(); var year = a.getFullYear(); var mo ...

  5. 【基础练习】【线性DP】codevs1576 最长严格上升子序列题解

    连题目都不放了,就是标题中说的那样.裸题 于是直接上代码 暑假要来了 好好学习 --炉火照天地,红星乱紫烟. 赧郎明月夜.歌曲动寒川.

  6. BZOJ 1509 逃学的小孩 - 树型dp

    传送门 题目大意: 在一棵树中, 每条边都有一个长度值, 现要求在树中选择 3 个点 X.Y. Z , 满足 X 到 Y 的距离不大于 X 到 Z 的距离, 且 X 到 Y 的距离与 Y 到 Z 的距 ...

  7. linux下Java程序中插入DB中国的数据乱码问题

    首先,插入到DB数据,在Linux在查询时,现场展示??. 再次,在windows连接到db上,查看的结果并非乱码. 改动Eclipse软件中的编码:如上图:windows菜单->prefere ...

  8. AndroidMainifest标签使用说明3——&lt;activity-alias&gt;

    格式: <activity-alias android:enabled=["true" | "false"] android:exported=[&quo ...

  9. 【hdu 2376】Average distance

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=2376 [题意] 让你计算树上任意两点之间的距离的和. [题解] 算出每条边的两端有多少个节点设为n ...

  10. 理解React生命周期的好例子

    class App extends React.Component { static propTypes = { }; static defaultProps = { }; constructor(p ...