易码技术论坛

 找回密码
 加入易码
搜索
查看: 567|回复: 4

我想学习编写parser。

[复制链接]
发表于 2016-9-11 10:30:36 | 显示全部楼层 |阅读模式
输入是源文件,输出…… 还没想好,总之要先parse完才行罢。
词法分析和预处理器是之前某个公开课的作业中留下的,这回就接着用。
所以这里输入已经是带有Token类型的Token流了。

完全不讲运行效率,只是个学习过程。
本来应该在大学就学会的,现在还不会。唉

用的是递归下降语法分析方法。语法是拉瓦语言。也就是LavaX。也就是GVMaker。
没系统地看过书,现在我觉得最后产生的语法树是决策树的子集。不知道这个想法是否正确。
暴力枚举法就是每次将决策树「往前进一格」,然后顺延下去。
但正常的解析不需要枚举整个解空间,而只需要在搜索解空间时尽快地将符合语法规则的结果输出来就好了。

为了学习的目的,就暂且尝试遍历整个解空间。对于下面这段很短的代码就尝试了46000多次(解空间的大小是 K的N次方 ,其中N为Token数。嗯很快就会爆炸。
  1. char GGV[] = "Golden Global View";
  2. int i, j = 2;
  3. struct FUN_LINK fun;
  4. void foo() {
  5.     label1: {}
  6.     "assignment" = "expression";
  7.     ;
  8.     1;
  9.     "哈哈";
  10. }
复制代码
最后解析出来的结果是:
  1. root
  2.   translation_unit  (4 children)
  3.     declaration
  4.       simple_declaration  (3 children)
  5.         decl_specifier_seq
  6.           decl_specifier
  7.             type_specifier
  8.               trailing_type_specifier
  9.                 simple_type_specifier
  10.                   char
  11.         init_declarator_list
  12.           init_declarator  (2 children)
  13.             declarator
  14.               ptr_declarator
  15.                 noptr_declarator  (2 children)
  16.                   noptr_declarator_root
  17.                     declarator_id
  18.                       id_expression
  19.                         GGV
  20.                   noptr_declarator_suffix  (2 children)
  21.                     [
  22.                     ]
  23.             initializer
  24.               brace_or_equal_initializer  (2 children)
  25.                 =
  26.                 initializer_clause
  27.                   assignment_expression
  28.                     conditional_expression
  29.                       logical_or_expression
  30.                         logical_and_expression
  31.                           inclusive_or_expression
  32.                             exclusive_or_expression
  33.                               and_expression
  34.                                 equality_expression
  35.                                   relational_expression
  36.                                     shift_expression
  37.                                       additive_expression
  38.                                         multiplicative_expression
  39.                                           pm_expression
  40.                                             cast_expression
  41.                                               unary_expression
  42.                                                 postfix_expression
  43.                                                   postfix_root
  44.                                                     primary_expression
  45.                                                       "Golden Global View"
  46.         ;
  47.     declaration
  48.       simple_declaration  (3 children)
  49.         decl_specifier_seq
  50.           decl_specifier
  51.             type_specifier
  52.               trailing_type_specifier
  53.                 simple_type_specifier
  54.                   int
  55.         init_declarator_list  (3 children)
  56.           init_declarator
  57.             declarator
  58.               ptr_declarator
  59.                 noptr_declarator
  60.                   noptr_declarator_root
  61.                     declarator_id
  62.                       id_expression
  63.                         i
  64.           ,
  65.           init_declarator  (2 children)
  66.             declarator
  67.               ptr_declarator
  68.                 noptr_declarator
  69.                   noptr_declarator_root
  70.                     declarator_id
  71.                       id_expression
  72.                         j
  73.             initializer
  74.               brace_or_equal_initializer  (2 children)
  75.                 =
  76.                 initializer_clause
  77.                   assignment_expression
  78.                     conditional_expression
  79.                       logical_or_expression
  80.                         logical_and_expression
  81.                           inclusive_or_expression
  82.                             exclusive_or_expression
  83.                               and_expression
  84.                                 equality_expression
  85.                                   relational_expression
  86.                                     shift_expression
  87.                                       additive_expression
  88.                                         multiplicative_expression
  89.                                           pm_expression
  90.                                             cast_expression
  91.                                               unary_expression
  92.                                                 postfix_expression
  93.                                                   postfix_root
  94.                                                     primary_expression
  95.                                                       2
  96.         ;
  97.     declaration
  98.       simple_declaration  (3 children)
  99.         decl_specifier_seq
  100.           decl_specifier
  101.             type_specifier
  102.               trailing_type_specifier
  103.                 elaborated_type_specifier  (2 children)
  104.                   class_key
  105.                     struct
  106.                   FUN_LINK
  107.         init_declarator_list
  108.           init_declarator
  109.             declarator
  110.               ptr_declarator
  111.                 noptr_declarator
  112.                   noptr_declarator_root
  113.                     declarator_id
  114.                       id_expression
  115.                         fun
  116.         ;
  117.     declaration
  118.       function_definition  (3 children)
  119.         decl_specifier_seq
  120.           decl_specifier
  121.             type_specifier
  122.               trailing_type_specifier
  123.                 simple_type_specifier
  124.                   void
  125.         declarator
  126.           ptr_declarator
  127.             noptr_declarator  (2 children)
  128.               noptr_declarator_root
  129.                 declarator_id
  130.                   id_expression
  131.                     foo
  132.               noptr_declarator_suffix
  133.                 parameters_and_qualifiers  (3 children)
  134.                   (

  135. (中间省略,因为有帖子字数限制)
  136.                                         multiplicative_expression
  137.                                           pm_expression
  138.                                             cast_expression
  139.                                               unary_expression
  140.                                                 postfix_expression
  141.                                                   postfix_root
  142.                                                     primary_expression
  143.                                                       "哈哈"
  144.                 ;
  145.             }
复制代码
还有好多好多地方没做完的,不知道几时能做完了。是件很忧伤的事情

[ 本帖最后由 cs900601 于 2016-9-11 17:00 编辑 ]
发表于 2016-9-11 12:40:06 | 显示全部楼层
这代码,猛一看还以为是json。。。
 楼主| 发表于 2016-9-11 13:55:58 | 显示全部楼层

回复 2# 的帖子

嗯,可能是因为括号比较多吧

我刚才把Yan的编译器中的“函数生成器.txt”丢进这个parser了。

预处理器的结果
  1. simple void KW_VOID
  2. emit_simple_directly push void
  3. identifier FunSeek
  4. emit_identifier push FunSeek
  5. simple ( OP_LPAREN
  6. emit_simple_directly push (
  7. simple ) OP_RPAREN
  8. emit_simple_directly push )
  9. simple { OP_LBRACE
  10. emit_simple_directly push {
  11. simple int KW_INT
  12. emit_simple_directly push int
  13. identifier i
  14. emit_identifier push i
  15. simple , OP_COMMA
  16. emit_simple_directly push ,
  17. identifier p
  18. emit_identifier push p
  19. simple ; OP_SEMICOLON
  20. emit_simple_directly push ;
  21. simple char KW_CHAR
  22. emit_simple_directly push char
  23. identifier n
  24. emit_identifier push n
  25. simple ; OP_SEMICOLON
  26. emit_simple_directly push ;
  27. identifier FunInsert
  28. emit_identifier push FunInsert
  29. simple ( OP_LPAREN
  30. emit_simple_directly push (
  31. literal "define" array of 7 char 646566696E6500
  32. simple , OP_COMMA
  33. emit_simple_directly push ,
  34. literal 0 int 00000000
  35. simple | OP_BOR
  36. emit_simple_directly push |
  37. identifier SK_BLANK
  38. emit_identifier push SK_BLANK
  39. simple << OP_LSHIFT
  40. emit_simple_directly push <<
  41. literal 4 int 04000000
  42. simple ) OP_RPAREN
  43. emit_simple_directly push )
  44. simple ; OP_SEMICOLON
  45. emit_simple_directly push ;
  46. identifier FunInsert
  47. emit_identifier push FunInsert
  48. simple ( OP_LPAREN
  49. emit_simple_directly push (
  50. literal "include" array of 8 char 696E636C75646500
  51. simple , OP_COMMA
  52. emit_simple_directly push ,
  53. literal 0 int 00000000
  54. simple | OP_BOR
  55. emit_simple_directly push |
  56. identifier SK_BAO
  57. emit_identifier push SK_BAO
  58. simple << OP_LSHIFT
  59. emit_simple_directly push <<
  60. literal 4 int 04000000
  61. simple ) OP_RPAREN
  62. emit_simple_directly push )
  63. simple ; OP_SEMICOLON
  64. emit_simple_directly push ;
  65. identifier FunInsert
  66. emit_identifier push FunInsert
  67. simple ( OP_LPAREN
  68. emit_simple_directly push (
  69. literal "undef" array of 6 char 756E64656600
  70. simple , OP_COMMA
  71. emit_simple_directly push ,
  72. literal 0 int 00000000
  73. simple | OP_BOR
  74. emit_simple_directly push |
  75. identifier SK_BLANK
  76. emit_identifier push SK_BLANK
  77. simple << OP_LSHIFT
  78. emit_simple_directly push <<
  79. literal 4 int 04000000
  80. simple ) OP_RPAREN
  81. emit_simple_directly push )
  82. simple ; OP_SEMICOLON
  83. emit_simple_directly push ;
  84. identifier FunInsert
  85. emit_identifier push FunInsert
  86. simple ( OP_LPAREN
  87. emit_simple_directly push (
  88. literal "ifdef" array of 6 char 696664656600
  89. simple , OP_COMMA
  90. emit_simple_directly push ,
  91. literal 0 int 00000000
  92. simple | OP_BOR
  93. emit_simple_directly push |
  94. identifier SK_BLANK
  95. emit_identifier push SK_BLANK
  96. simple << OP_LSHIFT
  97. emit_simple_directly push <<
  98. literal 4 int 04000000
  99. simple ) OP_RPAREN
  100. emit_simple_directly push )
  101. simple ; OP_SEMICOLON
  102. emit_simple_directly push ;
  103. identifier FunInsert
  104. emit_identifier push FunInsert
  105. simple ( OP_LPAREN
  106. emit_simple_directly push (
  107. literal "ifndef" array of 7 char 69666E64656600
  108. simple , OP_COMMA
  109. emit_simple_directly push ,
  110. literal 0 int 00000000
  111. simple | OP_BOR
  112. emit_simple_directly push |
  113. identifier SK_BLANK
  114. emit_identifier push SK_BLANK
  115. simple << OP_LSHIFT
  116. emit_simple_directly push <<
  117. literal 4 int 04000000
  118. simple ) OP_RPAREN
  119. emit_simple_directly push )
  120. simple ; OP_SEMICOLON
  121. emit_simple_directly push ;
  122. identifier FunInsert
  123. emit_identifier push FunInsert
  124. simple ( OP_LPAREN
  125. emit_simple_directly push (
  126. literal "endif" array of 6 char 656E64696600
  127. simple , OP_COMMA
  128. emit_simple_directly push ,
  129. literal 0 int 00000000
  130. simple ) OP_RPAREN
  131. emit_simple_directly push )
  132. simple ; OP_SEMICOLON
  133. emit_simple_directly push ;
  134. identifier FunInsert
  135. emit_identifier push FunInsert
  136. simple ( OP_LPAREN

  137. (因为长度限制略去)

  138. emit_simple_directly push }
  139. simple } OP_RBRACE
  140. emit_simple_directly push }
  141. eof
  142. We have 589 tokens.
  143. 0: void
  144. 1: FunSeek
  145. 2: (
  146. 3: )
  147. 4: {
  148. 5: int
  149. 6: i
  150. 7: ,
  151. 8: p
  152. 9: ;
  153. 10: char
  154. 11: n
  155. 12: ;
  156. 13: FunInsert
  157. 14: (
  158. 15: "define"
  159. 16: ,
  160. 17: 0
  161. 18: |
  162. 19: SK_BLANK
  163. 20: <<
  164. 21: 4
  165. 22: )
  166. 23: ;
  167. 24: FunInsert
  168. 25: (
  169. 26: "include"
  170. 27: ,
  171. 28: 0
  172. 29: |
  173. 30: SK_BAO
  174. 31: <<
  175. 32: 4
  176. 33: )
  177. 34: ;
  178. 35: FunInsert
  179. 36: (
  180. 37: "undef"
  181. 38: ,
  182. 39: 0
  183. 40: |
  184. 41: SK_BLANK
  185. 42: <<
  186. 43: 4
  187. 44: )
  188. 45: ;
  189. 46: FunInsert
  190. 47: (
  191. 48: "ifdef"
  192. 49: ,
  193. 50: 0
  194. 51: |
  195. 52: SK_BLANK
  196. 53: <<
  197. 54: 4
  198. 55: )
  199. 56: ;
  200. 57: FunInsert
  201. 58: (
  202. 59: "ifndef"
  203. 60: ,
  204. 61: 0
  205. 62: |
  206. 63: SK_BLANK
  207. 64: <<
  208. 65: 4
  209. 66: )
  210. 67: ;
  211. 68: FunInsert
  212. 69: (
  213. 70: "endif"
  214. 71: ,
  215. 72: 0
  216. 73: )
  217. 74: ;
  218. 75: FunInsert
  219. 76: (
  220. 77: "loadall"
  221. 78: ,
  222. 79: 0
  223. 80: |
  224. 81: SK_CR
  225. 82: <<
  226. 83: 4
  227. 84: )
  228. 85: ;
  229. 86: FunInsert
  230. 87: (
  231. 88: "secret"
  232. 89: ,
  233. 90: 0
  234. 91: |
  235. 92: SK_BLANK
  236. 93: <<
  237. 94: 4
  238. 95: )
  239. 96: ;
  240. 97: FunInsert
  241. 98: (
  242. 99: "code"
  243. 100: ,
  244. 101: 0
  245. 102: |
  246. 103: SK_NULL
  247. 104: <<
  248. 105: 4
  249. 106: )
  250. 107: ;
  251. 108: FunInsert
  252. 109: (
  253. 110: "loaddata"
  254. 111: ,
  255. 112: 0
  256. 113: |
  257. 114: SK_BLANK
  258. 115: <<
  259. 116: 4
  260. 117: )
  261. 118: ;
  262. 119: FunInsert
  263. 120: (
  264. 121: "begin"
  265. 122: ,
  266. 123: 0
  267. 124: |
  268. 125: SK_BLANK
  269. 126: <<
  270. 127: 4
  271. 128: )
  272. 129: ;
  273. 130: FunInsert
  274. 131: (
  275. 132: "end"
  276. 133: ,
  277. 134: 0
  278. 135: |
  279. 136: SK_CR
  280. 137: <<
  281. 138: 4

  282. (因为长度限制略去)

  283. 571: )
  284. 572: n
  285. 573: =
  286. 574: 1
  287. 575: ;
  288. 576: FunInsert
  289. 577: (
  290. 578: p
  291. 579: ,
  292. 580: n
  293. 581: |
  294. 582: SK_FUN
  295. 583: <<
  296. 584: 4
  297. 585: )
  298. 586: ;
  299. 587: }
  300. 588: }
复制代码

[ 本帖最后由 cs900601 于 2016-9-11 00:01 编辑 ]
 楼主| 发表于 2016-9-13 08:55:51 | 显示全部楼层
修理了一些语法分析和词法分析的错误,现在用19秒可以解析完 Yan 的编译器的 “编译器.txt”。这个文件有一些 #include 命令,结果就是它总共包含了81000多个 tokens。


螢幕快照_2016-09-12_19-51-21.jpeg (27.32 KB, 下载次数: 225)
发表于 2016-9-20 20:47:51 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2024-4-20 05:37 , Processed in 0.012235 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表