1
  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+)" integers:"(\d+)" separators: ? 运营商:?实数:?

4

1 回答 1

0

正则表达式将很难正确处理,因为在标记化时需要维护一些状态/上下文。最好是逐个字符地读取输入并手动构建标记。

以下是适用于 C 的内容(稍后将详细介绍 C++):

如果你看到/了,那么你需要向前看,如果有另一个/,你会跳过所有内容,直到行尾。

如果/紧随其后*,则跳过所有内容,直到另一个*,如果下一个*char 不是/,则返回跳过直到*,当您将开头/*与结尾匹配时结束*/

有了类似的东西,你会跳过所有的评论。

如果/后面没有/or *,则需要另外检查是否跟上=来区分/and /=

如果您看到其中任何一个,它就是一个标记:,;?:()[]{}

如果你看到!你需要向前看,因为它可以是!!=
如果你看到*你需要向前看,因为它可以是**=
如果你看到%你需要向前看,因为它可以是%%=
如果你看到^你需要向前看,因为它可以是^^=
如果你看到~你需要向前看,因为它可以是~~=

如果你看到+你需要向前看,因为它可以是+or+++=

如果你看到-你需要向前看,因为它可以是-or---=or ->

如果你看到<你需要向前看,因为它可以是<or<=<<or <<=
如果你看到>你需要向前看,因为它可以是>or>=>>or >>=

如果你看到&你需要向前看,因为它可以是&or&&&=
如果你看到|你需要向前看,因为它可以是|or|||=

如果您看到L(或小写l),则需要向前看,因为它可以以文字字符或字符串常量L'c'L"string". 否则,它是某个标识符的开始。

如果您看到_ASCII 字母 from atoz或 from Ato Z,它是某个标识符的开始。在此之后可以跟随任意数量的下划线、字母或十进制数字。以这种方式解析的标识符必须额外检查一组保留关键字,例如int, const, if,switch等。

如果从0to看到十进制数字9,则有多种选择:八进制整数常量、十进制整数常量、十六进制整数常量、浮点常量。您应该能够弄清楚如何与上述类似地解析它们。请记住,常量可以以UULULLL和为LL后缀F

如果你看到.你需要向前看,因为它可以是.or...或类似的东西.5

我不打算描述文字字符或字符串常量的解析和标记化,内部还有一些更多的逻辑,包括转义序列等等。

现在,在 C++ 中,您必须额外解析以下内容:(解析::扩展:)、.*.解析扩展)、->*(解析扩展-)和更多保留字(例如new,virtual等以及奇怪的and,bitornot_eq)。

C++ 中有一个惊喜。现在允许模板尖括号放在一起,中间没有任何空格:

X<Y<Z> >

现在可以合法地写成:

X<Y<Z>>

并且解析器必须对这个模板业务有足够的了解才能弄清楚最后一个>>是两个独立>的。

还有一些与预处理器相关的标记(例如#and ##, include, ifdef, if, undef, 等)和丑陋的三元组序列。而且,当然,还有与\.

这是一个有趣的小(或不是那么小)项目,您可以轻松完成,特别是如果您限制可接受的输入种类。

无论如何,您确实需要在此过程中实现一些状态机,无论它们多么简单(而且大多数都会很简单)。

于 2012-09-25T04:00:37.820 回答