2016-05-21 2 views
0

Я хочу работать на игрушечном языке с помощью парсера Flex/Bison с привязками к Rust. Для простоты я бы хотел, чтобы Bison просто вызвал функцию , определенную Rust для каждого согласованного правила, чтобы создать конкретное дерево синтаксиса (которое будет переведено в AST в Rust для дальнейшей обработки). Вызов функции должен включать соответствующий тип правила в качестве аргумента, чтобы мой код Rust знал, какой тип узла он (выражение, if-statement, while-statement, вызов функции, литеральная строка, число и т. Д.).Автоматически сгенерированный знак битса Enum

Просматривая сгенерированный анализатор Bison, похоже, что существует переменная yyn, которая, как представляется, представляет собой целое число, представляющее согласованное правило, хотя я не видел его документально нигде. Я знаю, что опция %defines даст мне перечисление токенов в parser.tab.h, но мне нужны перечисленные как конечные, так и нетерминальные символы. Я также видел опцию %token-table, которая также дает нетерминальные символы, но не совсем то, что мне нужно, а также идет прямо в файл parser.tab.c, а не файл parser.tab.h, что затрудняет использование чего-то вроде rust-bindgen.

Итак, есть ли способ, чтобы Bison генерировал перечисление, аналогичное перечислению yytokentype, которое включает в себя нетерминальные символы и помещается в заголовочный файл? Или я застрял в определении моего собственного перечисления для типов узлов КНТ, которые совпадают с символами, которые у меня есть? Является ли yyn документированным где угодно? Безопасно ли использовать в качестве способа определения правила, которое было согласовано в действии? Есть ли лучший способ, которым я могу это сделать?

ответ

0

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

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

Grammar 

    0 $accept: prog $end 

    1 prog: expr 
    2  | prog ';' expr 

    3 expr: NUMBER 
    4  | '(' expr ')' 
    5  | expr '+' expr 
    6  | expr '-' expr 
    7  | expr '*' expr 
    8  | expr '/' expr 

(. Затем следует список терминалов, которые я опущена)

Nonterminals, with rules where they appear 

$accept (11) 
    on left: 0 
prog (12) 
    on left: 1 2, on right: 0 2 
expr (13) 
    on left: 3 4 5 6 7 8, on right: 1 2 4 5 6 7 8 

Здесь вы можете увидеть, что есть два пользовательских терминалов, prog с маркер id 12 и expr с идентификатором 13. Существует девять определяемых пользователем производств, пронумерованных от 1 до 8. Совпадение только того, что эти диапазоны чисел не перекрываются; токеновые коды менее 11 были использованы для (перенумерованных) терминальных символов, а также некоторые внутренние токены.

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


Я думаю, вы приближаетесь к этой проблеме неправильно. Если я правильно понимаю, что вы пытаетесь сделать, вы хотите создать определенную функцию для каждой продукции, которая будет реализована в Rust, а также требует прототипа C. Это похоже на простую проблему генерации кода, которую вы можете создать, начиная с самой грамматики.

Это не сложно извлечь грамматику из исходного источника бизонов, но если вы не хотите идти на это, вы можете легко использовать листинг из файла .output, как показано выше, что может быть проанализировал довольно хорошо любой простой инструмент для обработки текста, такой как awk.

С небольшой работой и использованием недокументированных функций вы также можете вытащить грамматику из структур данных отладки бизонов.

Смежные вопросы