C语言中非上下文免费语言的例子?

时间:2012-10-22 13:53:34

标签: c programming-languages grammar context-free-grammar context-sensitive-grammar

C语言中非上下文免费语言的例子是什么? C语言中如何存在以下非CFL?

  

a)L1 = {wcw | w是{a,b} *}

     

b)L2 = {a ^ n b ^ m c ^ n d ^ m | n,m> = 1}

2 个答案:

答案 0 :(得分:4)

这个问题笨拙,所以我在这里读书。不过,这是一个常见的家庭作业/学习问题。

通常呈现的C语法中的各种歧义[1]不会使语言不具有上下文。 (实际上,它们甚至不会使语法无法上下文。)一般规则“如果它看起来像一个声明,它是一个声明而不管其他可能的解析”可能被编成一个非常复杂的无上下文语法(虽然这并非100%显而易见,因为CFG并未在交集或差异下关闭),但更容易使用更简单的CFG进行解析,然后根据声明规则消除歧义。

现在,关于C(和大多数编程语言)的重点是语言的语法比用于解释目的的BNF复杂得多。例如,如果在未定义的情况下使用变量,则C程序的格式不正确。这是一个语法错误,但它没有被CFG解析器检测到。由于语言的语法复杂,定义这些案例所需的语法制作非常复杂,但它们将归结为要求id在有效程序中出现两次。因此L1 = {wcw|w is {a,b}+}(此处w是标识符,c太复杂而无法拼写出来)。实际上,通常使用符号表来检查此要求,而正式的语言规则虽然准确,但不是以逻辑形式编写的。由于L1不是无上下文的语言,因此形式主义不能无上下文,但上下文敏感的语法可以识别L1,因此并非完全不可能。 (例如,参见Algol 68。)

符号表还用于决定特定identifier是否应缩减为typedef-name [2]。这是解决语法中的一些含糊之处所必需的。 (它还进一步限制了语言中的字符串集,因为在某些情况下,必须将identifier解析为typedef-name才能使程序有效。)

对于另一种类型的上下文敏感,函数调用需要匹配参数的 number 中的函数声明;此类要求由L2 = {a^n b^m c^n d^m| n,m >=1}建模,其中ac表示某些函数的定义和用法,bd表示定义和用法不同的功能。 (再次,以高度简化的形式。)

这第二个要求可能不太清楚一个句法要求。其他语言(例如Python)允许使用任意数量的参数进行函数调用,并将参数/参数计数匹配检测为仅在运行时检测到的语义错误。但是,在C的情况下,不匹配显然是语法错误。

简而言之,构成C语言的语法有效字符串集是C语言定义中提供的CFG识别的字符串集的适当子集;有效解析集是CFG生成的派生集的适当子集,语言本身是(a)明确的,(b)不是无上下文的。

注1:其中大部分都不是含糊不清的,因为它们取决于给定identifier的解析方式(typedef名称,函数标识符,声明的变量,......)。

注意2:如果identifier恰好是typedef-name,则t必须解析为{1}}。只发生在可能减少的地方。即使在相同的范围内,对类型和变量使用相同的标识符也不是语法错误。 (这不是一个好主意,但它是有效的。)以下示例改编自标准6.7.8节中的示例,显示了使用typedef signed int t; struct tag { unsigned t:4; // field named 't' of type unsigned int const t:5; // unnamed field of type 't' (signed int) }; 作为字段名称和typedef:

{{1}}

答案 1 :(得分:3)

这些东西在C语言中没有上下文:

foo * bar; // foo multiplied by bar or declaration of bar pointing to foo?
foo(*bar); // foo called with *bar as param or declaration of bar pointing to foo?
foo bar[2] // is bar an array of foo or a pointer to foo?
foo (bar baz) // is foo a function or a pointer to a function?