词法分析

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. 解决Eclipse 启动后总是Building WorkSpace(sleeping)

    打开eclipse后eclipse总是在Building WorkSpace(sleeping),我的解决方案是,Project -> Building AutoMatically关闭就好了,以 ...

  2. USB 3.0规范中译本 第2章 术语及缩略语

    本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章列出并定义本规范通篇将使用的术语及缩略语. 术语/略缩语 定义 ACK(确认包) 表示积极肯定的握手包. ...

  3. php利用反射机制查找类和方法的所在位置

    //参数1是类名,参数2是方法名 $func = new ReflectionMethod('UnifiedOrder_pub', 'getPrepayId'); //从第几行开始 $start = ...

  4. [iOS]iOS开发人员账号申请与注冊流程

    郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 游戏官方下 ...

  5. 【u219】最长链

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 现给出一棵N个结点二叉树,问这棵二叉树中最长链的长度为多少,保证了1号结点为二叉树的根. [提示] 关 ...

  6. tolua#是Unity静态绑定lua的一个解决方案

    tolua#代码简要分析 2017-04-16 23:02 by 风恋残雪, 98 阅读, 1 评论, 收藏, 编辑 简介 tolua#是Unity静态绑定lua的一个解决方案,它通过C#提供的反射信 ...

  7. 静态资源命名的注意点以及document.write与innerHTML的区别

    今天拿出了去年刚开始学前端的那本书来看,发现好多新东西. 使用下划线和混合大小写不利于SEO! document.write与innerHTML的区别 这个问题大概是初学前端的人才会问的吧,业务代码中 ...

  8. No handler for type [text] declared on field [content]

    Install 1.compile checkout ik version respective to your elasticsearch version git checkout tags/{ve ...

  9. ActiveReports 报告应用程序教程 (2)---上市类报告

     大多数数字在报告中系统类报告列表.实例:客户名单.产品列表.设备清单.采购清单.优惠券.商品发票.工作人员清点等..根据报告,查看类别列表相对简单.但,分丰富,在清单类报表中能够增加数据统计.数 ...

  10. Spring boot+RabbitMQ环境

    Spring boot+RabbitMQ环境 消息队列在目前分布式系统下具备非常重要的地位,如下的场景是比较适合消息队列的: 跨系统的调用,异步性质的调用最佳. 高并发问题,利用队列串行特点. 订阅模 ...