好吧,既然我现在有了答案,我想我应该分享一下。
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,因为我忽略了行号,并且不同的编译器对有效注释和继续字符有不同的规则。