编辑: 无理的喜欢 | 2019-07-02 |
第三章 语言翻译 程序结构 语法 程序是什么样的BNF (上下文无关文法) C 一种非常有用的描述语法的表示法.
语义 执行行为静态语义 C 语义在编译时确定:var A: integer;
A 的类型和存储int B[10];
数组 B 的类型和存储float MyProcC(float x;
float y){...};
函数属性动态语义 C 语义在执行时确定:X = ``ABC'
'
SNOBOL4语言的例子: X 是一个字符串X =
1 + 2;
X 是一个整数:(X)X 是一个地址;
转移到标号为 X 的地方 主要内容 程序语言的语法语法的一般准则、次要(或二级)准则语法的基本元素程序-程序的组织结构程序的翻译源程序分析:词法分析(扫描)、语法分析、语义分析目标程序的综合翻译模型BNF、正则文法(有限状态自动机)、下推自动机PERL概述 3.1 语言的语法 语法:单词的组织方式,用来展示单词之间的关系单词作为语句中的元素语法描述了构成有效程序的符号序列.如C中,x=y+z是有效的符号序列,而xy+-则不是.语法提供了理解程序的含义所需的信息,也提供了大量的从源程序到目标程序翻译所需的信息. 语言的语法(2) 单靠语法并不足以无二义地刻划语句的结构.如:x=2.45+3.67,语法并不能告诉我们x是否被声明过或是否声明为实数.x=5,6或6.12均是可能的.因此,对语言的完整描述单靠语法结构是不够的,还需涉及语义.如:声明的使用、操作、顺序控制和引用环境等影响变量性质的一些属性,并不总是由语法决定. 语言的语法(3) 虽然如此,语法仍是语言描述中的重要属性.现在,语法描述已是一个解决了的问题,源程序的语法理解阶段是相当机械的,YACC等工具可自动生成给定程序的语法描述. 返回 语法的一般准则 语法的主要目的是为程序员和语言处理器间通讯提供一套注记方法.而选择特殊的语法结构主要是为了传递特殊的信息项.例如:某特定变量有类型实数,可以用多种方式表达.可以是显式声明或隐含的命名约定,等.语法细节的选择大部分是基于第二准则,如可读性,它和通讯的主要目标无关.有很多二级准则,通常可按其目标分类,分为:易读、易写、易翻译、无二义等目标.这些目标间有时会有冲突. 易读性(Readabitity) 程序是易读的:如果程序表示的算法和数据的结构可以很容易从程序文本中了解到.一个易读的程序,通常称为自成文档的(不需其他用于理解的辅助文档).增加易读性的方式:自然的语句格式、结构化语句、关键字和噪音字的自由使用、嵌入式注释机制、不限长标识符、助记符、自由域格式、完全的数据声明等.不同的语法应反映不同语义,做相似事的程序结构是相似的.做不同事的程序其结构需有明显不同.语言如只提供了少数不同语法结构,通常导致程序易读性差.如APL,SNOBOL4等,只提供一种语句格式,赋值、子程序调用、简单GOTO、子程序返回,多路条件分支、及其它常见程序结构的差异只能通过个别操作算子的不同来反映. 易读性(Readabitity) 易读性并不能由语言设计保证,最好的设计也可能由于糟糕的编程而破坏.当然,语法设计也可能使好程序员写出难理解的程序,如APL.COBOL强调易读,但其代价是牺牲了易写和易翻译. 易写性 易写性(使用简明的、规则的语法结构)通常和易读性(冗余结构是有帮助的)相冲突.隐含的语法约定允许声明和操作不需预先刻划,从而使程序更短、更易写,但不易读.有些语法冗余性有用的,因它允许程序易读,并允许翻译时错误检测.缺点是不易写.语法称为冗余的,如果以多种方式传达同样的信息.大多数缺省规则(针对语言结构含义)试图减少冗余,而删去了某些显式的含义陈述,因为这些含义可从语境中导出.例,Fortran中约定,I-N打头的变量为整型,其他为实数,这样不需声明,但缺点是有副作用,如:拼写错误不能被编译器检测到,例如:INDEX被写成INDX→则变成新变量. 易写性 对两个目标均有增强的一些特征:如结构化语句、简单自然语句格式、助记符、未限制标记符等通常使程序易写通过允许在程序中直接表示问题的算法和数据的自然结构. 易验证性 和易读、易写相关的概念是程序正确性或程序验证.多年经验表明,理解每条程序语言语句是容易的,创建正确程序的整个过程却是困难的.因此,需有技术,使得能数学地证明程序是正确的. 易翻译性 即易于翻译成可执行形式.易读性和易写性是面向程序员的需要.易翻译性(关键是结构的正则性)是面向翻译器(处理被写成的程序)的需要.如LISP程序,不易读、也不易写、但易于翻译,主要由于其语法简单且正则.当特殊语法结构增加,将导致翻译困难,如COBOL,它允许大量的语句和声明形式. 无歧义性 含混性是语言设计中的一个中心问题.一个语言定义应尽可能地为每个语法结构提供唯一的意义.而含混性结构允许两个或多个不同解释.通常不是由个体程序元素的结构产生,而是由于不同结构的交迭.例如:if Boolean exp then statement1 else statement2.If Boolean exp then statement1当两种形式组合时,有可能出现二义情况.Fortran中,A(I,J)可能是数组元素,也可能是函数调用.事实上,上面提到的含混在语言中均有解决方案. 条件语句的两种不同解释 歧义性的解决方法 例:因组合而形成的悬空else:If Boolean exp1 then if Boolean exp2 then stat1 else stat2Algol解决方案:改变语法,引入分界符begin…end.Ada解决方案:每个if语句必须以end if分界符结尾.C和Pascal解决方案:从二义结构中任选一种解释.对本例而言,最后的else总是和最近的then配对.FORTRAN中函数调用和数组引用的二义性由规则解决:A(I, J)被视为函数调用,如果没有数组A的声明.但这个假定只能在程序装载、链接时被检查.Pascal中区分二者的方法是使用不同的括号,如:[…]用于界定数组参数,(…)用于界定函数调用的参数. 返回 语言的语法元素 (1/7) 语言的语法风格由各种基本语法元素的选取所决定.字符集字符集的选择是语言设计的第一件事.已有一些标准字符集,如:ASCII码.通常是选择一个标准的字符集.但也有不标准的,如APL.字符集的选择对确定可被用于语言实现的I/O设备的类型是非常重要的.如:C的字符集可用于大多数I/O设备.而APL的字符集则不能直接用于大多数I/O设备.通常用8位来表示字符(60年代早期用6位),这似乎是足够的.但是,随着计算机产业的国际化进程,可能16位表示是必需的(可有65536个字符). 语言的语法元素(2/7) 标识符字和数字串,以字母开头――常用的选择.也可能使用特殊字符,如用.或-来改善易读性和长度限制.操作符符号+,-,*,/表示基本算法操作.通常简单操作可完全使用特殊符号.当然,也可以使用标识符来表示简单操作,如LISP中的PLUS、TIMES.大多数语言采用二者的组合. 语言的语法元素(3/7) 关键字和保留字关键字――用于语句语法中固定部分的标识符.保留字――不能被程序员使用的关键字.大多数语言使用保留字以改善翻译器的错误检测能力,使语法分析更为容易.噪声字可选的字,被插入语句中以改善易读性.如:COBOL中Go语句可写为GO TO 语言的语法元素(4/7) 注释是文档中的重要部分,几种注释方式: