首页 > 其他分享 >编译原理-至下而上的语法分析

编译原理-至下而上的语法分析

时间:2023-11-13 15:47:10浏览次数:26  
标签:至下而上 算符 优先 语法分析 终结符 文法 编译 归约 quad

目录

至下而上分析的基本问题

归约

用一个寄存符号的先进后出栈,把输入符号一个一个地移进栈里,当栈顶形成某个产生式的一个候选式时,即把栈顶的这一部分归约成该产生式的左部符号

\[{E -> i|E + E|E-E|E*E|E/E|(E)} \]

输入符号串:

\[{i*i+i} \]

归约过程

\[{E*i+i} \quad \quad (1) \]

\[{E*E+i} \quad \quad (2) \]

\[{E+i} \quad \quad (3) \]

\[{E+E} \quad \quad (4) \]

\[{E} \quad \quad (5) \]

例子:设文法G(S):
\({S->aAcBe}\)
\({A->b}\)
\({A->Ab}\)
${b->d} \( 试对\){abbcde}$进行移进归约分析:
能进行归约就进行归约不能进行归约进行移进
image
image
image
image
此时我们进行归约的话就会出现矛盾,b是第二个推导的产生式,Ab是第二个产生式的候选式,这里我们选择第二种进行归约
image
image
image
image
在不能归约时我们就移进
image

短语

定义:令G是一个文法,S是文法的开始符号,假定\({\alpha \beta \delta}\)是文法G的一个句型,如果有:
image
就称\(\beta\)是句型\({\alpha \beta \delta}\)相对于非终结符\({A}\)的短语
如果有\({A => \beta}\),则称\(\beta\)是句型\({\alpha \beta \delta}\)相对于产生式\(A->B\)的直接短语,一个句型的最左直接短语称为该句型的句柄
一个句型对应的语法树中

  1. 以某非终结符为根的两代以上的子树的所有末端结点从左到右排列就是相对于该非终结符的一个短语
  2. 如果子树只有两代,则改短语是直接短语

句柄可以被用来对句子进行归约

规范归约

定义:假定\(\alpha\)是文法\(G\)的一个句子,我们称序列

\[{\alpha_n, \quad \alpha_n-1, \quad ... \quad, \alpha_0} \]

是\(\alpha\)的一个规范归约,如果此序列满足:
\({1. \alpha_n = \alpha}\)
\({2. \alpha_0为文法的开始符号,即\alpha_0=S}\)
\({3.对于任何i, 0 < i<= n,\alpha_{i - 1}是从\alpha_i经句柄替换成相应产生式左部符号而得到的}\)
规范推导:我们将规范归约的过程逆过来就是规范推导,规范推导也经常被称为最右推导
由规范推导推出来的句型被称为规范句型

符号栈的使用

  1. 栈是语法分析的一种基本数据结构,\(\#\)作为栈底符号
    文法\(G(E):\)
    \(E->T|E+T\)
    \(T->F|T*F\)
    \(F->(E)|i\)
    输入串为\(i_1*i_2+i_3\)的分析过程
    image
    image
    image

算符优先分析

  1. 算符优先就是定义算符之间(终结符之间)的某种优先关系,借助优先关系来寻找可归约串和进行归约
    考虑二义文法\(G(E) \quad: \quad i|E+E|E-E|E*E|E/E|(E)\)
    这个句子由几种不同的规范归约
    例如句子\(i+i-i*(i + i)\)的规约过程(按四则运算的优先顺序)

\[(1) \quad {i + i - i * (i + i)} \]

\[(2) \quad {E + i - i * (i + i)} \]

\[(3) \quad {E + E - i * (i + i)} \]

\[(4) \quad {E - i * (i + i)} \]

\[(5) \quad {E - E * (i + i)} \]

\[(6) \quad {E - E * (E + i)} \]

\[(7) \quad {E - E * (E + E)} \]

\[(8) \quad {E - E * (E)} \]

\[(9) \quad {E - E * E} \]

\[(10) \quad {E - E} \]

\[(11) \quad {E} \]

优先关系

image

算符文法及优先关表构造

算符文法:一个文法,如果它的任一产生式的右部都不含两个相继(并列)的非终结符,即不含如下形式的产生式右部:\(...QR...\),则我们称该文法为算符文法
约定:
\(a、b代表任意终结符\)
\(P、Q、R代表任意非终结符\)
\(...代表由终结符和非终结符组成的任意序列,包括空字\)

"等于":image
"小于":
image
"大于":
image
image
FIRSTYT:image

LASTVT:image
比较:
image
算符优先关系表
有了FIRSTVTLASTVT这两个概念后,我们就可以用算法构造优先关系表

image
我们只需对每个产生式检查一遍,把所有优先关系都找到就可以了

如何求FIRSTVT和LASTVT

image
image

算符优先分析算法

素短语:至少包含一个终结符,并且除了它自身外不包含任何更小的素短语,最左素短语就是句型最左边的素短语
我们考虑句型:

\[\# N_1 a_1 N_2 a_2 ... N_n a_n N_{n+1} \# \]

其中每一个\(a_i\)都是终结符,\(N_i\)都是可有可无的非终结符。
一个算符优先文法G的任何上述句型的最左素短语是满足如下条件的最左子串\({N_ja_j...N_ia_iN_{i + 1}}\)
image
算法
image

优先函数

我们在通常实现上面算法的时候在判断优先关系的时候一般不采用查表的方法而是用两个优先函数,优先函数可以将原来\(N * N\)的时间复杂度降低到\(2 * N\),缺点是原来可能两个符号不可比较优先级,但是经过优先函数之后会映射到自然数从而导致可以比较,这样会导致一些错误
image
f被称为栈优先函数
g被称为比较优先函数
如何构造优先函数(证明过程略)
image
经过构造完的优先函数需要我们进一步检验是否正确

标签:至下而上,算符,优先,语法分析,终结符,文法,编译,归约,quad
From: https://www.cnblogs.com/cxy8/p/17827200.html

相关文章

  • CentOS7编译安装openssl1.1.1
    Centos7默认提供的openssl版本是1.0.2的,想要升级openssl版本则需要手动进行编译一、下载openssl1.1.1cd/usr/local/src/wget--no-check-certificatehttps://www.openssl.org/source/openssl-1.1.1d.tar.gz二、创建安装目录mkdir-p/usr/local/openssl 三、解压......
  • imx.6ull芯片uboot编译下载
    开发环境配置及编译参考:linux开发基于iMX6ULL-uboot编译环境配置 下载官方的SDK包 下载完成之后开始直接安装将SDK包解压到对应的文件目录 本地安装目录是imx6ullSK打开文件夹里边有官方给的各种配置文件模板,MFGTools下载链接 下载最新的日期的工具,等待下载完成 ......
  • 编译方法
    ......
  • cmake编译介绍--cmakelist.txt
    1.cmake编译简介 单个文件编译C/C++时:gccmain.c/g++main.cpp 多代码文件时:MakeFile,解决多文件编译难问题,运行make命令编译自动完成 cmake编译引入:根据一定的规则自动生成MakeFile的,也是有语法(cmake还是依赖make编译)。自动管理makefile文件,写起来也更方便、没有makefile......
  • 【GCC】windows环境编译dll文件
    使用如下指令生成动态库:gcctest.c-I./inc-fPIC-shared-olibtest.dll参数解释:-I:添加头文件搜索目录-fPIC:生成位置无关的代码,在编译动态库的时候需要使用该选项-shared:表明生成一个共享对象,也就是动态库......
  • 编译原理 | Concepts & Review
    怎么感觉像是在学算法(本文主要从词法分析,语法分析,语义分析三个章节总结.1词法分析首先,应该知道编译器的流程是词法分析->语法分析->语义分析->中间代码生成->代码优化->目标代码生成.旁边还有一个符号表.词法分析分解源程序,输出单词序列(关键字,标......
  • 使用反编译软件jd-gui.exe,打开提示:The application requires a Java Runtime Enviro
      jd-gui.exe,打开提示:TheapplicationrequiresaJavaRuntimeEnvironment1.8.0 但是已经是java1.8版本了 这时候修改注册表win+R输入regedit打开注册表找到HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JavaRuntimeEnvironment\1.8如果 JavaRuntimeEnvironment......
  • linux开发基于iMX6ULL-kernel编译环境配置
    先把内核源码仓库下载下来,然后切换到对应版本的分支 切换分支 查看关于官方提供的编译配置文件有那些 只保留自己需要的其他的都删除 在源码根目录下创建脚本添加如下内容 给脚本添加执行权限后开始编译脚本 编译后出错误,安装对应的库 重新编译 至此内核......
  • linux开发基于iMX6ULL-uboot编译环境配置
    1、下载半导体官方的uboot和linux内核固件2、下载uboot 3、下载linux内核(选择5.4版本的分支下载) 下载后如下所示 解压后如下 查看文件夹中的内容 创建一个git仓库然后开始自己uboot编译开发官方给出的对应各种类型的芯片和开发板的配置文件kangxubo@kangxubo......
  • CentOS 7编译Linux内核(6.5.7)详细步骤
    CentOS7编译Linux内核(6.5.7)详细步骤参考链接:下载解压部分参考:Linux内核动手编译实用指南-LinuxEden比较详细,可用于了解原理,但没有给出针对CentOS7的方案(实验室用到的openEuler基于CentOS,所以需要CentOS的方案)。配置编译安装参考:CentOS7下编译安装Linux4.14内核-......