Parsing 如何在BNF中表示否定?
BNF或ABNF是否支持否定。是否排除集合中的某些成员? 我在它的语法中没有看到任何这样的否定运算符 例如,假设Parsing 如何在BNF中表示否定?,parsing,grammar,bnf,ebnf,ebnf-syntactic-exception,Parsing,Grammar,Bnf,Ebnf,Ebnf Syntactic Exception,BNF或ABNF是否支持否定。是否排除集合中的某些成员? 我在它的语法中没有看到任何这样的否定运算符 例如,假设S是不等于“foo” S的BNF是什么 上下文无关语法在“差异”或“补语”下不是封闭的。因此,虽然您可能决定向BNF中添加运算符“subtract”,但结果将不是上下文无关语法,即使它有一种简单的表达方式。结果:人们不允许在BNF语法中使用此类运算符来表示上下文无关的语法。虽然不在BNF中,但EBNF有except符号(通常定义为“-”)。在您的情况下,语法是: alphaNum=&q
S
是不等于“foo”
S
的BNF是什么 上下文无关语法在“差异”或“补语”下不是封闭的。因此,虽然您可能决定向BNF中添加运算符“subtract”,但结果将不是上下文无关语法,即使它有一种简单的表达方式。结果:人们不允许在BNF语法中使用此类运算符来表示上下文无关的语法。虽然不在BNF中,但EBNF有except符号(通常定义为“-”)。在您的情况下,语法是:
alphaNum="a"|"b"|...|"z"|"0"|"1"|...|"9"|"A"|...|"Z";
S= (alphaNum,{alphaNum}) - "foo";
或者,如果希望它不区分大小写:
foo="f"|"F","o"|"O","o"|"O";
alphaNum="a"|"b"|...|"z"|"0"|"1"|...|"9"|"A"|...|"Z";
S= (alphaNum,{alphaNum}) - foo;
这导致验收标准与评论中的验收标准略有不同,相当于:
alphaNum="a"|"b"|...|"z"|"0"|"1"|...|"9";
S= alphaNum - "f", {alphaNum}
|"f", alphaNum - "o", {alphaNum}
|"f", "o", alphaNum - "o", {alphaNum};
这就省去了字符串“f”和“fo”
然而,值得注意的是,正如Ira Baxter在他们的回答中所说,允许任何例外(否定)因素都会导致问题。报告中也指出了这一点:
4.7语法例外
句法例外由句法因素主语组成
对符号序列表示的限制
语法上的例外同样可以表示为
不包含元标识符的语法因素
注意-如果允许语法异常是任意的
由于句法因素,扩展的BNF可以定义更广泛的
与上下文无关的语法相比的语言,包括尝试
这导致了罗素式的悖论,例如
xx = "A" - xx;
“A”是xx的一个例子吗?这种许可证是不可取的
因此,语法异常的形式受到限制
可以证明是安全的。因此,鉴于
句法因素一般相当于一些上下文无关的因素
语法,语法异常总是等同于某些
正规语法。可以证明
上下文无关语法和常规语法总是另一回事
上下文无关语法;因此是一个句法术语(以及任何
根据本标准定义的语法)等同于
一些上下文无关的语法。那么现有的编译器如何检查变量不是保留字呢?识别关键字通常是在lexer中完成的,而不是在解析器中完成的。lexer通常只对比较进行排序,因此您首先查找关键字。如果且仅当失败时,您就有了其他标识符。更复杂的方案将标识符视为上下文中的关键字,在上下文中它们可以被视为关键字。这需要词法分析器和解析器进行交互以做出选择,和/或解析器尝试关键字和标识符替代方案,并选择关键字替代方案(如果可行)。虽然上下文无关语法通常不会在“差异”或“赞美”下关闭,但它们在差异规则语法下关闭,而关键字是其中的一个子集。因此,不可能支持一般否定的事实并不一定禁止对常规语法的否定表示法。研究结果表明,EBNF确实通过例外支持“否定”。至少根据调查结果。虽然大多数解析器可能无法实现它,但我认为可以通过使用单个字符构建字符串,以非常复杂的方式定义它。是的,您可以做到。你问过一般的否定。对于您的特定示例,此语法将起到以下作用:S=notF any*|'f'notO any*|'f'o'notO any*;notF='a'|……'e'|'g'|……'z′;notO='a'|……|'n’|‘p’|……'z′;any='a'|……|'z′;除了
(alphaNum,{alphaNum})
之外,您还可以使用另一个语法异常来禁止零次重复:{alphaNum}-
。第5.8节注释中的示例中也使用了这一点。