所以我正在阅读Walter Bright关于Bitwise(http://www.bitwisemag.com/copy/programming/d/interview/d_programming_language.html)中D语言的采访,我遇到了关于语言解析的非常有趣的引用:
然而,从理论角度来看,能够生成良好的诊断需要语法中存在冗余。冗余用于猜测预期的内容,冗余越多,猜测的可能性就越大。它就像英语一样 - 如果我们偶尔拼写错误,或者如果一个单词缺失,冗余使我们能够正确地猜出其含义。如果语言中没有冗余,则任何随机字符序列都是有效的程序。
现在我正试图弄清楚当他说“冗余”时他意味着什么。
我几乎无法绕过最后一部分,在那里他提到可以使用一种语言“任何随机的字符序列都是有效的程序”。我被告知有三种错误:句法,运行时和语义。是否存在唯一可能的错误是语义的语言?这样的集会吗?机器代码怎么样?
答案 0 :(得分:24)
我会关注为什么(我认为)Walther Bright认为redunancy很好。我们以XML为例。这个片段:
<foo>...</foo>
具有冗余,如果我们使用S-Expressions,则结束标记是冗余的:
(foo ...)
它更短,并且程序员不必更频繁地键入foo
来理解该片段。减少冗余。但它有缺点,例如http://www.prescod.net/xml/sexprs.html显示:
(document author: "paul@prescod.net"
(para "This is a paragraph " (footnote "(better than the one under there)" ".")
(para "Ha! I made you say \"underwear\"."))
<document author="paul@prescod.net">
<para>This is a paragraph <footnote>(just a little one).</para>
<para>Ha! I made you say "underwear".</para>
</document>
在两者中,缺少脚注的结束标记/结束标记。只要解析器看到</para>
,xml版本就会无效。 S-Expression只在文档末尾无效,并且只有在其他地方没有不需要的结束时才会失效。因此,在某些情况下,redunancy确实有助于udnerstand作者的意思(并指出他表达错误的方式)。
答案 1 :(得分:10)
汇编语言(大多数汇编语言,完全不是) - 它们的语法非常严格,大多数随机字符串都会被诊断为错误。
机器代码更接近。由于没有涉及从“源”到“对象”代码的转换,所有错误都是语义的,而不是语法的。大多数处理器确实具有它们拒绝的各种输入(例如,执行“坏操作码”陷阱/中断)。您可能会争辩说,在某些情况下,这将是语法(例如,根本无法识别的操作码),其他语义是语义的(例如,该指令不允许的一组操作数)。
对于那些记得它的人来说,TECO因为为几乎任何可能的输入分配一些含义而闻名(臭名昭着?),所以它几乎是一样的。一个有趣的挑战是弄清楚如果你输入(例如)你的名字会发生什么。
答案 2 :(得分:9)
nglsh nclds ll srts of xtr ltrs t mk it ezr t read
答案 3 :(得分:8)
好吧,使用C#中的一个例子(因为我不知道D)。如果你有一个带抽象方法的类,那么类本身必须标记为abstract:
public abstract class MyClass
{
public abstract MyFunc();
}
现在,编译器自动将MyClass标记为抽象(这是C ++处理它的方式)是微不足道的,但是在C#中,你必须明确地这样做,这样你的意图就清楚了。
与virtual
方法类似。在C ++中,如果在基类中声明virtual,则方法在所有派生类中自动为虚拟。在C#中,该方法必须明确标记为override
,因此不会混淆您想要的内容。
答案 4 :(得分:5)
我认为他在谈论语言中的句法结构以及如何解释它们。例如,考虑使用多种语言呈现的简陋的“if”语句。
在bash(shell脚本)中,它看起来像这样:
if [ cond ]; then
stmts;
elif [ other_cond ]; then
other_stmts;
else
other_other_stmts;
fi
C中的(带有单个参数,没有花括号):
if (cond)
stmt;
else if (other_cond)
other_stmt;
else
other_other_stmt;
你可以看到,在bash中,if语句的语法结构比C中的语法结构要多得多。实际上,bash中的所有控制结构都有自己的结束分隔符(例如if/then/fi
,{{ 1}},for/do/done
,...),而在C中,大括号随处可见。这些独特的分隔符消除了代码含义的歧义,从而提供了解释器/编译器可以诊断错误条件并将其报告给用户的上下文。
答案 5 :(得分:4)
这意味着语法包含的信息比编码工作程序所需的信息多。一个例子是函数原型。正如K&amp; R C向我们展示的那样,它们是多余的,因为编译器可以让调用者按下你想要的任何参数,然后让函数弹出正确的参数。但是C ++和其他语言强制要求它们,因为它们可以帮助编译器检查你是否以正确的方式调用函数。
另一个例子是在使用变量之前声明变量的要求。有些语言有这个,有些则没有。它显然是多余的,但它通常有助于防止错误(例如拼写错误,使用已删除的变量)。
答案 6 :(得分:3)
我认为更好的冗余示例就像int a[10] =
。此时,编译器知道接下来会发生什么,一个int数组初始化器,并且如果后面的内容不是int数组初始化器,则可以提出相应的错误消息。如果语言语法说任何事都可以跟int a[10]
一起,那么编译器就很难找出问题。
答案 7 :(得分:1)
然后任何随机字符序列都是有效的程序。
虽然不是“任何随机序列有效”,但请考虑Perl和正则表达式。它们非常短的语法使无效字符更容易通过句法和语义分析。