使用BNFC确定命题逻辑的基本语言(语法错误) [英] Using BNFC to determine a basic language for propositional logic (syntax error)

查看:145
本文介绍了使用BNFC确定命题逻辑的基本语言(语法错误)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用BNFC解析命题逻辑中的句子.我编写了以下BNF语法来简化此操作:

I would like to parse sentences in propositional logic using BNFC. I wrote the following BNF grammar to facilitate this:

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 ;

但是,通过这种构造,我得到以下错误:

However, with this construction I get the following error:

syntax error at line 6, column 27 before `|'

我提供的规范在语法上有何不正确?

What is syntactically incorrect about the specification I provided?

好,所以看起来bnfc真的不喜欢使用符号|进行联合的想法.然后,如果不通过联合,如何将多个生产分配给单个规则?我不想定义Atom1. L ::= Ident ;Atom2. L ::= N ;等,但是如果我想使它起作用,这是否有必要?

Ok, so it looks like bnfc really does not like the idea of using the symbol | for union. How do I then assign multiple productions to a single rule, if not via a union? I do not want to have to define Atom1. L ::= Ident ;, Atom2. L ::= N ; and so forth, but is this necessary if I want this to work?

好,所以给每个L产品赋予不同的标签,如

Ok, so giving different labels to each L-production, as in

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而没有任何错误.但是,使用命令编译文件时

allowed the file logic.cf to pass through bnfc without any errors. However, when the file is compiled using the command

bnfc -m -c file.cf

然后我尝试运行make,当Make尝试在bnfc生成的文件Printer.c上运行gcc时,出现以下错误:

and I then try running make, I get the following error when Make tries to run gcc on the bnfc-generated file 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

我不知道这意味着什么.为什么在我未在logic.cf中指定此类内容的情况下尝试找到atom_,如果有人对bnfc的内部知识有更深入的了解,我不会介意您的来信.

I have no idea what this means. Why is it trying to find atom_, when I've not specified such a thing in logic.cf If there are any people more experienced with the internals of bnfc, I wouldn't mind hearing from you.

好,所以将标签写为

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通过.但是,我的解析器不能完全正常工作,就像这样简单

somehow magically allowed make to pass. However, my parser isn't exactly working, as something as simple as

echo "p" | ./Testlogic

返回

error: line 1: syntax error at p

p不是有效的标识符,因此生产版本Atom. L ::= Ident;应该允许它通过吗?为什么不是这种情况?

Isn't p a valid identifier, and so the production Atom. L ::= Ident; should allow it to pass? Why is this not the case?

推荐答案

事实证明,就制作顺序而言,BNFC有点挑剔.我不得不写

It turns out BNFC is a bit picky, when it comes to the order of the productions. I had to write

Atom.         L ::= Ident;
AtomN.        L ::= N ;
AtomC.        L ::= C ;
AtomD.        L ::= D ;
AtomI.        L ::= I ;
AtomE.        L ::= E ;
Negation.     N ::= "(" "-" L ")";
Conjuction.   C ::= "(" L "&" L ")";
Disjuction.   D ::= "(" L "|" L ")";
Implication.  I ::= "(" L "=>" L ")";
Equivalence.  E ::= "(" L "<=>" L ")";

除了去除标签末尾的数字以使其起作用外.我现在可以用谓词逻辑解析简单的句子:

in addition to getting rid of the numbers at the ends of the labels to make it work. I am now able to parse simple sentences in predicate logic:

$ echo "(a&(a<=>b))" | ./Testlogic 

Parse Succesful!

[Abstract Syntax]
(AtomC [(Conjuction (Atom ["a"]) (AtomE [(Equivalence (Atom ["a"]) (Atom ["b"]))]))])

[Linearized Tree]
(a  & (a <=> b))

这篇关于使用BNFC确定命题逻辑的基本语言(语法错误)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆