Разбор столбца персонажа в Boost :: Spirit - PullRequest
4 голосов
/ 23 сентября 2009

Я работаю над парсером на основе Boost Spirit 2.0 для небольшого подмножества Fortran 77. У меня проблема в том, что Fortran 77 ориентирован на столбцы, и я не смог ничего найти в Духе, который может позволить его анализаторам быть осведомленными о столбцах. Есть ли способ сделать это?

Мне не обязательно поддерживать полный тайный синтаксис Фортрана, но он должен уметь игнорировать строки с символом в первом столбце (комментарии Фортрана) и распознавать строки с символом в шестом столбце как продолжение строки.

Кажется, у людей, имеющих дело с пакетными файлами, по крайней мере, будет та же проблема с первой колонкой, что и у меня. Похоже, что у Spirit есть парсер конца строки, но не парсер начала строки (и, конечно, не парсер столбца (x)).

1 Ответ

4 голосов
/ 16 октября 2009

Ну, так как у меня теперь есть ответ на этот вопрос, я думаю, я должен поделиться им.

Fortran 77, как и, вероятно, все другие языки, которые заботятся о столбцах, является строковым языком. Это означает, что ваш синтаксический анализатор должен отслеживать EOL и фактически использовать его при разборе.

Другим важным фактом является то, что в моем случае я не заботился о разборе номеров строк, которые Фортран может поместить в эти ранние контрольные столбцы. Все, что мне нужно, это знать, когда он говорит мне сканировать остальную часть строки по-другому.

Учитывая эти две вещи, я мог бы полностью решить эту проблему с помощью анализатора пропуска Spirit. Я написал свой

  • пропустить всю строку, если первый (комментарий) столбец содержит буквенный символ.
  • пропустить всю строку, если на ней ничего нет.
  • игнорировать предыдущий EOL и все, вплоть до пятого столбца, если в пятом столбце содержится «.» (продолжение строки). Это привязывает его к предыдущей строке.
  • пропустить все не-eol пробелы (даже пробелы не имеют значения в Фортране. Да, это странный язык.)

Вот код:

        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)]
        ;

Я бы не советовал слепо использовать это самостоятельно для ориентированного на строки Фортрана, так как я игнорирую номера строк, и разные компиляторы имеют разные правила для допустимых комментариев и символов продолжения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...