有点晕,先记录一下。
概述
PL/0语言的语法可以用以下上下文无关文法描述:
<程序>→<分程序>.
<分程序>→ [<常量说明部分>][<变量说明部分>][<过程说明部分>]<语句>
<常量说明部分> → CONST<常量定义>{ ,<常量定义>};
<常量定义> → <标识符>=<无符号整数>
<无符号整数> → <数字>{<数字>}
<变量说明部分> → VAR<标识符>{ ,<标识符>};
<标识符> → <字母>{<字母>|<数字>}
<过程说明部分> → <过程首部><分程序>;{<过程说明部分>}
<过程首部> → PROCEDURE <标识符>;
<语句> → <赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|<复合语句>|<空语句>
<赋值语句> → <标识符>:=<表达式>
<复合语句> → BEGIN<语句>{ ;<语句>} END
<条件> → <表达式><关系运算符><表达式>|ODD<表达式>
<表达式> → [+|-]<项>{<加减运算符><项>}
<项> → <因子>{<乘除运算符><因子>}
<因子> → <标识符>|<无符号整数>|(<表达式>)
<加减运算符> → +|-
<乘除运算符> → *|/
<关系运算符> → =|#|<|<=|>|>=
<条件语句> → IF<条件>THEN<语句>
<过程调用语句> → CALL<标识符>
<当型循环语句> → WHILE<条件>DO<语句>
<读语句> → READ(<标识符>{ ,<标识符>})
<写语句> → WRITE(<标识符>{,<标识符>})
<字母> → A|B|C…X|Y|Z
<数字> → 0|1|2…7|8|9
<空语句> → epsilon
原文描述的这个,感觉很乱……
整理
<程序>→<分程序>.
这是一整个程序的大体思路,然后接下来慢慢细分(注意文末这个 .
)。
声明
<分程序>→[<常量说明部分>][<变量说明部分>][<过程说明部分>]<语句>
一个分程序可以分出:常量、变量、过程,后面接的都是句子。
<常量说明部分> → CONST<常量定义>{ ,<常量定义>}; |
写的抽象复杂,其实也就如下的形式(其中 i
为标识符 identifier (由字母、数字组成),num
为无符号整数代表的数字):
常量
CONST i = num; |
CONST
可定义一个或多个常量,其中每部分都是 i = num
的形式( ,
隔开),以 ;
结尾。
变量
VAR i; |
和常量差不多,注意定义变量的时候不会进行赋值。
过程
PROCEDURE i; |
其中过程可以多层嵌套,但最大为3层:
PROCEDURE i1; |
PROCEDURE i1; |
语句
接下来是最麻烦的部分,声明好了之后就需要分析语句。
<语句> → <赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|<复合语句>|<空语句> |
有8种语句。用 syntax
代表语句。
赋值语句
<赋值语句> → <标识符>:=<表达式> |
循环嵌套,咋一看很乱,慢慢整理:
i := expression |
这个地方最好用 expression
代表一下表达式,不如很乱。表达式格式如下:
+i -i i |
就像这样的可以无限套娃,注意由乘除衔接的成为因子,用加减衔接的成为项。
综上,赋值语句表示为 i := 我们熟悉的只含加减乘除的那种式子
。
条件语句/当型循环语句
<条件语句> → IF<条件>THEN<语句> |
关系运算符的 #
代表 !=
。用 condition 代表条件:
IF condition THEN syntax; |
其中条件参考条件语句:
expression1 = | # | < | <= | > | >= expression2 |
过程调用语句
<过程调用语句> → CALL<标识符> |
比较简单,也就是
CALL i |
读语句/写语句
<读语句> → READ(<标识符>{ ,<标识符>}) |
也比较简单:
READ(i) |
复合语句
<复合语句> → BEGIN<语句>{ ;<语句>} END |
也就是说,形如:
BEGIN |
也可多个语句:
BEGIN |
分号大概是这样没错。
空语句
<空语句> → epsilon |
推出空,也就先放着吧。