游戏脚本编程 文本token解析
一个数字的组成由以下几个字符
正负号 + - 小数点 . 数字 0-9
比如
3
-3
3.13
-34.2234
但是符号和小数点不会出现多次
那么识别流程用图来表示 则是
整数
浮点数
一个读取C++源文件 将内容解析成一个个单独的TOKEN的代码
代码1
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
#include <string>
#include <exception> using namespace std; #define SOURCE_FILE_NAME "sourcefile.cpp"
#define DEST_FILE_NAME "destfile.cpp" // The input and output file streams.
ifstream fin;
ofstream fout; bool GetToken(string& token){
bool bRet = false;
char ch; ch = fin.get();
if(ch == EOF){
return false;
} if(isspace(ch)){
//进入接受连续空白符(' ' '\n'等)
while(isspace(ch)){
token += ch;
ch = fin.get();
}
fin.putback(ch);
bRet = true;
return bRet;
} if(isalpha(ch)){
while(isalpha(ch)){
token += ch;
ch =fin.get();
}
fin.putback(ch);
bRet = true;
return bRet;
} if(isdigit(ch)){
while(isdigit(ch) || ch == '.'){
token += ch;
ch = fin.get();
}
fin.putback(ch);
bRet = true;
return bRet;
} if(ch == '-' || ch == '+'){
token += ch;
ch = fin.get();
while(isdigit(ch) || ch == '.'){
token += ch;
ch = fin.get();
}
fin.putback(ch);
bRet = true;
return bRet;
} if(ch == '<' || ch == '>'){
token += ch;
ch = fin.get();
if(ch == '<' || ch == '>'){
token += ch;
}else{
fin.putback(ch);
}
bRet = true;
return bRet;
} token += ch;
bRet = true;
return bRet;
} int main(int argc, char *argv[])
{
fin.open(SOURCE_FILE_NAME);
if(!fin){
cout << "Open source file error.Exit!!" << endl;
return -1;
} fout.open(DEST_FILE_NAME);
if(!fout){
cout << "Open destinaton file error.Exit!!" << endl;
return -1;
} try{
string token;
while(GetToken(token)){
cout << token ;//<< endl;
token.clear();
} }catch(exception& e){
cerr << e.what() << endl;
} fin.close();
fout.close();
cout << "Hello World!"<<endl;
return 0;
}
测试文件
293048 24 895523
3.14159
235
253
52435 345 459245 22 .5 .35 2.0 1
0.0
1.0
0 02345 63246 0.2346
34.0
代码2
#include <iostream>
#include <fstream>
#include <exception>
#include <queue>
using namespace std; #define IN_FILE_NAME "SourceFile.cpp"
#define OUT_FILE_NAME "DestinationFile.cpp" enum STATE{
state_init = 0,
state_int,
state_float,
state_error
}; class FileParse{
public:
FileParse(const string& infileName,const string& outfileName){
fin_.open(infileName);
fout_.open(outfileName);
}
~FileParse(){
if(fin_.is_open())
fin_.close();
if(fout_.is_open())
fout_.close();
} bool ParseToTokens(){
STATE state = state_init;
bool isFinish = false;
string token; if(linestr_.empty())
return false; for(size_t i = 0;i<linestr_.size();++i){
char currentChar = linestr_[i];
if(currentChar == '\0')
break; switch(state){
case state_init:
if(isspace(currentChar)){
continue;
}else if(isdigit(currentChar)){
state = state_int;
token += currentChar;
continue;
}else if(currentChar == '.'){
state = state_float;
token += currentChar;
continue;
}else{
state = state_error;
break;
}
case state_int:
if(isdigit(currentChar)){
state = state_int;
token += currentChar;
continue;
}else if(currentChar == '.'){
state = state_float;
token += currentChar;
continue;
}else if(isspace(currentChar)){
isFinish = true;
break;
}else{
state = state_error;
break;
} case state_float:
if(isdigit(currentChar)){
state = state_int;
token += currentChar;
continue;
}else if(isspace(currentChar)){
isFinish = true;
break;
}else{
state = state_error;
break;
} case state_error:
break;
} if(isFinish ){
cout << token <<endl;
token.clear();
isFinish = false;
state = state_init;
}
} return true;
} bool run(){
try{
if(!fin_.is_open() || !fout_.is_open()) {
throw runtime_error("open file is null");
}
while(1){
if (fin_.eof())
break;
linestr_.clear();
getline(fin_,linestr_);
linestr_ += '\n';
ParseToTokens();
} }catch(exception& e){
cerr << e.what() << endl;
return false;
} } private:
string linestr_;
queue<string> vecToken_;
ifstream fin_;
ofstream fout_;
}; int main(int argc, char *argv[])
{
FileParse a(IN_FILE_NAME,OUT_FILE_NAME);
a.run();
return 0;
}
显示结果
代码3 新增字符串的识别解析
#include <iostream>
#include <fstream>
#include <exception>
#include <queue>
using namespace std; #define IN_FILE_NAME "SourceFile.cpp"
#define OUT_FILE_NAME "DestinationFile.cpp" enum STATE{
state_init = 0,
state_int,
state_float,
state_word,
state_error
}; class FileParse{
public:
FileParse(const string& infileName,const string& outfileName){
fin_.open(infileName);
fout_.open(outfileName);
}
~FileParse(){
if(fin_.is_open())
fin_.close();
if(fout_.is_open())
fout_.close();
} bool ParseToTokens(){
STATE state = state_init;
bool isFinish = false;
string token; if(linestr_.empty())
return false; for(size_t i = 0;i<linestr_.size();++i){
char currentChar = linestr_[i];
if(currentChar == '\0')
break; switch(state){
case state_init:
if(isspace(currentChar)){
continue;
}else if(isdigit(currentChar)){
state = state_int;
token += currentChar;
continue;
}else if(currentChar == '.'){
state = state_float;
token += currentChar;
continue;
}else if(isalpha(currentChar)|| currentChar == '_'){
state = state_word;
token += currentChar;
continue;
}else{
state = state_error;
break;
}
case state_word:
if(isalpha(currentChar)||isdigit(currentChar)||
currentChar == '_'){
state = state_word;
token += currentChar;
continue;
}else if(isspace(currentChar)){
isFinish = true;
break;
}else{
state = state_error;
break;
}
case state_int:
if(isdigit(currentChar)){
state = state_int;
token += currentChar;
continue;
}else if(currentChar == '.'){
state = state_float;
token += currentChar;
continue;
}else if(isspace(currentChar)){
isFinish = true;
break;
}else{
state = state_error;
break;
} case state_float:
if(isdigit(currentChar)){
state = state_int;
token += currentChar;
continue;
}else if(isspace(currentChar)){
isFinish = true;
break;
}else{
state = state_error;
break;
} case state_error:
break;
} if(isFinish ){
cout << token <<endl;
token.clear();
isFinish = false;
state = state_init;
}
} return true;
} bool run(){
try{
if(!fin_.is_open() || !fout_.is_open()) {
throw runtime_error("open file is null");
}
while(1){
if (fin_.eof())
break;
linestr_.clear();
getline(fin_,linestr_);
linestr_ += '\n';
ParseToTokens();
} }catch(exception& e){
cerr << e.what() << endl;
return false;
} } private:
string linestr_;
queue<string> vecToken_;
ifstream fin_;
ofstream fout_;
}; int main(int argc, char *argv[])
{
FileParse a(IN_FILE_NAME,OUT_FILE_NAME);
a.run();
return 0;
}
测试文本
293048 24 895523
3.14159
235
253
52435 345 MyVar0 MyVar1 MyVar2
459245 rEtUrN TRUE false 22 .5 .35 2.0 while 1
0.0 var
1.0 var
0 This_is_an_identifier 02345 _so_is_this___ 63246 0.2346
34.0
显示结果
游戏脚本编程 文本token解析的更多相关文章
- 高级Bash脚本编程指南(27):文本处理命令(三)
高级Bash脚本编程指南(27):文本处理命令(三) 成于坚持,败于止步 处理文本和文本文件的命令 tr 字符转换过滤器. 必须使用引用或中括号, 这样做才是合理的. 引用可以阻止shell重新解释出 ...
- shell编程系列24--shell操作数据库实战之利用shell脚本将文本数据导入到mysql中
shell编程系列24--shell操作数据库实战之利用shell脚本将文本数据导入到mysql中 利用shell脚本将文本数据导入到mysql中 需求1:处理文本中的数据,将文本中的数据插入到mys ...
- 转载:[转]如何学好3D游戏引擎编程
[转]如何学好3D游戏引擎编程 Albert 本帖被 gamengines 从 游戏引擎(Game Engine) 此文为转载,但是值得一看. 此篇文章献给那些为了游戏编程不怕困难的热血青年,它的 ...
- linux脚本编程技术
linux脚本编程技术 一.什么是脚本 脚本是一个包含一系列命令序列的可执行(777)文本文件.当运行这个脚本文件时,文件中包含的命令序列将得到自动执行. 二.脚本编程 #!/bin/sh 首行固定格 ...
- linux脚本编程技术---8
一.什么是脚本 脚本是一个包含一系列命令序列的可执行(777)文本文件.当运行这个脚本文件时,文件中包含的命令序列将得到自动执行. 二.脚本编程 #!/bin/sh 首行固定格式 #!表明该脚本的的解 ...
- 《Linux命令行与shell脚本编程大全》 第二十二章 学习笔记
第二十二章:使用其他shell 什么是dash shell Debian的dash shell是ash shell的直系后代,ash shell是Unix系统上原来地Bourne shell的简化版本 ...
- javascript进阶——分离式DOM脚本编程
编写分离式(unobstrusive)代码意味着对HTML内容的完全分离:数据来自服务器端,javascript代码用来动态化和交互.这种分离的好处是在不同浏览器之间使用是可以完全降级或升级运行,对于 ...
- Shell脚本编程(一):初识shell script
Shell简介 Shell是一个命令解释器,它是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核 ...
- 【Shell脚本编程系列】知识储备以及建立规范的脚本
前言 学习shell脚本编程需要的知识储备: vi/vim编辑器命令 vimrc设置要熟练 基础命令,100多个要熟练 基础和常用的网络服务命令要会:nfs . rsync. inotify . la ...
随机推荐
- problem:浏览器如何区分html超文本和普通文本
运营同学问:后端返回的一串元素标签,我想在网页中显示的时候,将标签中的内容渲染出来,不希望直接显示标签. 回答:bootstrap加模版组织的网页,模版渲染的数据只能渲染字符串,不能转化富文本. 运营 ...
- mysql识别中文
在配置的INI中加上这些 [mysql]default-character-set=utf8no-auto-rehash# Remove the next comment character if y ...
- 当通过Nuget包管理器获取还原组时,出现 提示 “xxxxx”已拥有为“xxxxx”定义的依赖项
当通过Nuget包管理器获取还原组件时,出现 提示 “xxxxx”已拥有为“xxxxx”定义的依赖项 时 解决方法: 工具---扩展和更新,把Nuget包管理器卸载后,重启VS,再安装,现打开VS项 ...
- eclipse中svn切换用户
如果永久保存svn用户账号及密码,再更换svn用户时需要先删除C:\Users\Administrator\AppData\Roaming下的Subversion文件,然后在刷新eclipse中的sv ...
- 使用redis-cli --pipe快速插入数据
具体实现步骤如下:(参考http://www.cnblogs.com/ivictor/p/5446503.html) 1. 新建一个文本文件redis_commands.txt,包含redis命令 S ...
- linux下自定义dubbo的shell脚本
- jdk 8 日期处理。
ZoneId id = ZoneId.systemDefault(); LocalDateTime dateTime = LocalDateTime.now(id); System.out.print ...
- IIS下https配置及安全整改
原文链接:https://www.cnblogs.com/JangoJing/p/6769759.html 1.https证书的分类 SSL证书没有所谓的"品质"和"等级 ...
- 如何解决python 图表中文显示乱码问题(matlplotlib 包)
目前搜到的是,下载一个字体到程序路径,设置成默认字体. https://blog.csdn.net/irene_loong/article/details/68955485 #图表显示中文设置 im ...
- 创建列表明细应用1-使用fragment
笔记自<Android编程权威指南第二版> 第七章,创建一个列表明细应用 fragment是一种控制器对象,activity可委派它完成一些任务,这些任务通常就是管理用户界面.(管理用户界 ...