词法分析

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
  1. 存Token的值之所以使用了union类型, 是因为对于int 和 float, 这里实际上只需要关注他们的真实值这里使用的是long和double来表示, 但是对于其他类型则仍然选择用字符串表示. 我也考虑过在Token上衍生出两个子类的做法, 但是考虑到子类getValue返回值不统一的情况, 所以这里只能选择用union, 这里我 自己也感觉有点别扭, 所以如果有更好的设计方式或者想法欢迎留言.
  2. 另外你可以看到, 正如我前面所说的我是在构造函数中将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)的更多相关文章

  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. js 鼠标坐标

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. USB 3.0规范中译本 第1章 引言

    本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 1.1 动机(Motivation) Universal Serial Bus (USB) 的原始动机来自于 ...

  3. ios开发日期的NSDate,NSCalendar分类

    #import <Foundation/Foundation.h> @interface NSDate (XMGExtension) /** */ // @property (nonato ...

  4. PXC安装

    安装软件依赖包yum install -y  perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes socat nc    openssl-devel l ...

  5. request与response对象详述

    request与response对象. 1. request代表请求对象 response代表的响应对象. 学习它们我们可以操作http请求与响应. 2.request,response体系结构. 在 ...

  6. [Javascript] Javascript 'in' opreator

    If you want to check whether a key is inside an Object or Array, you can use 'in': Object: const obj ...

  7. signed 与 unsigned 有符号和无符号数

    unsigned int a = 0; unsigned int b = -1; // b 为 0xffffffff unsigned int c = a - 1; // c 为 0xffffffff

  8. 【codeforces 768C】Jon Snow and his Favourite Number

    [题目链接]:http://codeforces.com/contest/768/problem/C [题意] 给你n个数字; 让你每次把这n个数字排序; 然后对奇数位的数字进行异或操作,然后对新生成 ...

  9. cocos2d-x 3.0学习游戏笔记的例子《卡塔防》第五步---开始建立游戏界面

    /* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写.第一别全然照搬代码.第二能够说 ...

  10. p2p-如何拯救k8s镜像分发的阿喀琉斯之踵

    K8s的出现为PaaS行业的发展打了一针兴奋剂,Docker+k8s的技术路线已经成为了容器云的主流.尤其针对大流量,大弹性的应用场景来说,k8s将其从繁杂的运维.部署工作中彻底拯救出来.然而事情往往 ...