自上而下语法分析LL(1)

本文详细阐述了语法分析在编译程序中的关键作用,包括其理论基础、分析方式以及如何通过上下文无关文法和下推自动机识别文法句子。文章还介绍了消除左递归、LL(1)文法判断以及递归下降分析法等技术细节,并探讨了它们在实际应用中的优劣。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 语法分析的地位 --- 是编译程序的核心部分
2. 语法分析的任务
   -- 识别由词法分析得出的单词序列是否是给定文法的句子
3. 语法分析的理论基础
   -- 上下文无关文法和下推自动机
4. 语法分析的方式
   1) 自上而下语法分析
      * 反复使用不同产生式进行推导以谋求与输入符号串相匹配
   2) 自下而上语法分析
      * 对输入符号串寻找不同产生式进行规约知道文法开始符号
   注: 上是指开始符号, 下是指句子本身.

5. 下推自动机(PDA)
模型:
    输入带 --->  有限状态控制器(下推栈) ---> 输出带(记录产生式编号)
1) PDA的动作由三个因素来决定: 当前状态、读头、所指向符号、下推栈栈顶符号
2) 一个输入串能被PDA所接受,仅当输入串读完,下推栈变空; 或者输入串读完,控制器到达某些终态
3) 正规文法和有限自动机仅适合于描述和识别高级语言的各类单词,语句可用于上下文无关文法描述,而下推自动机又恰好能识别上下文无关文法所描述的语言,因此上下文无关文法及其对应的下推自动机就成为编译技术中语法分析的理论基础.

定义:
  PDA是一个七元组: ε
   1) 所有状态集
   2) 输入字母表集合
   3) 下推栈内字母表集合
   4) 映射函数
   5) 开始状态
   6) 下推栈的栈初始符号
   7) 终态集
栈顶出现非终结符时, 根据输入字符使用产生式替换栈顶否则使用输入字符抵消,并转换当前的状态.

算法:
1) 栈顶符号x是非终结符, 查询语法表,找出一个以x作为左部的产生式,x出栈,并将其右部反序入栈,且输出带记下产生式编号 --- 推导
2) 若栈顶符号x是终结符,且读头下的符号也是x, 则x出栈, 读头指向下一个符号 -- 匹配
3) 若栈顶符号x是终结符,但读头下的符号不是x,则匹配失败. 退回到上次推导现场(包括栈顶符号、读头的指针和输出带上的信息) -- 回溯
4) 回溯后选取另一候选式进行推导,若没有候选式可选,则进一步回溯。若回溯到开始符号又无候选式可选,则识别失败
5) 若栈顶空,读头也空,则识别成功
问题: 文法不能左递归, 无启发式候选式选取, 无法指出错误的确切位置


消除左递归:
1、消除直接左递归
原文法: E --> E a1 | E a2 | ... | E an | b1 | b2 | ... | bn
消除后: E --> b1 E' | b2 E' | ... | bn E'
              E'--> a1 E' | a2 E' | ... | an E' | ε
2、消除间接左递归
a)  把所有非终结符号按一定序列排序为E1, E2, ... En;
b) for i=1 to n do /*依次处理每个非终结符号*/
       for j=1 to i-1 do /*处理第1个到i-1个*/
           若Ei --> Ej r
               则改为Ei --> S1 r | S2 r | ... | Sk r
               其中Ej --> S1 | S2 | ... | Sk
c) 对Ei消除直接左递归。
注:非终结符的排列顺序不同,结果可能不同。
3、去掉无用符号和无用产生式


1)  P->Px|b === P->bP', P'->xP'|ε (替换的只是第一个产生左递归的P)
例: 文法G: E->E+T|T,  T->T*F|F,  F->(E)|i
   E->TE', E'->+TE'|ε
   T->FT', T'->*FT'|ε
   F->(E)|i

预测:
1. 求候选式的终结首符集first(P) -- 随符集
2. 预读符号. 如果PDA中候选式的首符集两两不相交,那么根据预读符号可以准确的指派产生式
3. 提取公共左因子.  通过反复提取首符集使其两两不相交,但是会引入大量的产生式和ε因子

LL(1) 文法 : 预测分析表(2维数组中, 行: 非终结符, 列: 终结符), 使用哪个候选式来进行替换. 必须是无二义性的文法,只是一个上下文无关文法的子集
判断是不是LL1文法:
  1)消除左递归
  2)提取公共左因子
  3)求First集和Follow集
  4)A->x|b,  First(x)交First(b) = 空集


递归下降分析法
  1) 先转成LL(1)文法
  2) 为每个非终结符写一个递归函数
  缺点: 对文法要求高,必须满足LL(1)文法; 高深度递归会影响语法分析效率,速度慢,占空间多

 由于LL文法要求较高,所以编译一般使用规约(自下而上的分析法)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值