Я бы хотел разобрать предложения в логах высказываний c, используя BNF C. Я написал следующую грамматику BNF, чтобы облегчить это:
Negation. N ::= "(" "-" L")";
Conjuction. C ::= "(" L "&" L ")";
Disjuction. D ::= "(" L "|" L ")";
Implication. I ::= "(" L "=>" L ")";
Equivalence. E ::= "(" L "<=>" L ")";
Atom. L ::= Ident | N | C | D | I | E ;
Однако с этой конструкцией я получаю следующую ошибку:
syntax error at line 6, column 27 before `|'
Что синтаксически неверно в предоставленной мной спецификации?
Edit 1
Хорошо, похоже, bnfc
действительно не нравится идея использовать символ |
для объединения. Как тогда назначить несколько продукций одному правилу, если не через объединение? Я не хочу определять Atom1. L ::= Ident ;
, Atom2. L ::= N ;
и т. Д., Но необходимо ли это, если я хочу, чтобы это работало?
Edit 2
Хорошо, поэтому присваиваем различные метки для каждого L
-производства, как в
Negation. N ::= "(" "-" L")";
Conjuction. C ::= "(" L "&" L ")";
Disjuction. D ::= "(" L "|" L ")";
Implication. I ::= "(" L "=>" L ")";
Equivalence. E ::= "(" L "<=>" L ")";
Atom1. L ::= Ident ;
Atom2. L ::= N ;
Atom3. L ::= C ;
Atom4. L ::= D ;
Atom5. L ::= I ;
Atom6. L ::= E ;
, разрешалось файлу logic.cf
проходить через bnfc
без каких-либо ошибок. Однако, когда файл скомпилирован с использованием команды
bnfc -m -c file.cf
, а затем я пытаюсь запустить make
, я получаю следующую ошибку, когда Make пытается запустить gcc
на сгенерированном bnf c файле Printer.c
:
gcc -g -W -Wall -c Absyn.c
flex -Plogic -oLexer.c logic.l
gcc -g -W -Wall -c Lexer.c
Lexer.c:1477:16: warning: ‘input’ defined but not used [-Wunused-function]
static int input (void)
^~~~~
Lexer.c:1434:17: warning: ‘yyunput’ defined but not used [-Wunused-function]
static void yyunput (int c, char * yy_bp )
^~~~~~~
bison -t -plogic logic.y -o Parser.c
gcc -g -W -Wall -c Parser.c
gcc -g -W -Wall -c Printer.c
Printer.c: In function ‘ppL’:
Printer.c:289:20: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
ppIdent(_p_->u.atom_.ident_, 0);
^~~~~
atom1_
Printer.c:296:16: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
ppN(_p_->u.atom_.n_, 0);
^~~~~
atom1_
Printer.c:303:16: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
ppC(_p_->u.atom_.c_, 0);
^~~~~
atom1_
Printer.c:310:16: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
ppD(_p_->u.atom_.d_, 0);
^~~~~
atom1_
Printer.c:317:16: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
ppI(_p_->u.atom_.i_, 0);
^~~~~
atom1_
Printer.c:324:16: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
ppE(_p_->u.atom_.e_, 0);
^~~~~
atom1_
Printer.c: In function ‘ppInteger’:
Printer.c:336:31: warning: unused parameter ‘i’ [-Wunused-parameter]
void ppInteger(Integer n, int i)
^
Printer.c: In function ‘ppDouble’:
Printer.c:342:29: warning: unused parameter ‘i’ [-Wunused-parameter]
void ppDouble(Double d, int i)
^
Printer.c: In function ‘ppChar’:
Printer.c:348:25: warning: unused parameter ‘i’ [-Wunused-parameter]
void ppChar(Char c, int i)
^
Printer.c: In function ‘ppString’:
Printer.c:354:29: warning: unused parameter ‘i’ [-Wunused-parameter]
void ppString(String s, int i)
^
Printer.c: In function ‘ppIdent’:
Printer.c:360:28: warning: unused parameter ‘i’ [-Wunused-parameter]
void ppIdent(String s, int i)
^
Printer.c: In function ‘shL’:
Printer.c:507:20: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
shIdent(_p_->u.atom_.ident_);
^~~~~
atom1_
Printer.c:522:16: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
shN(_p_->u.atom_.n_);
^~~~~
atom1_
Printer.c:537:16: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
shC(_p_->u.atom_.c_);
^~~~~
atom1_
Printer.c:552:16: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
shD(_p_->u.atom_.d_);
^~~~~
atom1_
Printer.c:567:16: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
shI(_p_->u.atom_.i_);
^~~~~
atom1_
Printer.c:582:16: error: ‘union <anonymous>’ has no member named ‘atom_’; did you mean ‘atom1_’?
shE(_p_->u.atom_.e_);
^~~~~
atom1_
Makefile:42: recipe for target 'Printer.o' failed
make: *** [Printer.o] Error 1
Понятия не имею, что это значит. Почему он пытается найти atom_
, когда я не указал такую вещь в logic.cf
Если есть люди, более опытные с внутренностями bnfc
, я не возражаю услышать от вас.
Редактировать 3
Хорошо, поэтому написание меток как
Negation. N ::= "(" "-" L ")";
Conjuction. C ::= "(" L "&" L ")";
Disjuction. D ::= "(" L "|" L ")";
Implication. I ::= "(" L "=>" L ")";
Equivalence. E ::= "(" L "<=>" L ")";
Atom. L ::= Ident;
AtomN. L ::= N ;
AtomC. L ::= C ;
AtomD. L ::= D ;
AtomI. L ::= I ;
AtomE. L ::= E ;
каким-то волшебным образом позволило make
пройти. Тем не менее, мой синтаксический анализатор работает не совсем так просто, как
echo "p" | ./Testlogic
возвращается с
error: line 1: syntax error at p
Не является ли p
действительным идентификатором, и поэтому производство Atom. L ::= Ident;
должно позволить это пройти? Почему это не так?