- 浏览: 3053131 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
相关链接:
将ANTLR生成的.tokens文件重格式化(Ruby版)
将ANTLR生成的.tokens文件重格式化(C#版)
先前写了Ruby的版本,链接在上面。作为对比,我很想看看自己如果用C++以同样的思路写会写出怎样的东西出来。Java和C#就暂时算了,总之肯定是介于C++与Ruby版本之间的样子。
(更新:结果趁着热度顺便把C#的也写了,链接在上面)
于是下面的代码就是我交出的答卷。正好下午帮个同学写了俩短小C++作业,有些经验正好借鉴过来。
最重要的一点大概就是RAII的使用了。在vector里放指针的话,所指向的空间在程序结束的时候不会自动被释放掉,让人很郁闷。要么就自己记得在main()的最后显式的循环过整个vector来释放内存,要么就……RAII几乎是不二的选择了。就因为实现这很简陋的RAII类代码就多了不少,不过如果坚持要用C++的话,这绝对是值得的。
(如果要说“反正这是小程序,内存泄漏也无所谓,搞RAII那么麻烦有什么用”的话,那我也没话说了,摊手)
在字符串的模式匹配上,只用C和C++的标准库还是麻烦了点。我现在是用<string>里的getline(istream& is, string& str, char delim),不过这终究不是什么好办法。要用功能强点的模式匹配果然还是用正则表达式比较方便。MFC里CString提供的Split()就很合适这个场景。本来可以试试Boost::Regex,下次吧。
要是用Boost的话相关代码或许会像是这样吧:
我原本装的Boost乱掉了,用VS2008暂时还没装上,总之就是有问题 T T
在排序和输出方面,C++的代码还是相当简洁的。可惜C++里的functor无法做in-place definition,非得给那个functor一个名字,这样就有了下面的ValueLess结构。Java里好歹可以用匿名内部类,C#更好可以用delegate和lambda expression,Ruby的block也差不多。
reformat.h:
reformat.cpp:
用GCC 3.4.5的MinGW来编译测试的。效果还好吧。感觉是比Ruby版“快”一些,启动时间似乎稍微短些。(应该测一下……)
比起Ruby的代码,上面的C++最不顺手的地方就在内存管理和字符串的模式匹配吧。单就代码长度来看那绝对是长了不少,要做这么件小事显然是不爽的。
纯C的话,容器得自己写了吧,如果只能用纯C的话还是会怀念STL容器啊~想了下,如果是自己写的话,我可能会倾向于链式容器,主要是懒得去管动态增加容器大小时的复制。排序有<stdlib.h>里的qsort(),并不麻烦;输出也没什么麻烦的,fprintf()和fwrite()都可以用。果然还是在输入和内存管理上稍微麻烦些。
不知道大家是怎么看的呢。
将ANTLR生成的.tokens文件重格式化(Ruby版)
将ANTLR生成的.tokens文件重格式化(C#版)
先前写了Ruby的版本,链接在上面。作为对比,我很想看看自己如果用C++以同样的思路写会写出怎样的东西出来。Java和C#就暂时算了,总之肯定是介于C++与Ruby版本之间的样子。
(更新:结果趁着热度顺便把C#的也写了,链接在上面)
于是下面的代码就是我交出的答卷。正好下午帮个同学写了俩短小C++作业,有些经验正好借鉴过来。
最重要的一点大概就是RAII的使用了。在vector里放指针的话,所指向的空间在程序结束的时候不会自动被释放掉,让人很郁闷。要么就自己记得在main()的最后显式的循环过整个vector来释放内存,要么就……RAII几乎是不二的选择了。就因为实现这很简陋的RAII类代码就多了不少,不过如果坚持要用C++的话,这绝对是值得的。
(如果要说“反正这是小程序,内存泄漏也无所谓,搞RAII那么麻烦有什么用”的话,那我也没话说了,摊手)
在字符串的模式匹配上,只用C和C++的标准库还是麻烦了点。我现在是用<string>里的getline(istream& is, string& str, char delim),不过这终究不是什么好办法。要用功能强点的模式匹配果然还是用正则表达式比较方便。MFC里CString提供的Split()就很合适这个场景。本来可以试试Boost::Regex,下次吧。
要是用Boost的话相关代码或许会像是这样吧:
#include <iostream> #include <string> #include <boost/regex.hpp> int main() { boost::regex re("^([^=]+)=([0-9]+)$"); boost::cmatch matches; std::string str("Identifier=21"); boost::match(str, matches, re); string name(matches[1].first, matches[1].second); string value(matches[2].first, matches[2].second); cout << value << "=" << name << endl; // 21=Identifier return 0; }
我原本装的Boost乱掉了,用VS2008暂时还没装上,总之就是有问题 T T
在排序和输出方面,C++的代码还是相当简洁的。可惜C++里的functor无法做in-place definition,非得给那个functor一个名字,这样就有了下面的ValueLess结构。Java里好歹可以用匿名内部类,C#更好可以用delegate和lambda expression,Ruby的block也差不多。
reformat.h:
#ifndef REFORMAT_H #define REFORMAT_H #include <vector> #define BUFFER_SIZE 256 struct TokenNameValuePair { char m_name[256]; int m_value; TokenNameValuePair(); }; // RAII-style class ResourceManager { public: ResourceManager(std::vector<TokenNameValuePair*>* pLines) : m_pLines(pLines) { } ~ResourceManager() { for (std::vector<TokenNameValuePair*>::iterator it = m_pLines->begin(); it < m_pLines->end(); ++it) { delete *it; } } std::vector<TokenNameValuePair*>* getLines(); private: std::vector<TokenNameValuePair*>* m_pLines; }; #endif // end of REFORMAT_H
reformat.cpp:
#include <cstdlib> #include <cstring> // for memset #include <iostream> #include <fstream> #include <algorithm> #include "reformat.h" using namespace std; TokenNameValuePair::TokenNameValuePair() { memset(m_name, 0, BUFFER_SIZE); } vector<TokenNameValuePair*>* ResourceManager::getLines() { return m_pLines; } struct ValueLess { bool operator()(TokenNameValuePair* first, TokenNameValuePair* second) { return (first->m_value < second->m_value); } }; int main(int argc, char* argv[]) { if (argc != 3) { printf("Usage: %s [tokens file] [output file]", argv[0]); exit(1); } ResourceManager res(new vector<TokenNameValuePair*>); ifstream in(argv[1]); if (!in.fail()) { string line; while (in.good()) { getline(in, line, '='); if (!line.compare("")) break; TokenNameValuePair* pair = new TokenNameValuePair; strcpy(pair->m_name, line.c_str()); getline(in, line); pair->m_value = atoi(line.c_str()); res.getLines()->push_back(pair); } in.close(); } sort(res.getLines()->begin(), res.getLines()->end(), ValueLess()); ofstream out(argv[2]); if (!out.fail()) { for (vector<TokenNameValuePair*>::iterator it = res.getLines()->begin(); res.getLines()->end() != it; ++it) { out << (*it)->m_value << "=" << (*it)->m_name << endl; } out.flush(); out.close(); } return 0; }
用GCC 3.4.5的MinGW来编译测试的。效果还好吧。感觉是比Ruby版“快”一些,启动时间似乎稍微短些。(应该测一下……)
比起Ruby的代码,上面的C++最不顺手的地方就在内存管理和字符串的模式匹配吧。单就代码长度来看那绝对是长了不少,要做这么件小事显然是不爽的。
纯C的话,容器得自己写了吧,如果只能用纯C的话还是会怀念STL容器啊~想了下,如果是自己写的话,我可能会倾向于链式容器,主要是懒得去管动态增加容器大小时的复制。排序有<stdlib.h>里的qsort(),并不麻烦;输出也没什么麻烦的,fprintf()和fwrite()都可以用。果然还是在输入和内存管理上稍微麻烦些。
不知道大家是怎么看的呢。
发表评论
-
字符串的一般封装方式的内存布局 (0): 拿在手上的是什么
2013-11-04 18:22 21510(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
struct做参数不能从寄存器传?
2013-08-28 23:33 0test test test struct Foo { i ... -
[入门级] 使用inline函数的陷阱
2011-04-21 22:39 0xxx.hpp xxx.inline.hpp inline ... -
C++的vtable的name mangling
2011-04-21 21:53 0_ZTV 开头 -
C++里用typedef struct...
2010-06-12 14:42 3894今天要写个东西,参照的一段C++代码里看到了诡异的东西,形式类 ... -
C++的虚方法调用的开销
2010-01-10 02:53 0不只是从vftbl找到函数指针那么简单而已。因为C++支持多继 ... -
C++求值顺序
2009-12-12 23:16 0呵呵,有个例子总是形 ... -
__fastcall由callee做栈平衡
2009-10-14 01:51 0#include <iostream> usin ... -
typedef...
2009-06-16 21:22 0原来函数指针能这样用的啊……原来typedef不只可以用来声明 ... -
拿vtable来玩玩
2009-06-04 03:53 0#include <iostream> usin ... -
从1加到N……我败了
2009-05-11 10:06 0有人提到Python比C++优越因为代码短而简洁,并举例说1加 ... -
delete NULL会怎样?
2009-04-22 10:03 8110原文在此:Can you delete a NULL poin ... -
Boost 1.35.0
2008-06-25 04:45 0Boost C++ Library Version 1.35. ... -
确定性析构在有指针的环境下的麻烦之处
2008-05-16 11:26 2633刚考完大软,心里还在 ... -
typename关键字的使用
2008-05-15 11:31 2916忘了……模板啊忘光了 T T 今天有同学考C++,后来问了我 ... -
又是宏……do..while(0)的用法
2008-05-04 20:24 4673真是的,我用C++还是太少了。这个宏以前明明见过的,但其存在的 ... -
火星了,今天才知道C++0x也通过了lambda表达式/闭包的提案
2008-04-16 19:31 3083如题。我总是后知后觉诶。不过这提案有意思…… 之前我在C#与 ... -
奇怪的宏
2007-11-05 22:19 2120我C++确实不怎么样,不过近来不得不再唤醒那远古的记忆……即使 ...
相关推荐
ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR4是它的最新版本,它提供了显著的性能提升和许多新特性。这个开源项目“antlr-...
ANTLR( Anatomy of a Little Language Translator)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR主要用于构建语言、工具和框架。从简单的命令行工具到复杂的编程语言,...
ANTLR生成的解析器通常包括以下部分: 1. 词法分析器(Lexer):负责将输入的字符流分解为词法单元(tokens)。 2. 解析器(Parser):基于文法规则,将词法单元组合成语法结构,并验证输入是否符合文法规则。 3. ...
ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于各种语言和系统的开发,包括数据库查询解析、配置文件处理、编程...
1. **词法分析**:ANTLR首先将输入源代码转换为词法单元(tokens),这些单元是由词法规则定义的最小语法单元。 2. **语法分析**:然后ANTLR使用语法分析器对词法单元进行解析,生成抽象语法树(AST)。这一步骤...
这些文件包含了词法符号(tokens)和语法规则,允许ANTLR生成对应目标语言的解析器和词法分析器。 PEG(Parsers Expression Grammar)是一种上下文无关的语法表示法,全称为解析表达式语法。与传统的LL或LR解析器...
ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于构建语言、工具和框架,如SQL查询解析器、XML处理器、配置文件...
- options域:设置ANTLR生成器的选项,如目标语言、编码等。 - lexer和parser规则:定义词法规则和语法规则,每个规则代表一种语言结构。 - parser规则通常用于构建语法树,lexer规则用于生成Token。 - tokens域:可...
1. **Lexer**:词法分析器,它将输入的字符流分解为一系列的词法单元(tokens),每个词法单元代表语言中的一个基本元素,如关键字、标识符、数字等。 2. **Parser**:解析器,它接收词法分析器生成的词法单元流,...
ANTLR4(ANother Tool for Language Recognition)是一款强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架,如JSON解析器。ANTLR4可以生成Java、C#、...
最后,`FCmd.tokens`是一个生成的文件,它包含了Antlr为识别的标记分配的唯一整数值。这些值在内部用于快速比较和处理标记。 总的来说,通过Antlr,我们可以高效地解析特定语法格式的命令行,实现自定义的命令行...
ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架。ANTLR生成Java、C#、Python、JavaScript等语言...
ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架,包括SQL解析器、XML处理器以及Java、C#和Python...
ANTLR4 是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于各种编程语言的语法解析,包括但不限于Java、C#、Python、JavaScript等。在这个名为“smt-antlr4-javascript-...
4. **配置文件解析**:ANTLR可以用来解析复杂的配置文件格式,比如JSON、XML等。 5. **自然语言处理**:虽然主要应用于编程语言,但ANTLR也可以扩展用于自然语言处理领域。 #### 六、ANTLR的使用 - **安装**: ...
ANTLR4是一个强大的解析器生成器,广泛用于处理各种语言和格式,包括编程语言、查询语言、配置文件等。这个项目提供了一个很好的实践平台,帮助我们了解编译器设计的基本概念和技术。 首先,ANTLR4(ANother Tool ...
6. `c.grm`: 这可能是描述C语言语法的语法文件,可能使用类似YACC或ANTLR的格式。语法文件定义了C语言的语法规则,用于指导解析过程。 7. `c_parser.h`, `c_main.h`, `c_lexer.h`: 这些是头文件,包含了对应源文件...
通过词法和语法分析,开发者可以实现自定义的代码检查、格式化和转换功能。 6. **自定义解析规则**: 开发者可以根据需求定制词法和语法规则,例如,创建一个新的DSL(Domain Specific Language)或者解析非标准...
在IT行业中,ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。这个“PracticaObligatoria”项目很可能是一个基于ANTLR的编程实践作业,旨在帮助学生深入理解ANTLR的工作原理及其...