Разобрать включенный файл с метапарсной строкой Boost - PullRequest
2 голосов
/ 21 января 2020

Я хочу использовать boost Metaparse для разбора DSL во время компиляции. Однако для разделения я не хочу записывать свой DSL как один большой символ в файл C ++, а использовать препроцессор, вероятно, через #include, чтобы получить текст из отдельного файла во время компиляции.

В документации расширенного мета-анализа упоминается макрос препроцессора BOOST_METAPARSE_STRING, поэтому BOOST_METAPARSE_STRING("DSL content") преобразуется во время препроцессора в metaparse::string<'D','S','L',' ', 'c','o'...>

Так что вместо

using input = BOOST_METAPARSE_STRING("DSL content");

я хочу использовать что-то как

using input = BOOST_METAPARSE_STRING(#include "dsl.txt");

с dsl.txt, содержащим

DSL content

, но этот наивный подход не сработает, идеи?

Ответы [ 2 ]

1 голос
/ 21 января 2020

В настоящее время это невозможно; Для #include произвольного файла в форме, которую можно использовать непосредственно в программе, необходимо предварительно обработать файл, например, завернув его в необработанный строковый литерал или используя xxd.

( ) документы P1040 std::embed и P1967 Preprocessor embed (он же #embed) имеют целью добавить такую ​​возможность в C ++ и в препроцессор C соответственно. Если статья принята, она может войти в язык с помощью C ++ 23. Тем временем https://github.com/ThePhD/embed имеет патчи для g cc и clang; если вы заинтересованы в изучении этой функции, http://godbolt.org имеет версии g cc и clang trunk с патчами std :: embed, доступные для использования в Интернете.

1 голос
/ 21 января 2020

Если вы не против добавления небольшого количества текста во включаемый файл, вы можете сделать dsl.txt примерно таким:

BOOST_METAPARSE_STRING(r"//(
DSL content
)//");

А затем:

using input =
#include "dsl.txt"

(Предполагается, что вы используете версию C ++, которая содержит необработанные строки. В противном случае, это намного раздражает.)

Вы можете добавить первую и последнюю строки с помощью простой команды оболочки, если хотите.

Это не идеально, но поскольку BOOST_METAPARSE_STRING, кажется, требует строкового литерала, я не думаю, что есть лучший вариант.


С другой стороны, если вы обнаружите, что используете приемлемый внешний препроцессор, совсем не трудно написать тот, который создает вызов шаблона metaparse::string из текстового файла. Вам не нужно ограничивать себя препроцессором C ++. Любой инструмент сборки позволит вам использовать пользовательский шаг сборки; даже сначала скомпилируйте ваш препроцессор для предварительной обработки текстового файла.

...