正则表达式的解析器

时间:2014-03-18 08:08:44

标签: c++ regex parsing dfa

我最近一直在学习基础知识,作为一种实践,我决定在C ++环境中实现DFA。所以基本上它是正则表达式。当我从头开始构建树时,它运行良好,但是我不知道如何处理正则表达式。

我的意思是,如果我有正则表达式,例如(test)*我必须将其转换为DFA。问题是,为了做到这一点,我必须解析正则表达式。这似乎是一个恶性循环(更糟糕的是因为我实际上需要一个支架感知解析器,正则表达式在这里不起作用)。

那么如何应对呢?我完全理解我们现在有工具(例如Flex& Bison),但这些工具基于正则表达式(好吧,至少是标记器)。那么在开始时发生了什么?如何从头开始编写正则表达式解析器?对书籍/文章的任何提及都表示赞赏。

1 个答案:

答案 0 :(得分:3)

我曾经编写过自己的Flex版本,它生成了一组类而不是整个程序。首先,我必须手工解析正则表达式,但是当我最终编写它时,我将正则表达式解析机制替换为程序本身生成的机制。

手动解析正则表达式实际上非常简单。首先,您必须指定要实现的结果。例如,在我的情况下:

[abc]+test

被解释为:

[abc]@[abc]*@[t]@[e]@[s]@[t]

实际上是等价的(@是人工添加的连接运算符)。

然后你必须创建一套规则,例如

'[' spotted:
    - (optionally) expect '^' character;
    - repeat:
        - expect a non-special character;
            - If it is not last character and is succeeded by '-', expect another character
    - until `]` is spotted
    - Return a character set
'(' spotted:
    - Return a block-begin
')' spotted:
    - Return a block-end
'*' spotted:
    - Return a star-operator
'+' spotted:
    - Return a plus-operator
'.' spotted:
    - Return a whole character set
Any other char spotted:
    - Return a character set consisting of this single character

这样编写的算法将为您提供一个tokenizer - 例程,它将元素分解为逻辑标记。然后你必须将它们处理成表达式树,这可以通过实现Reverse Polish Notation algorithm来解决。

您可以检查我的解析器生成器here,尽管它会生成Delphi代码。不幸的是,自述文件是波兰语,但内部有一些例子。试试例如:

Number=[0-9]+
Operator=[\+\-\*/]

SpkParserGenerator -i myfile.regex -mc -sg

顺便说一句,你可以为自己生成一个解析器,然后简单地将它从Delphi转换为C ++,即使你不熟悉Delphi,它实际上也很简单。

这是我用于为解析器生成器生成解析器的一组规则:

SetRange=\{([0-9]*,[0-9]+)|([0-9]+,[0-9]*)|([0-9]+)\}
Star=\*
Plus=\+
QMark=\?
CharRange=\[\^?((\\.)|(\#[0-9]{3})|([^\\\#\]]))+\]
AnyChar=\.
EscapedChar=\\.
AsciiChar=\#[0-9]{3}
Char=[^\[\]\{\}\.\(\)\#\*\+\?\|\\]
OpenParenthesis=\(
CloseParenthesis=\)
Alternative=\|