形式语言之语言和语法树

1,句型,句子和语言:

从文法的开始符号出发,利用其中的产生式逐步推导出待分析的符号串,如果能推导出这个符号串则表明此符号串是该文法的一个句型或句子。否则便不是。句型与句子的区别在于符号串是否全部由终结符构成,如果经过多步推导出的符号串全部由终结符构成就是句子,否则便是句型(句子一定是句型,句型不一定是句子)。文法的所有的句子的集合就是该文法所对应的语言。

2,描述形式语言的两种方法

1,枚举(描述有穷的语言集合)

2,文法(描述无穷的语言集合)

3,文法和语言的关系:文法是用来生成(定义)语言的。从文法的开始符号出发,反复使用其中的产生式对非终结符进行替换和展开推导出语言中的各种句子。

a,给定一个文法,就能从结构上唯一的确定其语言。

b,给定一种语言,能确定其文法,但不唯一。

c,若文法G1和文法G2所产生的语言相同,即L(G1) = L(G2) ,则称文法G1和文法G2是等价的。

4,推导的类型??(最左推导或最右推导)

a,直接推导:对于产生式集合P中的所有产生式,每个产生式的右部是它左部的直接推导。

b,一步推导(直接推导):记为 v=>u ,称符号串u 是符号串v 的一步推导。

c,0步或多步推导:记为 v=>*u ,称符号串u 是符号串v 的0 步或多步推导。

d,1步或多步推导:记为 v=>+u,称符号串u 是符号串v 的1 步或多步推导。

e,最左推导:在一个推导的过程中,如果每一步直接推导所被替换的总是最左的非终结符号,那么这种推导称为最左推导。

f,最右推导:在一个推导的过程中,如果每一步直接推导所被替换的总是最右的非终结符号,那么这种推导称为最右推导。最右推导又称为规范推导。用规范推导得到的句型称为规范句型。

for example:

5,设文法G[E] = ({ E,T,F },{ i },{ E→E+T|T,T→T*F|F,F→(E)|i },E)。试写出 E+(E+T)*i 符号串的最右推导和最左推导。

最右推导:E => E+T

=> E+T*F

=> E+T*i

=> E+F*i

=> E+(E)*i

=> E+(E+T)*i

最左推导:E => E+T

=> E+T

=> E+T*F

=> E+F*F

=> E+(E)*F

=> E+(E+T)*F

=> E+(E+T)*i

6,递归规则和递归文法

1,递归规则:是指那些在规则(产生式)右部含有与规则左部相同符号的规则。例如,A→aAb 右部含有与规则左部相同符号A,那么就是递归规则。如果这个相同的符号出现在右部的最左端,则为左递归规则。如A→Aa。如果这个相同的符号出现在右部的最右端,则为右递归规则。如A→aA。

2,递归文法:若文法中至少包含一条递归规则,则称文法是直接递归的。若文法中不含递归规则,但有推导过程A=>+ aAb,所以该文法为间接递归文法。递归文法能使我们用有穷的文法刻画无穷的语言。

PS:含有递归规则的文法一定是递归文法,而递归文法不一定含有递归规则。

7,根据文法确定其所对应的语言

for example:求1 型文法G[S] = ({ S,X,Y,Z },{ x,y,z },{ S→xSYZ|xYZ,xY→xy,yY→yy,yZ→yz,zY→Yz,zZ→zz },S)所确定的语言。

解释:由题可知1 型文法G[S]是一个递归文法,所以我们可以分为两种情况进行讨论,一种是不进行递归,另一种是进行递归。再将进行递归情况分解为一次递归,两次递归,三次递归考虑。最后得出规律。

第一种情况:

非递归:S => xYZ

=> xyZ

=> xyz

递归一次:S => xSYZ

=> xxYZYZ

=> xxyZYZ

=> xxyzYZ

=> xxyYzZ

=> xxyyzZ

=> xxyyzz

递归二次:S => xSYZ

=> xxSYZYZ

=> xxxYZYZYZ

=> xxxyZYZYZ

=> xxxyzYZYZ

=> xxxyYzZYZ

=> xxxyyzZYZ

=> xxxyyzzYZ

=> xxxyyzYzZ

=> xxxyyYzzZ

=> xxxyyyzzZ

=> xxxyyyzzz

最后得出规律:文法G[S]确定的语言是 L(G[S]) = { x^ny^nz^n | n>=1 }。

8,语法树的生成

在自然语言中,可通过树形表示直观地分析句子的结构;在形式语言中,则是通过语法树直观地分析文法的句型结构。设文法G[S] = (Vn,Vt,P,S),对于文法G[E] 的任意一个句型都存在一个相应的语法树。

1,语法树中每个结点都有一个标记,该标记是 Vn ∪ Vt ∪ { ε } 中的一个符号。结点的名字就是该符号。

2,语法树的根结点标记是文法的识别符号 S。

3,如果语法树的一个结点至少有一个叶子结点,则该结点的标记一定是一个非终结符。

4,语法树中一个结点和它的子结点分别对应于文法中一个规则(产生式)的左部和右部。

5,语法树中的子树就是某个结点和它向下射出的部分。

6,叶子/末端结点:没有向下射出的边的结点(没有叶子结点)称为叶子/末端结点。在相对于句型的语法树中,叶子/末端结点可能是非终结符号。

for example:

9,设文法G[E] = ({ E,T,F },{ i },{ E→E+T|T,T→T*F|F,F→(E)|i },E)。依据文法G[E] 的产生式生成句型E+(E+T)*i 相应的语法树。

PS:未完待续。。。(^_^)

时间: 2024-12-28 19:24:33

形式语言之语言和语法树的相关文章

Clang之语法抽象语法树AST

语法分析器的任务是确定某个单词流是否能够与源语言的语法适配,即设定一个称之为上下文无关语言(context-free language)的语言集合,语法分析器建立一颗与(词法分析出的)输入单词流对应的正确语法树.语法分析树的建立过程主要有两种方法:自顶向下语法分析法和自底向上分析法.AST作为语法分析树(parse tree)的一种简写方式,它独立于具体编程语言(C++.Java.C等),而且与语法分析树的建立过程无关(自顶向下和自底向上逻辑等价),是联系编译器前端.后端的重要接口.Clang的

复杂网络,抽象语法树

近期看了一些软件抽象为复杂网络,以及软件抽象成静态语法树的文章.做一个小总结. 1.复杂网络是由大量的边和点组成的,边点都可以有类型,加权值,边还可以有方向.如何计算边和点的权值是一个关键点,如何在不执行代码的情况下确定边的方向,目前不确定是否已经解决. 有许多工具,可以直接扫描软件源代码,抽象为复杂网络.然而我还没亲身实践,且做个记录. Dependency Finder分析编译后的java代码,能够提取依赖图. Doxygen是使用c++开发的基于源代码注释的文档生成工具.但是这个注释,是人

1014 C语言文法定义与C程序的推导过程 程序:冒泡算法C程序(语法树)

1014 C语言文法定义与C程序的推导过程  程序:冒泡算法C程序(语法树)1 阅读并理解提供给大家的C语言文法文件. 2 参考该文件写出一个自己好理解版的现实版的完整版的C语言文法. 3 给出一段C程序,画出用上述文法产生这段C程序的完整语法树. 程序:冒泡算法C程序 点此文字查看原图(完整图片) 1 #include <stdio.h> 2 3 main() 4 { 5 int i,j,temp; 6 int a[10]; 7 8 for(i=0;i<10;i++) 9 scanf

使用PHP-Parser生成AST抽象语法树

0.前言 最近项目的流程逐渐清晰,但是很多关键性的技术没有掌握,也只能一步一步摸索. 由于要做基于数据流分析的静态代码分析,所以前端的工作如:词法分析.语法分析必不可少.Yacc和Lex什么的就不再考虑了,查了一天的资料,发现两款比较适合,一款是Java下的ANTLR,另一款是专门做PHP AST生成的PHP-Parser. ANTLR是编译原理领域比较著名的工具了,相对于Yacc和Lex,更加实用.但是对PHP的语法文件只有一个,折腾了半天才生成调通,发现不太适合,对于"$a=1"生

淘宝数据库OceanBase SQL编译器部分 源代码阅读--解析SQL语法树

OceanBase是阿里巴巴集团自主研发的可扩展的关系型数据库,实现了跨行跨表的事务,支持数千亿条记录.数百TB数据上的SQL操作. 在阿里巴巴集团下,OceanBase数据库支持了多个重要业务的数据存储.包含收藏夹.直通车报表.天猫评价等. 截止到2013年4月份.OceanBase线上业务的数据量已经超过一千亿条. 看起来挺厉害的,今天我们来研究下它的源码. 关于OceanBase的架构描写叙述有非常多文档.这篇笔记也不打算涉及这些东西,仅仅讨论OceanBase的SQL编译部分的代码. O

Atitti. 语法树AST、后缀表达式、DAG、三地址代码

抽象语法树的观点认为任何复杂的语句嵌套情况都可以借助于树的形式加以描述.确实,不得不承认应用抽象语法树可以使语句翻译变得相对容易,它很好地描述了语句.表达式之间的联系.不过,由于Neo Pascal并不会显式构造抽象语法树,所以不得不借助于其他数据结构实现.根据先前的经验,栈结构就是不二之选. DAG(有向无环图) 后缀表达式:也称为逆波兰表达式,这种形式简单明晰,便于存储.在处理表达式翻译时,后缀表达式有着其他形式无法比拟的优势.不过,由于后缀表达式的应用领域比较单一,所以很少独立作为一个实际

淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树

OceanBase是 阿里巴巴集团自主研发的可扩展的关系型数据库,实现了跨行跨表的事务,支持数千亿条记录.数百TB数据上的SQL操作.在阿里巴巴集团 下,OceanBase数据库支持了多个重要业务的数据存储,包括收藏夹.直通车报表.天猫评价等.截止到2013年4月份,OceanBase线上业务 的数据量已经超过一千亿条. 看起来挺厉害的,今天我们来研究下它的源代码.关于OceanBase的架构描述有很多文档,这篇笔记也不打算涉及这些东西,只讨论OceanBase的SQL编译部分的代码. Ocea

解释抽象语法树

创建了抽象语法树之后,有两个选择:解释或编译.解释,简单地说,就是遍历树,同时执行操作:编译,就是改变成其他形式,对于机器执行来说可能更简单,通常可能更快.这一小节先讨论如何解释结果,下面一小节再讨论编译的内容,最后,再讨论何时应该用解释,何时应该用编译的问题. 下面的例子是一个很小解释器,解释抽象语法树的主要工作由函数interpret 完成,它遍历树,并同时执行需要的动作.逻辑相当简单,如果发现一个文字值或标识符,就返回相应值: | Ident (s) ->variableDict.[s]

抽象语法树(Abstract Syntax Tree)

抽象语法树(AST)表示组成程序的结构,可以让程序员更容易使用,F# 适宜这种开发的一个原因就是它的联合类型.这种类型非常适合表示语言,因为它可以用来表示相关而结构不相同的项目.下面就是抽象语法树的例子: type Ast = | Ident of string | Val of System.Double | Multi of Ast * Ast | Div of Ast * Ast | Plus of Ast * Ast | Minus of Ast * Ast 树非常简单,只包含一种类型: