2015-11-23 2 views
1

Я использую для описания файла параметров BNF.Intellij idea BNF конец строки

root ::= commands * 
private commands ::= !<<eof>> (f_command | comments) {string_variable}* 
comments ::= LINE_COMMENT 
f_command ::= F 

Как я могу реализовать конец BNF линии? Поскольку BNF не может понять, где конец параметра F и где конец параметра Комментарии (параметр параметров может быть много). По аналогии с < < eof >>.

Пример параметров файла:

F option1 option2 optionN 
C option1 option2 optionN 

ответ

1

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

  1. Почему у вас есть !<<eof>> в разделе «Частные команды»? означает ли это, что «eof не может быть первым символом»? если это так, это кажется странным, и если вам это нужно для <<eof>>, то разве вам это не понадобится и для каждого другого недействительного стартового символа, и разве это не означает, что он действителен для любой другой продукции, начинающейся с <<eof>>? Как я могу видеть, единственное место, которое <<eof>> имеет смысл в самом первом производстве, может быть, как это:

    root ::= commands<<eof>>

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

Также не используйте '*' для повторения (если это то, что вы делаете) - вы должны включить его в грамматику. Я думаю, что вы хотите, чтобы грамматика сказать «один или постановка более последовательной„КОМАНДА“разрешена», если это так, то один из способов достижения этой цели может быть следующим:

root ::= commands<<eof>> 
commands ::= commandsX 
X ::= private_command | epsilon 
private_command ::= <whatever you want this to be> 

Я думаю, что ближе к что ты хочешь. Имейте в виду, что commands ::= commandsX остается рекурсивным, поэтому вам придется исправить это, если вам нужна грамматика LL. Если вы хотите, чтобы private_command принимал любое количество переменных, просто используйте аналогичный подход при определении производств для private_command.

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

Некоторой хороший BNF ссылка:

http://marvin.cs.uidaho.edu/Teaching/CS445/grammar.html

https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form

не уверен, что вы приложение для этого, но если цель просто получить рабочий парсер вы можете посмотреть в бизоне/Yacc (два очень похожих инструмента с разными именами, для синтаксического анализа) и lex/flex (опять же, две аналогичные программы с разными именами, для лексинга). Они напишут синтаксический анализатор и лексерский код для вас, но вам нужна разумная грамматика, чтобы дать им.

https://github.com/westes/flex

https://www.gnu.org/software/bison/

+1

1.! <> - это ошибка. Правильный курс, так как вы написали: root :: = команды <> – securelord

+0

2. Линейные комментарии излишни. это не влияет на общую картину. Мне нужно описать конец команд. В противном случае, для всего парсера после команды «команда». – securelord

+0

ОК, поэтому эта грамматика бессмысленна. нетерминальные «частные команды» нигде не используются. Это полная грамматика, или вы ничего не исключаете? если у вас есть полная грамматика, покажите мне, но если это полная грамматика, тогда она никогда не сработает! –