赞
踩
加深对语法分析器工作过程的理解;加强对算符优先分析法实现语法分析程序的掌握;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法翻译。
花一周时间写出表达式的文法,优先符号表等理论准备。设计好程序结构,画出模块结构图,写出模块接口和调用关系。描述每个模块的功能。上机编制子模块代码,并测试。业余继续完成代码设计。第二次上机进行调试、修改,对照测试数据比对结果。第三次上机要求全部通过。有余力的同学可编制解释执行程序,对表达式进行求值(此时可不考虑赋值语句)。
- #include <iostream>
- #include <cstring>
- #include <cstdio>
- #include <vector>
- #include <stack>
- #include <map>
- #include <set>
- #include <algorithm>
- #include <string>
- #include <cstdlib>
- #include <cctype>
- #define MAX 512
- using namespace std;
- class WF
- {
- public:
- string left;//产生式的左部
- vector<string> right;//产生式右部
- WF ( const string& str )
- {
- left = str;
- }
- //一个非终结符可以有多个产生式
- //把右部的起始指针存入right的最后
- void insert ( char str[] )
- {
- right.push_back(str);
- }
- //合并和打印产生式
- void print ( )
- {
- for ( unsigned i = 0 ; i < right.size() ; i++ )
- {
- if (i==0)
- {
- printf ( "%s->%s" , left.c_str() , right[i].c_str() );
- }
- else
- {
- 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];//firstVT集合
- set<char> last[MAX];//lastVT集合
- int used[MAX];//终结符的出现顺序表
- int vis[MAX];//标志第i条产生式是否处理了
- //找出每个非终结符的对应的firstVT
- //获取左部的非终结符
- //遍历右部
- void dfs_first (int x)
- {
-
- if ( vis[x] )
- {
- return;
- }
- vis[x] = 1;//表示第i条产生式处理过了
- string& left = VN_set[x].left;
- for ( unsigned 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_first ( y );
- set<char>::iterator it = first[y].begin();
- for ( ; it!= first[y].end() ; it++ )
- {
- first[x].insert ( *it );
- }
- }
- else
- {
- first[x].insert ( str[0] );
- }
- }
- }
- //构建firstVT集
- //如果vis[i]为0,表示第i条产生式还没处理,则调用dfs来查找它的firstVT,查找完后将vis[i]置1,表示已经处理了第i条产生式
- void make_first ( )
- {
- //将vis数组元素置0
- memset ( vis , 0 , sizeof ( vis ) );
- for ( unsigned i = 0 ; i < VN_set.size() ; i++ )
- {
- if ( vis[i] )
- {
- continue;
- }
- else
- {
- dfs_first (i);
- }
- }
- puts("------------FIRSTVT集-------------------");
- for ( unsigned 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 ("" );
- }
- }
- //找出每个非终结符的对应的lastVT
- void dfs_last ( int x )
- {
- if ( vis[x] )
- return;
- vis[x] = 1;
- string& left = VN_set[x].left;
- for ( unsigned 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] );
- }
- dfs_last ( y );
- set<char>::iterator it = last[y].begin();
- for ( ; it != last[y].end() ; it++ )
- {
- last[x].insert ( *it );
- }
- }
- else
- {
- last[x].insert ( str[n] );
- }
- }
- }
- //构建lastVT集
- void make_last ( )
- {
- memset ( vis , 0 , sizeof ( vis ) );//vis数组元素全部置0
- for ( unsigned i = 0 ; i < VN_set.size() ; i++ )
- if ( vis[i] ) continue;
- else dfs_last ( i );
- puts("--------------LASTVT集---------------------");
- for ( unsigned 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 ("" );
- }
- }
- //构造算法关系优先表
- void make_table ( )
- {
- for ( int i = 0 ; i < MAX ; i++ )
- for ( int j = 0 ; j < MAX ; j++ )
- relation[i][j] = ' ';
- for ( unsigned i = 0 ; i < VN_set.size() ; i++ )
- {
- for ( unsigned j = 0 ; j < VN_set[i].right.size() ; j++ )
- {
- string& str = VN_set[i].right[j];
- for ( unsigned 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]] = '=';
- }
- }
- }
- for ( unsigned i = 0 ; i < VT.size()*5 ; i++ )
- {
- printf ("-");
- }
- printf ( "算符优先关系表" );
- for ( unsigned i = 0 ; i < VT.size()*5 ; i++ )
- {
- printf ( "-" );
- }
- puts("");
- printf ( "|%8s|" , "" );
- for ( unsigned i = 0 ; i < VT.size() ; i++ )
- {
- printf ( "%5c%5s" , VT[i] , "|" );
- }
- puts ("");
- for ( unsigned i = 0 ; i < (VT.size()+1)*10 ; i++ )
- {
- printf ( "-" );
- }
- puts("");
- for ( unsigned i = 0 ; i < VT.size() ; i++ )
- {
- printf ( "|%4c%5s" , VT[i] , "|");
- for ( unsigned j = 0 ; j < VT.size() ; j++ )
- {
- printf ( "%5c%5s" , relation[VT[i]][VT[j]] , "|" );
- }
- puts ("");
- for ( unsigned i = 0 ; i < (VT.size()+1)*10 ; i++ )
- {
- printf ( "-" );
- }
- puts("");
- }
- }
- int main ( )
- {
- int n;
- char s[MAX];
- cout<<"产生式的条数n=";
- while ( ~scanf ( "%d" , &n ) )
- {
- memset ( used , 0 , sizeof ( used ) );
- cout<<"产生式:"<<endl;
- for ( int i = 0 ; i < n ; i++ )
- {
- scanf ( "%s" , s );
- int len = strlen(s);//每条产生式的长度
- int j;
- for ( j = 0 ; j < len ; j++ )
- {
- if ( s[j] == '-' )
- break;
- }
- s[j] = 0;//-替换成\0,以便截断产生式的左右部分
- //如果不存在这个非终结符,则会VN_dic中插入,对应的value为0
- if ( !VN_dic[s] )
- {
- VN_set.push_back ( WF(s) );//放入VN_set中
- VN_dic[s] = VN_set.size();//设置s的value当前元素个数
- }
- int x = VN_dic[s]-1;//获取这个产生式的下标
- VN_set[x].insert ( s+j+2 );//s+j+2为产生式右部的起始地址
- 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();//这个VT对应的位置,从1开始
- }
- }
- }
- puts ("************VT集*******************");
- for ( unsigned i = 0 ; i < VT.size() ; i++ )
- {
- printf ( "%c " , VT[i] );
- }
- puts ("");
- puts("*************产生式*****************");
- for ( unsigned i = 0 ; i < VN_set.size() ; i++ )
- {
- VN_set[i].print();
- }
- puts("************************************");
- make_first();
- make_last();
- make_table();
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。