Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383
大家有没想过,编程语言是如何被编译或解释执行的?使用sscanf还是正则表达式?今天我们一起来揭开编程语言的神秘面纱。
程序语言按照层次,可以分为普通语言以及语法描述语言。普通语言包括出语法描述语言外的其他所有语言。简单的说,C++,C#,Java、XML、JSON等等都属于这类;语法描述语言是用来描述一门语言的语法,通常一门语法描述语言就能描述所有的语言的语法。这类语言最著名的叫EBNF(扩展巴克斯范式)。
这类语言的作用就是定义一门语言的语法。语法定义完毕后,语言会按照设计思路,生成AST(抽象语法树)。抽象语法树能非常方便的生成中间语言。通常,这个过程就叫编译器前端。相应的,编译器后端是指将中间语言优化,再解析为本地字节码的过程,叫编译器后端。一般来说,生成AST后,一个语言基本上就设计完成了,后端可以自己撸,也可以对接llvm等,很方便就能实现一门编程语言。
语言前端基于EBNF的工具有很多,看一些工具的名称就能看出来,比如yacc(又一个编译器的编译器)。C++的“准”标准库也提供了全套库,叫“Boost.Spirit”。后面的代码我将以这个工具来举例。
说及这个库,首先不得不谈这个EBNF表达式。下面我给大家展示一个用于描述四则运算的EBNF代码:
1 2 3 4 5 6 | expr1 := oper1 ('+' | '-') (expr1 | oper1) expr2 := oper2 ('*' | '/') (expr2 | oper2) oper1 := expr2 | integer | block; oper2 := integer | block; block := '(' oper ')'; oper := expr1 | expr2 | integer | block; |