编译原理学习笔记(四)——语法分析(自上而下分析)

一、知识点

语法分析器:工作本质是文法的产生式,识别输入符号串是否为一个句子

自上而下分析方法:基本思想:对任何输入串,试图用一切可能的方法,从文法开始符号(根结)出发,从上而下地为输入串建立一棵语法树。即为输入串寻找一个最左推导。本质:是一种试探过程,是反复使用不同产生式谋求匹配输入串的过程。

LL(1)分析法:

1. 左递归消除

(1) 将间接左递归改造为直接左递归
     将文法中所有如下形式的产生式:
            Pi →Pjγ|β1|β2|…|βn
                  Pj→δ1|δ2|δ3|…|δk
      改写成:
     Pi →δ1γ|δ2γ|δ3γ|…|δkγ|β1|β2|…|βn

(2)消除直接左递归
    P→Pα1|Pα2|...|Pαm|β1| β2|...| βn
    消除P的左递归
    P→ β1P'| β2P'|...| βnP'
    P'→ α1 P'| α2 P'|...|αm P'| ε
(3)化简改写后的文法,即去除那些从开始符号出发却永远无法到达的非终结符的产生规则。
  最终得到无左递归的文法。

2. 消除回溯

2.1 建立FIRST集

FIRST(A)是对终结符A的所有可能推导的开头终结符,或可能的ε

若A所有候选首符两两不想交,则当要求A匹配输入串时,A就能唯一指定某一候选项

方法:提取公共左因子:

假设A的产生式为
        A→δβ1|δβ2|…|δβn|γ1| γ2|…|γm
其中每个γ不以δ开头
那么把这些产生式改写为:
        A→δA'|γ1| γ2|…|γm
        A'→β1|β2|…|βn

2.2 建立FOLLOW集

当非终结符A面临输入符号a,且a不属于A的任意候选式的FIRST集但A的某个候选式的FIRST集包含ε时,只有当a ∈FOLLOW(A),才可能允许A自动匹配。

FOLLOW(A)是所有句型中出现在紧接A之后的终结符或'#'


预测分析程序:

1. 构造分析表

分析表:预测分析表是一个M[A,a]的矩阵,A为非终结符,a是终结符或'#',其矩阵中元素值为当A面临输入符号a时采用的候选。

构造分析表步骤:

1.1 构造FIRST(X)

(1)如x是终结符,则FIRST(X)={X};

(2)如X是非终结符,且有产生式X→a···· 则将a加入FIRST(X)中,如X→ε也是一条产生式,则加入ε,

(3)如X→Y···是一个产生式,Y是一个非终结符,则将FIRST(Y)中的所有非ε元素加入,如X→Y1Y2Y3···是一个产生式,则如果对所有的Yj均含有ε,则加入ε,

1.2 构造FOLLOW(X)

(1)对于文法的开始符,置#于FOLLOW(S)中
(2)若A->αBβ, 则把FIRST (β)-ε加入到FOLLOW(B)中,

(3)若A->αB 是一个产生式,或 A->αBβ是一个产生式,而β-> ε,则把FOLLOW(A)加入到FOLLOW(B)中

1.3 构造分析表

对文法G的每个产生式, A->α,进行下面的处理
(1)对每个终结符a,如果a属于FIRST(α),则把该产生式写入到M[A,a]
(2)若ε属于FIRST(α),则对任何b属于FOLLOW(A), 把该产生式加入到M[A,b]
(3)所有无定义的M[A,a]标上出错标志


二、课后题


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
语法分析编译原理中的重要部分,它的作用是将词法分析阶段得到的词法单元序列转换成抽象语法树(AST)或语法分析树(Parse Tree),以便于后续的语义分析、中间代码生成和目标代码生成等环节的进行。在本次实验中,我们将使用Java语言实现一个简单的语法分析器。 实验要求: 1. 实现自顶向下的递归下降分析器。 2. 支持的文法如下: ``` <program> ::= <stmts_list> <stmts_list> ::= <stmt> | <stmts_list> <stmt> <stmt> ::= <if_stmt> | <while_stmt> | <assign_stmt> <if_stmt> ::= if <condition> then <stmts_list> end <while_stmt> ::= while <condition> do <stmts_list> end <assign_stmt> ::= <id> = <expr> <condition> ::= <expr> <relop> <expr> <expr> ::= <term> | <expr> <addop> <term> <term> ::= <factor> | <term> <mulop> <factor> <factor> ::= <id> | <number> | '(' <expr> ')' <relop> ::= '<' | '>' | '=' | '<=' | '>=' | '<>' <addop> ::= '+' | '-' <mulop> ::= '*' | '/' <id> ::= <letter> | <id> <letter> | <id> <digit> <number> ::= <digit> | <number> <digit> <letter> ::= A | B | ... | Z | a | b | ... | z <digit> ::= 0 | 1 | ... | 9 ``` 注意:文法中的关键字 if、then、end、while、do、and 等均为保留字。 3. 实现的语法分析器应具备以下功能: - 能够识别出语法正确的程序,并输出相应的语法分析树或抽象语法树。 - 能够识别出语法错误的程序,并给出相应的错误提示信息。 - 能够处理注释和空格等无意义的字符。 4. 实验提交要求: - 实验报告,包括程序设计和实验结果分析。 - 程序源代码。 实验设计思路: 1. 根据给定的文法,设计语法分析器的语法规则和对应的产生式。 2. 编写相应的Java代码,将文法转换为递归下降分析器所需要的形式。 3. 实现从输入的源代码中读取词法单元序列的功能。 4. 实现递归下降分析器的核心算法,对输入的词法单元序列进行语法分析,并构建相应的语法分析树或抽象语法树。 5. 在语法分析过程中,需要处理注释和空格等无意义的字符,以便于正确识别语法错误。 6. 在语法分析过程中,需要对输入的源代码进行错误检查,并给出相应的错误提示信息。 7. 输出语法分析树或抽象语法树,以便于后续的语义分析、中间代码生成和目标代码生成等环节的进行。 实验结果分析: 经过实验测试,我们的语法分析器能够正确地识别出合法的程序,并输出相应的语法分析树或抽象语法树。同时,它也能够正确地识别出语法错误的程序,并给出相应的错误提示信息。总的来说,本次实验取得了较好的实验效果。 实验源代码: 见下方代码框:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值