编译原理之算符优先分析
1.算符优先分析:
1.1定义
是一种简单直观、广泛使用、便于手工实现的自下而上的语法分析方法。
1.2原理
定义算符之间的某种优先关系,寻找“归约串”,并进行归约
1.3相关知识拓展
1.3.1 算符文法:产生式的右部不包含两个相继的非终结符,即不包含形如:.....QR.....
1.3.2 算符优先文法:任何终结符对(a,b)至多一种优先级关系。
1.3.3 构造优先关系表
步骤:(1)写出FIRSTVT、LASTVT
FIRSTVT(P)={a|P->a.....或P->Qa......}
LASTVT(P)={a|P->.....a或P->......aQ}
(2)列表,根据优先级填表
1.确定同一产生式的末尾终结符之间无优先关系
2.确定=,再使用FIRSTVT、LASTVT
1.4 算符优先分析算法
素短语:至少包含一个终结符且不包含更小的终结符,如p*p或 i
最左素短语:最左侧的素短语
缺点:跳过了所有单非产生式所对应的归约步骤。
(单非产生式:形如:P->Q ,右部只有一个非终结符的产生式)
1.5 构造优先函数
使用构造优先函数代替优先表
f:表入栈优先函数、g:表比较优先函数
1.6 举例
S→a|Λ|(T) T->T,S|S
(1)基本了解:
FIRSTVT(P)={a|P->a.... or Qa....}; LASTVT(P)={a|P->...a or P->....aQ}
所以
对于:S→a|Λ|(T) 则FIRSTVT(S)={a,Λ,(}
对于:S→a|Λ|(T) 则LASTVT(S)={a,Λ,)}
对于:T->T,S|S 则FIRSTVT(T)={, ,a,Λ,(}
对于:T->T,S|S 则LASTVT(T)={, ,a,Λ,)}
(2)
|
优先关系 |
a |
Λ |
( |
) |
, |
|
a |
|
|
|
> |
> |
|
Λ |
|
|
|
> |
> |
|
( |
< |
< |
< |
= |
< |
|
) |
|
|
|
> |
> |
|
, |
< |
< |
< |
> |
> |
由于G[S]中任何终结符对(a,b)之多只有一种关系成立,所以,G[S]为算符优先文法。
构造优先关系时需注意:
1)哪些不存在优先关系:末尾仅剩终结符A与同一产生式的其他终结符A’无优先关系。如题:a ,Λ, )均符合A条件,即其后无符号。且a ,Λ,)属于同一产生式,无优先级
2)比较优先级的顺序:先确定 = ,再比较FIRSTVT,最后比较LASTVT
(3)构造优先函数
F(x)为入栈优先函数
G(x)比较优先函数(还没入栈的终结符所表示的函数)

画优先表代码:

#include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <map> #include <set> #include <algorithm> #include <string> #include <cstdlib> #include <cctype> #define MAX 507 using namespace std; class WF { public: string left; vector<string> right; WF ( const string& str ) { left = str; } void insert ( char str[] ) { right.push_back(str); } void print ( ) { printf ( "%s->%s" , left.c_str() , right[0].c_str() ); for ( int i = 1 ; i < right.size() ; i++ ) printf ( "|%s" , right[i].c_str() ); puts(""); } }; char relation[MAX][MAX]; vector<char> VT; vector<WF> VN_set; map<string,int> VN_dic; set<char> first[MAX]; set<char> last[MAX]; int used[MAX]; int vis[MAX]; void dfs ( int x ) { if ( vis[x] ) return; vis[x] = 1; string& left = VN_set[x].left; for ( int i = 0 ; i < VN_set[x].right.size() ; i++ ) { string& str = VN_set[x].right[i]; if ( isupper(str[0]) ) { int y = VN_dic[str.substr(0,1)]-1; if ( str.length() > 1 && !isupper(str[1] ) ) first[x].insert ( str[1] ); dfs ( y ); set<char>::iterator it = first[y].begin(); for ( ; it!= first[y].end() ; it++ ) first[x].insert ( *it ); } else first[x].insert ( str[0] ); } } void make_first ( ) { memset ( vis , 0 , sizeof ( vis ) ); for ( int i = 0 ; i < VN_set.size() ; i++ ) if ( vis[i] ) continue; else dfs ( i ); #define DEBUG #ifdef DEBUG puts("------------FIRSTVT集-------------------"); for ( int i = 0 ; i < VN_set.size() ; i++ ) { printf ( "%s : " , VN_set[i].left.c_str() ); set<char>::iterator it = first[i].begin(); for ( ; it!= first[i].end() ; it++ ) printf ( "%c " , *it ); puts ("" ); } #endif } void dfs1 ( int x ) { if ( vis[x] ) return; vis[x] = 1; string& left = VN_set[x].left; for ( int i = 0 ; i < VN_set[x].right.size() ; i++ ) { string& str = VN_set[x].right[i]; int n = str.length() -1; if ( isupper(str[n] ) ) { int y = VN_dic[str.substr(n,1)]-1; if ( str.length() > 1 && !isupper(str[n-1]) ) last[x].insert ( str[1] ); dfs1 ( y ); set<char>::iterator it = last[y].begin(); for ( ; it != last[y].end() ; it++ ) last[x].insert ( *it ); } else last[x].insert ( str[n] ); } } void make_last ( ) { memset ( vis , 0 , sizeof ( vis ) ); for ( int i = 0 ; i < VN_set.size() ; i++ ) if ( vis[i] ) continue; else dfs1 ( i ); #define DEBUG #ifdef DEBUG puts("--------------LASTVT集---------------------"); for ( int i = 0 ; i < VN_set.size() ; i++ ) { printf ( "%s : " , VN_set[i].left.c_str() ); set<char>::iterator it = last[i].begin(); for ( ; it!= last[i].end() ; it++ ) printf ( "%c " , *it ); puts ("" ); } #endif } void make_table ( ) { for ( int i = 0 ; i < MAX ; i++ ) for ( int j = 0 ; j < MAX ; j++ ) relation[i][j] = ' '; for ( int i = 0 ; i < VN_set.size() ; i++ ) for ( int j = 0 ; j < VN_set[i].right.size() ; j++ ) { string& str = VN_set[i].right[j]; for ( int k = 0 ; k < str.length()-1 ; k++ ) { if ( !isupper(str[k]) && !isupper(str[k+1]) ) relation[str[k]][str[k+1]] = '='; if ( !isupper(str[k]) && isupper(str[k+1]) ) { int x = VN_dic[str.substr(k+1,1)]-1; set<char>::iterator it = first[x].begin(); for ( ; it != first[x].end() ; it++ ) relation[str[k]][*it] = '<'; } if ( isupper(str[k]) && !isupper(str[k+1]) ) { int x = VN_dic[str.substr(k,1)]-1; set<char>::iterator it = last[x].begin(); for ( ; it != last[x].end() ; it++ ) relation[*it][str[k+1]] = '>'; } if ( k > str.length()-2 ) continue; if ( !isupper(str[k]) && !isupper(str[k+2]) && isupper(str[k+1]) ) relation[str[k]][str[k+2]] = '='; } } #define DEBUG #ifdef DEBUG for ( int i = 0 ; i < VT.size()*5 ; i++ ) printf ("-"); printf ( "算符优先关系表" ); for ( int i = 0 ; i < VT.size()*5 ; i++ ) printf ( "-" ); puts(""); printf ( "|%8s|" , "" ); for ( int i = 0 ; i < VT.size() ; i++ ) printf ( "%5c%5s" , VT[i] , "|" ); puts (""); for ( int i = 0 ; i < (VT.size()+1)*10 ; i++ ) printf ("-"); puts(""); for ( int i = 0 ; i < VT.size() ; i++ ) { printf ( "|%4c%5s" , VT[i] , "|"); for ( int j = 0 ; j < VT.size() ; j++ ) printf ( "%5c%5s" , relation[VT[i]][VT[j]] , "|" ); puts (""); for ( int i = 0 ; i < (VT.size()+1)*10 ; i++ ) printf ("-"); puts(""); } #endif } int main ( ) { int n; char s[MAX]; while ( ~scanf ( "%d" , &n ) ) { memset ( used , 0 , sizeof ( used ) ); for ( int i = 0 ; i < n ; i++ ) { scanf ( "%s" , s ); int len = strlen(s),j; for ( j = 0 ; j < len ; j++ ) if ( s[j] == '-' ) break; s[j] = 0; if ( !VN_dic[s] ) { VN_set.push_back ( WF(s) ); VN_dic[s] = VN_set.size(); } int x = VN_dic[s]-1; VN_set[x].insert ( s+j+2 ); for ( int k = 0 ; k < j; k++ ) if ( !isupper(s[k] ) ) { if ( used[s[k]] ) continue; used[s[k]] = 1; VT.push_back ( s[k] ); } for ( int k = j+2 ; k < len; k++ ) if ( !isupper(s[k] ) ) { if ( used[s[k]] ) continue; VT.push_back ( s[k] ); used[s[k]] = VT.size(); } } #define DEBUG #ifdef DEBUG puts ("************VT集*******************"); for ( int i = 0 ; i < VT.size() ; i++ ) printf ( "%c " , VT[i] ); puts (""); puts("*************产生式*****************"); for ( int i = 0 ; i < VN_set.size() ; i++ ) VN_set[i].print(); puts("************************************"); #endif make_first(); make_last(); make_table(); } }

浙公网安备 33010602011771号