什么编程语言是上下文无关的?
或者,更精确一点:哪些编程语言是由上下文无关文法定义的?
从我收集的内容来看,由于macros和模板等原因,C ++没有上下文。 我的直觉告诉我,函数式语言可能是上下文无关的,但我没有任何硬性数据来支持。
额外代表简洁的例子:-)
对于几乎所有的语言,语法正确的程序集都是上下文无关的。
几乎所有的语言编译的程序集都不是上下文的。 例如,如果所有编译C程序的集合都是上下文无关的,那么通过与常规语言(也称为正则expression式)相交,所有编译C程序的集合
^int main\(void\) { int a+; a+ = a+; return 0; }$
将是上下文无关的,但是这显然是同构于语言a ^ kba ^ kba ^ k,这是众所周知的不是没有上下文的。
什么编程语言是上下文无关的? […]
TL; DR:几乎没有,但由于语法的简单性, Brainfuck和SKI combinator微积分是两个。
更长的版本:几乎没有,但这取决于。 通常情况下,上下文无关语法(CFG)仅用于粗略地指定语言的语法。 必须区分语法正确的程序和编译的程序 。 通常,编译器将语言分析分解为语法分析 ,这些语法分析构build并validation了一段代码的一般结构,并进行语义分析 ,validation程序的意义 。
如果用“上下文无关的语言”表示“所有程序编译的…”,那么答案是:几乎没有。 符合这个法案的语言几乎没有任何规则或复杂的function(如variables的存在,敏感的缩进,或types系统)。
我的直觉告诉我,函数式语言可能是上下文无关的
这是一个命令式语言的CFG Brainfuck:
Program → Instr Program | ε Instr → '+' | '-' | '>' | '<' | ',' | '.' | '[' Prog ']'
下面是function性SKI组合演算的CFG:
Program → E E → 'S' EEE E → 'K' EE E → 'I' E → '(' E ')'
语言是否是上下文无关与function无关。 这只不过是语言规则和特征要分析的复杂程度。
另一方面,如果“上下文无关语言”只意味着“所有程序都通过语法分析”,那么答案就是语法本身的复杂程度。 有许多句法特征难以或仅仅用CFG来描述。 其中一些通过向parsing器添加额外的状态来克服计数器,查找表等等。
使用CFG无法expression的语法特征示例:
-
高度缩进和空白敏感的语言,如Python和Haskell。 跟踪任意嵌套的缩进级别本质上是上下文敏感的,并且需要单独的缩进级别计数器。 (只允许固定级别的缩进将通过复制每个缩进级别的语法来工作。)
-
C Typedef分析问题说C程序在词法分析中是不明确的,因为它不能单独从语法知道某些东西是常规标识符还是现有types的typedef别名。
-
基于macros和模板的语言,如Lisp,C ++,模板Haskell,Nim等等。 由于语法在被parsing时会发生变化,因此解决方法之一就是使parsing器成为自修改程序。 正如对C ++上下文无关或上下文敏感的问题的答案中所expression的那样? ,答案既不是。
一个可以expression为CFG的语法特征的例子,但通常不是:
-
通常,运算符优先级和关联性不能直接在CFG中表示。 例如,对于小于+的绑定的小expression式语法的CFG可能如下所示:
E → E ^ E E → E × E E → E + E E → (E) E → num
然而,这个CFG是模棱两可的 ,并且通常伴随着一个优先级/关联性表,例如表示绑定最紧密,绑定比+更紧密,是正确关联,并且关联和关联。
优先级和关联性可以以系统化的方式编码到CFG中,使得它是明确的,并且仅在操作符正确行为的情况下才产生语法树。 上述语法的一个例子是:
E₀ → EA E₁ EA → E₁ + EA EA → ε E₁ → EM E₂ EM → E₂ × EM EM → ε E₂ → E₃ EP EP → ^ E₃ EP E₃ → num E₃ → (E₀)
但是模棱两可的CFG +优先级/关联性表是常见的,因为它们更具可读性,并且由于各种types的LR语法分析器生成器库可以通过消除移位/减less冲突来生成更高效的分析程序,而不是处理更大尺寸的明确,转换的语法。
从理论上讲,所有有限的string都是正规的语言,所有有限大小的合法程序都是规则的。 由于常规语言是上下文无关语言的一个子集,所有有限大小的程序都是上下文无关的。 争论还在继续,
虽然可以认为,只允许less于一百万行的程序对语言来说是一个可以接受的限制,但将一种编程语言描述为一种常规语言是不实际的:描述将会过于庞大。
– Torben Morgensen的编译器devise基础,ch。 2.10.2
CFG也是一样。 为了解决你的子问题有点不同,
哪些编程语言是由上下文无关语法定义的?
大多数现实世界的编程语言都是通过它们的实现来定义的,大多数现实世界编程语言的parsing器都是手写的,或者使用扩展上下文无关语法的parsing器生成器。 不幸的是,为您最喜欢的语言find一个精确的CFG并不常见。 当你这样做的时候,通常是以Backus-Naurforms (BNF),或者一个parsing器规范,而且很可能不是纯粹的上下文无关的。
来自野外的语法规范的例子:
- 标准ML的BNF
- 类似于Haskell的BNF
- BNF for SQL
- PHP的Yacc语法
- … 等等。
根据你对问题的理解,答案会改变。 但IMNSHO,正确的答案是所有现代编程语言实际上是上下文敏感的。 例如,没有上下文无关文法只接受语法上正确的C程序。 指向C的yacc / bison上下文自由语法的人没有这个意义。
为了find一个非上下文无关语法的最具戏剧性的例子,Perl的语法就像我所理解的那样是完整的 。
如果我理解你的问题,你正在寻找可以用上下文无关语法(cfg)来描述的编程语言,以便cfg生成所有有效的程序和唯一有效的程序。
我相信大多数(如果不是全部的话)现代编程语言不是上下文无关的。 例如,一旦你有用户定义的types(在现代语言中很常见),你自动上下文敏感。
validation语法和validation程序的语义正确性是有区别的。 检查语法是上下文无关的,而检查语义的正确性不是(在大多数语言中)。
但是,这并不意味着这种语言不可能存在。 例如,非types化的lambda演算可以使用上下文无关语法来描述,当然,它是图灵完备的。
我认为Haskell和ML支持上下文自由。 查看Haskell的链接 。
VHDL有些上下文敏感。
(Google:parsing-vhdl-is-very-hard)
大多数现代编程语言都不是上下文无关的语言。 作为一个certificate,如果我深入到CFL的根目录,其相应的机器PDA不能处理像{ww | w is a string}
这样的string匹配 {ww | w is a string}
。 所以大多数编程语言都要求
例:
int fa; // w fa=1; // ww as parser treat it like this