for(int k = 0 ; k < 5.25;k++)
{
cout<<"hello"<<endl;
}
return 0;
我正在编写一个 c++ 程序,用于对一个简单的文本文件进行词法分析,其中包含 C++ 代码。例如
然后,在程序从文件中提取代码后,它将输出到 控制台:
for: keyword
(: separator
int: keyword
k: identifier
=: operator
0: integer
;: separator
k: identifier
<: operator
5.25: real
and so forth.
I already have "(\w+)" for words, "(\d+)" for integers, however I don't
know how to write any of the rest.
为了让您了解我的正则表达式的实际代码是什么样子的,这里是。
void lexical_integer(string seq)
{
regex digits("(\d+)");
regex_iterator<string::iterator> itd(seq.begin(), seq.end(), digits);
regex_iterator<string::iterator> end;
for (; itd != end; ++itd)
{
cout << itd->str() <<" " <<" integer"<< endl;
}
}
我正在寻找可以在 c++ 中与正则表达式一起使用的正则表达式 所以 字数:"(\w+)" 整数:"(\d+)" 分隔符:? 运营商:? 实数: ?
正则表达式很难正确,因为在标记时需要维护一些状态/上下文。最好逐个字符读取输入并手动构建令牌。
以下是适用于 C 的方法(稍后会详细介绍C++):
如果你看到/
那么你需要向前看,如果有另一个/
,你跳过所有内容,直到行尾。
如果/
后面跟着*
,你跳过所有内容,直到另一个*
,如果*
字符之后的下一个字符没有/
,你回到跳过直到*
,当你将开/*
与结束*/
匹配时结束。
有了这样的东西,你跳过所有评论。
如果后面/
没有/
或*
,则需要另外检查它后面是否跟着=
以区分/
和/=
。
如果您看到其中任何一个,则它是一个令牌:,;?:()[]{}
。
如果您看到!
则需要向前看,因为它可以是!
的,也可以是!=
的。
如果您看到*
则需要向前看,因为它可以是*
的,也可以是*=
的。
如果您看到%
则需要向前看,因为它可以是%
的,也可以是%=
的。
如果你看到^
你需要向前看,因为它可以是^
的,也可以是^=
的。
如果您看到~
则需要向前看,因为它可以是~
的,也可以是~=
的。
如果你看到+
你需要向前看,因为它可以是+
的,也可以是++
的,也可以是+=
的。
如果你看到-
你需要向前看,因为它可以是-
的,也可以是--
的,也可以是-=
的,也可以是->
的。
如果你看到<
你需要向前看,因为它可以是<
的,也可以是<=
的,也可以是<<
的,也可以是<<=
的。
如果您看到>
则需要向前看,因为它可以是>
的,也可以是>=
的,也可以是>>
的,也可以是>>=
的。
如果您看到&
则需要向前看,因为它可以是&
的,也可以是&&
的,也可以是&=
的。
如果您看到|
,则需要向前看,因为它可以是|
的,也可以是||
的,也可以是|=
的。
如果您看到L
(或小写l
),则需要向前看,因为它可以开始文字字符或字符串常量L'c'
或L"string"
。否则,它是某个标识符的开始。
如果您看到从a
到z
或从A
到Z
的_
或ASCII字母,这是某个标识符的开始。在此之后,可以遵循任意数量的下划线,字母或十进制数字。以这种方式解析的标识符必须根据保留关键字的集合进行额外检查,例如int
、const
、if
、switch
等。
如果看到从0
到9
的十进制数字,则有多个选项:八进制整数常量、十进制整数常量、十六进制整数常量、浮点常量。您应该能够弄清楚如何像上面一样解析它们。请记住,常量可以用U
、UL
、ULL
、L
、LL
和F
作为后缀。
如果你看到.
你需要向前看,因为它可以是.
的,也可以是...
的,也可以是.5
之类的东西。
我不打算描述文字字符或字符串常量的解析和标记化,里面还有更多带有转义序列的逻辑等等。
现在,在C++中,您必须另外解析以下内容:::
(:
解析的扩展),.*
(.
解析的扩展),->*
(-
解析的扩展)和更多保留字(例如new
、virtual
等,以及奇数的,如and
、bitor
和not_eq
)。
C++中有一个惊喜。现在允许模板尖括号放在一起,中间没有任何空格:
X<Y<Z> >
现在可以合法地写成:
X<Y<Z>>
解析器必须充分了解此模板业务,才能确定最后一个>>
是两个独立的>
。
还有一些与预处理器相关的令牌(例如#
和##
、include
、ifdef
、if
、undef
等)和丑陋的三元组序列。而且,当然,还有与的行连接。
这是一个有趣的小(或不是那么小)项目,你可以在没有太多麻烦的情况下完成它,特别是如果你限制接受的各种输入。
无论如何,你确实需要在这个过程中实现一些状态机,无论它们多么简单(而且大多数都很简单)。