如何在BNF中表示否定?

Jus*_*s12 8 grammar parsing bnf ebnf

BNF或ABNF是否支持否定.那是否排除了某些成员?我的语法中没有看到任何这样的否定运算符.

例如,假设S是集所有字母数字串即是不相等的,以"foo" 什么的BNF S

Ira*_*ter 7

上下文无关文法不会在“差异”或“补语”下关闭。因此,虽然您可能决定向 BNF 添加运算符“减法”,但结果不会是上下文无关文法,即使它有一种简单的表达方式。结果:人们不允许在用于表达上下文无关文法的 BNF 文法中使用此类运算符。

  • 识别关键字通常在词法分析器中完成,而不是在解析器中完成。词法分析器通常只是对比较进行*排序*,因此您首先要查找关键字。当且仅当失败时,您还有其他一些标识符。 (5认同)
  • 那么现有的编译器如何检查变量不是保留字呢? (2认同)
  • 调查结果表明,EBNF *确实*支持通过异常进行“否定”。至少根据[ISO标准](http://www.iso.org/iso/catalogue_detail?csnumber=26153)。尽管大多数解析器可能无法实现它。 (2认同)

Ric*_*ick 6

虽然不在 BNF 中,但 EBNF 确实有异常符号(通常定义为“-”)。在您的情况下,语法将是:

alphaNum="a"|"b"|...|"z"|"0"|"1"|...|"9"|"A"|...|"Z";
S= (alphaNum,{alphaNum}) - "foo";
Run Code Online (Sandbox Code Playgroud)

或者,如果您希望它不区分大小写:

foo="f"|"F","o"|"O","o"|"O";
alphaNum="a"|"b"|...|"z"|"0"|"1"|...|"9"|"A"|...|"Z";
S= (alphaNum,{alphaNum}) - foo;
Run Code Online (Sandbox Code Playgroud)

这导致与评论中所做的接受标准略有不同,这相当于:

alphaNum="a"|"b"|...|"z"|"0"|"1"|...|"9";
S= alphaNum - "f", {alphaNum} 
  |"f", alphaNum - "o", {alphaNum}
  |"f", "o", alphaNum - "o", {alphaNum};
Run Code Online (Sandbox Code Playgroud)

这遗漏了字符串“f”和“fo”。

但是,重要的是要注意 Ira Baxter 在他们的回答中,允许任何例外(否定)因素都会导致问题。ISO标准中也指出了这一点:

4.7 语法异常

一个句法异常由一个句法因子组成,该限制是由该句法异常表示的符号序列同样可以由不包含元标识符的句法因子表示。

注意- 如果允许句法异常是任意句法因素,扩展 BNF可以定义比上下文无关文法更广泛的语言类别,包括导致类似罗素悖论的尝试,例如

xx = "A" - xx;
Run Code Online (Sandbox Code Playgroud)

“A”是 xx 的一个例子吗?这种许可是不可取的,因此语法异常的形式仅限于可以证明是安全的情况。因此,句法因素通常等同于某些上下文无关文法,而句法异常总是等同于某些常规文法。可以证明,上下文无关文法和正则文法之间的区别总是另一种上下文无关文法;因此,句法术语(以及根据该标准定义的任何文法)等价于一些上下文无关文法。