编译原理第二版4.4答案

4.4 节的练习

4.4.1

为下面的每个文法设计一个预测分析器,并给出预测分析表。你可能先要对文法进行提取左公因子或者消除左递归的操作。

练习 4.2.2 中 1 - 7 中的文法。

解答
  1. S -> 0 S 1 | 0 1

    step1. 提取左公因子

     S -> 0 A
     A -> S 1 | 1
    

    step2. 消除左递归

     S -> 0 A
     A -> 0 A 1 | 1
    

    step3. 预测分析表

    非终结符号输入符号
    01$
    SS -> 0 A
    AA -> 0 A 1A -> 1
  2. S -> + S S | * S S | a

    step1. 无左公因子

    step2. 无左递归

    step3. 预测分析表

    非终结符号输入符号
    +*a$
    SS -> + S SS -> * S SS -> a
  3. ! S -> S (S) S | ε

    step1. 无左公因子

    step2. 消除左递归

     S -> A
     A -> (S) S A | ε
    

    step3. 预测分析表

    非终结符号输入符号
    ()$
    SS -> AS -> AS -> A
    AA -> (S) S A
    A -> ε
    A -> εA -> ε
  4. ! S -> S + S | S S | (S) | S * | a

    step1. 提取左公因子

     S -> SA | (S) | a
     A -> +S | S | *
    

    进一步提取终结符

     S -> SA | T
     A -> +S | S | *
     T -> (S) | a  
    

    step2. 消除左递归(根据 p135 的算法 4.19)

     i = 1
             S -> TB
             B -> AB | ε
             
     i = 2
         j = 1
             A -> +S | TB | *
             
     i = 3
         j = 1
             无需处理
         j = 2
             无需处理
    

    得到最终的产生式

     S -> TB
     B -> AB | ε
     A -> +S | TB | *
     T -> (S) | a  
    

    step3. first && follow

     first(T) = [(, a]
     first(A) = [+, *] + first(T) =[+, *, (, a]
     first(B) = [ε] + first(A) = [ε, +, *, (, a]
     first(S) = first(T) = [(, a]
    
     follow(T) = [$, +, *, (, a]
     follow(A) = [$, +, *, (, ), a]
     follow(B) = [$]
     follow(S) = [$, +, *, (, ), a]
    

    step4. 预测分析表

    非终结符号输入符号
    ()+*a$
    SS -> TBS -> TB
    BB -> ABB -> ABB -> ABB -> ABB -> ε
    AA -> TBA -> +SA -> \*A -> TB
    TT -> (S)T -> a
  5. S -> (L) | a 以及 L -> L, S | S

    step1. 无左公因子

    step2. 消除左递归

     S -> (L) | a
     L -> SA
     A -> ,SA | ε
    

    step3. 预测分析表

  6. grammar for boolean expressions:

    bexpr -> bexpr or bterm | bterm
    bterm -> bterm and bfactor | bfactor
    bfactor -> not bfactor | ( bexpr ) | true | false
    

    step1. 无左公因子

    step2. 消除左递归

    bexpr -> bterm bexpr'
    bexpr' -> or bterm bexpr' | ε
    bterm -> bfactor bterm'
    bterm' -> and bfactor bterm' | ε
    bfactor -> not bfactor | (bexpr) | true | false
    

    step3. first && follow

    first(bexpr) = first(bterm) = first(bfactor) = [not, (, true, false]
    first(bexpr') = [or, ε]
    first(bterm') = [and, ε]
    
    follow(bexpr) = follow(bexpr') = [), $]
    follow(bterm) = follow(bterm') = [or, $]
    follow(bfactor) = [and, $]
    
    

    step4. 预测分析表

    非终结符号输入符号
    andornot()truefalse$
    bexprbexpr -> bterm bexpr'bexpr -> bterm bexpr'bexpr -> bterm bexpr'bexpr -> bterm bexpr'
    bexpr'bexpr' -> or bterm bexpr'bexpr' -> εbexpr' -> ε
    btermbterm -> bfactor bterm'bterm -> bfactor bterm'bterm -> bfactor bterm'bterm -> bfactor bterm'
    bterm'bterm' -> and bfactor bterm'bterm' -> εbterm' -> ε
    bfactorbfactor -> not bfactorbfactor -> (bexpr) bfactor -> truebfactor -> false

4.4.2 !!

有没有可能通过某种方法修改练习 4.2.1 中的文法,构造出一个与该练习中的语言(运算分量为 a 的后缀表达式)对应的预测分析器?

解答
S -> SS+ | SS* | a

step1. 提取左公因子

S -> SSA | a
A -> + | *

step2. 消除左递归

i = 1 
        S -> aB
        B -> SAB | ε
        A -> + | *
i = 2
    j = 1
        S -> aB
        B -> aBAB | ε
        A -> + | *

step3. 预测分析表

非终结符号输入符号
+*a$
SS -> aB
AA -> +A -> *
BB -> εB -> εB -> SABB -> ε

4.4.3

计算练习 4.2.1 的文法的 FIRST 和 FOLLOW 集合。

解答
  • first(S) = [a]
  • follow(S) = [a, +, *]

4.4.4

计算练习 4.2.2 中各个文法的 FIRST 和 FOLLOW 集合。

解答
  1. S -> 0 S 1 | 0 1

    • first(S) = [0]
    • follow(S) = [1, $]
  2. S -> + S S | * S S | a

    • first(S) = [+, *, a]
    • follow(S) = [+, *, a, $]
  3. S -> S (S) S | ε

    • first(S) = [(, ε]
    • followS(S) = [), $]
  4. S -> S + S | S S | (S) | S * | a

    • first(S) = [(, a]
    • follow(S) = [+, (, ), a, *, $]
  5. S -> (L) | a 以及 L -> L, S | S

    • first(S) = [(, a]
    • follow(S) = [",", $]
    • first(L) = first(S) = [(, a]
    • follow(L) = [), “,”, $]
  6. S -> a S b S | b S a S | ε

    • first(S) = [a, b, ε]
    • follow(S) = [a, b, $]
  7. 下面的布尔表达式对应的文法:

     bexpr -> bexpr or bterm | bterm
     bterm -> bterm and bfactor | bfactor
     bfactor -> not bfactor | (bexpr) | true | false
    

4.4.5

文法 S -> aSa | aa 生成了所有由 a 组成的长度为偶数的串。我们可以为这个文法设计一个带回溯的递归下降分析器。如果我们选择先用产生式 S -> aa 展开,那么我们只能识别串 aa。因此,任何合理的递归下降分析器将首先尝试 S -> aSa。

  1. ! 说明这个递归下降分析器识别输入 aa,aaaa 和 aaaaaaaa,但识别不了 aaaaaa。
  2. !! 这个递归下降分析器识别什么样的语言?

注意

以下题目请参考 Aho 本人的讲义:Aho: Properties of Context-Free Languages本地副本

此外还有另一篇内容相似的文章本地副本

关于 CNF 和 CYK 算法,有较多相关资料,自行搜索

4.4.6 !

如果一个文法没有产生式体为 ε 的产生式,那么这个文法就是无 ε 产生式的。

  1. 给出一个算法,他的功能是把任何文法转变成一个无 ε 产生式的生成相同语言的文法(唯一可能的例外是空串——没有哪个无 ε 产生式的文法能生成 ε)。提示:首先找出所有可能为空的非终结符号。非终结符号可能为空是指它(可能通过很长的推导)生成 ε。
  2. 将你的算法应用于文法 S -> aSbS | bSaS | ε

4.4.7 !

单产生式是指其产生式体为单个非终结符号的产生式,即形如 A -> B 的产生式。

  1. 给出一个算法,它可以把任何文法转变成一个生成相同语言(唯一可能的例外是空串)的、无 ε 产生式、无单产生式的文法。提示:首先消除 ε 产生式,然后找出所有满足下列条件的非终结符号对 A 和 B:存在 A =*=> B。
  2. 将你的算法应用于 4.1.2 节的算法。
  3. 说明作为 (1) 的一个结果,我们可以把一个文法转换成一个没有环的等价文法。

4.4.8 !!

如果一个文法的每个产生式要么形如 A -> BC,要么形如 A -> a,那么这个文法就成为 Chomsky 范式(Chomsky Normal Form, CNF)。说明如何将任意文法转变成一个生成相同语言(唯一可能的例外是空串——没有 CNF 文法可以生成 ε)的 CNF 文法。

4.4.9 !

对于每个具有上下文无关的语法,其长度为 n 的串可以在 O(n^3) 的时间内完成识别。完成这种识别工作的一个简单方法称为 Cocke-Younger-Kasami(CYK)算法。该算法基于动态规划技术。也就是说,给定一个串 a_1a_2…a_n,我们构造出一个 nxn 的表 T 使得 T_ij 是可以生成子串 a_ia_i+1…aj 的非终结符号的集合。如果基础文法是 CNF 的,那么只要我们按照正确的顺序来填表:先填 j-i 值最小的条目,则表中的每一个条目都可以在 O(n) 时间内填写完毕。给出一个能够正确填写这个表的条目的算法,并说明你的算法的时间复杂度为 O(n^3)。填完这个表之后,你如何判断 a_1a_2…a_n 是否在这个语言中?

4.4.10 !

说明我们如何能够在填好练习 4.4.9 中的表之后,在 O(n) 的时间内获得 a_1a_2…a_n 对应的一颗语法分析树?提示:修改练习 4.4.9 中的表 T,使得对于表的每个条目 T_ij 中的每个非终结符号 A,这个表同时记录了其他条目中的哪两个非终结符号组成的对偶使得我们将 A 放到 T_ij 中。

4.4.11 !

修改练习 4.4.9 中的算法,使得对于任意符号串,他可以找出至少需要执行多少次插入、删除和修改错误(每个错误是一个字符)的操作才能将这个串变成基础文法的语言的句子。

4.4.12 !

stmt -> if e then stmt stmtTail
      | while e do stmt
      | begin list end
      | s
stmtTail -> else stmt
          | ε
list -> stmt listTail
listTail -> ; list
          | ε

上面的代码给出了对应于某些语句的文法。你可以将 e 和 s 当做分别代表条件表达式和“其他语句”的终结符号。如果我们按照下列方法来解决因为展开可选“else”(非终结符号 stmtTail)而引起的冲突:当我们从输入中看到一个 else 时就选择消耗掉这个 else。使用 4.4.5 节中描述的同步符号的思想:

  1. 为这个文法构造一个带有错误纠正信息的预测分析表。
  2. 给出你的语法分析器在处理下列输入时的行为:
    1. if e then s; if e then s end
    2. while e do begin s; if e then e; end
<think>好的,用户现在问的是关于之前提供的Maven依赖配置的具体操作步骤,也就是说他们想知道如何在自己的项目中正确配置这些依赖项。首先,我需要确定用户可能的需求和背景。用户可能一个刚开始使用Hadoop和Maven的开发者,在Eclipse中配置项目时遇到了问题,或者对pom.xml的配置不太熟悉,需要详细的步骤说明。 接下来,我需要回顾之前提供的pom.xml内容,里面包含了Hadoop的核心依赖和Woodstox的依赖。用户可能已经尝试过这些配置,但可能遇到了构建错误,比如依赖冲突或缺少必要的库,特别是提到的XML解析错误,这说明用户可能在运行时遇到了相关的异常,比如ClassNotFoundException或者NoClassDefFoundError,特别是在处理Hadoop的XML配置文件时。 然后,我需要分解配置这些依赖的具体步骤。首先,用户需要在Eclipse中创建一个Maven项目,或者将现有的项目转换为Maven项目。然后,他们需要编辑pom.xml文件,添加这些依赖项。但可能用户对如何操作pom.xml不太清楚,所以需要详细的步骤,比如如何打开pom.xml,在哪里添加依赖代码块,以及如何保存更新项目依赖。 另外,用户可能不知道为什么要添加Woodstox的依赖,所以需要解释Hadoop内部可能使用的StAX解析器与项目中的其他库冲突,导致XML解析错误,而添加Woodstox可以解决这个问题。同时,需要提醒用户注意本兼容性,确保Hadoop的本和Woodstox的本是兼容的,避免引入新的问题。 还有,用户可能在配置完依赖后,不知道如何构建项目,或者如何处理Maven的依赖下载问题。需要指导他们使用Maven的更新项目功能,确保依赖正确下载,且检查构建路径是否有错误。如果出现依赖冲突,可能需要使用Maven的依赖排除功能,或者调整本号。 此外,用户可能遇到网络问题,无法从Maven中央仓库下载依赖,这时候需要建议他们检查网络设置,或者配置镜像仓库,比如阿里云的Maven镜像,以加速下载。 最后,考虑到用户可能是在Ubuntu系统下使用Eclipse,可能需要指导他们如何在Eclipse中配置Maven,比如指定settings.xml文件的位置,或者如何重新导入Maven项目。同时,提醒用户确认Hadoop的环境变量是否配置正确,确保程序在运行时能够访问Hadoop的相关库。 总结来说,用户需要的是一个从创建Maven项目开始,到正确配置pom.xml依赖,解决常见问题,成功构建项目的详细指南。需要分步骤说明,每一步的操作和可能遇到的问题及解决办法,确保用户能够顺利地完成配置运行之前的HDFS文件合程序。</think>以下是关于如何在Eclipse项目中配置Maven依赖的详细步骤说明: --- ### **完整配置流程(图文指引)** #### **步骤1:创建Maven项目** 1. 在Eclipse中: - 点击 `File > New > Other` - 选择 `Maven > Maven Project` - 勾选 `Create a simple project`,设置: ```ini GroupId: com.example ArtifactId: hdfs-merger Version: 1.0.0 ``` - 点击Finish完成创建 #### **步骤2:编辑pom.xml** 1. 在项目根目录找到`pom.xml` 2. **替换`<dependencies>`节点**为以下内容: ```xml <dependencies> <!-- Hadoop基础功能 --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>3.3.6</version> <!-- 排除冲突日志组件 --> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <!-- HDFS操作支持 --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>3.3.6</version> </dependency> <!-- 解决XML解析兼容问题 --> <dependency> <groupId>org.codehaus.woodstox</groupId> <artifactId>woodstox-core-asl</artifactId> <version>4.4.1</version> <!-- 显式声明依赖范围 --> <scope>runtime</scope> </dependency> </dependencies> ``` #### **步骤3:添加构建插件(可选)** 在`<build>`节点下添加(解决编译兼容性问题): ```xml <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> ``` --- ### **关键配置说明** #### **1. 依赖层次解析** | 依赖项 | 作用域 | 必要性 | |-----------------------|-------------|-------| | hadoop-common | compile | 必须 | | hadoop-hdfs | compile | 必须 | | woodstox-core-asl | runtime | 推荐 | #### **2. 本匹配原则** - **Hadoop 3.3.x**:要求Java 8环境 - **Woodstox 4.4.x**:兼容Hadoop 3.x的XML解析需求 - **避免本冲突**:如果项目中使用其他组件(如Spark),需统一Hadoop生态本 --- ### **验证配置正确性** #### **方法1:Maven依赖树分析** 在项目目录执行: ```bash mvn dependency:tree ``` 期望输出应包含: ``` [INFO] +- org.apache.hadoop:hadoop-common:jar:3.3.6:compile [INFO] +- org.apache.hadoop:hadoop-hdfs:jar:3.3.6:compile [INFO] \- org.codehaus.woodstox:woodstox-core-asl:jar:4.4.1:runtime ``` #### **方法2:Eclipse验证** 1. 右键项目 > Maven > Update Project 2. 检查`Maven Dependencies`库: - 应有`hadoop-common-3.3.6.jar` - 不应出现`xml-apis`或`xercesImpl`的冲突本 --- ### **常见问题处理** #### **问题1:Missing artifact错误** **现象**:pom.xml出现红色错误标记 **解决方案**: 1. 检查网络连接 2. 强制更新Maven仓库: ```bash mvn clean install -U ``` 3. 或手动删除本地仓库中对应路径: ``` ~/.m2/repository/org/apache/hadoop/ ``` #### **问题2:NoSuchMethodError** **原因**:依赖本冲突 **排查方法**: ```bash mvn dependency:tree -Dverbose -Dincludes=冲突类所在的包名 ``` **示例**:若报错涉及`com.fasterxml.jackson`,添加: ```xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.7</version> </dependency> ``` --- ### **配置优化建议** 1. **依赖管理**:建议使用`<dependencyManagement>`统一管理本号 2. **镜像加速**:在`settings.xml`中添加阿里云镜像: ```xml <mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror> ``` 如果需要更详细的配置截图或视频演示,请告知具体需要哪部分的操作演示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值