编译原理第八章


s6 r2 r4 s4 r6
s6 r1 r3 r5 s4 s4
r2 r4
acc r2 r4
1
2
3
s5 r6
s5 s5
8
2 9
3 3 10
r6 s11 r1 r3 r5
r6
s7 r3 r5
r1 r3 r5
24
表达式2 + 3 ∗ 5的求值
25
L-属性文法的语义处理
采用自上而下的方式可以较方便地进行
在两种情况下,属性b依赖于属性c1,c2…ck
5
AX1 X2 …Xn A的综合属性S(A)计算公式 S(A):=f(I(X1),…,I(Xn)) Xj的继承属性T(Xj)计算公式 T(Xj):=f(I(A),... I(Xn))
出现在产生式左边的继承属性和出现在产生式右边的 综合属性不由所给定的产生式的属性计算规则进行计算, 它们由其它产生式的属性规则计算或者由属性计算器的参 数提供。 1)非终结符既可有综合属性也可有继承属性,例外:文法 开始符号没有继承属性. 2)终结符只有综合属性,它们由词法程序提供.
11
3*5+4的带注释的分析树
继承属性

一个结点的继承属性值是由此结点的父结点和(或) 兄弟结点的某些属性来决定的。
生 产 式 D TL T int T real L L1,id L id 语 义 规 则 L.in:=T.type T.type=integer T.type:=real
(可以只是f(c1,c2,…ck) ,此时b结点为一个虚结点)
for i :=1 to k do
从ci结点到b结点构造一条有向边
17
在某些情况下可用一遍扫描实现属性文法的语 义规则计算-------在语法分析的同时完成语义规则的 计算,无须明显地构造语法树或构造属性之间的依 赖图。
单遍实现对于编译效率非常重要
23
文法G’ [S] 的LR 分析表
(0)SE (1)E E+T (2) E T (3)T TF (4) T F (5)F (E) (6)F d
状态 0 1 2 3 4 5 6 7 8 9 10 11
ACTION
d + ( ) # E
GOTO
T F
s5 s7 r4
s4
F:关于属性的属性断言或谓词集.每个断言与一个产生式
相联.而此断言只引用该产生式左端或右端的终结符或非 终结符相联的属性(语义子程序)
4
属性通常分为两类:综合属性和继承属性。 “自下而上”传递信息 “自上而下”传递信息
属性文法中,对应于每个产生式A都有一套与之相关联的 语义规则,每条规则的形式为b:=f(c1,c2…ck) f是一个函数, b和c1,c2…ck是该产生式文法符号的属性. (1)如果b是A的一个属性,c1,c2…ck是产生式右部文法符号的 属性或A的其他属性,则称b是A的综合属性 ( 2 )如果 b 是产生式右部某个文法符号 X 的一个属性 , 并且 c1,c2…ck是A或产生式右边任何文法符号的属性 ,则 称b是文 法符号X 的继承属性
a2
a3
L.in= real
,
.
语句real a1,a2,a3的 分析树,采用自上而 下的分析方法
13
a1
8.2 语法制导翻译概论

在语法分析过程中,随着分析的步步进展,根据每个产 生式所对应的语义子程序(或语义规则描述的语义动作) 进行翻译的办法称作语法制导翻译。
说明: 语法制导翻译是在语法分析过程中同时进行的; 一旦用到某个产生式推导/归约时,调用相应的语义子 程序进行翻译。 目的:用语法制导翻译的方法来说明程序设计语言 的结构怎样被翻译成中间形式
integer T.type:=real
L1.in:=L.in addtype(id.entry,L.in) addtype(id.entry,L.in)
L id
L.in= real
T.type=real
real
L.in= real
. ,
L
E.val=19 E.val=15
+
T.val=4 F.val=4 F.val=5 digit.lexval=4 digit.lexval=5
T.val=15 T.val=3 F.val=3 digit.lexval=3
*
如果一个语法制 导定义仅仅使用 综合属性,则称 这种语法制导定 义为S属性定义。 通常采用自底向 上的方法对其分 析树加注释,即 从树叶到树根, 按照语义规则计 算每个节点的属 性值。
L E E T T F F
E E1+T T T1 * F F (E) digit
T.val:=T1.val F.val T.val:=F.val F.val:=E.val F.val:=digit.lexval
以3*5+4为例说明
10
综合属性val
在语法制导定义中,一条语义规则完成一个计算属性 值的动作。digit是终结符,只使用综合属性,且其属 性值由词法分析器提供,通常不要计算属性值。
8
表达式文法 E→T+T| T or T T → n | true|false
E → T1 + T2 { T1.type = int T2.type= T1.type E.type :=int T1.type = bool T2.type= T1.type E.type :=bool T.type := int
7
属性文法举例
识别语言 L = { anbncn n 1} ?
产生式 S ABC A A1a A a B B1b Bb C C1c Cc 语义动作/限定条件 {(A.num=B.num) and (B.num=C.num) } { A.num := A1.num + 1 } { A.num := 1 } { B.num := B1.num + 1 } { B.num := 1 } { C.num := C1.num + 1 } { C.num := 1 }
16
构造算法
for 分析树中每一个结点n do for 结点n所用产生式的每个语义规则中涉及的每一个属性a do
为a在依赖图中建立一个结点;
for 结点n所用产生式中每个形如f(c1,c2,…ck)的语义规则 do
为该规则在依赖图中也建立一个结点(称为虚结点);
for 分析树中每一个结点n do for 结点n所用产生式对应的每个语义规则 b:=f(c1,c2,…ck) do
语义分析工具:常用属性文法来说明程序设计语言语义
3
8.1 属性文法
属性文法(attribute grammar)是一个三元 组:A=(G,V,F)
G:是一个上下文无关文法(形式化) V:有穷的属性集,每个属性与文法的一个终结符或非终结符
相连,这些属性代表与文法符号相关信息,如它的类型、值、 代码序列、符号表内容等等 . 属性可以进行计算和传递。属性加工的过程即是语义处理 的过程(并非每个文法符号都有属性,属性与具体产生式 的语义相关)
6
非终结符A,B和C,其中A有一个继承属性a和一个综合 属性b,B有综合属性c,C有继承属性d, 对ABC可能有语义规则 C.d:=B.c+1 A.b:=A.a+B.c 而属性A.a和 B.c是在其他地方计算的。 语义规则所描述的工作可以包括属性计算、静态语 义检查、符号表操作、代码(中间)生成等等。有 些语义规则可能产生副作用(如产生代码),也可 能是个函数,通常把这样的语义规则写成过程调用 或过程段。
21
采用LR分析技术进行S-属性文法的语义处理
语义动作中的综合属性可以通过存在于当前语义栈
栈顶部分的属性进行计算 例如,假设有相应于产生式 AXYZ 的语义规则 A.a := f(X.x, Y.y, Z.z)
在 XYZ 归约为 A 之前,Z.x, Y.y, 和 X.z 分别存放 于语义栈的 top,top-1 和 top-2 的相应域中,因 此 A.a 可以顺利求出
E → T1 or T2
T→n T → true
{
{
} } } }
{ T.type := bool
T → false
{ T.type := bool
类型检查的属性文法
}
9
综合属性
在分析树中,如果一个结点的某一个属性由其子结点的属性 确定,该属性为该结点的综合属性。 产 生 式 语 义 规 则 Print(E.val) E.val:=E1.val+T.val E.val:=T.val 过程Print 打印E表达 式 的值。
第八章 语法制导 翻译和中间代码 生成
主要内容:

属性文法与语法制导翻译 中间代码:逆波兰式、三元式、四元式、抽象语 法树的表示 常见语句的翻译( 布尔表达式,控制语句,循 环,数组 )
2
语义分析
语义分析的任务:在词法分析和语法分析基础上,分析 源程序含义,在理解含义的基础上为生成相应的目标 代码作好准备或直接生成目标代码。 1)静态语义检查 类型检查、运算、维数、越界 2)语义翻译(具体的动作) 语句的翻译(中间代码或目标代码生成) 语义分析方法:大多编译器采用语法制导翻译方法
19
S-属性文法的语义处理

通常采用自下而上的方式进行
若采用LR分析技术,可以通过扩充分析栈中的域, 形成语义栈来存放综合属性的值,计算相应产生式 左部文法符号的综合属性值刚好发生在每一步归约 之前的时刻
20
采用LR分析技术进行S-属性文法的语义处理
扩充分析栈中的域形成语义栈存放综合属性的值
具体的实现希望在单遍扫描中完成翻译
一个一般的属性文法的翻译器可能是很难建立 的,然而有一大类属性文法的翻译器很容易建立
合集下载

编译原理第8章

编译原理第8章

8.3 动态存储分配
TOP 临时变量 内情向量 局部变量
1. 返回地址 保存该被调过程 返回后的地址。
2. 动态链 指向调用该过程 前的最新活动记录 地址(即前一个活动 记录的地址)。
形式单元 静态链
SP 动态链 返回地址
8.3 动态存储分配
TOP 临时变量 内情向量 局部变量 3. 静态链 指向静态直接外层 最新活动记录地址的 指针,用来访问非局 部数据。
形式单元 静态链
SP 动态链 返回地址
8.3 动态存储分配
TOP 临时变量 内情向量 局部变量
4. 形式单元 存放相应的实在 参数的地址或值。
5. 局部变量 一个子程序(过程) 的局部变量。
形式单元 静态链
SP 动态链 返回地址
8.3 动态存储分配
TOP 临时变量 内情向量 局部变量 6. 临时变量 比如计算表达式过 程中需存放中间结果 用的临时值单元。 连接数据
8.2 静态存储分配
CNSUME 的代码 PRDUCE 的代码 CHARACTER * 50 BUF INTEGER NEXT CHARACTER C CHARACTER * 80 BUFFER INTEGER NEXT
代码
静态数据
该图描 述了程 序中局 部变量 的静态 存储位 置。
8.2 静态存储分配
8.1 概述
程序设计语言关于名字的作用域和 生成期的定义规则决定了分配目标程序 数据空间的基本策略。
在大部分现有编译中目标程序数据 空间的分配策略有:
8.1 概述
静态存储分配策略 分配策略
栈式动态存储分配
动态存储分配策略
堆式动态存储分配
8.1 概述
静态存储分配策略

编译原理-第八章

编译原理-第八章
依赖关系; ❖ ③ 如果q是某个产生式中文法符号V的继承属性,
那么,属性q的值仅依赖于该产生式右部位于V左边 的符号的属性。
8.6 中间代码形式
中间代码形式是指用来表述源程序并与之等效的一 种编码方式,可根据具体情况将它设计成各种形 式。 8.6.1 逆波兰表示法 特点:运算符直接写在其运算对象之后。 ❖ 不再有括号 ❖ 运算对象出现的次序未变,同一层中运算符则按 其优先级出现 ❖ 求值过程简单
❖ 除了最右边的w之外,(输出)终结符不可能出现 在翻译成分之中,那么,称这个SDTS为简单后缀 的(Simple Post Fix)。
❖ 定理8.2 对其基础源文法为LR(k)的每一简单后缀 的SDTS,存在一确定的LR(k) PDT, ①它接收从该 基础源文法可推导出的每一句子;②它将这种句 子的翻译作为输出。
对应的抽象代码形成
8.7 属性翻译文法的应用
由以上分析可将原文法改造成:
ST else S2, Sub1
①生成 S2 的中间代码 ②设置位置标号 12
TI then S1, Sub2
① 生成 S1 的中间代码 ② 生成无条件转 12 的代码 ③ 设置位置标号 11
① 生成计算 E 的中间代码 Iif E, Sub3 ② 生成若 E 之值为 false, 则转 11 的中间代码
8.7 属性翻译文法的应用
8.7.4 条件语句的翻译 基本思路: ❖ ① 先对定义它的文法进行改造,以便能在相应处添
加上语义子程序; ❖ ② 根据它的语义,设计出相应语义子程序的动作。
8.7 属性翻译文法的应用
计算 E
true
false
执行 S1
执行 S2
后继语句
条件语句的语义

编译原理,清华大学,第2版_第8章 语法制导翻译和中间代码生成

编译原理,清华大学,第2版_第8章 语法制导翻译和中间代码生成

将if-then-else看作一个完整的操作符,则e、x和 y 分别是三个操作数,这显然是一个三元运算。根据后缀式 的特点,它的后缀式可以写为:
exy if-then-else(记为: exy¥) 但是,这样的表示有个弱点。按照算法的计算次序,e、 x和y均需计算,而实际上,根据条件e的取值,计算x则不 计算y,计算y则不计算x。
一、逆波兰表示 典型特征是操作数在前,操作符紧跟其后。 特点:由于操作符紧跟操作数之后,因此只要知道操作 符有几个操作数,每一步的运算就可以确定。
1、 表达式的表示:
例:a+b 例:-a+b*c 例: (a+b)*c ab+ a@bc*+ ab+c* <左部><表达式的逆波兰式> ::=
2、 赋值语句的逆波兰表示:
E → E1 + E2
E → E1 * E2 E → (E1) E → num
E.val := E1.val + E2.val;
val[top] := val[top]+val[top+2];
E.val := E1.val * E2.val; E.val := E1.val; E.val := num.lexval;
第八章 语法制导翻译和中间代码生成
• 教学要求:本章介绍编译程序的第三个阶段语 义分析及中间代码生成的设计原理和实现方法,
要求理解语法制导翻译、语义动作的基本概念;
掌握语义规则和中间代码的表示形式。 • 教学重点:语义规则,中间代码的表示形式, 自下而上分析制导翻译概述。
语义处理功能: • 1、静态语义审查:验证语法结构合理 的程序是否真正有意义。 • 2、解释执行动态语义、生成代码:执 行真正的翻译(生成中间代码或目标代 码)。

编译原理蒋宗礼课件第8章

编译原理蒋宗礼课件第8章

22
8.4.2 程序块结构符号表的其他实现
对图8.10 中的程序
...
a0 ... b0 ...
NULL NULL
(a) 处理到语句(5)时的符号表
... a0 ... b1 ... b0 NULL NULL
(b) 处理到语句(7)时的符号表
23
8.4.2 程序块结构符号表的其他实现
对图8.10中的程序
名字 符号种类 符号表表项1 符号表表项2 符号表表项3 abc i myarray ... 变量 变量 数组 int int int ... 基本属性 类型 地址 扩展属性指针 0 4 8 NULL NULL 维数 2 各维维长 3 4 扩展属性
图8.3 多种符号共用符号表的一种实现结构
11
8.1.2 符号表中的属性
19
8.4.2 程序块结构符号表的其他实现
• 将所有块的符号表放在一个大数组中,然后再引入 一个程序块表来描述各程序块的符号表在大数组中 的位置及其相互关系
名字 外层块 符号个数 起始指针 0 1 2 3 -1 0 1 1 2 1 1 1 程序块表 1 2 3 4 5 a b b b a 符号表 属性
– 如栈式存储分配时,i的地址是以栈指针sp为基址 加上i相对于活动记录起始地址的偏移量offseti
• 符号表中各符号的地址属性就是该符号相对于 第一个符号的偏移地址
13
8.3 符号表的组织结构 8.3.1 符号表的线性表实现
• 用线性表实现符号表较为直观
– 数组实现:插入n个符号、执行e次查找操作的时 间复杂度为T(n, e) = O(n(n+e)) – 有序数组实现:插入n个符号、执行e次查找操作 的时间复杂度为T(n, e) = elog n+ (log i) + i ≤ (n+e)log n+O(n2)

编译原理第8章

编译原理第8章

2
在程序的执行过程中,程序中数据的存取是通过对 应的存贮单元进行的。
在早期的计算机上,这个存贮管理工作是由程 序员自己来完成的。在程序执行以前,首先要将用机 器语言或汇编语言编写的程序输送到内存的某个指定 区域中,并预先给变量和数据分配相应的内存地址。
在有了高级语言之后,程序员不必直接和内存 地址打交道,程序中使用的存贮单元都由逻辑变量(标 识符)来表示,他们对应的内存地址都是由编译程序在 编译时或由其生成的目标程序运行时进行分配。程序 执行时,源程序中同样的名字可以指示目标机器中不 同的数据对象,本章即考察名字与数据对象的对应关 系。所以,对编译程序来说,存贮的组织及管理是一 个复杂而又十分重要的问题。 编译程序根据如何组织运行环境而生成目标代码。
• 简单变量: (以字节为单位)
– char:1,可以分配在任何地址。 – integer,short:2,对齐到2(即从能被2或4整除的
地址开始分配) – long : 4,对齐到4 – float: 4至16,对齐到相应字节数 – double(双精度型):8,对齐到8 – booleans: 1位,但常设为1个字节 • 指针:unsigned integers • 一维数组:一块连续的存储区 • 多维数组:一块连续的存储区,按行存放 • 结构(记录):把所有域(field)存放在一块存储区 • 对象:类的实例变量象结构的域一样存放在一块连续 的存储区,但方法(成员函数)不存在该对象里
即使在一个程序中每一个名字只被说明一次,同一个名 字在运行时刻仍可能代表不同的数据目标。 一个名字的说明是静态的概念,名字的联编是名字的说 明的动态副本。
7
•引进两个函数,environment(环境) state (状态) – environment把名字映射到一个存储单元上(Lvalue左-值)。 – state把存储单元映射到那里所存放的值上,即把 一个L-value(左-值)映射为一个 R-value(右-值)。如 下图所示。

编译原理第8章

编译原理第8章
第八章 符号表
6、翻译模式
P:说明语句,D:类型说明语句,id:标识符(变量名),T:类型 T T T T integer {T.type:=integer;T.width:=4} 变量名及 real {T.type:=real;T.width:=8} 其性质填 T1 {T.type:=pointer(T1.type);T.width:=4} 入符号表 array[num] of T1 {T.type:=array(num.val,T1.type); offset T.width:=num.val*T1.width} D id:T {Enter(,T.type,offset); offset:=offset+T.width} offset D D;D P D {offset:=0} 内存用户区 语义子程序(语义动作) 产生式
* a * b * @b * @ b * @
c c c c b d a+a*(b-c)+(b-c)*d的DAG a:=b*-c+b*-c的语法树 a:=b*-c+b*-c的DAG
第八章 符号表
3、与后缀式的关系:表达式的抽象语法树形式的中间代码与后 缀式等价,后缀式是抽象语法树的线性表现形式,是树的结点 序列(每个结点都在其所有子结点之后立即出现 )。
第八章 符号表
符号表的作用和地位 符号的主要属性及作用 符号表的组织
第八章 符号表
一、符号表的作用和地位
一、本章主要内容: 静态语义检查和翻译中间代码; 二、静态语义检查的内容: 类型检查、控制流检查、一致性检查、相关名字检查、 名字的作用域分析等; 三、翻译产生中间代码的优点: 便于进行与机器无关的代码优化工作、使编译程序改变目标 机更容易、使编译程序的结构在逻辑上更为简单明确; 四、静态语义检查和中间代码产生在编译程序中的地位:

编译原理编译第八章


一. 状态转换图的定义
有限的有向图 有向边上标记字符
x
2
唯一初态
1
若干终态(至少一个)
y
3
精选ppt
二. 状态转换图识别的串
从初态出发到某一终态路径上字符的连 接。下图是识别标识符的状态转换图:
字母或数字
字母
0
1 其它字符
* 2
精选ppt
第四节 词法分析器的设计
一. 单词符号
第四章设计的语言允许下述单词: 标识符、数字串、begin、end、integer、if、 then、else、function、read、write、
精选ppt
(9)buildlist:将token中的标识符存入符号表,并 将其在符号表中的位置填入val (10)dtb:将token中的数字串转换成二进制,并 存入常数表,位置填入val (11)val:存放标识符在符号表中的位置,或常数 在常数表中的位置 (12)return(c,val):返回二元式 (13)error:出错处理
<=
<>
类别编码
9 10 11 12 13 14
15
16
精选ppt
助记符
$FUNCTION $READ $WRITE $SUB $MUL $LT
$LE
$NE
单词符号
= > >= := ; (
)
类别编码
17 18 19 20 21 22 23
精选ppt
助记符
$EQ $GT $GE $ASSIGN $SEM $LPAR $RPAR
‘ : ‘: begin getchar; if character = ‘ = ‘ then return($ASSIGN,—) else error

编译原理 第八章


② for(i=6,j=0; j<i; ++j) fun(i); 在六次循环中,i的值保持为6,则可优化为: for(i=6,j=0;j<6; ++j) fun(6);
3. 综合使用常数传播和常数合并进行优化处理 为了对保持定值的所有变量之值进行跟踪,建立一个局部符号表,使 每一个活动的变量在该表中有一个登记项,每当对这些变量进行再定 值时,就相应的修改其登记项中的内容。 例: t1=1; t1+=5; 优化为: t1=6; t2=t1; t2=6;
一. 强度削弱
用一种(或一串)执行时间较短的操作去等价的代替一个操作。 1. x*2n 替换为 x<<n (乘法用左移运算替换) x/2n 替换为 x>>n x%2n 替换为 x&(2n-1) 2. 乘以一个较小的整数可以用多个加法代替 x*=3 替换为 x1=x; x+= x1; x+= x1; 3. 较大整数的乘法可以联合使用位移和加法进行强度削弱优化 x*=9 替换为 x1=x; x*=27 替换为 x1=x; x1<<=3; x1<<=1; x+= x1; x+= x1; x1<<=2; x+= x1; x1<<=1; 4. 对于非算术运算进行强度削弱的情形 x+= x1; 例如:许多机器有多种形式的转移指令, 优化程序可以从其中选择效率更高的指令。
三. 无用变量与无用代码的删除
1. 无用变量:变量的最后一次引用到对该变量再置初值期间,可视为无用 变量。在变量的无用期间,对该变量的所有定值(如赋值)指令均可删去。 例: t=a; t+=5; x=t; …… /*此后的一个时间间隔内,t成为无用变量*/ t=c; /*在t的无用期内,对t的定值可以删除*/ …… t=b; /*t被再次置初值,无用期结束*/ y=t+a;

编译原理第八章


2013年8月21日2时45分
(3) 在符号表的信息栏中引入一个指针域(previous)用以 链接它在同一过程内的前一域名字在表中的下标(相对位 置)。每一层的最后一个域名字,其previous之值为0。这 样,每当需要查找一个新名字时,就能通过DISPLAY找出 当前正在处理的最内层的过程及所有外层的子符号表在栈 符号表中的位置。然后,通过previous可以找到同一过程 内的所有被说明的名字。
2013年8月21日2时45分
8.4 符号表的内容
符号表的信息栏中登记了每个名字的有关的性质,如类型、 种属、大小以及相对数。 对于变量名、数组名和过程名,信息栏中一般有下列信息: (1)变量 类型(整数、实、双实、布尔、字符、复、标号 或指针); 种属(简单变量、数组或记录结构); 长度(所需的存储单元数); 相对数(存储单元数); 若为数组,则记录其内情况向量。
2013年8月21日2时45分
杂凑技术
对于表格处理来说,根本问题在于如何保证查表与填表两 方面的工作都能高效地进行。对于线性表来说,填表快, 查表慢。而对于对折法而言,则填表慢,查表快。杂凑法 正是一种争取查表、填表两方面都能高速进行的统一技术。 这种办法是:假定有一个足够大的区域,这个区域以填写 一张含N项的符号表。构造一个地址函数H。对于地址函 数H有两点要求:第一,函数的计算要简单、高效;第二, 函数值能比较均匀地分布。对于杂凑技术还应设法解决 “地址冲突”的问题。
2013年8月21日2时45分
8.2 整理与查找
符号表作为一个多元组,表中元组的排列组织是构造符号 表的重要成分。在编译程序的整个工作过程中,符号表被 频繁地用来建立表项,找查表项,填充和引用表项的属性 。因此表项的排列组织对该系统运行的效率起着十分重要 的作用。在编译程序中,符号表项的组织传统上采用三种 构造方法。即线性法,二分法及散列法。

编译原理 第八章

义子程序。
例 算术表达式求值的语义描述
(0)L→E
print(E.val)
(1)E→ E1 + T E.val:=E1.val+T.val
(2)E→ T
E.val:=T.val
(3)T→ T1 * F T.val:=T1.val*F.val
(4)T→ F
T.val:=F.val
(5)F→(E) F.val:=E.val
2
r
r44rr44
S4
8 23
r
r
6
6
r
r
6
6
S4
93
S
10
4
S
S
6
11
r1
S7
r1
r1
r
r
3
3
r
r
3
3
r
r
5
5
r
r
5
5
LR分析输入串2+3*5
步骤 状态栈 语义栈(值栈) 符号栈
1
0
-
#
剩余输入串 归约动作
2+3*5#
2
05
--
#2
+3*5#
3
03
-2
#F
+3*5#
r6
4
02
-2
#T
+3*5#
r4
E { T1.t =T2.t}
{ T1.= int} T + T { T2.= int}
3
4
A为属性文法
如果对G中的某一输入串而言,A中的所有断言 对该输入串的语法树的结点的属性全为真,则该串 也是A语言中的句子。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档