Я пытаюсь портировать грамматику-4 / javascript грамматику на C ++ с подходом, используемым в уже представленных реализациях C # и Java. (https://github.com/antlr/grammars-v4/tree/master/javascript).
Во-первых, позвольте мне объяснить, как реализации C # и Java предоставляют сгенерированный код Lexer и Parser для клиентов. Например, каждая реализация определяет базовый класс для Lexer — JavaScriptBaseClass
— с определенными методами NextToken()
, RegexPossible()
и т.д., который, естественно, унаследован от класса Antlr Lexer. Файл грамматики JavaScriptLexer.g4
определяет JavaScriptBaseLexer
как суперкласс для сгенерированного лексера.
В то же время некоторые объекты, которые будут доступны только после JavaScriptLexer
генерация исходного кода используется внутри определенных методов базового класса JavaScriptBaseClass
,
Например JavaScriptBaseLexer::NextToken
метод использует OpenBrace
Значение enum, которое описывает один из токенов грамматики. (https://github.com/antlr/grammars-v4/blob/a2b8cdfae4057f330f1ec46e8b8e87ea3e7ad962/javascript/CSharpSharwell/JavaScriptBaseLexer.cs#L68)
Это особенность C # или Java — не задавать заголовочные файлы, а затем включать их в код, где может появиться имя из заголовочного файла. Таким образом, можно использовать поля еще не сгенерированного исходного кода JavaScriptLexer
класс внутри базового класса.
Но как этого достичь в реализации C ++?
Во-первых, сгенерированный класс должен знать определение своего родителя, поэтому директива #include “JavaScriptBaseLexer.h”
должен быть представлен в сгенерированном JavaScriptLexer.h
файл,
в противном случае код не будет компилироваться, поскольку имя базового класса не определено. Кажется, вариант Лексера header
может быть добавлен в файл грамматики лексера,
lexer::header {
#include "JavaScriptBaseLexer.h"}
но параметры не зависят от языка и появятся в коде, сгенерированном лексером C # / Java, а в коде C # / Java этого не ожидается.
Во-вторых, JavaScriptLexer’s
Токен enum должен быть определен где-то перед генерацией исходного кода, который будет использоваться внутри кода базового класса. Эта проблема может быть решена путем включения сгенерированных JavaScriptLexer.h
внутри JavaScriptBaseLexer.cpp
файл. Выглядит странно …
Есть идеи, как реализовать С # / Java подход в C ++? Я буду признателен за любую помощь.
Спасибо.
Задача ещё не решена.
Других решений пока нет …