例如,有一个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
你怎么能做到?是否有相关工具或开源?
答案 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。