自上而下的LL(1)语法分析法
LL(1)文法:从文法的开始符,向下推导,推出句子。
已知算术表达式文法 G[E]:
E → T E'
E' → + T E'|ε
T → F T'
T' → * F T'|ε
F → ( E )|i
判断该文法是否为 LL(1)文法,计算 FIRST 集合和 FOLLOW 集合
SELECT(E→T E')= FIRST(T)= {(, i}
SELECT(E'→+ T E')= {+}
SELECT(E'→ε)= FOLLOW(E')= {), #}
SELECT(T→F T')= FIRST(F)= {(, i}
SELECT(T' →* F T')= {*}
SELECT(T'→ε)= FOLLOW(T')= {+, ), #}
SELECT(F → ( E ))= {(}
SELECT(F → i)= {i}
具有相同左部产生式的 SELECT 集合交集为空
SELECT(E'→+ T E')∩SELECT(E'→ε)= {+}∩{), #}=Φ
SELECT(T' →* F T')∩SELECT(T'→ε) = {*}∩{+, ), #}=Φ
SELECT(F → ( E ))∩SELECT(F → i) = {(}∩{i}=Φ
所以,转换后的文法是 LL(1)文法。
此外,我们构造LL(1)分析表
表1-1 LL(1)分析表
|
i |
+ |
* |
( |
) |
# |
|
|
E |
E->TE’ |
E->TE’ |
||||
|
E’ |
E’->+TE’ |
E’->ε |
E’->ε |
|||
|
T |
T->FT’ |
T->FT’ |
||||
|
T’ |
T’->ε |
T’->*FT’ |
T’->ε |
T’->ε |
||
|
F |
F->i |
F->(E) |
1 #include<bits/stdc++.h>
2 #define ROW 6
3 #define COLUMN 9
4 using namespace std;
5 string table[ROW][COLUMN]={
6 {"","(",")","*","+","-","/","i","#"},
7 {"E","Te","","","","","","Te",""},
8 {"e","","ε","","+Te","-Te","","","ε"},
9 {"T","Ft","","","","","","Ft",""},
10 {"t","","ε","*Ft","ε","ε","/Ft","","ε"},
11 {"F","(E)","","","","","","i",""}};
12 string Get_table(string x,string a){
13 string ans="";
14 for(int i=0;i<ROW;i++){
15 for(int j=0;j<COLUMN;j++){
16 if(x==table[i][0]&&a==table[0][j]){
17 ans=table[i][j];
18 return ans;
19 }
20 }
21 }
22 return ans;
23 }
24 bool check_LL1(string input){
25 bool flag=true;
26 stack < string > s;
27 s.push("#");
28 s.push("E");
29 int i=0;
30 string a=input.substr(i,1);
31 string x;
32 while(flag){
33 string RS;
34 x=s.top();
35 if(x==a && a=="#"){
36 break;
37 }else if(x==a && a!="#"){
38 s.pop();
39 i++;
40 a=input.substr(i,1);
41 }else if((RS=Get_table(x,a))!=""){
42 if(RS!="ε"){
43 s.pop();
44 for(int j=RS.length()-1;j>=0;j--){
45 string tmp=RS.substr(j,1);
46 s.push(tmp);
47 }
48 }else{
49 s.pop();
50 }
51 }else{
52 flag=false;
53 break;
54 }
55 }
56 return flag;
57 }
58 int main(){
59 string input;
60 while(cin>>input){
61 input=input+"#";
62 if(check_LL1(input)){
63 cout<<"correct"<<endl;
64 }else{
65 cout<<"error"<<endl;
66 }
67 }
68 return 0;
69 }
实验截图:

自上而下的LL(1)语法分析法的更多相关文章
- 《编译原理》-用例题理解-自底向上的语法分析,FIRSTVT,LASTVT集
<编译原理>-用例题理解-自底向上的语法分析,FIRSTVT,LASTVT集 上一篇:编译原理-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法 本 ...
- 《程序设计语言——实践之路》【PDF】下载
程序设计语言--实践之路>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382240 内容简介 本书在美国大学已有使用了十余年,目前被欧 ...
- 【编译原理】语法分析LL(1)分析法的FIRST和FOLLOW集
近来复习编译原理,语法分析中的自上而下LL(1)分析法,需要构造求出一个文法的FIRST和FOLLOW集,然后构造分析表,利用分析表+一个栈来做自上而下的语法分析(递归下降/预测分析),可是这个FIR ...
- 编译原理学习笔记·语法分析(LL(1)分析法/算符优先分析法OPG)及例子详解
语法分析(自顶向下/自底向上) 自顶向下 递归下降分析法 这种带回溯的自顶向下的分析方法实际上是一种穷举的不断试探的过程,分析效率极低,在实际的编译程序中极少使用. LL(1)分析法 又称预测分析法, ...
- TINY语言采用递归下降分析法编写语法分析程序
目录 自顶向下分析方法 TINY文法 消左提左.构造first follow 基本思想 python构造源码 运行结果 参考来源:聊聊编译原理(二) - 语法分析 自顶向下分析方法 自顶向下分析方法: ...
- 编译原理实习(应用预测分析法LL(1)实现语法分析)
#include<iostream> #include<fstream> #include<iomanip> #include<cstdio> #inc ...
- Atitit 表达式原理 语法分析 原理与实践 解析java的dsl 递归下降是现阶段主流的语法分析方法
Atitit 表达式原理 语法分析 原理与实践 解析java的dsl 递归下降是现阶段主流的语法分析方法 于是我们可以把上面的语法改写成如下形式:1 合并前缀1 语法分析有自上而下和自下而上两种分析 ...
- 语法设计——基于LL(1)文法的预测分析表法
实验二.语法设计--基于LL(1)文法的预测分析表法 一.实验目的 通过实验教学,加深学生对所学的关于编译的理论知识的理解,增强学生对所学知识的综合应用能力,并通过实践达到对所学的知识进行验证.通过对 ...
- 语法分析~LL1的实现
语法分析之 LL1分析法实现 一.设计目的 根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析.本次实验的目的主要是加深对预测分析LL(1)分析法的理解. 二.设计要求 程序输入/ ...
- K近邻法(KNN)原理小结
K近邻法(k-nearst neighbors,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用.比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出 ...
随机推荐
- API接口的设计思路
API接口设计是软件开发中非常重要的一环,良好的设计规范能够提高开发效率.减少问题和错误,并增强系统的可维护性和可扩展性.本文从程序员的视角,讨论一些常见的API接口设计规范. 一.遵循RESTf ...
- P251——用RadialGradientBrush填充椭圆,并进行RotateTransform变换
一.认识RadialGradientBrush(径向渐变) 1.坐标 RadialGradientBrush可以用来填充矩形(正方形)和椭圆(正圆), 填充区域使用比例坐标, 椭圆的坐标(0,0)和( ...
- 在 Android Studio Java 项目里混合 Kotlin 编程
首先,先搞明白一个概念,这里的 Java 混合 Kotlin 是指文件层级的混合,即 Java 代码还是写在 .java 文件中,Kotlin 代码还是写在 .kt 文件中,只不过是可以在 Java ...
- linux下查找文件中某字符串出现的行以及该行前后n行
linux下查找文件中某字符串出现的行以及该行前后n行 查找指定字符串的前后n行 grep -A 100 -B 100 "要查找的字符串" 被查找的文件 -A after 后面 - ...
- 深入理解RocketMQ 广播消费
这篇文章我们聊聊广播消费,因为广播消费在某些场景下真的有奇效.笔者会从基础概念.实现机制.实战案例.注意事项四个方面一一展开,希望能帮助到大家. 1 基础概念 RocketMQ 支持两种消息模式:集群 ...
- 一套基于 .NET Core 开发的支付SDK集 - paylink
前言 在我们的日常工作开发中对接一些第三方支付是比较常见的,如最常见的就是支付宝.微信支付的对接.今天给大家推荐一个基于.NET Core开发的支付SDK集:paylink,它极大简化了API调用及通 ...
- jmeter的全局变量(将登陆token设置全局)
1.首先调用登陆接口,用json提取器,取出响应内的token值 2.在beanshell取样器中设置全局变量 //设置全局变量方法一:用函数__setProperty设置${__setProper ...
- Error in v-on handler: “TypeError: _user.default is not a function“
碰到这个问题一开始以为是方法名重复了,后来检查了一遍也没发现方法名或者属性名重复然后发现是 这个导入方法时没加{}的问题. , 无语.
- Codeforces Round 856 (Div. 2)C
C. Scoring Subsequences 思路:我们想要找到满足的最大值的长度最长的的区间,因为单调不减,所以更大的数一定在最大值的里面包含,所以我们用两个指针维护这样一个满足当前i的最大值区间 ...
- 高精度加法(C语言实现)
高精度加法(C语言实现) 介绍 众所周知,整数在C和C++中以int ,long,long long三种不同大小的数据存储,数据大小最大可达2^64,但是在实际使用中,我们仍不可避免的会遇到爆long ...