GF徽标

语法框架教程

阿内·兰塔

GF 3.2 2010年12月



概述

这是GF语法写作的实践入门。

GF的主要成分:

前提条件:

大纲

第1课:多语言“Hello World”语法。英语、芬兰语、意大利语。

第2课:食物领域的更大语法。英语和意大利语。

第3课:参数-形态和一致性。

第4课:使用资源语法库。

第5课:语义-依赖类型,变量绑定、和语义定义.

第6课:实现形式语言。

第7课:嵌入式语法应用程序。

第1课:GF入门

目标:

GF是什么

我们将GF一词用于三个不同的方面:

GF系统是GF编程语言的实现,而该语言又建立在GF理论的思想之上。

本教程的重点是使用GF编程语言。

同时,我们学习了GF理论中的思维方式。

我们使用GF系统使语法在计算机上运行。

GF语法和语言处理任务

GF程序称为语法.

语法定义了一种语言。

根据此定义,可以派生语言处理组件:

一般来说,GF语法是多语种的:

获取GF系统

开源免费软件,通过GF主页下载:

语法框架.org

你找到了

本教程中的许多示例包括联机.

通常你不需要自己编译GF。但是,如果您确实想从源代码编译GF,请遵循开发人员指南.

运行GF系统

类型玻璃纤维在Unix(或Cygwin)shell中:

%玻璃纤维

您将看到GF的欢迎信息和提示>.命令

>帮助

将为您提供可用命令的列表。

作为一种常见惯例,我们将使用

因此,您不应该键入这些提示,而应该只键入它们后面的字符。

“Hello World”语法

像大多数编程语言教程一样,我们从在终端上打印“Hello World”的程序开始。

其他功能:

程序:抽象语法和具体语法

一般来说,GF项目是多语言文法.其主要部件有

抽象语法定义了意思可以用语法表达

抽象语法的GF代码:

--“Hello World”语法abstract你好={flags startcat=问候语;猫问候;收件人;乐趣您好:收件人->问候语;世界,妈妈,朋友:收件人;}

代码包含以下部分:

英语具体语法(从意义到字符串的映射):

Hello的具体HelloEng={lincat问候语,收件人={s:Str};Hello recip={s=“Hello”++recip.s};世界={s=“世界”};妈妈={s=“妈妈”};朋友={s=“朋友”};}

该代码的主要部分包括:

请注意连接++和记录投影..

芬兰和意大利的具体语法:

Hello的具体HelloFin={lincat问候语,收件人={s:Str};Hello recip={s=“terve”++recip.s};世界={s=“maailma”};妈妈={s=“äiti”};朋友={s=“ystävät”};}Hello的具体HelloIta={lincat问候语,收件人={s:Str};Hello recip={s=“ciao”++recip.s};世界={s=“mondo”};妈妈={s=“妈妈”};朋友={s=“朋友”};}

在GF系统中使用语法

为了在GF中编译语法,我们创建了四个文件,每个模块一个,命名为模块名称.gf(平方英尺):

Hello.gf HelloEng.gf HelloFin.gf Hello意大利.gf

第一个GF命令:进口语法。

>导入HelloEng.gf

所有命令都有短名称;在这里:

>i Hello工程.gf

GF系统将编译将语法转换为内部表示,并显示CPU时间消耗情况,然后显示新的提示:

>i Hello工程.gf-编译Hello.gf…写入文件Hello.gfo 8毫秒-编译HelloEng.gf…写入文件HelloEng.gfo 12毫秒12毫秒>

您可以使用GF解析(解析=第页)

>解析“hello world”你好,世界

解析需要一个一串抽象语法树.

树的符号是功能应用程序:

函数参数1。..论据

括号仅用于分组。

解析不在语法中的内容将失败:

>解析“hello dad”解析程序在标记2处失败:“dad”>解析“world hello”找不到树

您还可以使用GF线性化(线性化=l).它把树变成了线:

>线性化Hello World你好,世界

翻译:线性化到解析:

>导入HelloEng.gf>导入HelloIta.gf>parse-lang=HelloEng“hello mum”|线性化-lang=HelloItaciao妈妈

语言标志的默认值(-朗):最后导入的具体语法。

多语言生成:

>parse-lang=HelloEng“hello friends”|线性化特威夫·伊斯特·瓦特友爱委员会你好,朋友们

线性化默认为所有可用语言。

Hello World语法练习

  1. 用不同的语言组合测试上面显示的解析和翻译示例以及其他一些示例。

  2. 扩展语法Hello.gf公司五个新的接受者和一个新的问候语形式的一些具体句法。

  3. 为您可能知道的其他一些语言添加具体语法。

  4. 添加一对问候语,用一种语言以一种相同的方式表达,用另一种语言的两种不同方式表达。例如,早上好下午好在英语中都表示为早上好意大利语。测试翻译时会发生什么早上好在GF学习英语。

  5. 在中插入错误你好例如,语法省略了一些行,省略了规则,或在变量的一次出现中更改名称。检查GF生成的错误消息。

使用GF外部的语法

您可以使用玻璃纤维Unix管道中的程序。

%echo“l你好世界”|gf HelloEng.gf Hello Fin.gf HelloIta.gf

您还可以编写脚本,一个包含行的文件

导入HelloEng.gf导入HelloFin.gf导入HelloIta.gf线性化Hello World

GF脚本

如果我们命名此脚本你好,gfs,我们可以做到

$gf—运行<hello.gfs乔蒙多特尔夫·迈尔玛你好,世界

选项--运行删除提示、CPU时间和其他消息。

请参见第7课对于不需要GF系统运行的独立程序。

练习(针对Unix黑客。)编写一个GF应用程序,从标准输入中读取英语字符串,并将意大利语翻译写入输出。

语法还能做什么

还将介绍其他一些功能:

嵌入式语法应用程序

应用程序,使用来自的技术第7课:

第2课:为复杂短语设计语法

目标:

抽象语法Food

用于谈论食物的短语:

抽象语法:

抽象食物={flags startcat=短语;短语;项目;种类;质量;乐趣是:项目->质量->短语;这个,那个:种类->项目;QKind:质量->种类->种类;葡萄酒、奶酪、鱼:种类;非常:质量->质量;新鲜、温暖、意大利、昂贵、美味、无聊:质量;}

例子短语

Is(This(QKind Delicious,QKind Italian Wine))(非常(非常昂贵))这种美味的意大利葡萄酒非常非常昂贵

具体语法FoodEng

具体食品工程={林肯猫短语,项目,种类,质量={s:Str};是项目质量={s=item.s++“Is”++quality.s};这种={s=“This”++kind.s};那种={s=“那种”++kind.s};QKind质量kind={s=quality.s++kind.s};葡萄酒={s=“葡萄酒”};奶酪={s=“奶酪”};鱼={s=“鱼”};非常质量={s=“非常”++quality.s};新鲜={s=“新鲜”};温暖={s=“温暖”};意大利语={s=“意大利语”};昂贵={s=“昂贵”};美味=“美味”;钻孔={s=“钻孔”};}

测试语法以进行分析:

>导入FoodEng.gf>解析“这款美味的葡萄酒非常意大利”Is(这款(QKind美味葡萄酒)(非常(非常意大利))

在其他类别中分析设置标志:

p-cat=种类“非常意大利葡萄酒”QKind(非常意大利)葡萄酒

食物语法练习

  1. 扩展食物通过十种新的食物种类和质量进行语法分析,并使用新种类的示例运行解析器。

  2. 添加启用表单问题短语的规则这是意大利奶酪吗.

  3. 启用带有单词“对不起,但是”的可选短语前缀。这样做时,前缀最多只能出现一次。

用于测试语法的命令

生成树和字符串

随机生成(generate_random=gr):build根据抽象语法构建随机树:

>生成_随机(这(QKind意大利鱼)新鲜吗

通过使用管道,可以将随机生成输入线性化:

>generate_random|线性化这条意大利鱼很新鲜

使用生成多棵树的标志:

>gr-数字=4|l那酒很无聊那块新鲜的奶酪很新鲜那奶酪很无聊这奶酪是意大利的

要生成全部的语法可以产生、使用的短语generate_trees=gt.

>generate_trees生成树那奶酪很意大利那个奶酪很无聊那奶酪很好吃...这酒很新鲜这酒很热

默认值深度为3;深度可以通过使用深度标志:

>generate_trees-深度=2|l

命令有哪些选项可以通过帮助=小时命令:

>帮助gr>帮助gt

生成练习

  1. 如果命令gt公司生成了语法中的所有树,它永远不会终止。为什么?

  2. 测量语法给出的深度分别为4和5的树数。提示。您可以使用Unix字数命令厕所计算行数。

有关管道的详细信息:跟踪

追踪选项-信托收据要查看其输出的每个命令:

>gr-tr|l-tr|p(这奶酪)无聊吗这个奶酪很无聊(这奶酪)无聊吗

用于测试目的:上面的管道可以显示语法是否模棱两可的,即包含可以以多种方式解析的字符串。

练习.扩展食物语法使其产生歧义字符串,并尝试歧义测试。

写入和读取文件

要将输出保存到文件中,请将其通过管道传输到write_file=wf命令,

>gr-number=10|线性化|写入文件-文件=exx.tmp

要将文件读取到GF,请使用读取文件=射频命令,

>read_file-file=exx.tmp-lines |解析

国旗-行告诉GF分别读取文件的每一行。

带示例的文件可用于回归测试语法-最系统的方法是树库;请参见在这里.

可视化树

括号给出了树的线性表示,对计算机很有用。

人眼可能更喜欢看到可视化效果:visualize_tree=vt:

>parse“这款美味的奶酪非常意大利”|visualize_tree

树是在postscript中生成的(.ps(磅))文件。这个-视图选项用于告诉要使用哪个命令查看文件。

这适用于Mac OS X:

>parse“这个美味的奶酪很意大利”|visualize_tree-view=open

在Linux上,可以使用以下命令之一。

>parse“这款美味的奶酪非常意大利”|visualize_tree-view=eog>parse“这个美味的奶酪很意大利”|visualizetree-view=xdg-open

此命令使用程序格拉夫维兹,您可能没有,但可以在网上免费获得。

您可以保存临时文件_grph.dot(英文),该命令及物动词生产。

然后可以使用程序(来自Graphviz包)。

%dot-Tpng _grph.dot>mytree.png

你也可以想象解析树,它显示类别和单词,而不是功能符号。命令是可视化解析=vp:

>parse“这款美味的奶酪非常意大利”|visualize_parse

系统命令

你可以给系统命令不离开GF:!然后是Unix命令,

>!dot-Tpng grphtmp.dot>mytree.png>!打开mytree.png

系统命令也可以从GF管道接收其参数。然后使用符号?:

>generate_trees-深度=4 |?wc-l型

此命令示例返回生成的树的数量。

练习.测量语法中有多少棵树食品工程深度分别为4和5。使用Unix字数命令厕所计算行数,以及从GF命令到Unix命令的系统管道数。

意大利语的具体句法

只需(?)用字典中的对等词替换英语单词:

食物的混凝土食物={林肯猫短语,项目,种类,质量={s:Str};是项目质量={s=item.s++“è”++质量.s};这种={s=“questo”++kind.s};那种={s=“quel”++kind.s};QKind质量kind={s=kind.s++quality.s};葡萄酒={s=“葡萄酒”};奶酪={s=“formaggio”};鱼={s=“佩斯”};非常质量={s=“molto”++quality.s};新鲜={s=“壁画”};温暖={s=“caldo”};意大利语={s=“italiano”};昂贵={s=“caro”};美味={s=“delizioso”};钻孔={s=“noioso”};}

不仅仅是替换单词:

质量的顺序及其修改的种类在

QKind质量kind={s=kind.s++quality.s};

意大利人这样说意大利酒对于意大利葡萄酒.

(一些意大利语形容词放在名词之前。这种区别可以由参数控制,这些参数在第3课.)

多语言语法还有另一个可视化选项:单词对齐,它显示了哪些单词相互对应。从技术上讲,这意味着在抽象语法中具有相同的最小生成子树的单词。命令是align_words=aw:

>解析“这美味的奶酪很意大利”| align_words

多语种练习

  1. 写一个具体的语法食物用于其他语言。你可能会以语法错误的线性化而告终,但现在不要担心。

  2. 如果你写了食物对于德语、瑞典语或其他语言,用随机或详尽的生成测试出哪些结构不正确,并准备一个列表,列出那些当前可用的GF片段无法帮助的结构。您可以在完成后返回列表第3课.

自由变化

语义上无法区分的表达方式。

这个变体GF结构表达自由变异。例如,

lin Delicious={s=“美味”|“精致”|“美味”};

默认情况下使线性化命令仅显示此类列表中的第一个变量;要查看全部内容,请使用选项-全部:

>p“这款精致的葡萄酒非常美味”这种美味的葡萄酒很美味这种美味的葡萄酒很精致...

变量的等效符号为

lin Delicious=变体{“美味”;“精致”;“美味”}};

这种符号也允许极限情况:空变量列表,

变体{}

例如,如果一个单词缺少某种屈折形式,就可以使用它。

自由变体适用于具体语法中的所有类型;变量列表中的所有术语必须是同一类型。

多语言文法的更多应用

多语言树库

多语言树库:一组树及其在不同语言中的线性化:

>gr-number=2 | l-树库是(那奶酪)(很无聊)quel formaggioèmolto noioso公司那奶酪很无聊(那奶酪)新鲜吗《壁画》那奶酪是新鲜的

翻译测验

翻译测验=tq:生成随机句子,用一种语言显示,并检查用户用另一种语言给出的答案。

>translation_quish-from=FoodEng-to=FoodIta欢迎参加GF翻译测验。当你至少做了10个例子后,测验就结束了成功率至少为75%。您可以通过输入由点(“.”)组成的行来中断测验。这条鱼很热请求>是的。分数1/1这奶酪是意大利的探索formaggioènoioso>不,不是要求格式化noioso,但是意大利足球队得分1/2这条鱼很贵

无上下文语法与GF

“cf”语法格式

语法食品工程可以用BNF格式编写,如下所示:

Is.Phrase::=项“是”质量;那。项目::=“那”类;这个。项目::=“本”类;QKind公司。种类::=质量种类;奶酪。种类::=“奶酪”;鱼。种类::=“鱼”;葡萄酒。种类::=“葡萄酒”;意大利语。质量::=“意大利”;真无聊。质量::=“无聊”;美味可口。质量::=“美味”;价格昂贵。质量::=“昂贵”;新鲜。质量::=“新鲜”;非常。质量::=“非常”质量;温暖。质量::=“温暖”;

GF可以将BNF语法转换为GF。BNF文件由文件名后缀识别/cf(用于无上下文的):

>导入食品.cf

编译器在内部创建独立的抽象模块和具体模块。

上下文无关文法的限制

将具体语法和抽象语法分开会导致与上下文无关语法的三种偏差:

练习.定义非文本自由复制语言{x|x<-(a|b)*}在GF中。

模块和文件

GF使用后缀识别不同的文件格式:

导入将从源生成目标:

>i食品工程.gf-编译Food.gf…写入文件Food.gfo 16毫秒-编译FoodEng.gf…写入文件FoodEng.gf 20毫秒

这个.gfo型格式(=“GF对象”)是预编译的GF,加载速度比源GF快(.gf(平方英尺)).

读取模块时,GF决定是否使用现有的.gfo型文件或通过查看修改时间生成新文件。

练习。导入时会发生什么食品工程.gf第二次?在不同的情况下尝试:

使用操作和资源模块

操作定义

功能编程的黄金法则:

每当你发现自己是通过复制和粘贴来编程的时候,就写一个函数来代替。

使用关键字定义具体语法中的函数操作人员(用于操作),不同于乐趣为了清楚起见。

例子:

操作步骤:Str->{s:Str}=\x->{s=x};

操作可以是应用一场争论,GF会计算值:

ss“男孩”===>{s=“男孩”}

符号===>将用于计算。

请注意λ抽象形式

内容如下:

对于具有多个参数的lambda抽象,我们有一个简写

\x、 y->t===\x->y->t

线性化规则实际上使用语法糖进行抽象:

lin f x=t==lin f=\x->t

``resource``模块类型

这个资源模块类型用于打包操作人员定义为可重用资源。

资源StringOper={操作人员SS:类型={s:Str};ss:Str->ss=\x->{s=x};抄送:SS->SS->SS=\x,y->SS(x.s++y.s);前缀:Str->SS->SS=\p,x->SS(p++x.s);}

打开资源

任意数量的资源模块可以是打开a中的ed混凝土语法。

混凝土FoodEng of Food=打开StringOper{林肯猫S、 项目、种类、质量=SS;Is item quality=cc item(前缀“Is”quality);This k=前缀“This”k;k=前缀“That”k;QKind k q=cc k q;Wine=ss“葡萄酒”;奶酪=ss“奶酪”;Fish=ss“Fish”;Very=前缀“Very”;新鲜=ss“新鲜”;暖=ss“暖”;意大利语=ss“意大利语”;昂贵=ss“昂贵”;美味=ss“美味”;钻孔=ss“钻孔”;}

部分应用

规则

lin This k=前缀“This”k;

可以写得更简洁

lin This=前缀“This”;

函数编程的艺术之一:决定函数中参数的顺序,以便尽可能多地使用部分应用程序。

例如,前缀通常应用于具有常量字符串的线性化变量。因此,我们将Str公司参数之前的不锈钢参数。

练习.定义操作中缀类似于前缀,这样你就可以写

lin Is=中缀“Is”;

测试资源模块

带标志导入-保留,

>导入-保留StringOper.gf

使用计算值compute_concrete=立方厘米,

>compute_concrete前缀“in”(ss“addition”){s:Str=“in”++“addition”}

语法体系结构

扩展语法

新模块可以延伸一个旧的:

abstract更多食物=食物**{问题;乐趣QIs:项目->质量->问题;披萨:种类;}

与抽象语法类似,可以为具体语法构建扩展:

混凝土MorefoodEng of Morefood=食品工程**{林肯猫问题={s:Str};QIs项目质量={s=“is”++item.s++quality.s};披萨={s=“披萨”};}

扩展的效果:将扩展模块和扩展模块的所有内容放在一起。

换句话说:新模块继承旧模块的内容。

同时延伸和打开:

concrete MorefoodIta of Morefood=FoodIta**在中打开StringOper{林肯猫问题=SS;QIs项目质量=ss(item.s++“è”++quality.s);披萨=ss“披萨”;}

资源模块可以扩展其他资源模块,因此可以构建资源层次结构。

多重继承

同时扩展多个语法:

abstract Foodmarket=食品、水果、蘑菇**{乐趣水果种类:水果->种类;蘑菇种类:蘑菇->种类;}

哪里

抽象水果={猫果;有趣的苹果,桃子:水果;}抽象蘑菇={猫蘑菇;fun Cep,木耳:蘑菇;}

练习.重构食物通过拆开葡萄酒变成特别的喝酒模块。

第3课:带参数的语法

目标:

可以跳过本章直接进入下一章,因为GF资源语法库的使用使得不必使用参数:它们可以留给库实现者。

问题是:单词必须有屈折变化

像这样的东西需要复数形式

这些意大利葡萄酒很美味

这需要两件事:

不同的语言有不同的屈折变化和一致性。

在多语言语法中,我们希望忽略抽象语法中的这种区别。

练习列出一些你知道的语言中名词、形容词和动词的可能形式。

参数和表格

我们定义参数类型用一种新的判断形式表示英语中的数字:

param编号=Sg|Pl;

该判断定义了参数类型编号通过列出其两个施工人员,Sg公司Pl公司(单数和复数)。

我们给予种类具有桌子取决于数量:

lincat种类={s:Number=>Str};

这个肉用 数量=>Str类似于函数类型(编号->Str).

差异:参数必须是参数类型。然后,可以在有限表中列出参数-值对。

这里有一张桌子:

lin奶酪={s=表格{Sg=>“奶酪”;Pl=>“奶酪”}} ;

桌子上有分支,带有图案在箭头的左边=>和a价值在右边。

表的应用程序由选择操作人员!.

其计算公式为模式匹配:返回模式与参数匹配的第一个分支的值。例如,

表{Sg=>“奶酪”;Pl=>“芝士”}!Pl公司===>“奶酪”

Case表达式是语法糖:

{…}===表{…{的大小写e!e(电子)

由于Haskell和ML程序员都很熟悉它们,所以在编写GF程序时它们会很方便。

构造函数可以从其他参数类型获取参数。

示例:英语动词的形式(除):

param VerbForm=VPresent编号|VPast|VPastPart|VPresPart;

事实表明:只有现在时才有数字变化。

示例表:动词的形式:

表格{VPresent Sg=>“饮料”;VPresent Pl=>“饮料”;VPast=>“喝了”;VPastPart=>“醉酒”;VPresPart=>“饮酒”}

练习在前面的练习(上一节)中,您列出了一些您知道的语言中名词、形容词和动词可能的形式。现在获取一些结果,并使用参数类型定义和表实现它们。将它们写入资源模块,您可以使用命令对其进行测试计算机_混凝土.

弯曲表和范例

形态学范式是一个公式,用来说明一类单词是如何屈折的。

从GF的观点来看,范式是一个需要引理(也称为字典形式,或引文格式)并返回一个变形表。

以下操作定义了英语的常规名词范式:

操作注册名:Str->{s:Number=>Str}=\dog->{s=表格{Sg=>狗;Pl=>狗+“s”}} ;

这个胶合操作人员+将字符串粘贴到一个代币:

(regNoun“奶酪”).s!Pl===>“奶酪”+“s”====“奶酪”

一个更复杂的例子:正则动词,

操作regVerb:Str->{s:VerbForm=>Str}=\talk->{s=表格{VPresent Sg=>对话+“s”;VPresent Pl=>对话;VPresPart=>通话+“ing”;_=>谈话+“ed”}} ;

过去时态和过去分词的catch-all大小写使用通配符图案_.

形态学练习

  1. 确定以下情况注册名称范式不适用于英语,并实现了一些替代范式。

  2. 为您在前面的练习中考虑过的其他语言实现一些常规范例。

在具体语法中使用参数

目的:语言之间的一种更激进的变化,而不仅仅是使用不同的单词和词序。

我们增加了语法食物构成复数项目的两个规则:

有趣的这些,那些:种类->项目;

我们还添加了一个在意大利语中具有女性格的名词:

趣味披萨:亲切;

这将迫使我们处理性别问题-

协议

在英语中,短语构成规则

乐趣在于:项目->质量->短语;

受数字影响的原因是主题-verb协议:句子的动词在主语的数量上必须有屈折变化,

(这个披萨)热吗===>“这个披萨热”(这些披萨)暖和吗===>“这些披萨暖和”

它是连接线(动词)受影响的:

操作连接词:数字->字符串=\n->第n种情况,共种情况{Sg=>“是”;Pl=>“是”} ;

这个主题 项目必须有这样一个数字以提供给copula:

lincat项={s:Str;n:Number};

现在我们可以写了

lin是item qual={s=item.s++连接词item.n++qual.s};

决定性因素

如何项目受试者收到号码了吗?规则

有趣的是,这些:种类->项目;

添加限定词,或者这些,需要不同的这个披萨与。这些披萨.

因此种类必须具有单数和复数形式:

lincat种类={s:Number=>Str};

我们可以写

lin这种={s=“this”++种类.s!Sg;n=Sg} ;lin这些种类={s=“这些”++种类.s!Pl;n=Pl} ;

为了避免复制和粘贴,我们可以找出决定的模式,

操作检测:Str->Number->{s:Number=>Str}->{s:Str;n:Number}=\det,n,种类->{s=det++kind.s!n;n=n} ;

现在我们可以写了

lin This=det Sg“This”;lin这些=det Pl“这些”;

在更多词汇化语法,限定词将是一个类别:

lincat Det={s:Str;n:Number};乐趣探测:探测->种类->物品;lin Det Det种类={s=det.s++种类.s!详细信息;n=测定值} ;

参数化与固有特征

种类s的编号为参数化特征:可以构成单数和复数,

lincat种类={s:Number=>Str};

项目s的编号为固有特征:它们本质上是单数或复数,

lincat项={s:Str;n:Number};

意大利人种类将具有参数编号和固有性别:

lincat种类={s:Number=>Str;g:性别};

设计参数时要问的问题:

字典给出了很好的建议:

uomo公司,邮政编码:。uomini公司,n.m.“男子”

告诉我们uomo公司是复数形式的阳性名词uomini公司因此,参数数和固有性别。

对于单词,固有特征通常作为词汇信息给出。

对于组合,它们是继承从结构的某些部分(通常称为).意大利修改:

lin QKind等于种类=让gen=kind.g{s=表{n=>kind.s!n++等于s!gen!n};g=发电机} ;

通知

带参数的Foods的英语具体语法

我们使用库中的一些字符串操作前奏曲使用。

concrete FoodsEng of Foods=开放式前奏曲{林肯猫S、 质量=SS;种类={s:Number=>Str};项目={s:Str;n:数字};项目质量=ss(item.s++copula-item.n++quality.s);This=det Sg“This”;That=det Sg“That”;这些=det Pl“这些”;那些=det Pl“那些”;QKind质量kind={s=表{n=>quality.s++kind.s!n}};葡萄酒=regNoun“葡萄酒”;奶酪=regNoun“奶酪”;Fish=名词“Fish”;披萨=regNoun“披萨”;Very=前缀SS“Very”;新鲜=ss“新鲜”;暖=ss“暖”;意大利语=ss“意大利语”;昂贵=ss“昂贵”;美味=ss“美味”;钻孔=ss“钻孔”;

参数编号=Sg|Pl;操作人员det:编号->Str->{s:Number=>Str}->{s:Str;n:编号}=\n、 d,cn->{s=d++cn.s!n;n=n} ;名词:Str->Str->{s:Number=>Str}=\男,男->{s=表{Sg=>人;Pl=>男性}} ;regNoun:Str->{s:Number=>Str}=\car->名词car(car+“s”);连接词:数字->字符串=\n->第n种情况{Sg=>“是”;Pl=>“是”} ;}

关于屈折范式的更多信息

让我们扩展英语名词范式,以便我们能够处理所有名词,而不仅仅是常规名词。其目标是提供一个形态学模块,使向词典中添加单词变得容易。

最坏情况函数

我们执行数据抽象从名词的类型看写a最坏情况函数:

操作名词:类型={s:Number=>Str};操作mkNoun:Str->Str->Noun=\x,y->{s=表格{Sg=>x;Pl=>y}} ;操作regNoun:Str->Noun=\x->mkNoun x(x+“s”);

然后我们可以定义

lincat N=名词;lin Mouse=mkNoun“Mouse”“mices”;lin House=regNoun“House”;

其中看不到底层类型。

我们可以自由更改未定义的定义,例如添加案例(主格或属格)到名词的屈折变化:

param Case=Nom|Gen;操作名词:类型={s:Number=>Case=>Str};

现在我们必须重新定义最坏情况函数

操作mkNoun:Str->Str->Noun=\x,y->{s=表格{Sg=>表格{标称值=>x;Gen=>x+“s”} ;Pl=>表格{标称值=>y;Gen=>y+案例最后一个y{“s”=>“”;_=>“的”}}} ;

但从这个层面上来说,我们可以保留旧的定义

lin Mouse=mkNoun“Mouse”“mices”;操作regNoun:Str->Noun=\x->mkNoun x(x+“s”);

在最后一个定义中mk名称,我们在复数的最后一个字符上使用了case表达式,以及前奏曲操作

last:Str->Str;

返回由最后一个字符组成的字符串。

case表达式使用字符串上的模式匹配GF中支持,以及参数上的模式匹配。

聪明的范例

普通人-范式有可预测的变化:

我们可以提供其他范例:

noun_y:Str->noun=\fly->mkNoun-fly(init-fly+“ies”);noun_s:Str->noun=\bus->mkNoun-bus(总线+“es”);

(前奏曲功能初始化删除标记的最后一个字符。)

缺点:

更好的解决方案:a智能范式:

regNoun:Str->名词=\w->ws:Str=案例w,共个{_+(“a”|“e”|“i”|“o”)+“o”=>w+“s”;——竹子_+(“s”|“x”|“sh”|“o”)=>w+“es”;——巴士,英雄_+“z”=>w+“zes”;--测验_+(“a”|“e”|“o”|“u”)+“y”=>w+“s”;--男孩x+“y”=>x+“ies”;--飞_=>w+“s”--汽车}在里面mkNoun与ws

GF有正则表达式模式:

模式的排序方式如下:例如,后缀“哦”阻止竹子从匹配后缀“o”.

规则模式练习

  1. 英语复数名词的构成规则同样适用于第三人称单数动词的构成。写一个使用这个想法的常规动词范例,但首先要重写注册名称因此分析需要建立-表单被分解为单独的操作人员,与共享regVerb(正则动词).

  2. 扩展动词范例,涵盖英语中的所有动词形式,特别注意后缀的变化预计起飞时间(例如。尝试-尝试,使用-习惯于).

  3. 实施德语乌姆劳特词干操作。该操作改变了重音干音节的元音,如下所示:ä,澳大利亚阿乌,o个ö、和u个ü。您可以假设该操作仅将音节作为参数。测试操作以查看其是否正确更改阿尔茨阿瓦尔扎特,鲍姆Bäum村,顶部(Topf)特普夫、和库赫库赫.

带变量的函数类型

第5课,相关函数类型需要一个将变量绑定到参数类型的符号,如

关闭:(k:种类)->操作k

函数类型没有变量实际上是一种简写:

预处理VP:NP->VP->S

方法

PredVP:(x:NP)->(y:VP)->S

或变量的任何其他命名。

有时变量会缩短代码,因为它们可以共享一个类型:

八元组:(x,y,z,u,v,w,s,t:Str)->Str

如果未使用绑定变量,可以用通配符替换:

八元组:(_,_,_

一个好的做法是指出参数的数量:

八倍:(x1,_,_,__,_,,_,x8:Str)->Str

对于屈折范式,使用启发式变量名很方便,看起来像预期的形式:

mkNoun:(鼠标,鼠标:Str)->名词

分离操作类型和定义

在库中,将类型签名与定义分开分组是很有用的。可以将操作人员判断,

oper regNoun:Str->Noun;oper regNoun s=mkNoun s(s+“s”);

把零件放在不同的地方。

使用接口实例模块类型(请参见在这里):零件甚至可以放在不同的文件中。

操作过载

超载:不同的函数可以使用相同的名称,例如在C++中。

编译器执行过载解决方案,只要函数具有不同的类型就可以工作。

在GF中,功能必须分组在一起超载组。

示例:英语中定义名词的不同方式:

oper mkN:过载{mkN:(dog:Str)->名词;--正则名词mkN:(小鼠,小鼠:Str)->名词;--不规则名词}

查字典:如果单词是规则的,只需要一种形式。如果是不规则的,则给出更多形式。

定义可以单独给出,也可以与类型同时给出:

操作mkN=过载{mkN:(dog:Str)->名词=regNoun;mkN:(小鼠,小鼠:Str)->名词=mkNoun;}

练习设计一个由超载组呈现的英语动词范例系统。

形态学分析和形态学测验

命令morpho_analyse=ma可用于阅读文本并返回每个单词的分析结果(在当前语法中):

>read_file bible.txt |形态分析

命令morpho_quiz=mq生成屈折练习。

%gf所有时态/不规则Fre.gfo>morpho_quiz-类别=V欢迎参加GF形态学测验。...设备:VFin VCondit Pl P2简历>不,不是简历,但简历得分0/1

意大利食品语法

参数不仅包括数字,还包括性别。

混凝土食品Ita of Foods=开场前奏曲{参数编号=Sg|Pl;性别=Masc|Fem;

质量因性别和数量而发生变化,而种类有参数数字和固有性别。物品具有固有的数量和性别。

林肯猫Phr=不锈钢;质量={s:性别=>数量=>Str};种类={s:Number=>Str;g:性别};项目={s:Str;g:性别;n:数字};

Quality是一个形容词,每种性别数字组合都有一种形式。

操作人员形容词:(_,_,_:Str)->{s:性别=>数字=>Str}=\尼禄、尼拉、尼瑞、尼雷->{s=表格{马斯克=>表{Sg=>尼禄;Pl=>内里} ;Fem=>表格{Sg=>nera;Pl=>内尔}}} ;

正规形容词的作用是在词干上加上词尾。

regAdj:Str->{s:性别=>号码=>Str}=\nero->设ner=init-nero形容词nero(ner+“a”)(ner+”i”)(ner+”e”);

对于名词屈折变化,我们很乐意明确给出两种形式和性别:

名词:Str->Str->Gender->{s:Number=>Str;g:Gender}=\葡萄酒,葡萄酒,g->{s=表格{Sg=>葡萄酒;Pl=>葡萄酒} ;g=克} ;

我们只需要copula的数值变化。

连接词:数字->字符串=\n->第n种情况{Sg=>“è”;Pl=>“sono”} ;

由于性别的原因,决定比英语更复杂:

det:数字->字符串->字符串->{s:数字=>字符串;g:性别}->{s:Str;g:性别;n:数字}=\n、 m、f、cn->{s={Masc=>m的案例cn.g;Fem=>f}++cn.s!n;g=cn.g;n=n} ;

整套线性化规则:

是否为项目质量=ss(item.s++连接词item.n++质量.s!item.g!item.n);这=确定Sg“questo”“questa”;那就是det Sg“quel”“quella”;这些=det Pl“questi”“queste”;这些=det Pl“quei”“quelle”;QKind质量种类={s=\\n=>种类.s!n++质量.s!好样的。g!n;g=种类.g} ;葡萄酒=名词“vino”“vini”Masc;奶酪=名词“formaggio”“formagji”Masc;Fish=名词“pesce”“pesci”Masc;Pizza=名词“Pizza”“pizze”Fem;非常相等={s=\\g,n=>“molto”++qual.s!g!n};新鲜=形容词“fresco”“fresca”“fresschi”“fresche”;暖=regAdj“caldo”;意大利语=regAdj“italiano”;昂贵=regAdj“caro”;美味=regAdj“delizioso”;钻孔=regAdj“noioso”;}

使用参数的练习

  1. 食品语法。

  2. 在语法中添加词条、性质和限定词,并尝试正确处理它们的屈折变化和固有特征。

  3. 写一个具体的语法食物对于您选择的语言,现在的目标是通过使用参数实现完全的语法正确性。

  4. 测量对应于的上下文无关语法的大小食品Ita。您可以通过以无上下文格式打印语法来完成此操作(print_grammar-打印机=bnf)并计算行数。

不连续成分

线性化记录可能包含多个字符串,并且这些字符串可以在线性化中分开。

例如:英语助词动词(关闭).对象可以出现在以下两者之间:

他把它关掉了

动词关闭称为不连续成分.

我们可以如下定义及物动词及其组合:

lincat V2={s:Number=>Str;部分:Str};有趣的AppV2:项目->V2->项目->短语;lin AppV2 subv v2对象={s=主题s++v2.s!主题n++obj.s++v1.part};

练习.定义语言a ^n b ^n c ^n在GF中,即任何数量的的后面跟相同数量的b条的和相同数量的c(c)的。这种语言不是无上下文的,但可以通过使用不连续成分在GF中定义。

编译时的字符串与运行时的字符串

令牌的创建方式如下:

编译时必须知道标记,上述操作可能不适用于运行时变量(即在线性化规则中代表函数参数的变量)。

因此,书写是不合法的

猫名词;趣味复数:名词->名词;lin复数n={s=n.s+“s”};

因为n个是一个运行时变量。阿尔索

lin复数n={s=(regNoun n).s!Pl};

与不正确注册名称按定义在这里,因为运行时变量最终被发送到字符串模式匹配和粘合。

如何在没有空格的情况下将标记写在一起?

lin问题p={s=p+“?”};

不正确。

方法是使用未经授权的人这样可以在线性化后创建正确的间距。

相应地列克瑟例如分析“暖和吗?”解析之前需要into到tokens。本主题将在中介绍在这里.

具体语法的补充结构

记录扩展名和子类型

符号**用于记录类型和记录对象。

lincat V2=动词**{c:Case};lin Follow=regVerb“folgen”**{c=Dative};

第2版(及物动词)变成子类型属于动词.

如果T型是的子类型R(右),的对象T型可以在以下情况下使用R(右)是必需的。

协方差:返回记录的函数T型as值还可以用于返回超类型的值R(右).

矛盾:函数采用R(右)as参数也可以应用于子类型的任何对象T型.

元组和产品类型

产品类型和元组是记录类型和记录的语法糖:

T1*。..*Tn==={p1:T1;…;pn:Tn}<t1。..,tn>==={p1=T1;…;pn=tn}

因此,标签第1页、第2页、,。..是硬编码的。

前缀相关选项

英语不定冠词:

操作artIndef:Str=预(pre){(“a”|“e”|“i”|“o”)=>“an”;_=>“a”} ;

因此

artIndef++“奶酪”--->“a”++“奶酪”artIndef++“苹果”--->“一个”++“苹果“

第4课:使用资源语法库

目标:

图书馆的覆盖面

当前的16种资源语言(GF 3.2版,2010年12月)是

前三个字母(工程等)用于语法模块名称(ISO 639-3标准)。

图书馆的结构

语义语法(到目前为止在本教程中):语法定义了一个意义系统(抽象语法),并告诉它们是如何表达的(具体语法)。

资源语法(一如语言学传统):语法指定语法正确的单词组合,不管它们的含义是什么。

使用资源语法,我们可以实现比使用语义语法更广泛的覆盖范围。

词汇与短语规则

资源语法有两种类别和两种规则:

通用电气没有对这两种产品进行正式区分。

但这是一个很好的纪律。

词汇类别

两种词汇类别:

词汇规则

封闭类:模块语法。在食品语法,我们需要

this_Det、that_Det、these_Det、those_Det:Det;very_AdA:广告;

命名约定:单词后跟类别(因此我们可以区分量词那个从连词那个).

打开的类中没有对象语法。单词是根据应用程序的需要构建的:如果我们有

趣味葡萄酒:亲切;

我们将定义

lin Wine=mkN“葡萄酒”;

我们使用的位置mkN(百万牛顿)范例工程:

资源词典

的替代具体语法

有趣的葡萄酒:种类;

是为了提供资源词典,其中包含以下定义

oper-wine_N:N=mkN“葡萄酒”;

这样我们就可以写了

lin Wine=葡萄酒_N;

优势:

短语类别

食品,我们只需要四个短语类别:

氯;--子句,例如“这个披萨很好”NP;--名词短语,例如“this pizza”中国;--常见名词,例如“温暖的比萨饼”AP;--形容词短语,例如“非常温暖”

子句与句子相似(S公司)但没有固定的时态和情绪;参见在这里了解它们之间的关系。

普通名词通过添加限定词而成为名词短语。

句法组合

我们需要以下组合:

mkCl:NP->AP->Cl;——例如“这个披萨很热”mkNP:Det->CN->NP;--例如“这个披萨”mkCN:亚太->中国->中国;--例如“热披萨”mkAP:AdA->AP->AP;--例如“非常温暖”

我们还需要词汇插入,用单个单词组成短语:

mkCN:N->CN;mkAP:A->AP;

命名约定:构造C类,使用函数百万C类.

重载:当前库(1.2版)有23个名为mkNP公司!

句法组合示例

这句话

这些非常暖和的披萨是意大利的

可以按如下方式构建:

mkCl公司(mkNP主题集(mkCN(mkAP very_AdA(mkAP warm_A))(mkCN pizza_N))(mkAP意大利语_AP)

现在的任务是:定义食品因此,该语法树给出了将语义树线性化的值

这些(QKind(非常温暖)披萨)是意大利语吗

资源API

特定于语言和独立于语言的部分——大致来说,

在线完整API文档:资源概要,

语法框架.org/lib/doc/synopsis.html

微型资源API:类别

类别

解释

例子

从句(句子),带所有时态

她看着这个

AP公司

形容词短语

非常温暖

中国

普通名词(无限定词)

红色房屋

NP公司

名词短语(主语或宾语)

红色的房子

AdA公司

形容词修饰副词,

非常

Det公司

测定器

这些

A类

一位形容词

温暖的

N个

普通名词

房子

小型资源API:规则

功能

类型

例子

mkCl公司

NP->AP->Cl

约翰很老了

mkNP公司

Det->CN->NP

这些老人

mkCN公司

N->中国

房子

mkCN公司

亚太地区->中国->中国

非常大的蓝色房子

mkAP公司

A->应付账款

古老的

mkAP公司

广告->AP->AP

非常非常古老

小型资源API:结构词

功能

类型

英语

this_Det(设置)

Det公司

那_Det

Det公司

那个

这些设置(_D)

Det公司

those_Det(设置)

Det公司

那个

每个_广告

AdA公司

非常

小型资源API:范例

发件人范例工程:

功能

类型

mkN(百万牛顿)

(狗:Str)->N

mkN(百万牛顿)

(男,男:Str)->N

万卡

(冷:Str)->A

发件人范例ITA:

功能

类型

mkN(百万牛顿)

(葡萄酒:Str)->N

万卡

(卡罗尔:斯特尔)->A

小型资源API:更多范例

发件人范式Ger:

功能

类型

性别

类型

男性的

性别

女性的

性别

中性的

性别

mkN(百万牛顿)

(Stufe:Str)->N

mkN(百万牛顿)

(图片,Bilder:Str)->性别->N

万卡

(克莱因:Str)->A

万卡

(内脏、贝塞尔、贝斯特:Str)->A

发件人ParadigmsFin示例:

功能

类型

mkN(百万牛顿)

(目录:Str)->N

mkA公司

(高度:Str)->A

练习

1.尝试不同语言中的形态范例。执行以下操作:

>i-path=所有时态-保留所有时态/ParadigmsGer.gfo>cc-表mkN“Farbe”>cc-表mkA“gut”“besser”“bester”

示例:英语

我们假设抽象语法食品第3课.

我们不需要考虑屈折变化和一致性,只需从资源语法库中选择函数即可。

我们需要一条

因此,模块的开头是

--#-路径=。:../食物:存在concrete FoodsEng of Foods=开放语法Eng,ParadigmsEng in{

英文示例:线性化类型和组合规则

作为线性化类型,我们使用子句短语,名词短语项目,的常用名词种类,和形容词短语质量.

林肯猫短语=Cl;项目=NP;种类=CN;质量=AP;

现在,我们几乎需要自动编写组合规则:

项目质量=mkCl项目质量;This kind=mkNP This_Det kind;That kind=mkNP That_Det kind;这些种类=mkNP These_Det种类;那些种类=mkNP Those_Det种类;QKind质量种类=mkCN质量种类;非常质量=mkAP Very_AdA质量;

英语示例:词汇规则

我们使用资源范式和词汇插入规则。

两位名词范式只需要一次,因为-其他一切都是有规律的。

葡萄酒=mkCN(mkN“葡萄酒”);披萨=mkCN(mkN“披萨”);奶酪=mkCN(mkN“奶酪”);鱼=mkCN(mkN“鱼”“鱼”);新鲜=mkAP(mkA“新鲜”);暖=mkAP(mkA“暖”);意大利语=mkAP(mkA“意大利语”);昂贵=mkAP(mkA“昂贵”);美味=mkAP(mkA“美味”);钻孔=mkAP(mkA“钻孔”);}

英语示例:练习

1.编译语法食品工程生成并解析一些句子。

2.写一个具体的语法食品意大利语或资源库中包含的其他语言。您可以将结果与本教程前面介绍的手写语法进行比较。

多语言文法的函数实现

通过复制和粘贴实现新语言

如果你写一个具体的语法食品对于其他语言,大部分代码看起来与英语完全相同。这是因为

但词汇规则更依赖于语言。

因此,要将语法移植到新语言,您需要

  1. 复制给定语言的具体语法
  2. 改变单词(字符串和屈折变化模式)

我们可以通过复制和粘贴来避免这种编程吗?

函数:模块级的函数

函子熟悉函数式编程语言ML和OCaml,也称为参数化模块.

在GF中,函子是一个模打开是一个或多个接口.

接口是类似于资源,但它只包含类型属于操作人员s、 不一定是他们的定义。

functors的语法:添加关键字不完整的。我们将使用标题

不完整的具体食品I of Foods=开放语法,LexFoods in

哪里

接口语法——资源语法接口接口LexFoods——领域词典接口

此外,当我们

语法的实例语法——英语资源语法LexFoods的实例LexFood Eng——英语领域词典

我们可以写一个函子实例化,

食物的具体食物=食物(语法=SyntaxGer),(LexFoods=LexFoodesGer);

Foods函数的代码

--#-路径=。:../食物不完整的具体食品I of Foods=开放语法,LexFoods in{林肯猫短语=Cl;项目=NP;种类=CN;质量=AP;项目质量=mkCl项目质量;This kind=mkNP This_Det kind;That kind=mkNP That_Det kind;这些种类=mkNP These_Det种类;那些种类=mkNP Those_Det种类;QKind质量种类=mkCN质量种类;非常质量=mkAP Very_AdA质量;葡萄酒=mkCN Wine_N;披萨=mkCN披萨_N;奶酪=mkCN奶酪_N;鱼类=mkCN鱼类_N;新鲜=mkAP新鲜_A;温暖=mkAP Warm_A;意大利语=mkAP意大利语_A;昂贵=mkAP昂贵_A;美味=mkAP美味_A;钻孔=mkAP钻孔_A;}

LexFoods接口的代码

interface LexFoods=中的开放语法{操作人员葡萄酒N:N;披萨_N:N;奶酪_N:N;鱼类编号:N;新鲜A:A;warm_A:A;意大利语_A:A;费用_A:A;美味_A:A;钻孔_A:A;}

词典德语实例的代码

instance LexFoodsGer of LexFood=打开SyntaxGer,ParadigmsGer in{操作人员wine_N=mkN“韦恩”;pizza_N=mkN“pizza”“Pizzen”女性化;cheese_N=mkN“Käse”“Kä)sen”阳性;fish_N=mkN“Fisch”;fresh_A=mkA“frisch”;warm_A=mkA“warm”“wärmer”“wärmste”;italian_A=mkA“italianisch”;expensive_A=mkA“teuer”;美味_A=mkA“köstlich”;boring_A=mkA“langweilig”;}

德国函子实例化的代码

--#-路径=。:../食物:存在食物的具体食物=食物(语法=SyntaxGer),(LexFoods=LexFoodesGer);

向函子实现添加语言

只需要两个模块:

函数实例化是完全机械化的。

领域词典实例需要对该语言的单词有一些了解:

示例:添加芬兰语

词典实例

例如LexFoods的LexFoodfin=打开SyntaxFin,ParadigmsFin{操作人员wine_N=mkN“viini”;pizza_N=mkN“披萨”;cheese_N=mkN“juusto”;fish_N=mkN“卡拉”;fresh_A=mkA“tuore”;warm_A=mkA“lämmin”;italian_A=mkA“italialainen”;expensive_A=mkA“kallis”;美味_A=mkA“herkullinen”;boring_A=mkA“tylsä”;}

函数实例化

--#-路径=。:../食物:存在混凝土食品Fin of Foods=食品I(语法=SyntaxFin),(LexFoods=LexFoodesFin);

设计模式

这可以看作是设计模式对于多语言语法:

混凝土领域L*实例LexDomainL实例SyntaxL*不完整混凝土领域I/           |              \interface LexDomain抽象域接口语法*

标有的模块*要么在库中给出,要么微不足道。

在手写模块中,只有LexDomainL公司依赖于语言。

Functors:练习

1.编译和测试FoodsGer公司.

2.重构食品工程到函子实例化中。

3.实例化函子食品I用你选择的语言。

4.设计一个可以用来控制MP3播放器的小语法。语法应该能够识别以下命令播放这首歌,具有以下变体:

实施分为以下几个阶段:

  1. 抽象语法
  2. (可选:)基于字符串的原型具体语法
  3. 资源语法和词典接口上的函子
  4. 第一语言的词典实例
  5. 第一语言的函子实例化
  6. 第二语言的词典实例
  7. 第二语言的函子实例化
  8. ...

受限继承

函子的一个问题

问题:只有当所有语言都使用该资源时,函子才有效语法以同样的方式。

示例(人为的):假设英语中没有单词表示披萨,但必须使用意译意大利馅饼.这不再是名词N个,但在类别中是一个复杂短语中国.

可能的解决方案:更改接口LexFoods公司具有

运营比萨饼_CN:CN;

此解决方案的问题:

限制继承:包括或排除

模块可能只继承选定的名称。

示例:食品市场示例“Rsecarchitecture:

食品市场=食品、水果[桃]、蘑菇-[木耳]

这里,来自水果我们包括只有,并且来自蘑菇我们排除在外木耳.

的具体语法食品市场必须做出类似的限制。

函子问题已解决

英语实例化继承了除常量之外的函子实现披萨。此常量在正文中定义:

--#-路径=。:../食物:存在concrete FoodsEng of Foods=FoodsI-[Pizza]与(语法=SyntaxEng),(LexFoods=LexFoodesEng)**开放语法工程,范例工程{lin Pizza=mkCN(mkA“意大利语”)(mkN“馅饼”);}

语法重用

抽象语法模块可用作接口,具体语法可用作实例。

然后应用以下对应关系:

类别C操作C:类型乐趣f:A操作f:Alincat C=T操作C:类型=Tlin f=t操作f:A=t

图书馆练习

1.查找以下英语短语的资源语法术语(在类别中博士).您可以首先尝试手动构建术语。

每个男人都爱一个女人

这个语法可以说十多种语言

哪些语言不在语法中

你想说哪种语言

然后把短语翻译成其他语言。

时态

食品语法,我们使用了路径

--#-路径=。:../食物

库子目录目前是资源的受限版本,只有动词和句子的现在时态。

通过改变路径,我们可以得到所有时态:

--#-路径=。:../foods:所有时态

现在我们可以通过使用-全部线性化中的标志:

>gr|l-全部这酒很好吃这酒好吃吗这酒不好吃这酒不好吃吗这酒不好吃这酒不好吃吗这酒很美味这酒好吃吗这酒不好吃这酒不是很好吃吗这酒不好吃这酒不好吃吗这酒很美味这酒好吃吗这酒不好吃这酒不是很好吃吗这酒不好吃这酒不好吃吗这酒很美味这酒好吃吗这酒不好吃这酒不是很好吃吗这酒不好吃如果这酒不好吃这酒会很美味的这酒好吃吗这酒不好吃这酒不好吃吗这酒不好吃这酒不好吃吗这酒一定很美味这酒好吃吗这酒不会很美味这酒不是很美味吗这酒不会很美味这酒不好吃吗这酒会很美味这酒好吃吗这酒不好吃这酒不是很美味吗这酒不好吃这酒不好吃吗这酒会很美味的这酒好吃吗这酒本来就不好吃这酒不是很美味吗这酒不会很美味这酒不好吃吗

我们也看到了

在有更多时态和语气的语言中,这个列表甚至更长,例如浪漫主义语言。

第5课:精炼抽象语法中的语义

目标:

依赖类型

问题:表达语义完形的条件.

例如:“智能房屋”的语音命令系统希望消除无意义的命令。

因此,我们希望限制特定设备的特定操作-我们可以调暗灯光,但我们不能调暗风扇.

以下示例是从Regulus Book(Rayner&al.2006)中借来的。

一个简单的例子是“智能家居”系统,它定义了家用电器的语音命令。

依赖型系统

本体论:

将其形式化的抽象语法:

指挥;种类;设备种类;--参数类型Kind动作类型;乐趣C操作:(k:种类)->操作k->设备k->命令;

设备行动都是依赖类型。

设备和操作示例

假设种类风扇,

灯、风扇:种类;dim:行动灯;

给一种,k,您可以形成设备k.

DKindOne:(k:种类)->设备k;--灯光

现在我们可以形成语法树

C行动灯暗淡(DKindOne灯)

但我们不能形成树

C操作灯暗淡(DKindOne风扇)C活动风扇暗淡(DKindOne灯)C活动风扇尺寸(DKindOne风扇)

依赖类型的线性化和解析

具体语法不知道类别是否是依赖类型。

lincat操作={s:Str};lin CAction_act-dev={s=act.s++dev.s};

请注意种类线性化过程中抑制了参数。

使用依赖类型进行分析包括两个阶段:

  1. 上下文无关剖析
  2. 通过类型检查器过滤

    分析type-correct命令的工作原理与预期一致:

    >解析“调暗灯光”C行动灯暗淡(DKindOne灯)

    但是,typecheck会拒绝输入正确的命令:

    >解析“调暗风扇”分析成功,但类型检查失败,出现错误:无法匹配预期的类型设备指示灯相对于埋入式设备风扇表达式中:DKindOne fan

    ==多态性==

    有时,可以在各种设备上执行操作。

    这表示为一个接受种类作为一个论点,并生成一个行动为了那个种类:

    fun开关On,switchOff:(k:种类)->动作k;

    这种函数称为多态的.

    我们也可以在具体语法中使用这种多态性来表达Haskell类型库函数:

    操作常数:(a,b:类型)->a->b->a=\_,_,c,_->c;操作翻转:(a,b,c:类型)->(a->b->c)->b->a->c=\_,_,_,f,x,y->f y x;

    ===依赖类型:练习===

    1.用上述内容和适当的英语具体语法编写一个抽象语法模块。尝试解析命令调暗灯光调暗风扇.

    2.执行随机和详尽的生成。

    3.在语法中添加一些设备类型和动作。

证明对象

咖喱-霍华德同构=命题作为类型原则命题是一种证明(即证明对象)。

示例:定义小于自然数命题,

猫Nat;乐趣零:Nat;有趣的成功:Nat->Nat;

归纳定义数字的含义x个成为小于一个数字:

用依赖类型表示类型理论中的这些公理减去 x年以及构建其对象的两个函数:

无猫Nat Nat;无趣Z:(y:Nat)->无趣(Succy);无趣S:(x,y:Nat)->少x y->少(Succ x)(Succy);

示例:2小于4这一事实具有证明对象

lessS(Succ-Zero)(Succ(Succ-Zero))(lessS-Zero(Succ(Succ-Zero))(lessZ(Succ-0ro)):减去(Succ(Succ-Zero))

证明文件

想法:为了在语义上完善,文档的抽象语法必须包含某些属性的证明,尽管具体文档中没有显示该证明。

示例:描述航班衔接的文件:

从哥德堡飞往布拉格,首先乘坐LH3043前往法兰克福,然后乘坐OK0537前往布拉格。

此文本的格式良好部分可以通过依赖键入来表达:

城市;飞行城市;乐趣哥德堡、法兰克福、布拉格:城市;LH3043:法兰克福哥德堡航班;OK0537:布拉格法兰克福航班;

为了将条件扩展到航班连接,我们引入了一类证明可能发生变化的证据:

cat IsPossible(x,y,z:城市)(航班x y)(航班y z);

法律联系由功能构成

fun连接:(x,y,z:城市)->(u:航班x y)->(v:航班y z)->IsPossible x y z u v->航班x z;

限制多态性

以上,所有操作都是

为了扩大新种类的规模,我们可以将其细化为限制多态性:为特定种类定义

类的概念使用Curry-Howard同构,如下所示:

示例:开关和调光类

我们修改了智能房屋语法:

可切换类型;可调光类型;乐趣switchable_light:可切换灯光;switchable_fan:可切换风扇;dimmable_light:可调光;开关打开:(k:种类)->可切换k->动作k;dim:(k:种类)->可调光k->动作k;

可以增量添加新操作的类。

变量绑定

数学符号和编程语言的表达式绑定变量。

示例:通用量词公式

(全部x)B(x)

变量x个有一个结合 (全部x),并发生跳跃在中身体 B(x).

非正式数学语言示例:

对于所有x,x等于x对于任何数字x和y,返回x+y的最大值的函数和x*y设x为自然数。假设x是偶数。那么x+3是奇数。

高阶抽象语法

抽象语法可以使用函数作为参数:

cat Ind公司;道具;全部乐趣:(Ind->Prop)->Prop

哪里印度是指个人的类型和道具命题的类型。

让我们添加一个等式谓词

趣味方程式:Ind->Ind->Prop

现在我们可以组成树了

全部(\x->等式x x)

我们想把它与普通符号联系起来

(全部x)(x=x)

高阶抽象语法(HOAS),所有变量绑定都使用高阶语法构造函数来表示。

高阶抽象语法:线性化

HOAS已被证明在变量绑定表达式的语义和计算机实现中非常有用。

我们如何将HOAS与具体语法联系起来?

在GF中,我们写道

全部乐趣:(Ind->Prop)->Proplin全部B={s=“(”++“全部”++B.$0++“)”++B

一般规则:如果参数类型为乐趣函数是函数类型A->C,此参数的线性化类型为C类加上一个新领域$0:Str(零美元).

争论B类因此具有线性化类型

{s:Str;$0:Str},

如果有更多绑定,我们将添加$1,$2等。

Eta扩展

为了理解线性化,语法树必须eta-膨胀:对于任何类型的函数

A->B

eta-expanded语法树的形式如下

\x->b

哪里乙:乙根据假设x:A.

给定线性化规则

lin等式a b={s=“(”++a.s++“=”++b.s++“)”}

树的线性化

\x->等式x x

是记录

{$0=“x”,s=[“(x=x)”]}

然后我们可以计算公式的线性化,

全部(\x->等式x x)-->{s=“[(全部x)(x=x)]”}。

变量的线性化x个是“自动”字符串“x”.

分析变量绑定

GF可以将任何单字字符串视为变量符号。

>p-cat=道具“(全部x)(x=x)”全部(\x->等式x x)

如果使用变量,则必须对其进行绑定:

>p-cat=属性“(全部x)(x=y)”找不到树

变量绑定练习

1.写出整体的抽象语法谓词演算,使用连接词“和”、“或”、“暗示”和“不是”,以及量词“存在”和“所有人”。使用高阶函数确保不会出现无界变量。

2.为你最喜欢的谓词演算符号写一个具体的语法。如果你想要好的输出,请使用Latex作为目标语言。您还可以尝试生成某些编程语言的布尔表达式。根据需要使用尽可能多的括号,以确保无歧义性。

语义定义

这个乐趣GF的判断是函数的声明,给出了它们的类型。

我们能不能计算 乐趣功能?

大多数情况下,我们对此不感兴趣,因为函数被视为构造函数,即数据表单-与通常一样

乐趣零:Nat;有趣的成功:Nat->Nat;

但也可以给予语义定义到函数。关键词是定义:

有趣的一个:Nat;def-one=成功归零;有趣的两次:Nat->Nat;def两倍x=加x x;趣味附加:Nat->Nat->Nat;定义加x零=x;加x(成功)=成功(总和x年);

计算树

计算:遵循定义链,直到无法应用定义,

加一个-->加号(Succ-Zero)(Succ Zero)-->成功(加上(成功零)零)-->成功(成功归零)

GF中的计算使用输入项(_T)命令和计算转换,例如。

>parse-tr“1+1”|put_term-transform=计算-tr |l加上一个成功(成功归零)秒(0)

定义上的平等

如果两棵树计算到同一棵树中,那么它们在定义上是相等的。

定义相等并不保证线性化的一致性:

加一==>1+1成功(成功归零)===>秒(s(0))

这个概念的主要用途是在类型检查中:类型的相同性。

因此,例如,以下类型是相等的

减去零一减零(Succ Zero)

所以一个物体也是另一个物体。

施工人员判断表

判决书数据说明类别作为构造函数具有某些功能:

data Nat=成功|零;

构造函数的类型签名分别给出,

乐趣零:Nat;有趣的成功:Nat->Nat;

还有一个简写:

数据成功:Nat->Nat;===有趣成功:Nat->Nat;data Nat=成功;

注意:在定义定义,标识符模式未标记为数据将被视为变量。

语义定义练习

1.使用自然数、列表、对、lambdas等实现小型函数式编程语言的解释器。对语义定义使用高阶抽象语法。作为具体的语法,请使用您最喜欢的编程语言。

2.无终止检查定义定义。构造一个使类型检查循环的示例。可以使用调用类型检查put_term-transform=求解.

第6课:形式语言的语法

目标:

算术表达式

我们用整数的加法、减法、乘法和除法构造了一个计算器。

抽象计算器={标志startcat=Exp;cat Exp;乐趣EPlus、EMinus、ETimes、EDiv:Exp->Exp->Exp;EInt:内部->外部;}

类别国际是内置的整数类别。它的语法树整数字面常数,即数字序列:

5457455814608954681:国际

这些是类型的唯一对象国际:不允许使用语法声明函数国际作为值类型。

具体语法:一种简单的方法

我们从一个具体的语法开始,它总是在二进制运算符应用程序周围使用括号:

具体计算器计算器的P=打开序曲{林肯猫Exp=不锈钢;EPlus=中缀“+”;EMinus=中缀“-”;ETimes=中缀“*”;EDiv=中缀“/”;EInt i=i;操作人员中缀:Str->SS->SS->SS=\f,x,y->ss(“(”++x.s++f++y.s++“)”);}

现在我们有了

>线性化EPlus(EInt 2)(E时间(EInt 3)(EInt 4))( 2 + ( 3 * 4 ) )

首要问题:

除法和非除法

GF中解析的输入不仅仅是一个字符串,而是一个列表代币,由返回列克瑟.

GF中的默认lexer返回由空格分隔的块:

"(12 + (3 * 4))"  ===>  "(12", "+", "(3". "*". "4))"

正确的方法是

"(", "12", "+", "(", "3", "*", "4", ")", ")"

此外,代币"12","3"、和"4"应该被识别为整型文字-它们在语法中找不到。

Lexer由命令的标志调用输入字符串=ps.

>输入字符串-lexcode“(2+(3*4)”( 2 + ( 3 * 4 ) )

这可以像往常一样通过管道传输到解析器中:

>ps-lexcode“(2+(3*4))”|解析EPlus(EInt 2)(E时间(EInt 3)(EInt 4))

在线性化中,我们使用相应的未经授权的人:

>线性化EPlus(EInt 2)(ETimes(EInt 3)(EInt 4))|ps-无励磁(2 + (3 * 4))

最常见的词汇和非词汇

列克瑟

未经授权的人

描述

焦炭

无变化的

每个字符都是一个标记

词汇代码

无编码

程序代码约定(使用Haskell的lex)

词汇混合

未混合的

类似文本,但在$符号之间类似代码

文字

非文本

标点符号和大写字母的约定

解除武装

(默认)由空格字符分隔的标记

优先性和固定性

算术表达式应该是明确的。如果我们写

2 + 3 * 4

它应该被解析为一个,而不是两个

EPlus(EInt 2)(E时间(EInt 3)(EInt 4))E时间(EP+(EInt 2)(EInt 3))(EIint 4)

我们选择前一棵树,因为乘法较高优先级而不是添加。

要表示后一棵树,我们必须使用括号:

(2 + 3) * 4

通常的优先规则:

作为参数的优先级

优先顺序可以成为表达式的固有特征:

操作人员Prec:PType=整数2;TermPrec:类型={s:Str;p:Prec};mkPrec:Prec->Str->TermPrec=\p,s->{s=s;p=p};林肯猫Exp=TermPrec;

通知积分2:参数类型,其值为整数0,1,2.

使用优先级:将表达式的固有优先级与预期优先级进行比较。

这个想法被编码在操作中

操作usePrec:TermPrec->Prec->Str=\x,p->case lessPrec x.p第页,共页{真=>“(”x.s“)”;假=>x.s} ;

(我们使用更少Preclib/前奏曲/正式.)

固定装置

我们可以定义左联中缀表达式:

中缀:Prec->Str->(_,_:TermPrec)->TermPrec=\p,f,x,y->mkPrec p(usePrec x p++f++usePrec-y(nextPrec p));

类常量表达式(最高级别):

常数:Str->TermPrec=mkPrec 2;

所有这些操作都可以在中找到lib/前奏曲/正式,共有5个级别。

现在我们可以编写计算器紧凑地:

计算器的具体计算器C=开放形式,序曲{flags lexer=码字;unlexer=代码;startcat=Exp;lincat Exp=TermPrec;EPlus=中缀0“+”;EMinus=中缀0“-”;ETimes=中缀1“*”;EDiv=中缀1“/”;EInt i=常数i.s;}

优先级练习

1.定义非关联和右关联中缀操作,类似于中缀.

2.添加一个构造函数,该构造函数在表达式周围放置括号以提高其优先级,但这被定义定义。使用和不使用管道测试分析pt-transform=计算.

作为线性化的代码生成

将算术(中缀)转换为JVM(后缀):

2 + 3 * 4===>图标2:图标3;图标4;imul;国际原子能机构

只需给出JVM的线性化规则:

EPlus=后缀“iadd”;EMinus=后缀“isub”;ETimes=后缀“imul”;EDiv=后缀“idiv”;EInt i=ss(“iconst”++i.s);操作人员后缀:Str->SS->SS->SS=\op,x,y->ss(x.s++“;”++y.s++“;“++op);

带变量的程序

A类直接代码编程语言,使用初始化作业:

int x=2+3;整数y=x+1;x=x+9*y;

我们通过以下构造函数定义程序:

乐趣PEmpty:程序;P单位:Exp->(Var->Prog)->Prog;PAss:Var->Exp->Prog->Prog;

P装置使用高阶抽象语法使初始化变量在延续程序的。

上述代码的抽象语法树是

PInit(EP+(EInt 2)(EInt 3))(\x->PInit(EP+(EVar x)(EInt 1))(\y->PAss x(EP+(EVar x)(E时间(EInt 9)(EVar y))P空))

不允许未初始化的变量-没有的构造函数变量!但我们有规则

趣味EVar:Var->Exp;

语法的其余部分与算术表达式相同在这里。实现它的最佳方法可能是编写一个扩展表达式模块的模块。扩展最自然的开始类别是掠夺.

代码生成练习

1.定义直接代码语言的类C的具体语法。

2.将直接代码语言扩展到类型表达式浮动。为了保证类型安全,可以定义类别类型类型和品牌费用变量依赖于类型。基本浮点表达式可以由内置GF类型的文本构成浮子。算术运算应该是多态的(如在这里).

3.使用另外两条指令将JVM生成扩展到直接代码语言

因此,上一节中示例的代码是

图标2;图标3;iadd;历史学家x;iload x;图标1;iadd;历史;iload x;图标9;iload y;imul;iadd;历史学家x;

4.如果您尝试在语言中添加浮点数,那么现在可以利用类型检查的主要优势来生成代码:选择类型正确的JVM指令。浮点指令与整数指令完全相同,只是前缀是(f)而不是,还有那个fconst公司采用浮点文字作为参数。

第7课:嵌入式语法

目标:

嵌入式语法格式的功能

GF语法可以用作用其他编程语言编写的程序的一部分,称为主机语言。该设施基于以下几个组件:

可移植语法格式

可移植格式称为PGF,即“可移植语法格式”。

此格式是通过使用GF作为批处理编译器生成的,带有选项-制造,来自操作系统外壳:

%gf-制作源.gf

PGF是推荐的分发最终语法产品的格式,因为它们被从多余的信息中剥离出来,并且可以比单独的模块组更快地启动和应用。

应用程序程序员从不需要读取或修改PGF文件。

因此,PGF在通用编程(或Java中的字节码)中扮演着与机器代码相同的角色。

Haskell:EmbedAPI模块

Haskell API包含(除其他外)以下类型和函数:

读取PGF::文件路径->IO PGF线性化::PGF->语言->树->字符串parse::PGF->语言->类别->字符串->[树]linearizeAll::PGF->Tree->[String]linearizeAllLang::PGF->Tree->[(Language,String)]parseAll::PGF->类别->字符串->[[Tree]]parseAllLang::PGF->Category->String->[(Language,[Tree])]语言::PGF->[语言]类别::PGF->[类别]startCat::PGF->类别

这是Haskell应用程序中唯一需要导入的模块。它是GF发行版的一部分,位于文件中src/PGF.hs.

第一个应用程序:翻译

让我们首先构建一个独立的翻译器,它可以在语法中的任何语言之间翻译任何多语言语法。

模块Main,其中导入PGF导入系统。环境(getArgs)主::IO()main=做文件:_<-getArgsgr<-readPGF文件交互(translate gr)翻译::PGF->String->Stringtranslate gr s=案例parseAllLang gr(startCat gr)s of(lg,t:_):_->非线性[线性化gr l t | l<-语言gr,l/=lg]_->“无理由”

要运行转换器,首先通过以下方式编译它

%ghc-make-o trans转换器.hs

为此,您需要Haskell编译器GHC公司.

为翻译人员制作PGF

然后生成一个PGF文件。例如食物语法集可以编译如下:

%gf-制作食品工程.gf食品Ita.gf

这将生成文件食品.pgf(它的名字来自抽象语法)。

Haskell库函数相互作用使反式该程序的工作方式类似于Unix过滤器,它从标准输入读取数据并写入标准输出。因此,它可以是管道和读写文件的一部分。最简单的翻译方法是回声程序输入:

%echo“这酒很好吃”。/反式食品.pgf美味葡萄酒

结果以输入语言以外的所有语言给出。

转换器循环

要避免反复启动翻译器:更改相互作用在主函数中,定义如下:

循环::(字符串->字符串)->IO()回路传输=dos<-getLine如果s==“quit”,则putStrLn“bye”else doputStrLn$trans秒回路变压器

循环继续逐行转换,直到输入行退出.

问答系统

下一个应用程序也是一个转换器,但它添加了一个转移组件-转换语法树的函数。

我们使用的传递函数是将问题计算为答案的函数。

该程序接受关于算术的简单问题,并用提出问题的语言回答“是”或“否”:

123是素数吗?不。77是否受损?乌伊。

我们通过提供翻译将传输用作额外参数:

翻译::(树->树)->PGF->String->String

作为特殊情况的普通翻译,其中传递是身份功能(身份证件哈斯克尔)。

要在中回复相同的作为问题的语言:

translate tr gr=案例parseAllLang gr(startCat gr)s of(lg,t:):->线性化gr-lg(trt)_->“无理由”

查询系统的抽象语法

输入:抽象语法判断

抽象查询={flags startcat=问题;答案;问题;对象;乐趣偶数:对象->问题;奇数:对象->问题;质数:宾语->问句;编号:Int->Object;是:回答;否:回答;}

将GF数据类型导出到Haskell

为了便于定义传递函数,我们将抽象语法导出到Haskell数据类型系统:

%gf-make--output-format=haskell查询工程.gf

结果是一个名为查询.hs,包含名为查询.

输出:Haskell定义

模块查询,其中导入PGF数据GAnswer=GYes公司|全球导航卫星组织data GObject=G编号GInt数据GQuestion=GPrime G对象|GOdd G对象|GEven G对象newtype GInt=GInt整数

所有类型和构造函数名称都以G公司以防止冲突。

Haskell模块名称与抽象语法名称相同。

问答功能

Haskell的类型检查器确保函数对于GF也是类型良好的。

答案::GQuestion->GAnswer答案p=案例pGOdd x->测试奇数xGEven x->测试偶数xG素数x->测试素数x值::G对象->Int值e=的情况eG编号(GInt i)->来自整数i测试::(Int->Bool)->GObject->GAnswertest f x=如果f(值x),则GYes else GNo

在Haskell树和GF树之间转换

生成的Haskell模块还包含

类Gf a其中gf::a->树fg::树->a实例Gf GQuestion其中gf(GEven x1)=DTr[](AC(CId“偶数”))[gf x1]gf(GOdd x1)=DTr[](AC(CId“奇数”))[gf x1]gf(G素数x1)=DTr[](AC(CId“素数”))[gf x1]前景t=第t种情况DTr[](AC(CId“偶数”))[x1]->GEven(fg x1)DTr[](AC(CId“奇数”))[x1]->GOdd(fg x1)DTr[](AC(CId“基本”))[x1]->G基本(fg x1)_->错误(“无问题”++显示t)

对于程序员来说,只要知道:

总而言之:传输定义

模块TransferDef,其中导入PGF(树)导入查询--从GF生成传输::树->树转移=gf。回答。前景答案::GQuestion->GAnswer答案p=案例pGOdd x->测试奇数xGEven x->测试偶数xG素数x->测试素数x值::G对象->Int值e=的情况eG编号(GInt i)->来自整数i测试::(Int->Bool)->GObject->GAnswertest f x=如果f(值x),则GYes else GNo素数::Int->Bool素数x=元素x素数,其中底漆=筛子[2..x]筛子(p:xs)=p:sieve[n|n<-xs,n`mod`p>0]筛子[]=[]

总而言之:主模块

以下是Haskell文件中的完整代码传输环路.

模块Main,其中导入PGF导入TransferDef(传输)主::IO()main=做gr<-readPGF“查询.pgf”循环(translate transfer gr)循环::(字符串->字符串)->IO()回路传输=dos<-getLine如果s==“quit”,则putStrLn“bye”else doputStrLn$trans秒回路变压器翻译::(树->树)->PGF->String->Stringtranslate tr gr s=case parseAllLang gr(startCat gr)s的(lg,t:):->线性化gr-lg(trt)_->“无理由”

把它们放在一起:Makefile

为了自动化系统的生产,我们编写了一个生成文件如下:

全部:gf-make--output-format=haskell QueryEngghc—制造-o。/数学传输环路条形数学

(Makefile中开始命令行的空段必须是制表符。)现在,我们只需键入以下命令即可编译整个系统

制作

然后你可以输入

./数学

总而言之,应用程序的源代码由以下文件组成:

生成文件——生成文件Math.gf—抽象语法数学???.gf——混凝土合成TransferDef.hs——问答功能的定义TransferLoop.hs—Haskell主模块

Web服务器应用程序

PGF文件可以在web服务器中使用,其中包含一个Haskell库src/服务器/。如何为翻译人员等任务构建服务器在自述文件文件。

可以使用库轻松构建的服务器之一(无需任何编程)是冰箱诗歌磁铁它是一个使用增量解析器建议语法正确的下一个单词的应用程序。下面是它在食品语法。

JavaScript应用程序

JavaScript是一种编程语言,在大多数web浏览器中都内置了解释器。因此,它可用于客户端web程序,这些程序甚至可以在不访问internet的情况下运行。下图显示了在iPhone上运行时从GF语法编译的JavaScript程序。

编译为JavaScript

JavaScript是GF批处理编译器的输出格式之一。因此,下面的命令从两个食物语法。

%gf-make--输出格式=js FoodEng.gf FoodIta.gf

生成文件的名称为食品.js,派生自最顶层的抽象语法名称。此文件包含作为JavaScript对象的多语言语法。

使用JavaScript语法

要执行解析和线性化,运行时库gflib.js使用。它包含在/src/runtime/javascript/以及其他一些JavaScript和HTML文件;这些文件可以用作构建应用程序的模板。

用法示例如下翻译.html,它实际上是用指向Food语法的指针初始化的,因此它提供了英语和意大利语语法之间的翻译:

语法必须有名称语法.js。中的抽象语法和开始类别名称翻译.html必须与语法中的匹配。通过这些更改,翻译人员可以使用任何多语言语法。

语音识别的语言模型

在语音识别中使用GF的标准方法是基于语法的语言模型.

GF支持多种格式,包括GSLNuance语音识别器.

GSL由GF通过运行玻璃纤维带着国旗--输出格式=gsl.

示例:GSL生成自食品工程.gf.

%gf-制造--输出格式=gsl FoodsEng.gf%更多FoodsEng.gsl;GSL2.0;用于FoodsEng的Nuance语音识别语法;由GF生成.主要短语_cat项目_1[(“that”Kind_1)(“this”Kind_)]第2项[(“这些”第2类)(“那些”第2种)]项目_状态[项目_1项目_2]种类_1[“奶酪”“鱼”“披萨”(质量_1种类_1)“葡萄酒”]种类2[“奶酪”“鱼”“披萨”(质量_1类_2)“葡萄酒”]金德_卡特[金德_1金德_2]短语_1[(项目_1为“质量_1”)(第2项“是”质量_1)]短语_cat短语_1质量_1[“无聊”“美味”“昂贵”“新鲜”“意大利语”(“非常”质量_1)“温暖”]质量_猫质量_ 1

更多语音识别语法格式

其他格式可通过--输出格式标志包括:

格式

描述

全球供应链

Nuance GSL语音识别语法

jsgf公司

Java语音语法格式(JSGF)

jsgf_sisr_old

带有SISR WD 20030401格式语义标记的JSGF

srgs_abnf公司

SRGS ABNF格式

srgs_xml文件

SRGS XML格式

srgs_xml_prob

SRGS XML格式,带权重

slf公司

HTK SLF格式的有限自动机

slf子

HTK SLF中带子自动机的有限自动机

可以使用查看所有当前可用的格式gf--帮助.