当前位置:   article > 正文

算符优先文法语法分析_(1)用算符优先分析法对符合文法的输入串中所有种语法成分进行分析; 1) 给定算符优

(1)用算符优先分析法对符合文法的输入串中所有种语法成分进行分析; 1) 给定算符优

1、实验目的及要求

1.1、实验目的

        加深对语法分析器工作过程的理解;加强对算符优先分析法实现语法分析程序的掌握;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法翻译。

1.2、实验要求

        花一周时间写出表达式的文法,优先符号表等理论准备。设计好程序结构,画出模块结构图,写出模块接口和调用关系。描述每个模块的功能。上机编制子模块代码,并测试。业余继续完成代码设计。第二次上机进行调试、修改,对照测试数据比对结果。第三次上机要求全部通过。有余力的同学可编制解释执行程序,对表达式进行求值(此时可不考虑赋值语句)。

2、实验步骤

2.1、模块一:构建firstVT()和lastVT()集合

 

 

3、实验内容

3.1、流程图

 

3.2、源代码 

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <vector>
  5. #include <stack>
  6. #include <map>
  7. #include <set>
  8. #include <algorithm>
  9. #include <string>
  10. #include <cstdlib>
  11. #include <cctype>
  12. #define MAX 512
  13. using namespace std;
  14. class WF
  15. {
  16. public:
  17. string left;//产生式的左部
  18. vector<string> right;//产生式右部
  19. WF ( const string& str )
  20. {
  21. left = str;
  22. }
  23. //一个非终结符可以有多个产生式
  24. //把右部的起始指针存入right的最后
  25. void insert ( char str[] )
  26. {
  27. right.push_back(str);
  28. }
  29. //合并和打印产生式
  30. void print ( )
  31. {
  32. for ( unsigned i = 0 ; i < right.size() ; i++ )
  33. {
  34. if (i==0)
  35. {
  36. printf ( "%s->%s" , left.c_str() , right[i].c_str() );
  37. }
  38. else
  39. {
  40. printf ( "|%s" , right[i].c_str() );
  41. }
  42. }
  43. puts("");
  44. }
  45. };
  46. char relation[MAX][MAX];//优先关系表
  47. vector<char> VT;//终结符集合
  48. vector<WF> VN_set;//文法产生式
  49. map<string,int> VN_dic;//非终结符及对应的顺序
  50. set<char> first[MAX];//firstVT集合
  51. set<char> last[MAX];//lastVT集合
  52. int used[MAX];//终结符的出现顺序表
  53. int vis[MAX];//标志第i条产生式是否处理了
  54. //找出每个非终结符的对应的firstVT
  55. //获取左部的非终结符
  56. //遍历右部
  57. void dfs_first (int x)
  58. {
  59. if ( vis[x] )
  60. {
  61. return;
  62. }
  63. vis[x] = 1;//表示第i条产生式处理过了
  64. string& left = VN_set[x].left;
  65. for ( unsigned i = 0 ; i < VN_set[x].right.size() ; i++ )
  66. {
  67. string& str = VN_set[x].right[i];//右部
  68. //如果第一个是大写的 ,获取它的下标
  69. if ( isupper(str[0]) )
  70. {
  71. int y = VN_dic[str.substr(0,1)]-1;//下标
  72. //后边还有且不是非终结符
  73. if ( str.length() > 1 && !isupper(str[1] ) )
  74. {
  75. first[x].insert ( str[1] );
  76. }
  77. dfs_first ( y );
  78. set<char>::iterator it = first[y].begin();
  79. for ( ; it!= first[y].end() ; it++ )
  80. {
  81. first[x].insert ( *it );
  82. }
  83. }
  84. else
  85. {
  86. first[x].insert ( str[0] );
  87. }
  88. }
  89. }
  90. //构建firstVT集
  91. //如果vis[i]为0,表示第i条产生式还没处理,则调用dfs来查找它的firstVT,查找完后将vis[i]置1,表示已经处理了第i条产生式
  92. void make_first ( )
  93. {
  94. //将vis数组元素置0
  95. memset ( vis , 0 , sizeof ( vis ) );
  96. for ( unsigned i = 0 ; i < VN_set.size() ; i++ )
  97. {
  98. if ( vis[i] )
  99. {
  100. continue;
  101. }
  102. else
  103. {
  104. dfs_first (i);
  105. }
  106. }
  107. puts("------------FIRSTVT集-------------------");
  108. for ( unsigned i = 0 ; i < VN_set.size() ; i++ )
  109. {
  110. printf ( "%s : " , VN_set[i].left.c_str() );
  111. //迭代输出
  112. set<char>::iterator it = first[i].begin();
  113. for ( ; it!= first[i].end() ; it++ )
  114. {
  115. printf ( "%c " , *it );
  116. }
  117. puts ("" );
  118. }
  119. }
  120. //找出每个非终结符的对应的lastVT
  121. void dfs_last ( int x )
  122. {
  123. if ( vis[x] )
  124. return;
  125. vis[x] = 1;
  126. string& left = VN_set[x].left;
  127. for ( unsigned i = 0 ; i < VN_set[x].right.size() ; i++ )
  128. {
  129. string& str = VN_set[x].right[i];
  130. int n = str.length() -1;
  131. if ( isupper(str[n] ) )
  132. {
  133. int y = VN_dic[str.substr(n,1)]-1;
  134. if ( str.length() > 1 && !isupper(str[n-1]) )
  135. {
  136. last[x].insert ( str[1] );
  137. }
  138. dfs_last ( y );
  139. set<char>::iterator it = last[y].begin();
  140. for ( ; it != last[y].end() ; it++ )
  141. {
  142. last[x].insert ( *it );
  143. }
  144. }
  145. else
  146. {
  147. last[x].insert ( str[n] );
  148. }
  149. }
  150. }
  151. //构建lastVT集
  152. void make_last ( )
  153. {
  154. memset ( vis , 0 , sizeof ( vis ) );//vis数组元素全部置0
  155. for ( unsigned i = 0 ; i < VN_set.size() ; i++ )
  156. if ( vis[i] ) continue;
  157. else dfs_last ( i );
  158. puts("--------------LASTVT集---------------------");
  159. for ( unsigned i = 0 ; i < VN_set.size() ; i++ )
  160. {
  161. printf ( "%s : " , VN_set[i].left.c_str() );
  162. set<char>::iterator it = last[i].begin();
  163. for ( ; it!= last[i].end() ; it++ )
  164. printf ( "%c " , *it );
  165. puts ("" );
  166. }
  167. }
  168. //构造算法关系优先表
  169. void make_table ( )
  170. {
  171. for ( int i = 0 ; i < MAX ; i++ )
  172. for ( int j = 0 ; j < MAX ; j++ )
  173. relation[i][j] = ' ';
  174. for ( unsigned i = 0 ; i < VN_set.size() ; i++ )
  175. {
  176. for ( unsigned j = 0 ; j < VN_set[i].right.size() ; j++ )
  177. {
  178. string& str = VN_set[i].right[j];
  179. for ( unsigned k = 0 ; k < str.length()-1 ; k++ )
  180. {
  181. if ( !isupper(str[k]) && !isupper(str[k+1]) )
  182. relation[str[k]][str[k+1]] = '=';
  183. if ( !isupper(str[k]) && isupper(str[k+1]) )
  184. {
  185. int x = VN_dic[str.substr(k+1,1)]-1;
  186. set<char>::iterator it = first[x].begin();
  187. for ( ; it != first[x].end() ; it++ )
  188. relation[str[k]][*it] = '<';
  189. }
  190. if ( isupper(str[k]) && !isupper(str[k+1]) )
  191. {
  192. int x = VN_dic[str.substr(k,1)]-1;
  193. set<char>::iterator it = last[x].begin();
  194. for ( ; it != last[x].end() ; it++ )
  195. relation[*it][str[k+1]] = '>';
  196. }
  197. if ( k > str.length()-2 ) continue;
  198. if ( !isupper(str[k]) && !isupper(str[k+2]) && isupper(str[k+1]) )
  199. relation[str[k]][str[k+2]] = '=';
  200. }
  201. }
  202. }
  203. for ( unsigned i = 0 ; i < VT.size()*5 ; i++ )
  204. {
  205. printf ("-");
  206. }
  207. printf ( "算符优先关系表" );
  208. for ( unsigned i = 0 ; i < VT.size()*5 ; i++ )
  209. {
  210. printf ( "-" );
  211. }
  212. puts("");
  213. printf ( "|%8s|" , "" );
  214. for ( unsigned i = 0 ; i < VT.size() ; i++ )
  215. {
  216. printf ( "%5c%5s" , VT[i] , "|" );
  217. }
  218. puts ("");
  219. for ( unsigned i = 0 ; i < (VT.size()+1)*10 ; i++ )
  220. {
  221. printf ( "-" );
  222. }
  223. puts("");
  224. for ( unsigned i = 0 ; i < VT.size() ; i++ )
  225. {
  226. printf ( "|%4c%5s" , VT[i] , "|");
  227. for ( unsigned j = 0 ; j < VT.size() ; j++ )
  228. {
  229. printf ( "%5c%5s" , relation[VT[i]][VT[j]] , "|" );
  230. }
  231. puts ("");
  232. for ( unsigned i = 0 ; i < (VT.size()+1)*10 ; i++ )
  233. {
  234. printf ( "-" );
  235. }
  236. puts("");
  237. }
  238. }
  239. int main ( )
  240. {
  241. int n;
  242. char s[MAX];
  243. cout<<"产生式的条数n=";
  244. while ( ~scanf ( "%d" , &n ) )
  245. {
  246. memset ( used , 0 , sizeof ( used ) );
  247. cout<<"产生式:"<<endl;
  248. for ( int i = 0 ; i < n ; i++ )
  249. {
  250. scanf ( "%s" , s );
  251. int len = strlen(s);//每条产生式的长度
  252. int j;
  253. for ( j = 0 ; j < len ; j++ )
  254. {
  255. if ( s[j] == '-' )
  256. break;
  257. }
  258. s[j] = 0;//-替换成\0,以便截断产生式的左右部分
  259. //如果不存在这个非终结符,则会VN_dic中插入,对应的value为0
  260. if ( !VN_dic[s] )
  261. {
  262. VN_set.push_back ( WF(s) );//放入VN_set中
  263. VN_dic[s] = VN_set.size();//设置s的value当前元素个数
  264. }
  265. int x = VN_dic[s]-1;//获取这个产生式的下标
  266. VN_set[x].insert ( s+j+2 );//s+j+2为产生式右部的起始地址
  267. for ( int k = j+2 ; k < len; k++ )
  268. {
  269. if ( !isupper(s[k] ) )
  270. {
  271. if ( used[s[k]] )
  272. continue;
  273. VT.push_back ( s[k] );//把终结符放入终结符数组中
  274. used[s[k]] = VT.size();//这个VT对应的位置,从1开始
  275. }
  276. }
  277. }
  278. puts ("************VT集*******************");
  279. for ( unsigned i = 0 ; i < VT.size() ; i++ )
  280. {
  281. printf ( "%c " , VT[i] );
  282. }
  283. puts ("");
  284. puts("*************产生式*****************");
  285. for ( unsigned i = 0 ; i < VN_set.size() ; i++ )
  286. {
  287. VN_set[i].print();
  288. }
  289. puts("************************************");
  290. make_first();
  291. make_last();
  292. make_table();
  293. }
  294. }

4、实验结果

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/754787
推荐阅读
相关标签
  

闽ICP备14008679号