编译原理之表达式语法分析(一)——自顶向下
2015-12-30 15:31
316 查看
文法变换
G(E):E→Eω0T|T E为算术表达式,T为项
T→Tω1F|F F为因式项,ω0为 +或 -, ω1为 * 或 /
F→i|(E) i 为变量或常量
G(E)不是LL(1)文法,所以需要进行文法变换
G’(E):
E→T{ω0T}
T→F{ω1F}
F→i|(E)
或者G”(E):
E→TA
A→{ω0T}A
T→FB
B→{ω1F}B
F→i|(E)
递归下降法
Preset.h#ifndef PRESET_H_INCLUDED #define PRESET_H_INCLUDED std::string Str; int top; void HandleE(); void HandleA(); void HandleT(); void HandleB(); void HandleF(); #endif // PRESET_H_INCLUDED
main.c
#include <iostream> #include <cstdio> #include <cstring> #include "Preset.h" using namespace std; int main() { while(cin >> Str) { top=0; if(Str[top]=='#') cout << "Yes" << endl; else cout << "No" << endl; } return 0; } void HandleE() { HandleT(); HandleA(); } void HandleA() { if(Str[top]=='+' || Str[top]=='-') { top++; HandleT(); HandleA(); } } void HandleT() { HandleF(); HandleB(); } void HandleB() { if(Str[top]=='*' || Str[top]=='/') { top++; HandleF(); HandleB(); } } void HandleF() { if(isalpha(Str[top])) top++; else if(Str[top]=='(') { top++; HandleE(); if(Str[top]==')') top++; } }
LL(1)
LL(1)分析表如下:栈顶符/当前符 | i | + | * | ( | ) | # |
---|---|---|---|---|---|---|
E | 1 | 1 | ||||
A | 2 | 3 | 3 | |||
T | 4 | 4 | ||||
B | 3 | 5 | 3 | 3 | ||
F | 6 | 7 | ||||
) | 6 | |||||
# | OK |
(AT,P)
(AT,N)
(空,P)
(BF,P)
(BF,N)
(空,N)
( )E,N)
P表示不变,N表示读取下一个
故
AT ——1、2
BF——4、5
空——3、6
)E——7
P——1、3、4
N——2、5、6、7
Preset.h
#ifndef PRESET_H_INCLUDED #define PRESET_H_INCLUDED std::string Str; int top;//栈顶符指针 int stop;//当前符指针 int tell(); std::string Stack_ch; #endif // PRESET_H_INCLUDED
main.c
#include <iostream> #include <cstring> #include <string> #include <cstdio> #include "Preset.h" using namespace std; int main() { while(cin >> Str) { top=0; stop=0; Stack_ch[top]='#'; Stack_ch[++top]='E'; int ans=0; ans=tell(); while(ans!=-1 && ans!=0) { ans=tell(); } if(ans==-1)cout << "Yes" << endl; else cout << "No" << endl; } return 0; } int tell() { int op=-1; if(Stack_ch[top]=='#' && Str[stop]=='#') { return op; } op=0; switch(Stack_ch[top]) { case 'E': if(Str[stop]=='(' || isalpha(Str[stop]))op=1; break; case 'A': if(Str[stop]=='+' || Str[stop]=='-')op=2; else if(Str[stop]==')' || Str[stop]=='#')op=3; break; case 'T': if(Str[stop]=='(' || isalpha(Str[stop]))op=4; break; case 'B': if(Str[stop]=='+' || Str[stop]=='-' || Str[stop]==')' || Str[stop]=='#')op=3; else if(Str[stop]=='*' || Str[stop]=='/')op=5; break; case 'F': if(Str[stop]=='(')op=7; else if(isalpha(Str[stop]))op=6; break; case ')': if(Str[stop]==')')op=6; break; default: break; } if(op==0)return op; top--; if(op==2 || op==5 || op==6 || op==7)stop++; switch(op) { case 1: case 2: Stack_ch[++top]='A'; Stack_ch[++top]='T'; break; break; case 4: case 5: Stack_ch[++top]='B'; Stack_ch[++top]='F'; break; case 7: Stack_ch[++top]=')'; Stack_ch[++top]='E'; break; default: break; } return op; }
相关文章推荐
- Android资源管理框架(Asset Manager)简要介绍
- 嵌入式linux驱动程序,内核源码树
- Error:The SDK Build Tools revision (19.0.3) is too low for project ':app'. Minimum required is 19.1.
- Appium自动化中截图的问题
- OpenGl中的Nurbs B样条曲面的封装的GLU的NURBS的接口
- 数据现象——PC端的上班效应
- 排序算法之希尔排序
- 使用Xcode和Instruments调试解决iOS内存泄露
- Jinx项目2015-12-30日记
- Shiro HelloWorld (二)从数据库中获得数据
- LeetCodeP079 Word Search
- Linux下实现U盘、SD卡自动挂载功能(转)
- iOS 微信分享
- 列出目录和文件并链接的两种方法
- android 动态改变字体大小
- 减少网卡中断收包产生的CPU消耗
- Android编程获取系统隐藏服务实现锁屏的方法
- Django-blog开源
- 通过ViewController的关键流程来理解流程建模
- 2015.12.30