LR(0)分析法

LR(0)是一种自底向上的语法分析方法。两个基本动作是移进和规约。

具体例子如下

已知文法G[E]

(1) E→aА

(2) E→bB

(3) A→cА

(4) A→d

(5) B→cB

(6) B→d

编写LR(0)分析算法,用于识别符号串是否为合法的句子。

  设计方法

a.将文法 G[E]拓广为文法 G[E']

(0) S'→E 

(1) E→aA

(2) E→bB

(3) A→cA 

(4) A→d

(5) B→cB 

(6) B→d

b.构造识别可归约前缀的 NFA

c. 将识别可归约前缀的 NFA 确定化成DFA

 

 

 

d. 根据识别可归约前缀的 DFA 构造文法的 LR(0)分析表

表2-1 LR(0)分析表

状态

a

b

c

d

#

E

A

B

0

S1

S2

 

 

 

3

 

 

1

 

 

S4

S5

 

 

6

 

2

 

 

S7

S8

 

 

 

9

3

 

 

 

 

acc

 

 

 

4

 

 

S4

S5

 

 

10

 

5

r4

r4

r4

r4

r4

 

 

 

6

r1

r1

r1

r1

r1

 

 

 

7

 

 

S7

S8

 

 

 

11

8

r6

r6

r6

r6

r6

 

 

 

9

r2

r2

r2

r2

r2

 

 

 

10

r3

r3

r3

r3

r3

 

 

 

11

r5

r5

r5

r5

r5

 

 

 

 

e. 设计 LR(0)分析程序

自底向上的语法分析的两个基本动作就是,移进与规约。分析一下表 2-1 中 文法的 LR(0)分析表,可以发现这两个动作在表中都有。进一步分析可知,这些 移进与规约动作在表的前面终结符列中,因此,这部分称之为 ACTION 表。

表中不但给出了两个基本动作,还给出了规约时,弹出产生式右部,压入左 部之后,应该转换到的状态。例如,当前状态为 9,状态 9 为句柄识别态,查表 得:r2,表示使用第二个产生式E→bB 进行规约。规约动作分为两步:第一步弹 出句柄 bB,从识别文法可归约前缀的 DFA 中可知,弹出句柄 bB后,从当前状态为 9 回到状态 0;第二步就是压入左部 E, 从当前状态 0,转换到状态 3。在表中 的第 0 行第 E 列中就给出状态 3。

分析表 可知,表中的非终结符列填入的是某一规约动作,压入产生式左 部(非终结符)之后,转换到的状态。因此,这部分称之为 GOTO 表。

 

实验代码:

  1 #include<bits/stdc++.h>
  2 #define ROW 13
  3 #define COLUMN 9
  4 using namespace std;
  5 //产生式
  6 string products[7][2]={
  7 "","",
  8 "E","aA",
  9 "E","bB",
 10 "A","cA",
 11 "A","d",
 12 "B","cB",
 13 "B","d"
 14 };
 15 //LR(0)分析表
 16 string actiontable[ROW][COLUMN]={
 17 {" " ,"a"  ,"b"  ,"c"  ,"d"  ,"#"  ,"E"  ,"A"  ,"B"},
 18 {"0" ,"s1" ,"s2" ," "  ," "  ," "  ,"3"  ," "  ," "},
 19 {"1" ," "  ," "  ,"s4" ,"s5" ," "  ," "  ,"6"  ," "},
 20 {"2" ," "  ," "  ,"s7" ,"s8" ," "  ," "  ," "  ,"9"},
 21 {"3" ," "  ," "  ," "  ," "  ,"acc"," "  ," "  ," "},
 22 {"4" ," "  ," "  ,"s4" ,"s5" ," "  ," "  ,"10" ," "},
 23 {"5" ,"r4" ,"r4" ,"r4" ,"r4" ,"r4" ," "  ," "  ," "},
 24 {"6" ,"r1" ,"r1" ,"r1" ,"r1" ,"r1" ," "  ," "  ," "},
 25 {"7" ," "  ," "  ,"s7" ,"s8" ," "  ," "  ," "  ,"11"},
 26 {"8" ,"r6" ,"r6" ,"r6" ,"r6" ,"r6" ," "  ," "  ," "},
 27 {"9" ,"r2" ,"r2" ,"r2" ,"r2" ,"r2" ," "  ," "  ," "},
 28 {"10","r3" ,"r3" ,"r3" ,"r3" ,"r3" ," "  ," "  ," "},
 29 {"11","r5" ,"r5" ,"r5" ,"r5" ,"r5" ," "  ," "  ," "}};
 30 stack<int> sstatus; //状态栈
 31 stack<char> schar;  //符号栈
 32 struct Node{
 33     char type;
 34     int num;
 35 };
 36 //打印步骤
 37 void print_step(int times){ 
 38     stack<char> tmp2;
 39     cout<<times<<setw(4);
 40     while(!schar.empty()){
 41         char t=schar.top();
 42         schar.pop();
 43         tmp2.push(t);
 44         cout<<t;
 45     }
 46     while(!tmp2.empty()){
 47         int t=tmp2.top();
 48         tmp2.pop();
 49         schar.push(t);
 50     }
 51 }
 52 //查表
 53 Node Action_Goto_Table(int status,char a){
 54     int row=status+1;
 55     string tmp;
 56     for(int j=1;j<COLUMN;j++){
 57         if(a==actiontable[0][j][0]){
 58             tmp=actiontable[row][j];
 59         }
 60     }
 61     Node ans;
 62     if(tmp[0]>='0'&&tmp[0]<='9'){
 63         int val=0;
 64         for(int i=0;i<tmp.length();i++){
 65             val=val*10+(tmp[i]-'0');
 66         }
 67         ans.num=val;
 68         ans.type=' ';
 69     }else if(tmp[0]=='s'){
 70         int val=0;
 71         for(int i=1;i<tmp.length();i++){
 72             val=val*10+(tmp[i]-'0');
 73         }
 74         ans.type='s';
 75         ans.num=val;
 76     }else if(tmp[0]=='r'){
 77         int val=0;
 78         for(int i=1;i<tmp.length();i++){
 79             val=val*10+(tmp[i]-'0');
 80         }
 81         ans.type='r';
 82         ans.num=val;
 83     }else if(tmp[0]=='a'){
 84         ans.type='a';
 85     }else{
 86         ans.type=' ';
 87     }
 88     return ans;
 89 }
 90 //LR(0)分析算法
 91 bool LR0(string input){
 92     while(!sstatus.empty()){
 93         sstatus.pop();
 94     }
 95     while(!schar.empty()){
 96         schar.pop();
 97     }
 98     int times=0;
 99     bool flag=true;
100     int st=0;
101     sstatus.push(st);
102     schar.push('#');
103     int i=0;
104     char a=input[i];
105     while(true){
106         Node action=Action_Goto_Table(st,a);
107         if(action.type=='s'){
108             st=action.num;
109             sstatus.push(st);
110             schar.push(a);
111             a=input[++i];
112             print_step(++times);
113             cout<<setw(10)<<'s'<<st<<endl;
114 
115         }else if(action.type=='r'){
116             int n=action.num;
117             string ls=products[n][0];
118             string rs=products[n][1];
119             for(int j=0;j<rs.length();j++){
120                 sstatus.pop();
121                 schar.pop();
122             }
123             schar.push(ls[0]); //only one char
124             st=sstatus.top();
125             action =Action_Goto_Table(st,ls[0]);
126             st=action.num;
127             sstatus.push(st);
128             print_step(++times);
129             cout<<setw(10)<<'r'<<" "<<ls<<"->"<<rs<<endl;
130 
131         }else if(action.type=='a'){
132             flag=true;
133             break;
134         }else{
135             flag=false;
136             break;
137         }
138     }
139     return flag;
140 }
141 int main(){
142     string input;
143     while(cin>>input){
144         if(LR0(input)){
145             cout<<"syntax correct"<<endl;
146         }else{
147             cout<<"syntax error"<<endl;
148         }
149     }
150     return 0;
151 }

 

 

 

转载于:https://www.cnblogs.com/ISGuXing/p/11119643.html

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LR(0)语法分析法是一种自底向上的语法分析方法,它可以通过构建LR(0)自动机来实现对给定文法的语法分析。以下是Python实现LR(0)分析法的步骤: 1. 定义文法符号类 首先,我们需要定义一个文法符号类,用来表示终结符和非终结符。 ```python class Symbol: def __init__(self, name, is_terminal): self.name = name self.is_terminal = is_terminal def __str__(self): return self.name ``` 2. 定义产生式类 接下来,我们需要定义一个产生式类,用来表示文法的产生式。 ```python class Production: def __init__(self, lhs, rhs): self.lhs = lhs self.rhs = rhs def __str__(self): return f"{self.lhs} -> {' '.join(str(s) for s in self.rhs)}" ``` 3. 定义文法类 接着,我们需要定义一个文法类,用来表示整个文法。 ```python class Grammar: def __init__(self, productions, start_symbol): self.productions = productions self.start_symbol = start_symbol def __str__(self): return '\n'.join(str(p) for p in self.productions) ``` 4. 定义LR(0)自动机状态类 现在,我们需要定义一个LR(0)自动机状态类,用来表示LR(0)自动机的状态。 ```python class LR0State: def __init__(self, items): self.items = items def __str__(self): return '\n'.join(str(item) for item in self.items) ``` 其中,items是一个包含LR(0)项的列表,每个LR(0)项都是一个元组,包含产生式和一个位置。 ```python class LR0Item: def __init__(self, production, dot): self.production = production self.dot = dot def __str__(self): rhs = list(map(str, self.production.rhs)) rhs.insert(self.dot, '·') return f"{self.production.lhs} -> {' '.join(rhs)}" ``` 5. 定义LR(0)分析器类 最后,我们需要定义一个LR(0)分析器类,用来实现LR(0)分析法。 ```python class LR0Parser: def __init__(self, grammar): self.grammar = grammar self.start_state = LR0State([LR0Item(grammar.productions[0], 0)]) self.states = [] self.transitions = {} self.build() def build(self): self.states.append(self.start_state) unprocessed_states = [self.start_state] while unprocessed_states: state = unprocessed_states.pop(0) for symbol in self.get_next_symbols(state): items = self.get_items_for_symbol(state, symbol) if items: new_state = LR0State(items) if new_state not in self.states: self.states.append(new_state) unprocessed_states.append(new_state) self.transitions[(state, symbol)] = new_state def get_next_symbols(self, state): symbols = set() for item in state.items: if item.dot < len(item.production.rhs): symbols.add(item.production.rhs[item.dot]) return symbols def get_items_for_symbol(self, state, symbol): items = [] for item in state.items: if item.dot < len(item.production.rhs) and item.production.rhs[item.dot] == symbol: items.append(LR0Item(item.production, item.dot + 1)) return items def parse(self, input_string): stack = [self.start_state] input_tokens = input_string.split() input_tokens.append('$') i = 0 while True: state = stack[-1] if state == LR0State([]): return False elif i == len(input_tokens): return True elif (state, input_tokens[i]) in self.transitions: stack.append(self.transitions[(state, input_tokens[i])]) i += 1 else: return False ``` 以上就是Python实现LR(0)分析法的全部步骤。通过定义文法符号类、产生式类、文法类、LR(0)自动机状态类和LR(0)分析器类,我们可以很容易地实现LR(0)分析法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值