如何标记cpp源码?

时间:2014-07-26 13:33:19

标签: c++ tokenize code-analysis

例如,有一个cpp源代码,如:

 #include<iostream>
 using namespace std;
 int main()
 {
 int counta=0;
 int countb=0;
 while(cin.get()!='*')
 count++;
 cout<<count<<" char";
 }
像这样的代币:

head_iostream
namesp_std
begin_main
var_int
var_int
begin_while,cin_char,var_char!=’*’
assign,var_int++
end_while

你怎么能做到?是否有相关工具或开源?

2 个答案:

答案 0 :(得分:2)

基本上,您所做的是编写一个有限状态机(FSM),它处理源文件中的输入字符流。每个状态都会转换从流中读取的单个字符。

FSM开始状态是“不知道接下来会有什么标记”#34;。中间状态是&#34;根据自开始状态以来已经看到的字符,当前令牌可以是集合X,Y,Z ...... [特定于状态]&#34;中的任何一个。叶子状态是&#34;当前令牌是完整的X&#34;或者&#34;自开始以来的字符不对应任何有效的令牌&#34;。请注意,有一个&#34;完整的X&#34;并不意味着无法读取更多字符来扩展X或成为Y.

有人可能会将空白/注释作为FSM启动状态的附加分支来处理,这些分支最终会返回到空白序列末尾的FSM启动状态。

你可以很容易地手工编写有限字符集(例如ASCII)这样的有限语句机器;这通常是为编译器完成的,因为这样的FSM处理输入流的速度非常快,编译器会看到很多源代码字符。快速实现这一目标往往有助于加快编译速度。

各种状态通常将转换后的字符存储到令牌缓冲区中非常有用,因此当到达叶子状态时,已捕获令牌内容。人们可以根据当前的中间状态有条件地做到这一点;例如,如果当前状态只能导致关键字,则无需存储此类字符。

您可以使用名为&#34;词法生成器&#34;的各种工具生成此类FSM。 (Lex,Yacc,Flex,许多其他人)。通常这些工具会列出一对

<token_name, regular_expression>

并构建一个统一的FSM,它集成了正则表达式的效果,并为每个token_name生成叶状态。这样生成的词法分析器可以非常快。手动生成的词法分析器几乎总能更快,因为人们可以将更多的知识带到桌面上。

机器生成的词法分析器对于具有大量令牌的语言更方便,每个令牌具有复杂的正则表达式(C ++ 11和COBOL适合此类别),或者涉及Unicode的语言(因为每个州的转换数量可以很大,类别真的很乱,谢谢Unicode)。 Unicode成为首选字符集表明机器生成的词法分析器将成为长期的自然选择。 (令人惊讶的是,许多lexer生成器似乎无法处理Unicode。[我有一个可以做到]。)

答案 1 :(得分:0)

我假设您要做的是lexical analysis代码,它使用某些规则将文本输入解析为令牌。可以执行此操作的一个工具是Lex