因此,我一直在使用Boost Spirit Compiler教程。目前,它非常适合整数。我正在研究一种扩展它以处理字符串的方法。这是源代码的链接。

http://www.boost.org/doc/libs/1_57_0/libs/spirit/example/qi/compiler_tutorial/mini_c/

对于熟悉Boost的人来说,以下内容应该看起来很熟悉-这是主要表达式的生产规则:

 primary_expr =
            uint_
        |   function_call
        |   identifier
        |   bool_
        |   '(' > expr > ')'
        ;


uint_可以为primary_expr分配一个int值。通常,我们可以通过创建一些生产规则,或者使用正则表达式来标识引号等类似的简单文本解析器,为char或字符串添加一些简单功能。如果您备份我发送的链接的根,则有很多示例。

真正的问题来自以下事实:要实现编译器,代码会将字节码操作推入向量。在此处推送单个字符很简单,因为所有字符都有一个附带的ASCII代码,它将被隐式转换为该字符,但对于一个字符数组却不是这种情况,因为它们在处理过程中会作为较大字符串的一部分丢失上下文(例如,构成一个句子)。

我能想到的最好的选择是更改

vector<int>




vector<uintptr_t>


据我了解,这种类型的指针可以指向整数和字符。不过,在上述生产规则内将'uint_'更改为'uintptr_t'并不是简单的问题。编译器告诉我在此特定实例中这是非法使用。

顺便说一句,您将看到我们的向量的实现,该向量将字节码保存在compiler.cpp / .hpp文件中。

任何帮助将不胜感激,如果您需要更多信息,请询问。谢谢。

最佳答案

通常,我们可以通过创建更多生产规则,或者使用正则表达式来标识引号或类似内容的简单文本解析器,为char或字符串添加一些简单功能。


不支持正则表达式。您可以在Boost Spirit Lex模式中使用正则表达式语法的子集(可以在token_def中使用),但这会使画面复杂得多。


  真正的问题来自以下事实:要实现编译器,代码会将字节码操作推入向量。在此处推送单个字符很简单,因为所有字符都有一个附带的ASCII代码,它将被隐式转换为该字符,但对于一个字符数组却不是这种情况,因为它们在处理过程中会作为较大字符串的一部分丢失上下文(例如,构成一个句子)。


用术语来说:AST不包含非整数值。

最简单的方法是为操作数扩展AST:

typedef boost::variant<
        nil
      , bool
      , unsigned int
      , identifier
      , std::string                          // ADDED
      , boost::recursive_wrapper<unary>
      , boost::recursive_wrapper<function_call>
      , boost::recursive_wrapper<expression>
    >
operand;


(注意:这也是primary_exprunary_expr公开的属性的类型)

现在让我们扩展规则:

    quoted_string = '"' >> *('\\' >> char_ | ~char_('"')) >> '"';

    primary_expr =
            uint_
        |   function_call
        |   identifier
        |   quoted_string
        |   bool_
        |   ('(' > expr > ')')
        ;


请注意,我们声明了quoted_string而不用使其跳过,因此我们不必进行lexeme[]咒语(Boost spirit skipper issues)。



编译器支持

接下来,编译时发现compiler访问者尚不知道字符串。因此,我们添加

    op_string,      //  push constant string into the stack




bool compiler::operator()(std::string const& x)
{
    BOOST_ASSERT(current != 0);
    current->op(op_string, x);
    return true;
}


在各个地方。



(仍然使用https://www.livecoding.tv/sehe/编码,推送了答案,以便您可以提前阅读)

10-02 01:05
查看更多