c++ - 如何编写递归下降解析器?

标签 c++ parsing compiler-construction

<分区>

C++ 我不知道如何为以下语法编写递归下降解析器:

<Datalog Program>     ->  Schemes : <Scheme List>     
                         Facts   : <Fact List>
                         Rules   : <Rule List>
                         Queries : <Query List>
                         <EOF>
<Scheme List>         ->  <Scheme> <Scheme List Tail>
<Scheme List Tail>    ->  <Scheme List> | ε
<Scheme>              ->  <Identifier> ( <Identifier List> )
<Identifier List>     ->  <Identifier> <Identifier List Tail>
<Identifier List Tail>->  , <Identifier List> | ε
<Fact List>           ->  <Fact> <Fact List> | ε
<Fact>                ->  <Identifier> ( <Constant List> ) .
<Constant List>       ->  <String> <Constant List Tail>
<Constant List Tail>  ->  , <Constant List> | ε
<Rule List>           ->  <Rule> <Rule List> | ε
<Rule>                ->  <Head Predicate> :- <Predicate List> .
<Head Predicate>      ->  <Identifier> ( <Identifier List> )
<Predicate List>      ->  <Predicate> <Predicate List Tail>
<Predicate List Tail> ->  , <Predicate List> | ε
<Predicate>           ->  <Identifier> ( <Parameter List> )
<Parameter List>      ->  <Parameter> <Parameter List Tail>
<Parameter List Tail> ->  , <Parameter List> | ε
<Parameter>           ->  <String> | <Identifier> | <Expression>
<Expression>          -> ( <Parameter> <Operator> <Parameter> )
<Operator>            -> + | *
<Query List>          ->  <Query> <Query List Tail>
<Query List Tail>     ->  <Query List> | ε
<Query>               ->  <Predicate> ?

这是一个简单的类似数据日志的语法。我完全迷失在尝试编写解析器的过程中。我已经编写了一个词法分析器,它输出一个包含所有标记的 vector 。我知道我需要为每个产品编写方法,但我不知道如何将标记连接到解析树中(因此我可以在树完成后运行 toString() 函数)。我需要被指出正确的方向。谢谢。

最佳答案

鉴于您已经编写的内容,它主要是从 EBNF 到 C++ 源代码的机械翻译,因此(例如)这样的规则:

<Scheme>              ->  <Identifier> ( <Identifier List> ) 
<Identifier List>     ->  <Identifier> <Identifier List Tail>
<Identifier List Tail>->  , <Identifier List> | ε

转换成这个一般顺序的东西(但要小心——我只是在脑海中打字,所以它根本没有经过测试;更多地把它想象成类似 C 的伪代码比按原样编译的任何东西)。

bool scheme() { 
    return identifier()        &&
           check_input('(')    &&
           identifier_list()   &&
           check_input(')');
}

bool identifier_list() { 
    if (identifier()) {
        if (check_input(','))
            return identifier_list();
        else
            return true;
    }
    return false;
}

bool identifier() { 
    // you haven't said what's a legal identifier, so for the moment I'm assuming
    // rules roughly like C's.
    int ch;
    std::string id;

    if (!((ch=getinput()) == '_' || isalapha(ch))
        return false;

    do { 
        id += ch;
        ch = getinput();
    } while (isalpha(ch) || isdigit(ch) || ch == '_');
    putback(ch);
    return true;
}

一旦你让它正确识别输入(并构建标识符等,正如我上面所做的,即使我没有对它做任何事情)你就可以开始构建一个解析树(或其他)添加东西在你认出它们的那棵树上。如果你在 C 中这样做,你通常使用 union 。在 C++ 中,您可能想改用类层次结构(尽管它会是一个非常短、浓密的层次结构——事实上,很容易是所有其他直接从基类派生的层次结构)。

关于c++ - 如何编写递归下降解析器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14794293/

相关文章:

c++ - 为什么复制省略如此有限?

c++ - QTableWidget单元格更新

python - PathLike 对象中的 __fspath__() 函数

java - XML 解析太慢了!

c++ - 构建项目时遇到了 Eclipse C++ 问题。

c - C编译涉及哪些内部过程?

c++ - 二叉搜索树后序和前序遍历错误

c++ - 在 qt 中创建 QLabels 的 QVector

java - 在文档的子字符串周围绘制一个框

c++ - C/C++ 函数 - 如何允许原型(prototype)?