Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 这是一个模棱两可的语法吗?我应该如何解决它?_Algorithm_Grammar_Theory_Context Free Grammar - Fatal编程技术网

Algorithm 这是一个模棱两可的语法吗?我应该如何解决它?

Algorithm 这是一个模棱两可的语法吗?我应该如何解决它?,algorithm,grammar,theory,context-free-grammar,Algorithm,Grammar,Theory,Context Free Grammar,在这之前,我对这类东西的了解很少 无论如何,我一直在开发一种上下文无关语法来描述alegbraic表达式的结构,这样我就可以自学CYK解析算法的工作原理。我理解这样一种结构如何只适用于中缀代数表达式,但我不理解如何开发一种既能处理“-”运算符的一元定义又能处理“-”运算符的二元定义的语法 以下是我用CNF编写的语法(其中s是开始符号),仅供参考: S->x A->O S S->L B B->sr S->K S O->+ O->- O->* O->/ O->^ K->- L->( R->) 问题是

在这之前,我对这类东西的了解很少

无论如何,我一直在开发一种上下文无关语法来描述alegbraic表达式的结构,这样我就可以自学CYK解析算法的工作原理。我理解这样一种结构如何只适用于中缀代数表达式,但我不理解如何开发一种既能处理“-”运算符的一元定义又能处理“-”运算符的二元定义的语法

以下是我用CNF编写的语法(其中s是开始符号),仅供参考:

S->x
A->O S
S->L B
B->sr
S->K S
O->+
O->-
O->*
O->/
O->^
K->-
L->(
R->)


问题是,当遇到“-”运算符时,CYK解析算法如何提前知道是否在S->K S和A->O S之间做出决定?这样的语法上下文是自由的吗?最重要的是,由于编程语言可以处理具有二进制和一元减号的语言,我应该如何合理地解析它?

语法是不明确的,解析器无法决定采用哪种情况

您可能应该使用如下语法:

S -> EXPR
EXPR -> (EXPR)
EXPR -> - EXPR
EXPR -> EXPR + EXPR
EXPR -> EXPR - EXPR
// etc...

这似乎是一个与有限状态自动机相关的问题,我不记得我的课程中的所有内容,但我用OCaml编写了一个CYK解析器,所以我将继续尝试:)

例如,如果您试图解析像
3--4
这样的表达式,您将让
S->ks
规则使用
-4
,然后
A->os
规则将吸收
-4
。这将最终达到最顶层的
S
生产规则。不过,您应该小心使用语法,因为您列出的
A
生成规则无法从
S
访问,您可能应该有某种
S->S O S
规则

CYK解析算法的工作方式是通过回溯,而不是通过您在问题中提到的“提前知道”。CYK算法应该做的是将
-4
解析为
S->ks
规则,然后它将尝试再次使用
S->ks
规则吸收第二个
-
,因为该生成规则允许任意长的一元
-
链。但是,一旦您的算法意识到它被中间解析卡住了,它就会意识到它没有可以用来解析的生产符号。一旦它意识到这不再是可解析的,它将返回并尝试将
-
解析为
S->os
规则,然后继续它的快乐之路


这意味着您的语法保持上下文无关,因为上下文敏感语法意味着您在产生式规则的左侧有终端,所以您在这方面做得很好。嗯

基于代数表达式的语法很难消除歧义。以下是一些需要解决的问题示例:

a+b+c自然创建两个解析树。要解决这个问题,您需要解决+的关联性的模糊性。您可能希望使用从左到右的解析策略来解决这一问题,但要小心:求幂可能会将从右到左关联起来

a+b*c自然创建两个解析树。要解决此问题,需要处理运算符优先级

如果允许的话,隐式乘法(a+bc)会产生各种各样的噩梦,主要是在标记化阶段

正如你提到的,一元减法是有问题的

如果我们想解决这些问题,但仍然有一个专门用于代数的快速解析语法,一种方法是有不同的EXPR“级别”,一个用于优先级所需的绑定级别。比如说,

TERM -> (S)
EXPO -> TERM ^ EXPO
PROD -> PROD * EXPO
PROD -> PROD / EXPO
PROD -> -PROD
SUM -> SUM + PROD
SUM -> SUM - PROD
S -> SUM
这要求您还允许“升级”类型:SUM->PROD,PROD->EXP,EXP->TERM等,以便可以终止


希望这有帮助

这意味着二进制语法之前总是需要一个数字,而一元语法要么在开头,要么前面有一个运算符。这种语法的问题在于它不是乔姆斯基范式(如果我错了,请纠正我),这使得它很难与CYK语法分析器一起工作。此外,我不完全确定如何将任何CFG转换为CNF语法。对于CYK,您需要CNF是正确的,但您可以将任何CFG转换为CNF。谢谢,这大大有助于解决如何解析减号运算符的一元和二元定义的主要问题。:)