如何为编程语言定义语法

30

如何为新编程语言(命令式编程语言)定义一个上下文无关文法。

换句话说:当你想从零开始创建一个新的编程语言时,该如何进行。


编程中的define是什么意思?用于参考的define又是什么? - Baget
也许如果您提供更多信息会更好。您提到编译器作为标签,是要为一种新的编程语言编写编译器吗? - tzenes
5个回答

35

一步一个脚印。

说真的,从表达式和操作符开始,逐步向上到语句,然后到函数/类等等。保留每种标点符号所用的列表。

同时定义引用变量、数组、哈希、数字文本、字符串文本和其他内置字面值的语法。还要并行定义数据命名模型和作用域规则。

要检查你的语法是否合理,专注于一个级别(文字/变量、操作符、表达式、语句、函数等),确保来自其他级别的标点符号和标记交错或附加/前置不会造成歧义。

最后将所有内容写成EBNF格式,并通过ANTLR或类似工具运行。

此外最好不要重复发明轮子。我通常从选择开始和结束语句块和函数、以及数学运算符等基本上是C、ECMAScript、Basic、基于命令列表或基于XML的语言序列开始。这很有帮助,因为人们习惯使用这些东西。

当然,你必须想出一个相当有力的理由,才能不放弃编写新语言,而只是坚持使用经过测试和广泛使用的C、ECMAScript或Basic。

我经常开始定义新语言,只是发现其他人已经在某个现有语言的某个地方实现了某种功能。

如果你的目标是针对某个具体项目的开发速度,那么在像Python、Lua或SpiderMonkey等地方进行原型设计可能更好,这些编程语言可以快速启动并减少大多数编译语言所需的输入量。


你能解释一下第三步(确保来自其他级别的标点符号和标记交错或附加/前置不会导致歧义)如何实现吗?单独的结构很好,但当它们组合在一起时就会导致冲突。我正在使用YACC/BISON作为编译器构建工具。 - sonus21

11

如果您想编写上下文无关文法,那么您需要查看EBNF(扩展巴克斯-诺尔范式)。

(假设您想编写上下文无关文法。)


EBNF仅适用于表达CFG,而不是实际设计它。 - David Kanarek
4
OP希望定义一种语法; 问如何实现可能会涉及大量包含lex / yacc(或flex / bison)的答案 - 在这种情况下,yacc / bison语法与EBNF仅有一步之遥。此外,实现语言与实现链表不同(在学术或实际层面上)。需要有一个强大的理论基础,否则所有的“移位/规约”冲突都会让人困惑。在我看来,EBNF是入门的好地方。 - Chris Tonkinson

3
如果您想定义语法,最好从现有的语言开始,并修改其语法以符合您的需求。创建语法规范是一项相当机械化的练习,使用您自己头脑中的一组模式。例如,if语句长什么样子?它看起来像C吗? if <- if(exp) block if <- if(exp) block else block2 还是像ML? if <- if exp then block else block end 或者你想像Lua一样使用elseif: if <- if exp then exp end if <- if exp then exp (elseif exp)* else exp end 语法和语义编码这些决策。请注意,这些都不太适合在LALR或LL(*)编译器生成器中实现,因为它们是含糊不清的,所以必须进行修改才能实现。
Michael Scott的《编程语言实践》是编程语言设计的良好入门书籍。它可以在Amazon上购买,链接在此

1

看一下Bison,也许那就是你要找的东西?


1
Bison相比ANTLR或Racket已经完全过时了。 - Carlo V. Dango

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接