parser.yy 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. %{
  2. #include <config.h>
  3. #include <iostream>
  4. #include <sstream>
  5. #include <stdexcept>
  6. #include "tree.hpp"
  7. #include "globals.hpp"
  8. %}
  9. %pure-parser
  10. %union {
  11. char* str;
  12. int ival;
  13. float fval;
  14. Class* _class;
  15. Function* function;
  16. Field* field;
  17. Type* type;
  18. AtomicType* atomic_type;
  19. Namespace* _namespace;
  20. }
  21. %{
  22. extern int yylex(YYSTYPE* yylval);
  23. void yyerror(const char* s);
  24. extern int yylineno;
  25. bool search_down = true;
  26. Namespace* search_namespace = 0;
  27. Namespace* current_namespace = 0;
  28. static Class* current_class = 0;
  29. static Function* current_function = 0;
  30. static Type* current_type = 0;
  31. static Field* current_field = 0;
  32. static ClassMember::Visibility current_visibility;
  33. class ParseError : public std::exception
  34. {
  35. public:
  36. ParseError(const std::string& message) throw() :
  37. message()
  38. {
  39. std::ostringstream msg;
  40. msg << "Parse error in '" << current_file
  41. << "' line " << getCurrentLine() << ": "
  42. << message;
  43. this->message = msg.str();
  44. }
  45. virtual ~ParseError() throw()
  46. {}
  47. const char* what() const throw()
  48. {
  49. return message.c_str();
  50. }
  51. private:
  52. std::string message;
  53. };
  54. %}
  55. %token <ival> T_INT
  56. %token <fval> T_FLOAT
  57. %token <str> T_STRING
  58. %token <str> T_ID
  59. %token <atomic_type> T_ATOMIC_TYPE
  60. %token <_namespace> T_NAMESPACEREF
  61. %token T_CLASS
  62. %token T_STRUCT
  63. %token T_STATIC
  64. %token T_SUSPEND
  65. %token T_CUSTOM
  66. %token T_CONST
  67. %token T_UNSIGNED
  68. %token T_SIGNED
  69. %token T_VOID
  70. %token T_BOOL
  71. %token T_CHAR
  72. %token T_SHORT
  73. %token T_LONG
  74. %token T_DOUBLE
  75. %token T_PUBLIC
  76. %token T_PROTECTED
  77. %token T_PRIVATE
  78. %token T_NAMESPACE
  79. %token T_DDCOL "::"
  80. %type <_class> class_declaration
  81. %type <function> function_declaration
  82. %type <function> constructor_declaration;
  83. %type <function> destructor_declaration;
  84. %type <field> field_declaration;
  85. %type <type> type
  86. %type <atomic_type> type_identifier
  87. %%
  88. input:
  89. {
  90. current_namespace = unit;
  91. }
  92. namespace_members
  93. ;
  94. namespace_members: /* empty */
  95. | namespace_members namespace_member
  96. ;
  97. namespace_declaration:
  98. T_NAMESPACE T_ID '{'
  99. {
  100. Namespace* newNamespace = new Namespace();
  101. newNamespace->name = $2;
  102. free($2);
  103. current_namespace->add_namespace(newNamespace);
  104. current_namespace = newNamespace;
  105. }
  106. namespace_members '}'
  107. {
  108. current_namespace = current_namespace->parent;
  109. }
  110. | T_NAMESPACE T_NAMESPACEREF '{'
  111. {
  112. current_namespace = $2;
  113. }
  114. namespace_members '}'
  115. {
  116. current_namespace = current_namespace->parent;
  117. }
  118. ;
  119. namespace_member:
  120. class_declaration
  121. { current_namespace->add_type($1); }
  122. | function_declaration
  123. { current_namespace->functions.push_back($1); }
  124. | namespace_declaration
  125. | field_declaration
  126. { current_namespace->fields.push_back($1); }
  127. ;
  128. class_declaration:
  129. T_CLASS T_ID
  130. {
  131. current_class = new Class();
  132. current_class->name = $2;
  133. free($2);
  134. current_class->docu_comment = last_docucomment;
  135. last_docucomment = "";
  136. current_visibility = ClassMember::PROTECTED;
  137. }
  138. superclass_list '{' class_body '}' ';'
  139. {
  140. $$ = current_class;
  141. }
  142. ;
  143. superclass_list:
  144. /* empty */
  145. | ':' superclasses
  146. ;
  147. superclasses:
  148. superclass
  149. | superclasses ',' superclass
  150. ;
  151. superclass:
  152. superclass_visibility type_identifier
  153. {
  154. Class* superclass = dynamic_cast<Class*> ($2);
  155. if(superclass == 0)
  156. throw ParseError("SuperClass is not a Class type");
  157. current_class->super_classes.push_back(superclass);
  158. superclass->sub_classes.push_back(current_class);
  159. }
  160. ;
  161. superclass_visibility:
  162. T_PUBLIC
  163. | T_PROTECTED
  164. | T_PRIVATE
  165. ;
  166. class_body: /* empty */
  167. | class_body class_body_element
  168. ;
  169. class_body_element:
  170. visibility_change
  171. | constructor_declaration
  172. {
  173. $1->visibility = current_visibility;
  174. current_class->members.push_back($1);
  175. }
  176. | destructor_declaration
  177. {
  178. $1->visibility = current_visibility;
  179. current_class->members.push_back($1);
  180. }
  181. | function_declaration
  182. {
  183. $1->visibility = current_visibility;
  184. current_class->members.push_back($1);
  185. }
  186. | field_declaration
  187. {
  188. $1->visibility = current_visibility;
  189. current_class->members.push_back($1);
  190. }
  191. ;
  192. visibility_change:
  193. T_PUBLIC ':'
  194. { current_visibility = ClassMember::PUBLIC; }
  195. | T_PROTECTED ':'
  196. { current_visibility = ClassMember::PROTECTED; }
  197. | T_PRIVATE ':'
  198. { current_visibility = ClassMember::PRIVATE; }
  199. ;
  200. constructor_declaration:
  201. T_ID '('
  202. {
  203. current_function = new Function();
  204. current_function->type = Function::CONSTRUCTOR;
  205. current_function->docu_comment = last_docucomment;
  206. last_docucomment = "";
  207. free($1);
  208. }
  209. parameter_list ')' ';'
  210. {
  211. $$ = current_function;
  212. }
  213. ;
  214. destructor_declaration:
  215. '~' T_ID '(' ')' abstract_declaration ';'
  216. {
  217. current_function = new Function();
  218. current_function->type = Function::DESTRUCTOR;
  219. current_function->docu_comment = last_docucomment;
  220. last_docucomment = "";
  221. free($2);
  222. $$ = current_function;
  223. }
  224. ;
  225. field_declaration:
  226. type T_ID
  227. {
  228. current_field = new Field();
  229. current_field->type = $1;
  230. current_field->docu_comment = last_docucomment;
  231. last_docucomment = "";
  232. current_field->name = $2;
  233. free($2);
  234. }
  235. maybe_const_initialisation ';'
  236. {
  237. $$ = current_field;
  238. }
  239. ;
  240. maybe_const_initialisation:
  241. /* empty */
  242. | '=' T_INT
  243. {
  244. if(current_field->type->atomic_type == &BasicType::FLOAT) {
  245. current_field->const_float_value = (float) $2;
  246. } else {
  247. current_field->const_int_value = $2;
  248. }
  249. current_field->has_const_value = true;
  250. }
  251. | '=' T_FLOAT
  252. {
  253. current_field->const_float_value = $2;
  254. current_field->has_const_value = true;
  255. }
  256. | '=' T_STRING
  257. {
  258. current_field->const_string_value = $2;
  259. current_field->has_const_value = true;
  260. }
  261. ;
  262. function_declaration:
  263. type T_ID '('
  264. {
  265. current_function = new Function();
  266. current_function->type = Function::FUNCTION;
  267. current_function->return_type = *($1);
  268. delete $1;
  269. current_function->name = $2;
  270. free($2);
  271. current_function->docu_comment = last_docucomment;
  272. last_docucomment = "";
  273. }
  274. parameter_list ')' function_attributes abstract_declaration ';'
  275. {
  276. $$ = current_function;
  277. }
  278. ;
  279. function_attributes:
  280. /* empty */
  281. | T_CONST function_attributes
  282. | T_CUSTOM '(' T_STRING ')' function_attributes
  283. {
  284. current_function->parameter_spec = $3;
  285. current_function->custom = true;
  286. }
  287. | T_SUSPEND function_attributes
  288. {
  289. current_function->suspend = true;
  290. }
  291. ;
  292. abstract_declaration:
  293. /* empty */
  294. | '=' T_INT
  295. ;
  296. parameter_list:
  297. /* empty */
  298. | parameters
  299. ;
  300. parameters:
  301. parameter
  302. | parameters ',' parameter
  303. ;
  304. parameter:
  305. type
  306. {
  307. Parameter parameter;
  308. parameter.type = *($1);
  309. delete $1;
  310. current_function->parameters.push_back(parameter);
  311. }
  312. | type T_ID
  313. {
  314. Parameter parameter;
  315. parameter.type = *($1);
  316. delete $1;
  317. parameter.name = $2;
  318. free($2);
  319. current_function->parameters.push_back(parameter);
  320. }
  321. ;
  322. type:
  323. {
  324. current_type = new Type();
  325. }
  326. prefix_type_modifiers atomic_type postfix_type_modifiers
  327. {
  328. $$ = current_type;
  329. }
  330. ;
  331. prefix_type_modifiers:
  332. /* empty */
  333. | prefix_type_modifiers prefix_type_modifier
  334. ;
  335. prefix_type_modifier:
  336. T_UNSIGNED
  337. { current_type->_unsigned = true; }
  338. | T_SIGNED
  339. { current_type->_unsigned = false; }
  340. | T_STATIC
  341. { current_type->_static = true; }
  342. | T_CONST
  343. { current_type->_const = true; }
  344. ;
  345. postfix_type_modifiers:
  346. /* empty */
  347. | postfix_type_modifiers postfix_type_modifier
  348. ;
  349. postfix_type_modifier:
  350. T_CONST
  351. { current_type->_const = true; }
  352. | '*'
  353. { current_type->pointer++; }
  354. | '&'
  355. { current_type->ref++; }
  356. ;
  357. atomic_type:
  358. T_VOID
  359. { current_type->atomic_type = &BasicType::VOID; }
  360. | T_BOOL
  361. { current_type->atomic_type = &BasicType::BOOL; }
  362. | T_CHAR
  363. { current_type->atomic_type = &BasicType::CHAR; }
  364. | T_SHORT
  365. { current_type->atomic_type = &BasicType::SHORT; }
  366. | T_INT
  367. { current_type->atomic_type = &BasicType::INT; }
  368. | T_LONG
  369. { current_type->atomic_type = &BasicType::LONG; }
  370. | T_FLOAT
  371. { current_type->atomic_type = &BasicType::FLOAT; }
  372. | T_DOUBLE
  373. { current_type->atomic_type = &BasicType::DOUBLE; }
  374. | type_identifier
  375. { current_type->atomic_type = $1; }
  376. ;
  377. type_identifier:
  378. T_ATOMIC_TYPE
  379. {
  380. $$ = $1;
  381. }
  382. | namespace_refs "::" T_ATOMIC_TYPE
  383. {
  384. $$ = $3;
  385. search_namespace = 0;
  386. search_down = true;
  387. }
  388. ;
  389. namespace_refs:
  390. T_NAMESPACEREF
  391. {
  392. search_namespace = $1;
  393. search_down = false;
  394. }
  395. | namespace_refs "::" T_NAMESPACEREF
  396. {
  397. search_namespace = $3;
  398. }
  399. ;
  400. %%
  401. __attribute__((noreturn))
  402. void yyerror(const char* error)
  403. {
  404. throw ParseError(error);
  405. }