Haskell 98报告
顶部|后面|下一个|目录|功能索引

9  语法参考

9.1  符号约定

这些符号约定用于表示语法:

[图案] 可选择的
{图案} 零次或多次重复
(图案) 分组
拍打1|拍2 选择
<帕特'> 差异---由拍打
除了那些由拍'
斐波那契 打字机字体中的终端语法

自始至终都使用类似BNF的语法,产品的形式如下:
非开庭期 -> 中高音1|alt(高度)2| ... | 中高音n个

有一些由索引的非终结符族优先级(写为上标)。类似地非终结符操作,瓦洛普、和conop公司可能具有双重索引:一封信,第页,或n个对于左、右或非关联性,以及优先级别。先例级别变量范围从0到9;关联性变量不同于{l,r,n}因此,例如
aexp公司 -> (经验i+1(输入+1)qop(qop)(a,i) )
实际上代表30部作品,有10个替代品和3用于

在词汇和上下文无关语法中,都有一些通过将语法短语设置为尽可能长,从左到右(在换档时解析,通过移位解决移位/减少冲突)。在词汇方面语法,这就是“最大咀嚼”规则。无上下文语法,这意味着条件、let-expressions和lambda抽象尽可能向右侧扩展。

9.2  词汇句法

程序 -> {词素|空白}
词素 -> qvarid | qconid | qvarsym | qconsym
| literal|special|reservedop|reserverdid
字面意义的 -> integer|float|char|string
特殊的 -> (|)|,|;|[|]| `|{|}
空白 -> 白色{白色}
白色的东西 -> whitechar |注释|注释
白炭色 -> 换行符|vertab|space|tab|uniWhite
换行符 -> return linefeed | return | linefeed |formfeed
返回 -> 回车
换行符 -> 换行符
维塔布 -> 垂直标签
表单馈送 -> 换页
空间 -> 空格
选项卡 -> 水平选项卡
单色白色 -> 定义为空白的任何Unicode字符
评论 -> 破折号[任意<符号>{any}]换行
破折号 -> --{-}
开放式通信 -> {-
近距离通信 -> -}
ncomment(注释) -> opencom ANYseq{ncomment ANYseq}关闭com
ANYseq公司 -> {任何}<{ANY}(opencom|closecom){ANY}>
任何 -> graphic|白色字符
任何 -> 图形|空间|选项卡
图解的 -> 小|大|符号|数字|特殊|:|"|'
小的 -> ascSmall|uniSmall|_
asc小 -> |b条| ... |z(z)
uni小 -> 任何Unicode小写字母
大的 -> ascLarge|uniLarge
asc大型 -> A类|B类| ... |Z轴
uniL码 -> 任何大写或标题大写的Unicode字母
符号 -> ascSymbol|uniSymbol<特殊|_|:|"|'>
asc符号 -> !|#|$|%|&|*|+||/|<|=|>|?| @
| \|^|||-|~
uniSymbol(统一符号) -> 任何Unicode符号或标点符号
数字 -> ascDigit|uniDigit
asc数字 -> 0|1| ... |9
单数字 -> 任何Unicode十进制数字
八位元 -> 0|1| ... |7
六边形 -> 数字|A类| ... |F类|| ... |(f)

各种各样的 -> (小{小|大|数字|'})<保留>
圆锥 -> 大{小|大|数字|'}
保留(reservedid) -> 案例||数据|违约|推导||其他的
| 如果|进口|在里面|中缀|中缀|中缀|实例
| |模块|新类型|属于|然后|类型|哪里|_
瓦尔西姆 -> (符号{符号|:})<reservedop|破折号>
同源词 -> (:{符号|:})<保留>
保留(reservedop) -> ..|:|::|=|\|||<-|->|@|~|=>
各种各样的 (变量)
圆锥 (施工人员)
典型值 -> 可变的(类型变量)
典型值 -> 圆锥(类型构造函数)
典型的 -> 圆锥(类型类)
修改后的 -> 圆锥(模块)
qvarid型 -> [修改日期]各种各样的
qconid码 -> [修改日期]圆锥
数量子 -> [修改日期]典型值
数量周期 -> [修改后]典型的
qvarsym公司 -> [修改日期]瓦尔西姆
q同义词 -> [修改日期]同源词
十进制的 -> 数字{digit}
八进制 -> 八位{八位}
十六进制 -> 六边形{六边形}
整数 -> 十进制的
| 0个八进制|0个八进制
| 0x个十六进制|0倍十六进制
浮动 -> 十进制的十进制[指数]
| 十进制指数
指数 -> (e(电子)|E类) [+|-]十进制
焦炭 -> '(图形<'|\>|空格|转义<\&>)'
一串 -> "{图形<"|\>|空格|转义|间隙}"
逃跑 -> \(charesc|ascii|十进制|o个八进制|x个十六进制)
查莱斯克 -> |b条|(f)|n个|第页|t吨|v(v)|\|"|'|&
ascii公司 -> ^中国核试验研究所|NUL(无)|SOH公司|STX公司|交易所交易系统|EOT公司|ENQ公司|确认
| BEL公司|英国标准|HT(高温)|低频|及物动词|截止日期|CR公司|SO公司||DLE公司
| 数据中心1|数据中心2|数据中心3|DC4公司|NAK公司|SYN(同步)|电子交易委员会|CAN总线
| 相对长度单位|潜艇|电子稳定控制系统|可行性研究|GS公司|RS系列|美国|服务提供商|DEL公司
中国核试验研究所 -> ascLarge|@|[|\|]|^|_
缺口 -> \whitechar{whitechar}\

9.3  布局

章节2.7对布局进行非正式讨论规则。本节对其进行了更精确的定义。

Haskell程序的含义可能取决于布局布局对其含义的影响可以通过添加由布局决定的位置中的大括号和分号。的含义这个增强程序现在对布局不敏感。

本节通过描述来说明布局的效果如何在下岗程序中添加大括号和分号。规范采用函数形式L(左)执行翻译的。输入到L(左)是:

词素的“缩进”是列号该词位的第一个字符;直线的缩进是其最左侧词汇的缩进。要确定列号,假定固定宽度的字体具有以下约定:

出于布局规则的目的,源程序中的Unicode字符被认为与ASCII字符具有相同的固定宽度。然而,为了避免视觉上的混乱,程序员应该避免在其中编写程序隐含布局的含义取决于非空格字符的宽度。

应用程序

L标记[]

提供对布局敏感的翻译代币,其中代币是对模块进行词汇分析并添加列编号的结果如上所述。定义L(左)如下所示,我们使用“:“作为一条小溪施工操作员,以及“[]“用于空流。

L(<n>:ts)(米:毫秒)= ;:(L ts(m:ms))如果m=n
= }:(L(<n>:ts)毫秒)如果n<m
L(<n>:ts)毫秒=L ts毫秒
L({n}:ts)(米:毫秒)= {:(L ts(n:m:ms))如果n>m(注1)
L({n}:ts)[]= {:(L ts[n])如果n>0(注1)
L({n}:ts)毫秒= {:}:(L(<n>:ts)毫秒)(注2)
L(左)(}:ts)(0:ms)= }:(L ts ms)(注3)
L(左)(}:ts)毫秒=解析错误(注3)
L(左)({:ts)毫秒= {:(L ts(0:ms))(注4)
L(t:ts)(米:毫秒)= }:(L(t:ts)毫秒)如果m/=0且解析错误(t)
(注5)
L(t:ts)毫秒=t:(L ts ms)
L[][]=[]
L[](米:毫秒)= }:L[]毫秒如果m/=0(注6)

注1。
嵌套上下文必须进一步缩进而不是封闭上下文(n> 米). 如果没有,L(左)失败,编译器应指示布局错误。例如:

f x=let
h y=let
p z=z
单位:p
单位:小时

这里,定义缩进量小于封闭上下文,在本例中由小时

注2。
如果哪里(说)没有缩进更多则块必须为空,因此为空插入支架。{n}标记替换为<n>,以模拟如果空大括号是显式的。

注释3。
通过匹配当前布局上下文的0,我们确保显式右大括号只能匹配显式左大括号。如果显式右大括号与隐式左大括号匹配,则会导致分析错误。

注释4。
此子句意味着所有大括号对都被视为显式布局上下文,包括标记的构造和更新(第节3.15). 这是该公式与Haskell 1.4之间的差异。

注释5。
次要条件解析错误(t)解释如下:如果到目前为止生成的令牌L(左)连同下一个令牌t吨表示Haskell语法的无效前缀到目前为止生成的令牌L(左)后跟标记“}"表示Haskell语法的有效前缀,然后解析错误(t)是真的。

测试m/=0检查隐式添加的右大括号是否匹配隐式开大括号。

注释6。
在输入的末尾,将插入任何挂起的close-brace。此时处于非布局上下文中是错误的(即。m=0).

如果上面给出的规则都不匹配,那么算法就会失败。可能会失败,例如,当到达输入的末尾时非布局上下文处于活动状态,因为缺少右大括号。一些算法没有检测到错误情况,尽管可以是:例如让}

注1实现了布局处理可以停止的功能过早地被解析错误。例如

设x=e;y=x in e’

是有效的,因为它翻译为

设e'中的{x=e;y=x}

由于上面的解析错误规则,右大括号被插入。解析错误规则很难完全通用,因为这样做涉及固定性。例如,表达式

做a==b==c

有一个明确的(尽管可能是输入不正确的)解析,即

(do{a==b})==c

因为(==)是非关联的。因此建议程序员避免编写需要解析器在其中插入右大括号的代码情况。

9.4  识字人评论

“文学评论”会议,首先由理查德·伯德和菲利普·沃德勒为奥威尔,又受到唐纳德·科努特的“识字者”的启发编程”是编码Haskell源代码的另一种方式代码。文字风格通过将注释设为默认值来鼓励注释。A类其中“>“是第一个字符被视为程序;所有其他行都是注释。

程序文本已恢复只取以“>", 并替换前导“>“带空格。布局和注释适用完全如第章所述9在结果文本中。

要捕获省略“>“错了,它是一个程序行出现在非空白注释行附近时出错,其中,如果一行仅由空白组成,则该行被视为空白。

按照惯例,注释的样式由文件指示扩展名,带“.hs(小时)“表示一个普通的Haskell文件".lhs“表示有文字的Haskell文件。使用此样式简单的阶乘程序是:

这个识字程序提示用户输入数字
并打印该数字的阶乘:

>主::IO()

>main=do putStr“输入数字:”
>l<-readLine(读取行)
>putStr“n!=”
>打印(事实(读l))
          
这是阶乘函数。

>事实::Integer->Integer
>事实0=1
>事实n=n*事实(n-1)

另一种文盲编程风格是适用于LaTeX文本处理系统。在这个惯例中,只有识字程序中完全封闭在\开始{code}...\结束{code}分隔符是视为程序文本;所有其他行都是注释。更准确地说:

没有必要在这些分隔符之前或之后插入额外的空行这在风格上可能是可取的。例如,

\文档样式{文章}

\开始{文档}

\章节{引言}

这是一个打印前20个阶乘的简单程序。

\开始{code}
主::IO()
main=打印[(n,产品[1..n])|n<-[1..20]]
\结束{代码}

\结束{文档}

此样式使用相同的文件扩展名。不建议混合这两种样式在同一个文件中。

9.5  上下文无关语法

模块 -> 模块modid[导出]哪里身体
| 身体
身体 -> {杂质;顶倾的}
| {杂质}
| {顶部倾斜}
杂质 -> impdecl公司1 ;...;impdecl公司n个 (n>=1)

出口 -> (出口1 ,...,出口n个[,]) (n>=0)
出口 -> qvar(量化变量)
| 数量子[(..)|(中国名称1 ,...,中国名称n个 )](n>=0)
| 数量周期[(..)|(qvar(量化变量)1 ,...,qvar(量化变量)n个 )](n>=0)
| 模块modid(修改)

impdecl公司 -> 进口[有资格的]modid(修改)[作为修改][impspec]
| (空声明)
impspec公司 -> (进口1 ,...,进口n个[,]) (n>=0)
| 躲藏 (进口1 ,...,进口n个[,]) (n>=0)
进口 -> 无功功率,无功功率
| 典型值[(..)|(中国名称1 ,...,中国名称n个 )](n>=0)
| 大亨[(..)|(无功功率,无功功率1 ,...,无功功率,无功功率n个 )](n>=0)
中国名称 -> var|con变量

顶部倾斜 -> 顶部倾斜1 ;...;顶部倾斜n个 (n>=0)
上倾斜的 -> 类型简单类型=类型
| 数据[上下文=>]简单类型=对比[衍生]
| 新类型[上下文=>]简单类型=newconst[派生]
| [正文=>]tycls类型变量[哪里cdecls]
| 实例[正文=>]qtycls指令[哪里idecls]
| 违约 (类型1 ,...,类型n个) (n>=0)
| 下降

下降 -> {下降1 ;...;下降n个 } (n>=0)
下降 -> gendecl(性别)
| (漏斗|pat0)相对湿度
cdecls公司 -> {调用约定1 ;...;调用约定n个 } (n>=0)
调用约定 -> 性别
| (funlhs|var)rhs
意大利语 -> {意大利语1 ;...;意大利语n个 } (n>=0)
意大利语 -> (funlhs|var)rhs
| (空)
性别 -> 变量::[上下文=>]类型(类型签名)
| 固定[整数]操作(固定性声明)
| (空声明)
操作 -> 操作1 ,...,操作n个 (n>=1)
变量 -> 无功功率,无功功率1 ,...,无功功率,无功功率n个 (n>=1)
固定性 -> 中缀|中缀|中缀

类型 -> b类型[->类型](功能类型)
b类型 -> [btype]类型(类型应用)
阿特ype -> gtycon公司
| 典型值
| (类型1 ,...,类型k个 ) (元组类型,k>=2)
| [类型] (列表类型)
| (类型) (带括号的构造函数)
gtycon公司 -> 数量子
| () (单元类型)
| [] (列出构造函数)
| (->) (函数构造函数)
| (,{,}) (tupling构造函数)
上下文 ->
| (1 ,...,n个 ) (n>=0)
-> qtycls类型
| 数量周期(典型值类型1…类型n个 ) (n>=1)
scontext(文本) -> 简单通行证
| (简单通行证1 ,...,简单通行证n个 ) (n>=0)
简单通行证 -> qtycls类型

简单类型 -> 典型值1…类型k个 (k>=0)
施工 -> 施工1 |...|施工n个 (n>=1)
施工 -> 犯罪[!]阿特ype1... [!]阿特ypek个 (arity con=k,k>=0)
| (b类型|!atype)conop(btype)|!atype)(中缀连音)
| 反对的论点{菲尔德代尔1 ,...,菲尔德代尔n个 } (n>=0)
新施工 -> con类型
| 反对的论点{无功功率,无功功率::类型}
菲尔德代尔 -> 变量::(类型|!atype)
衍生 -> 衍生(d类|(数据类1,...,数据类n个))(n>=0)
数据类别 -> 数量周期

安装 -> gtycon公司
| (gtycon类型1…类型k个 ) (k>=0,类型变量不同)
| (典型值1 ,...,典型值k个 ) (k>=2,类型变量不同)
| [典型值]
| (典型值1 ->典型值2 ) 泰瓦尔1和tyvar2不同的

漏斗 -> 变量apat{apat}
| 拍打i+1(输入+1)瓦洛普(a,i)拍打i+1(输入+1)
| 液化石油气瓦洛普(l,i)拍打i+1(输入+1)
| 拍打i+1(输入+1)瓦鲁普(r,i)无线功率放大器
| (漏斗)apat{apat}
相对湿度 -> =经验[哪里拒绝]
| gdrhs公司[哪里拒绝]
gdrhs公司 -> gd公司=经验[gdrhs]
gd公司 -> |经验0

经验 -> 经验0 ::[上下文=>]类型(表达式类型签名)
| 经验0
经验 -> 经验i+1(输入+1)【qop】(n,i)经验i+1(输入+1)]
| 列克斯普
| 再膨胀
lexp公司 -> (lexp|经验i+1(输入+1))qop(qop)(l,i)经验i+1(输入+1)
列克斯普6 -> -经验7
再膨胀 -> 经验i+1(输入+1)qop(qop)(r,i)(再膨胀|经验i+1(输入+1))
经验10 -> \阿帕特1…阿帕特n个 ->经验(lambda抽象,n>=1)
| 下降在里面经验(let表达式)
| 如果经验然后经验其他的经验(有条件)
| 案例经验属于 {备选方案} (case表达式)
| {stmts公司} (do表达式)
| 联邦快递
联邦快递 -> [fexp]aexp(功能应用)

aexp公司 -> qvar(量化变量)(变量)
| gcon公司(总建造师)
| 字面意义的
| (经验) (带括号的表达式)
| (经验1 ,...,经验k个 ) (元组,k>=2)
| [经验1 ,...,经验k个 ] (列表,k>=1)
| [经验1[,经验2]..[出口]] (算术序列)
| [经验|质量1 ,...,质量n个 ] (列表理解,n>=1)
| (经验i+1(输入+1)qop(qop)(a,i) ) (左侧部分)
| (列克斯普qop(qop)(l,i) ) (左侧部分)
| (qop(qop)(a,i)<->经验i+1(输入+1) ) (右侧部分)
| (qop(qop)(r,i)<->再膨胀 ) (右侧部分)
| 质量控制{fbind公司1 ,...,fbind公司n个 } (标记结构,n>=0)
| aexp公司<qcon> {fbind公司1 ,...,fbind公司n个 } (标记为更新,n>=1)

质量 -> 拍打<-经验(发电机)
| 下降(当地申报)
| 经验(防护装置)
备选方案 -> 中高音1 ;...;中高音n个 (n>=1)
中高音 -> 拍打->经验[哪里拒绝]
| 帕特·格德帕特[哪里拒绝]
| (空的备选方案)
格德帕特 -> gd公司->经验[gdpat]
stmts公司 -> 声明1…语句n个经验[;](n>=0)
声明 -> 经验;
| 拍打<-经验;
| 下降;
| ; (空语句)
fbind公司 -> qvar(量化变量)=经验

拍打 -> 无功功率,无功功率+整数(后继模式)
| 拍打0
拍打 -> 拍打i+1[qconop公司(n,i)拍打i+1(输入+1)]
| 液化石油气
| 无线功率放大器
液化石油气 -> (lpat)|拍i+1(输入+1))qconop公司(l,i)拍打i+1(输入+1)
液化石油气6 -> -(整数|浮点)(否定文字)
无线功率放大器 -> 拍打i+1(输入+1)qconop公司(r,i)(转/分/秒)|拍i+1(输入+1))
拍打10 -> 阿帕特
| gcon-apat1…阿帕特k个 (arity gcon=k,k>=1)

阿帕特 -> 无功功率,无功功率[@阿帕特](作为图案)
| gcon公司(arity gcon=0)
| qcon公司{英尺/平方英寸1 ,...,平板电视k个 } (标记图案,k>=0)
| 字面意义的
| _ (通配符)
| (拍打) (括号模式)
| (拍打1 ,...,拍打k个 ) (元组模式,k>=2)
| [拍打1 ,...,拍打k个 ] (列表模式,k>=1)
| ~阿帕特(无可辩驳的模式)
平板电视 -> qvar(量化变量)=拍打
gcon公司 -> ()
| []
| (,{,})
| qcon公司
无功功率,无功功率 -> 各种各样的|(varsym公司) (变量)
qvar(量化变量) -> qvarid型|(qvarsym公司) (限定变量)
反对的论点 -> 圆锥|(同源词) (建造师)
qcon公司 -> qconid码|(g同义词) (合格建造师)
瓦洛普 -> varsym | `varid(变量)`(可变运算符)
qvarop公司 -> qvarsym | `qvarid`(合格的变量运算符)
conop公司 -> 同义词`(施工操作员)
qconop公司 -> gconsym|`qconid`(合格的施工人员)
操作 -> varop|conop(操作员)
qop(qop) -> qvarop | qconop(合格操作员)
g同义词 -> :|q同义词


Haskell 98报告
顶部|后面|下一个|目录|功能索引
2002年12月