编译原理(八) 算符优先分析法(分析过程的算法和C++实现)

来源:互联网 发布:mac终端打开文件 编辑:程序博客网 时间:2024/05/18 14:23

算法描述

算符优先关系主要用于界定右句型的句柄:

<标记句柄的左端; 
=出现在句柄的内部; 
>标记句柄的右端。

发现句柄的过程:

  • 从左端开始扫描串,直到遇到第一个>为止。
  • 向左扫描,跳过所有的=,直到遇到一个<为止。
  • 句柄包括从上一步遇到的<右部到第一个>左部之间的所有符号,包括介于期间或者两边的非终结符

非终结符的处理: 
因为非终结符不能影响语法分析,所以不需要区分它们,于是只用一个占位符来代替它们

算法的主体思想: 
用栈存储已经看到的输入符号,用优先关系指导移动归约语法分析器的动作 
如果栈顶的终结符和下一个输入符之间的优先关系是<或=,则语法分析器移动,表示还没有发现句柄的右端 
如果是>关系,就调用归约 
算法描述: 
输入:输入字符串ω和优先关系表 
输出:如果ω是语法产生的一个句子,则输出其用来归约的产生式;如果有错误,则转入错误处理

代码实现

#include <iostream>#include <cstring>#include <cstdio>#include <vector>#include <stack>#include <map>#include <set>#include <algorithm>#include <string>#include <cstdlib>#include <cctype>#define MAX 507using 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 fa[MAX];int _find ( int x  ){    return x==fa[x]?x:fa[x] = _find ( fa[x] );}bool judge ( char x , char y ){    if ( _find ( x ) == _find ( y ) )        return true;    return false;}void _union ( char x , char y ){    x = _find(x);    y = _find(y);    fa[x] = y;}void print ( string s1 , string s2 , string s3 , string s4 , string s5 , string s6 ){    printf ( "%-14s|%-15s%-15s%-15s%-15s%-15s\n" , s1.c_str(), s2.c_str(), s3.c_str() ,s4.c_str(),s5.c_str() , s6.c_str() );}void init ( ){    for ( int i = 0 ; i < MAX ; i++ )        fa[i] = i;    for ( int i = 0 ; i < VN_set.size() ; i++ )    {        string& left = VN_set[i].left;        for ( int j = 0 ; j < VN_set[i].right.size() ; j++ )        {            string& str = VN_set[i].right[j];            if ( left.length() == 1 && str.length() == 1 )            {               // cout << left[0] << " " << str[0] << endl;                _union ( left[0] , str[0] );               // cout << _find(left[0]) << " " << _find ( str[0] )  << endl;            }        }    }    print("步骤","栈","优先关系","当前符号","剩余符号","动作");}string get_stk ( vector<char>& stk ){    string ret = "";    for ( int i = 0 ; i < stk.size() ; i++ )        ret += stk[i];    return ret;}bool check ( const string& str1 , const string& str2 ){    if ( str1.length() != str2.length() )         return false;    for ( int i = 0 ; i < str1.length() ; i++ )        if ( isupper(str1[i]) )        {            if ( !judge(str1[i],str2[i])) return false;        }        else         {            if ( str1[i] != str2[i] ) return false;        }    return true;}string reduction ( string src ){    for ( int i = 0 ; i < VN_set.size() ; i++ )        for ( int j = 0 ; j < VN_set[i].right.size() ; j++ )            if ( check ( VN_set[i].right[j] , src ) )                return VN_set[i].left;    return "";}void move_reduction ( string src ){    init ();    //cout <<"flag : " << check ( "P+P" , "E+T" ) << endl;;    vector<char> stk;    int steps= 1;    src += "#";    stk.push_back ( '#' );    for ( int i = 0 ; i < src.length() ; i++ )    {        char top = stk[stk.size()-1];        for ( int j = stk.size()-1 ; j >= 0 ; j-- )            if ( isupper(stk[j]) ) continue;            else               {                top = stk[j];                break;            }        char ch = relation[top][src[i]];        if ( ch == '<' || ch == '=' )        {            string temp = "";            if ( i == src.length() - 1 )                print ( temp+(char)(steps+48) , get_stk( stk ) , temp+ch , temp+src[i] , "" , "移进" );            else                print ( temp+(char)(steps+48) , get_stk( stk ) , temp+ch , temp+src[i] , src.substr(i+1,src.length()-i-1) , "移进" );            stk.push_back ( src[i] );          }        else        {            string temp ="";            string str ="";            int x = stk.size()-2;            if ( i == src.length() )                print ( temp+(char)(steps+48) , get_stk(stk) , temp+ch , temp + src[i] , "" , "归约" );            else                 print ( temp+(char)(steps+48) , get_stk(stk) , temp+ch , temp + src[i] , src.substr(i+1,src.length()-i-1) , "归约" );            while ( true )            {                if ( stk.size() == 0 ) break;                if ( !isupper(stk[x] ) &&relation[stk[x]][top] == '<' )                         break;                x--;            }            for ( int j = stk.size()-1 ; j > x; j-- )            {                str += stk[j];                stk.pop_back();            }            //cout << "YES : " << i <<" " << str <<  endl;            str = reduction(str);            //cout << "finish: " << i << " " << str << endl;            for ( int j = 0 ; j < str.length() ; j++ )                stk.push_back ( str[j] );            /*if ( i == src.length() )                print ( temp+(char)(steps+48) , get_stk(stk) , temp+ch , temp + src[i] , "" , "移进" );            else                 print ( temp+(char)(steps+48) , get_stk(stk) , temp+ch , temp + src[i] , src.substr(i+1,src.length()-i-1) , "移进" );            stk.push_back ( src[i] );*/            i--;        }          steps++;    }    //string temp ="";    //cout << "result" << endl;    //print ( temp+(char)(steps+48) , get_stk(stk) , "","","","");}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();        move_reduction("i+i");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397

Input:


S->#E# 
P->i 
F->P 
T->F 
E->T 
E->E+T

Output:

这里写图片描述

阅读全文
0 0
原创粉丝点击