4

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

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

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

4

1 回答 1

4

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

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,因为我忽略了行号,并且不同的编译器对有效注释和继续字符有不同的规则。

于 2009-10-16T15:26:33.990 回答