“::=” ,在此上下文中表示"定义为"或者"组成" 或者"由其衍生而来"。
非终结符:可以再分的字符或串
终结符:不可再分的字符或串
在编译原理中,非终结符不可以再分,所以用小写字母表示终结符,大写字母表示非终结符。
总结符一般位于式子的右边,非终结符一般位于式子的左边。
INTEGER 表示整型数据
FLOAT 表示浮点型数据
field_const_decl:字段常量声明
const_expr:常量表达式
IDENT:标识符
visibilty:可见性
decl(declaration):声明的缩写
小步语义
设计一台抽象机器维护一些执行状态,然后定义一些规约规则,这些规则详细说明了如何才能对每种程序结构循序渐进地求值。特别地,小步语义大部分都带有迭代的味道,它要求抽象机器反复执行规约步骤(Machine#run中的 while 循环),这些步骤以及与它们同样类型的信息可以作为自身的输入和输出,这让它们适合这种反复进行的应用程序。小步语义明确定义了操作应该发生的顺序,因为在每一步都明确了下一步规约应该是什么。
small-step SOS 又称为 transitional semantics ,它描述了执行中的每个步骤。
可以将 small-step SOS 视为一个能够 step-by-step 地执行给定代码的机器。
小步语义可以清楚地为复杂特性建模,比如并发、divergence 和运行时错误。
small-step SOS 的形式化定义包括三个部分:
configuration :对 IMP non-terminal configuration 的简记。
transition :一组等待推导的 configuration 。
rule :描述了基于 transition 推导 configuration 的规则,表示为如下形式,其中 前提 (premise) 是零至多个 transition 或 equation ,结论 (conclusion) 是一个 transition :
非形式化地讲,rule 的含义是在 premise 成立的情况下可以将 conclusion 式左的 configuration 推导到式右的 configuration 。
注意,形式化定义不是唯一的,原则上只需形式语义规范、语法合适、逻辑正确即可。
表达式演算规则
在表达式演算中,transition 表现为如下两种形式之一,其中v∈{int,bool}:
- <e,σ>→<e’,σ>
- <e,σ>→v
这里给出一个简单的实例来帮助理解。
对于算术表达式的其它运算符,以及布尔表达式的运算,均有类似规则,不予赘述。不过,一元布尔运算符稍有不同:
事实上,我们可以将所有二元(算术或布尔)运算符的 arg 1 和 arg 2 规则结合为更简洁的一条规则:
⟨e, σ⟩→⟨e ′ , σ⟩
其中E[] 定义为:
E[] ::= [] + e | int + []
| [] - e | int - []
| ...
对于更复杂的表达式(例如多元的、复合的),可以递归或归约地进行演算,并构造出对应的 派生树 (derivation tree) 。
#命令执行规则
在命令执行中,transition 表现为如下两种形式之一:
- ⟨c, σ⟩→⟨c ′ , σ ′ ⟩
- ⟨c, σ⟩→σ ′
注意 σ 和 σ ′ 。与表达式的演算不同,命令的执行可能会改变状态。
对于状态 σ ,定义 σ[y/x] 如下:
定义 skip 命令的执行规则如下:
大步语义
也称自然语义,定义如何从一个表达式或者语句直接得到它的结果。这必然需要把程序的执行当成一个递归的而不是迭代的过程:大步语义说的是,为了对一个更大的表达式求值,我们要对所有比它小的子表达式求值,然后把结果结合起来得到最终答案。大步语义经常会写成更为松散的形式,只会说哪些子计算会执行,而不会指明它们按什么顺序执行。
-
可以将 big-step SOS 视为一个递归解释器,能对于给定的代码和状态给出演算结果。
-
在某些情况下,小步语义的细致性是不必要的,大步语义将小步语义中那些指定求值顺序的“枯燥”规则折叠起来,使规则变得更少、证明变得更快。
-
然而在大步语义中,所有没有 final configuration 的程序(例如无限循环、get stuck等)看起来都一样,因此我们有时无法用大步语义证明与此相关的内容。
-
big-step SOS 的形式化定义同样由 configuration 、transition 和 rule 三个部分组成。
不同的是,大步语义的一步 transition 直接描述了演算的结果,而不考虑演算过程的中间状态: -
⟨e, σ⟩⇓int
-
⟨c, σ⟩⇓σ ′
表达式演算规则
大步语义推导
我们用记号 M 表示大步语义的推导结果:若 ⟨S, σ⟩⇓σ ′ ,则 M(S, σ)=σ ′。
**
伪状态
伪状态 (pseudo-state) 指的是不能成功终止的程序状态,用 ⊥ 表示,并且有 ⊥∈{⊥ d , ⊥ e } 。
若 ⟨S, σ⟩⇓⊥ d ,则称从状态 σ 出发执行程序片段 S 导致 发散 (diverge) ,其中 ⊥ 是表示程序因始终运行而不能终止(例如死循环)的伪状态。
若 ⟨S, σ⟩⇓⊥ e,则称从状态 σ 出发执行程序片段 S 时出现 运行时错误 (runtime error) ,其中 ⊥ e是表示程序因出现错误而无法正常终止的伪状态。
操作语义的应用
一元运算符(unary operator)unop
二元运算符(binary operator)binop
本文部分内容转载于 JM233333,https://blog.jm233333.com/