📜  编译器理论 |设置 1

📅  最后修改于: 2021-09-27 22:37:59             🧑  作者: Mango

以下问题已在 GATE CS 考试中提出。

1. 自顶向下的解析器在解析输入字符串使用以下哪个派生?假设按从左到右的顺序扫描输入 (GATE CS 2000)。
(a) 最左推导
(b) 逆向追踪的最左推导
(c) 最右推导
(d) 逆向求出的最右推导

答案(一)

自顶向下解析 (LL)
在自上而下的解析中,我们只是从开始符号开始,并将不同产生式的右侧与第一条输入进行比较,以查看应该使用哪些产生式。

自上而下的解析器称为LL解析器,因为它解析从L- EFT向右输入,并构建句子的A L eftmost推导。

算法(自顶向下解析)

a) In the current string, choose leftmost nonterminal.
  b) Choose a production for the chosen nonterminal. 
  c) In the string, replace the nonterminal by the right-hand-side 
     of the rule.
  d) Repeat until no more nonterminals. 

LL 文法通常按数字进行分类,例如 LL(1)、LL(0) 等。括号中的数字表示我们在语法中的任何点选择正确产生式时可能需要查看的最大终结符数。

最常见(和有用)的 LL 语法是 LL(1),您可以通过在任何给定时间仅查看输入的第一个终端来选择正确的产生式。对于 LL(2),您必须查看两个符号,依此类推。对于 k 的任何固定值,存在根本不是 LL(k) 文法的文法,遗憾的是,它们非常普遍。

让我们看一个自顶向下解析以下语法的例子。令输入字符串为 ax。

S -> Ax
    A -> a
    A -> b

LL(1) 解析器以 S 开头并询问“我应该尝试哪种产生式?”自然地,它预测 S 的唯一选择。从那里它尝试通过调用方法 A(在递归下降解析器中)匹配 A。前瞻 a 预测生产

A -> a

解析器匹配 a,返回 S 并匹配 x。完毕。推导树是:

S
    / \
   A   x
   |
   a

参考:
http://www.garshol.priv.no/download/text/bnf.html
http://en.wikipedia.org/wiki/Top-down_parsing
http://en.wikipedia.org/wiki/LL_parser

2.为程序的各个部分分配加载地址并调整程序中的代码和数据以反映分配的地址的过程称为(GATE CS 2001)

a) 组装
b) 解析
c) 搬迁
d) 符号解析

答案:(c)
重定位是在运行程序之前用内存中的实际可用地址替换符号引用或库名称的过程。它通常在编译期间(在编译时)由链接器完成,尽管它可以在运行时由重定位加载器完成。编译器或汇编器通常以零作为最低起始地址生成可执行文件。在执行目标代码之前,应调整这些地址,以便它们表示正确的运行时地址。

重定位通常分两步完成:
1. 每个目标代码都有不同的部分,如代码、数据、.bss 等。为了将所有目标组合成一个单一的可执行文件,链接器将所有相似类型的部分合并为该类型的单个部分。然后链接器为每个部分和每个符号分配运行时地址。此时,代码(函数)和数据(全局变量)将具有唯一的运行时地址。
2. 每个部分引用一个或多个应该修改的符号,以便它们指向正确的运行时地址。

参考:
http://en.wikipedia.org/wiki/Relocation_(computer_science)
3、以下哪项说法是错误的? (GATE CS 2001)
a) 一个明确的文法具有相同的最左和最右推导
b) LL(1) 解析器是自顶向下的解析器
c) LALR 比 SLR 更强大
d) 对于任何 k,二义性文法永远不会是 LR(k)

答案:(一)
如果一个语法对于单个句子形式有多个最左边(或最右边)的派生,则该语法是二义性的。句子形式的最左边和最右边的派生可能不同,即使在明确的语法中

4. 以下哪项语法规则违反了运算符语法的要求? P、Q、R 是非终结符,而 r,s,t 是终结符 (GATE CS 2004)。
(i) P -> QR
(ii) P -> QsR
(iii) P -> ε
(iV) P -> QtRr

a) (i) 仅
b) 仅 (i) 和 (iii)
c) (ii) 和 (iii) 仅
d) (iii) 和 (iv) 仅

答案:(b)
解释:
运算符优先级解析器是一种自底向上的解析器,用于解释运算符优先级语法。例如,大多数计算器使用运算符优先级解析器将具有操作顺序格式的人类可读的中缀表示法转换为内部优化的计算机可读格式,如逆波兰表示法 (RPN)。

运算符优先文法是一种可以用运算符优先解析器解析的上下文无关文法。它具有这样的性质,即没有产生式的右侧有空 (ε) 或右侧有两个相邻的非终结符。这些属性允许语法的终结符由优先关系描述,并且利用该关系的解析器比更通用的解析器(如 LALR 解析器)要简单得多。

参考:

http://en.wikipedia.org/wiki/Operator-precedence_grammar
http://en.wikipedia.org/wiki/Operator-precedence_parser


5. 考虑具有以下翻译规则和 E 作为起始符号的语法。
E -> E1 #T {E.value = E1.value * T.value}
| T {E.value = T.value}
T -> T1 & F {T.value = T1.value + F.value}
|F {T.value= F.value}
F -> num {F.value = num.value}

计算表达式的解析树根的 E.value:2 # 3 & 5 # 6 &4。 (GATE CS 2004)

一)200
b) 180
c) 160
d) 40

答案:(c)
解释:
我们可以通过为表达式 2 # 3 & 5 # 6 &4 构建解析树来计算该值。

或者,我们可以通过考虑以下优先级和关联性规则来计算。
语法中的优先级通过确保具有较高优先级运算符产生式规则永远不会产生与运算符的表达与低优先级执行。
在给定的语法中,’&’ 的优先级高于 ‘#’。

语法中运算符* 的左结合是通过确保对于语法中像 S -> S1 * S2 这样的产生式规则,S2 不应该产生带有 * 的表达式来强制执行的。另一方面,为了确保右结合,S1 不应该产生带有 * 的表达式。
在给定的语法中,’#’ 和 & 都是左结合的。

所以表达式 2 # 3 & 5 # 6 &4 将变成
((2 # (3 & 5)) # (6 & 4))
让我们应用翻译规则,我们得到
((2 * (3 + 5)) * (6 + 4)) = 160。