【问题标题】:Character column parsing in Boost::SpiritBoost::Spirit 中的字符列解析
【发布时间】:2009-09-22 21:34:01
【问题描述】:

我正在为 Fortran 77 的一小部分开发基于 Boost Spirit 2.0 的解析器。我遇到的问题是 Fortran 77 是面向列的,我无法在 Spirit 中找到任何可以允许的内容它的解析器是列感知的。有没有办法做到这一点?

我真的不需要支持完整的神秘 Fortran 语法,但它确实需要能够忽略第一列中包含字符的行(Fortran cmets),并识别第六列中包含字符的行作为续行。

似乎处理批处理文件的人至少会遇到与我相同的第一列问题。 Spirit 似乎有一个行尾解析器,但没有行首解析器(当然也不是 column(x) 解析器)。

【问题讨论】:

  • 哇!我有一个风滚草徽章(stackoverflow.com/badges/63/tumbleweed)。 Jon Skeet 没有其中之一,而且可能永远不会。 :-)
  • 这很有趣,不要问我是怎么找到这个帖子的。我刚做了!
  • 好吧,欢迎回答我的问题 JonH。请尽量不要过多地破坏灰尘。我刚刚把它放在我想要的地方。 :-)
  • 以防万一其他人在这里徘徊,我提出了我的答案。

标签: parsing boost-spirit


【解决方案1】:

好吧,既然我现在有了答案,我想我应该分享一下。

Fortran 77 可能与所有其他关心列的语言一样,是一种面向行的语言。这意味着您的解析器必须跟踪 EOL 并在解析中实际使用它。

另一个重要的事实是,就我而言,我并不关心解析 Fortran 可以放入那些早期控制列中的行号。我只需要知道它何时告诉我以不同的方式扫描其余部分。

鉴于这两点,我完全可以使用 Spirit 跳过解析器来处理这个问题。我写给我的

  • 如果第一(注释)列包含字母字符,则跳过整行。
  • 如果没有任何内容,请跳过整行。
  • 如果第五列包含“.”,则忽略前面的 EOL 以及直到第五列的所有内容。 (续行)。这会将其添加到前一行。
  • 跳过所有非 eol 空格(在 Fortran 中,即使空格也不重要。是的,这是一种奇怪的语言。)

代码如下:

        skip = 
            // Full line comment
            (spirit::eol >> spirit::ascii::alpha >> *(spirit::ascii::char_  - spirit::eol))
            [boost::bind (&fortran::parse_info::skipping_line, &pi)]
        |  
            // remaining line comment
            (spirit::ascii::char_ ('!') >> *(spirit::ascii::char_ - spirit::eol)
             [boost::bind (&fortran::parse_info::skipping_line_comment, &pi)])
        |
            // Continuation
            (spirit::eol >> spirit::ascii::blank >> 
             spirit::qi::repeat(4)[spirit::ascii::char_ - spirit::eol] >> ".")
            [boost::bind (&fortran::parse_info::skipping_continue, &pi)]

        |   
            // empty line 
            (spirit::eol >> 
             -(spirit::ascii::blank >> spirit::qi::repeat(0, 4)[spirit::ascii::char_ - spirit::eol] >> 
               *(spirit::ascii::blank) ) >> 
             &(spirit::eol | spirit::eoi))
            [boost::bind (&fortran::parse_info::skipping_empty, &pi)]
        |   
            // whitespace (this needs to be the last alternative).
            (spirit::ascii::space - spirit::eol)
            [boost::bind (&fortran::parse_info::skipping_space, &pi)]
        ;

我建议不要自己盲目地将其用于面向行的 Fortran,因为我忽略了行号,并且不同的编译器对有效注释和继续字符有不同的规则。

【讨论】:

  • 仅供参考:这是 Spirit 2.1 代码,这意味着它可以与新发布的 Boost (1.41) 一起使用,但可能无法与早期版本一起编译。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-04
  • 2017-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多