惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
博客园_首页
宝玉的分享
宝玉的分享
S
SegmentFault 最新的问题
Jina AI
Jina AI
Hugging Face - Blog
Hugging Face - Blog
V
Visual Studio Blog
美团技术团队
IT之家
IT之家
罗磊的独立博客
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
月光博客
月光博客
Microsoft Azure Blog
Microsoft Azure Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
博客园 - 叶小钗
M
MIT News - Artificial intelligence
B
Blog RSS Feed
有赞技术团队
有赞技术团队
Y
Y Combinator Blog

姓王者的博客

Linux用户Secure Boot自主维护指南 | 姓王者的博客 MAD Bugs 已经开始——关于信息安全的军备竞赛 | 姓王者的博客 解决钉钉Dingtalk无法在Linux新版内核上启动问题-修复可执行栈错误 | 姓王者的博客 突发:GitHub 正遭受大规模 Issue 赌博广告轰炸 | 姓王者的博客 Ubuntu26.04-beta体验:坚毅浣熊! | 姓王者的博客 fakeclaw装作龙虾发贴吧 | 姓王者的博客 找回12年前的QQ记忆 | 姓王者的博客 在Linux上玩Flash网页游戏-洛克王国 | 姓王者的博客 Copilot将使用交互数据来训练 | 姓王者的博客 重要通知-请更新我的GPG公钥 | 姓王者的博客 为了自由Android | 姓王者的博客 GPL"2,3"事 | 姓王者的博客 短文-对VitePlus的一点🤏小贡献 | 姓王者的博客 Bing收录没了?亲测有效的快速恢复指南 | 姓王者的博客 解决桌面设备二维码快速识别的工具-ClipQR | 姓王者的博客 解决 Nautilus 自定义终端插件安装依赖问题 | 姓王者的博客 OpenClaw 该熄火了 | 姓王者的博客 Vite8 - 统一的基建开始 | 姓王者的博客 Astro 6 推出啦 | 姓王者的博客 ubuntu的openvpn异常暂停推送更新 | 姓王者的博客 Ubuntu 24.04 安装 Win10 虚拟机 | 姓王者的博客 ESA-后记:热爱阿里云 | 姓王者的博客 Moonbit 0.8.0 重大发布,我也要改一下我的包 | 姓王者的博客 ESA Pages 边缘开发大赛获奖 | 姓王者的博客 Astro: 优化katex,mermaid和灯箱使用 | 姓王者的博客 从edgeone迁移到esa | 姓王者的博客 出租人类:AI时代的荒诞与真实 | 姓王者的博客 Astro 5.17构建性能优化实践:从18s到13s | 姓王者的博客 Moonbit License Checker 开发使用 | 姓王者的博客 Stalux Astro博客主题自荐 | 姓王者的博客
编译原理:文法转换 | 姓王者的博客
作者:xingwangzhe · 2025-03-26 · via 姓王者的博客

编译原理:文法转换

🕒 阅读时间:1 分钟 📝 字数:361 👀 阅读量: Loading...

文法转换

文法GS→aAd∣aBeA→cB→b输入abc 文法G\\ S \rarr aAd | aBe \\ A \rarr c \\ B \rarr b \\ 输入 a b c

:::warning 同一非终结符的多个候选式存在共同前缀,将导致回溯现象 :::

文法GE→E+T∣E−T∣TT→T∗F∣T/F∣FF→(E)∣id输入id+id∗idE⇒E+TE⇒E+T+T... 文法G\\ E \rarr E+T | E - T | T \\ T \rarr T*F | T/F | F \\ F \rarr ( E ) | id \\ 输入 id + id * id\\ E \Rightarrow E + T \\ E \Rightarrow E + T + T \\ ...\\

:::danger

左递归文法会使递归下降分析器陷入无限循环

:::

概念

:::tip

含有A→AaA \rarr Aa形式产生式的文法称为是直接左递归


如果一个文法中有一个非终结符A使得对某个串a存在一个推导A⇒+AaA \Rightarrow {}^{+}Aa,那么这个文法就是左递归


经过两步或两步以上推到产生的左递归成为是间接左递归

:::

消除直接左递归

A→Aα∣β(a≠ε,β不以A开头)⇓A→βA′A′→αA′∣εA \rarr A\alpha | \beta (a \not= \varepsilon,\beta不以A开头)\\ \Downarrow \\ A \rarr \beta A^{'} \\ A^{'} \rarr \alpha A^{'} |\varepsilon

:::info

事实上,这种消除过程,就是把左递归转换成了右递归

:::

更一般地

A→Aα1∣Aα2∣...∣Aαn∣β1∣β2∣...∣βm(αi≠ε,βj不以A开头)⇓A→β1A′∣β2A′∣...∣βmA′A′→α1A′∣α2A′∣...∣anA′∣εA \rarr A \alpha_1 | A \alpha_2 | ... | A \alpha_n | \beta_1 | \beta_2 | ... | \beta_m \\ (\alpha_i \not= \varepsilon, \beta_j不以A开头 )\\ \Downarrow \\ A \rarr \beta_1 A^{'} | \beta_2 A^{'}|...|\beta_m A^{'} \\ A^{'} \rarr \alpha_1 A^{'} | \alpha_2 A^{'}| ... | a_n A^{'} | \varepsilon

:::warning

消除左递归是要付出代价的---引进了一些非终结符ε\varepsilon _产生式

:::

消除间接左递归

S→Aα∣bA→Ac∣Sd∣ε>>将S的定义带入A−产生式,得:A−Ac∣Aad∣bd∣ε>>消除A−产生式的直接左递归,得:A→bdA′∣AA′→cA′∣adA′∣εS \rarr A \alpha | b \\ A \rarr Ac | Sd | \varepsilon \\ >>将S的定义带入A-产生式,得:\\ A-Ac | Aad | bd | \varepsilon \\ >> 消除A-产生式的直接左递归,得: \\ A \rarr bdA^{'} | A \\ A^{'} \rarr cA^{'} | adA^{'} | \varepsilon

提取左公因子

文法G

S→aAd∣aBeA→cB→b⇓S \rarr aAd | aBe \\ A \rarr c \\ B \rarr b \\ \Downarrow \\

文法G′G^{'}

S→aS′S′→Ad∣BeA→cB→bS \rarr aS^{'} \\ S^{'} \rarr Ad |Be \\ A \rarr c \\ B \rarr b \\

:::info

通过改写产生式来推迟决定,等读入了足够多的输入,获得足够信息后再做出正确的选择

:::