生成解析器:Fsyacc

扫描器就是一段程序或模块,把文本流拆成片断,解析器可以看作是把文本重新组织为更有意义的内容。解析器的目标通常是产生抽象语法树,通过定义规则,确定符号应该出现的顺序。工具fsyacc.exe 生成的解析器,是向前看从左到右(look-ahead left-to-right)的解析器,通常称为 LALR(1)[ 好像解释的有点问题,下面的内容来自百度百科 LR 分析法:Look-Ahead为“向前看”,L代表对输入进行从左到右的检查,R代表反向构造出最右推导序列]。这是一种语法解析算法,并不是所有的语法都能用这个算法解析,但是,不能解析的语法是很罕见的。

 

注意

fsyacc.exe 名字中的 YACC 是 Yet AnotherCompiler Compiler 的缩写。

工具fsyacc.exe 处理的文本文件的扩展名是.fsy。文件分为三个部分。第一部分是头部,这是一段纯F# 代码,用百分号和大括号括起来(%{ 表示开始,%} 表示结束),这一段通常用于导入(open)自己的抽象语法树模块,以及为创建这个抽象语法树而定义的简单的辅助函数。接下来是声明,定义了语言中的终结符。终结符(terminal)是语法中的一些具体名词,比如标识符名或符号。通常,它会由词法分析器发现。声明有几种不同的形式,汇总在表13-1 中。第三部分包含组成语法的规则,在下一段有具体描述。

表 13-1 fsyacc.exe 文件中终结符的声明

声明

描述

%token

它声明了给定符号,作为语言中的符号。

%token<type>

它声明了给定符号,作为语言中的符号,如 %token,但是,有给定类型的参数。当需要存储有关如标识符和文字的信息时,这是有用的。

%start

声明解析器应该开始解析的规则。

%type<type>

声明特定规则的类型,对于开始规则是强制的,而对于其他所有规则都是可选的。

%left

声明符号作为左关联(left-associative),可以帮助解决语法的歧义。

%right

声明符号作为右关联(right-associative),可以帮助解决语法的歧义。

%nonassoc

声明符号作为无关联(nonassociative),可以帮助解决语法的歧义。

声明与规则用两个百分号分开,它是文件的最后一段。规则是语法上的非终结符(nonterminals)。非终结符是由几个终结符组成的。这样,每一个规则必须有名字,加冒号,然后是组成规则的所有条目的定义,之间用竖线隔开。组成规则的条目,既可以是已经定义的符号名,也可以是规则名;它后面必须跟一个动作,用大括号括起来的 F# 代码。下面就是一个规则的片断:

Expression: ID { Ident($1)}

| FLOAT {Val($1) }

Expession 是规则名,ID 和 FLOAT 是两个规则,只由终结符组成,{ Ident($1) } 和{ Val($1) } 是规则的动作 [ 原文中两个都是 Ident,应该是复制过来,忘记改了]。在这些动作中,可以收集到和终结符、非终结符相关联的数据,用美元符号($)加上数字,表示我们感兴趣条目的位置。动作的结果会和规则相关联。规则的所有的动作都必须有相同的类型,因为,规则实现为 F# 函数,动作作为参数,返回条目。在规则中的所有注释都应该用 C 风格的注释标记/* */。

下面的例子就是我们前面语言的一个简单解析器定义。注意,和规则相关联的所有动作都很简单,只创建了抽象语法树中类型的实例,所有的语言的终结符都大写。当使用 fsyacc.exe 工具编译这个示例时,很重要的一点是使用 --module 开关指定模块名,在这里,应该指定的模块名是Strangelights.ExpressionParser.Parser。

/* This example shows how to write a parser filewhich creates */

/* nodes that carry F# values. */

%{

openStrangelights.ExpressionParser.Ast

%}

%start Expression

%token <string> ID

%token <System.Double> FLOAT

%token LPAREN RPAREN EOF MULTI DIV PLUS MINUS

%type <Strangelights.ExpressionParser.Ast.Expr > Expression

%left MULTI

%left DIV

%left PLUS

%left MINUS

%%

Expression: ID { Ident($1)}

| FLOAT {Val($1) }

| LPARENExpression RPAREN { $2 }

|Expression MULTI Expression { Multi($1, $3) }

|Expression DIV Expression { Div($1, $3) }

|Expression PLUS Expression { Plus($1, $3) }

|Expression MINUS Expression { Minus($1, $3) }

让我们近距离看一下组成规则的条目,最简单的规则条目只由一个终结符组成,在这里,是一个标识符 ID:

ID { Ident($1) }

在这个规则条目的动作中,字符串,表示标识符的字符串用于创建Ident 构造函数的实例,来自抽象语法树。稍许复杂一些的规则,既包含终结符,也包含非终结符:

| Expression MULTI Expression { Multi($1, $3)}

这个规则条目可以识别为,一个有效的表达式,加乘号,再加一个有效的表达式。这些表达式然后被装进抽象语法树的构造器Multi;这些表达式可能是语言中的终结符,比如标识符或文字,也可能是由多个终结符组成的表达式,比如,乘法运算。

创建语法最困难的就是保证没有歧义。当有两个或多个规则匹配相同的输入时,语法就有歧义了。幸运的是,fsyacc.exe 可以自动发现,并在发现时发出警告;但也只是警告而已,因为,解析器仍然能够正常,只是有些规则未能匹配,在某些方面可能不正确。

生成解析器:Fsyacc相关推荐

  1. 使用JavaCC生成解析器(前言)

    前言 JavaCC是Java编程语言中最古老.使用最广泛的解析器生成器之一,但它往往被认为难以使用.有些程序员还没有遇到过解析器生成器范式,因此不熟悉编写规范然后据此生成解析器的过程.其他程序员对使用 ...

  2. CSS大会 | 打破常“规”:挖掘语法解析器规则漏洞

    2019年7月30-31日,第五届互联网安全领袖峰会(CSS 2019)在北京开幕.作为前沿技术安全研究团队代表,Tencent Blade Team两位高级安全研究员受邀登台,探讨如何挖掘语法解析器 ...

  3. 解析器生成器 ANTLR的详细介绍

    什么是ANTLR ANTLR(Another Tool for Language Recognition)是一个强大的解析器生成器,用于读取.处理.执行和翻译结构化文本或二进制文件.它被广泛应用于构建 ...

  4. java定义语法解析器,java开发工具intellij idea使用教程:定义语法和解析器.pdf

    java开发工具intellij idea使用教程:定义语法和解析器.pdf 还剩 3页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: 慧都 科技 -- ...

  5. 使用Lemon编写最简单的SQL解析器

    使用SQLite自带的Lemon解析器生成工具,制作最简单的解析器.以解析器仅解析Create table语句. 以下的生成解析器所需的.y文件. // All token codes are sma ...

  6. 自制编程语言crowbar(v0.1)构建解析器时分配内存

    crowbar中第一次申请内存是在生成解析器的时候: /* interface.c */CRB_Interpreter *CRB_create_interpreter(void) {MEM_Stora ...

  7. boost::spirit模块实现一个类似于 XML 的小型解析器,Karma 用于打印生成的 AST

    boost::spirit模块实现一个类似于 XML 的小型解析器,Karma 用于打印生成的 AST 实现功能 C++实现代码 实现功能 boost::spirit模块实现一个类似于 XML 的小型 ...

  8. Android学习笔记---15_采用Pull解析器解析和生成XML内容

    15_采用Pull解析器解析和生成XML内容 -------------------------------------- 使用SAX或者DOM或者pull解析XML文件 -------------- ...

  9. 一图看懂 tomli 模块:一个 TOML解析器、使用 mformat -toc 生成的目录,资料整理+笔记(大全)

    本文由 大侠(AhcaoZhu)原创,转载请声明. 链接: https://blog.csdn.net/Ahcao2008 一图看懂 tomli 模块:一个 TOML解析器.使用 mformat -t ...

  10. 15_采用Pull解析器解析和生成XML内容

    java还提供SAX和DOM用于解析XML Android还集成了Pull解析器--推荐 package cn.itcast.service;import java.io.InputStream; i ...

最新文章

  1. python画饼图-python画饼图的多种方式
  2. js解析二维码_最新最全阿里巴巴,今日头条,腾讯Flutter面试真题全解析(狂虐不止)...
  3. deque与vector的主要区别
  4. 大网高级技术笔记(一)
  5. 使用jclouds在S3上分段上传
  6. 跟2G说再见?这些IoT“钉子户”表示做不到……
  7. 【codevs1869】硬币购物,背包+神奇的容斥原理
  8. 找不到具有不变名称“System.Data.SqlClient”的ADO.NET提供程序的实体框架提供程序
  9. explanatory variable(independent vs dependent)、design matrix
  10. 项目经理要提升需求分析的能力
  11. ubuntu执行configure配置代码出现unable to guess system type报错
  12. Lucas(卢卡斯)定理---组合数取模问题
  13. eclipse清理无用import(一次性清理整个项目所有)
  14. vivo手机点击android,了解Vivo手机几个小技巧,让您的手机变得更好用
  15. FAST_ICA MTALAB工具包下载/ICA分析/独立成分分析MATLAB安装包/ICA toolbox
  16. A Easy Game(FZU 2146)
  17. 汽车LED驱动器MPQ3326替代替换
  18. 概率论中两个独立连续随机变量X,Y,变量Z=X+Y的密度函数为X,Y的卷积与特征函数原理
  19. Python 爬虫 爬取 煎蛋网 图片
  20. PhpStorm 2018 最新激活码 license server

热门文章

  1. Ubuntu 定时锁屏改进
  2. coolfire文章之八
  3. postman自动化测试
  4. WinForm中使用DXperience控件中XtraForm,如何实现换肤
  5. OtterCTF 内存取证(1-5)
  6. 查看生产DB2数据库空间及使用情况
  7. 余贞侠C语言程序设计(课后答案)
  8. office 2016 安装 excel 最新 数据挖掘插件
  9. 集体智慧编程 简介
  10. hive表中加载数据