我可以在c ++中使用正则表达式,使用正则表达式来解析分隔符,运算符,标识符和实数?

时间:2012-09-24 23:53:17

标签: c++ regex expression lexical

  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 ++中使用regex的正则表达式         所以         单词:“(\ w +)”         整数: “(\ d +)”         分隔符:?         经营者:?         实数:?

1 个答案:

答案 0 :(得分:0)

正则表达式很难做到正确,因为在tokenizng时需要维护一些状态/上下文。最好按字符读取输入字符并手动构建标记。

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

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

如果/后跟*,则会跳过所有内容,直到另一个*,如果*字符后面的/不是*,那么你去返回跳至/*,当您将开头*/与结束/匹配时结束。

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

如果/*后面没有=,则您需要另外检查/后面是否/=区分,;?:()[]{}! 1}}。

如果你看到其中任何一个,那就是一个标记:!

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

如果您看到++,则需要向前看,因为它可以是+=--

如果您看到--,则需要向前看,因为它可以是-=-><<

如果您看到<=,则需要向前看,因为它可以是<<<<=>>
如果您看到>=,则需要向前看,因为它可以是>>>>=&&

如果您看到&&,则需要向前看,因为它可以是&=||
如果您看到||,则需要向前看,因为它可以是|=Ll

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

如果您看到z或从AZ或从intconst的ASCII信件,则它是某个标识符的开头。在此之后可以跟随任意数量的下划线,字母或十进制数字。以这种方式解析的标识符必须另外根据保留关键字集合进行检查,例如ifswitch09等等。

如果您看到从UUL的十进制数字,您有多个选项:八进制整数常量,十进制整数常量,十六进制整数常量,浮点常量。你应该能够弄清楚如何解析它们与上面类似。请记住,常量可以加上ULLLLLF..的后缀。

如果您看到...,则需要向前看,因为它可以是.5::,也可以是:

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

现在,在C ++中,您还需要解析以下内容:.*.解析的扩展名),->*-解析的扩展名),{{1 } {(new解析的扩展名)和更多保留字(例如virtualand等等,以及奇数的bitornot_eqX<Y<Z> > )。

C ++令人惊讶。现在允许模板尖括号一起使用,中间没有任何空格:

X<Y<Z>>

现在可以合法地写成:

>>

并且解析器必须了解此模板业务,以确定最后>是两个单独的#

还有一些与预处理器相关的令牌(例如##includeifdefifundef\等)和丑陋的三角形序列。当然,还有{{1}}的行连接。

这是一个有趣的小项目(或者不是那么少),你可以做很多麻烦,特别是如果你限制所接受的各种输入。

无论如何,你真的需要在这个过程中实现一些状态机,不管它们多么简单(大多数都很简单)。