parser.y 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /* =============================================================================
  2. //
  3. // This file is part of the qlow compiler.
  4. //
  5. // Copyright (C) 2014-2015 Nicolas Winkler
  6. //
  7. // This program is free software: you can redistribute it and/or modify
  8. // it under the terms of the GNU General Public License as published by
  9. // the Free Software Foundation, either version 3 of the License, or
  10. // (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. // GNU General Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public License
  18. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. //
  20. // ===========================================================================*/
  21. %{
  22. #include <string>
  23. #include <vector>
  24. #include <iostream>
  25. #include <cstdio>
  26. #include "Ast.h"
  27. using namespace qlow::ast;
  28. extern int qlow_parser_lex();
  29. int qlow_parser_error(const char*)
  30. {
  31. throw "syntax error";
  32. }
  33. using ClassList = std::vector<std::unique_ptr<qlow::ast::Class>>;
  34. std::unique_ptr<ClassList> parsedClasses;
  35. %}
  36. %define api.prefix {qlow_parser_}
  37. /*
  38. %skeleton "lalr1.cc" // generate C++ parser
  39. //%define api.namespace {uetli::parser}
  40. //%define api.value.type {struct semantic_type}
  41. //%define parser_class_name {Parser}
  42. //%name-prefix "uetli_parser_"
  43. */
  44. %union {
  45. //using qlow::ast::Class;
  46. std::vector<std::unique_ptr<qlow::ast::Class>>* classes;
  47. qlow::ast::Class* classDefinition;
  48. qlow::ast::FeatureDeclaration* featureDeclaration;
  49. std::vector<std::unique_ptr<qlow::ast::FeatureDeclaration>>* featureList;
  50. std::vector<std::unique_ptr<qlow::ast::ArgumentDeclaration>>* argumentList;
  51. std::vector<std::unique_ptr<qlow::ast::Statement>>* statements;
  52. std::vector<std::unique_ptr<qlow::ast::Expression>>* expressionList;
  53. qlow::ast::ArgumentDeclaration* argumentDeclaration;
  54. qlow::ast::DoEndBlock* doEndBlock;
  55. qlow::ast::Statement* statement;
  56. qlow::ast::Expression* expression;
  57. qlow::ast::Operation::Operator op;
  58. qlow::ast::MethodDefinition* methodDefinition;
  59. qlow::ast::FeatureCall* featureCall;
  60. qlow::ast::AssignmentStatement* assignmentStatement;
  61. qlow::ast::NewVariableStatement* newVariableStatement;
  62. qlow::ast::UnaryOperation* unaryOperation;
  63. qlow::ast::BinaryOperation* binaryOperation;
  64. const char* cString;
  65. std::string* string;
  66. int token;
  67. };
  68. %token <string> IDENTIFIER
  69. %token <token> CLASS DO END IF
  70. %token <token> NEW_LINE
  71. %token <token> COLON COMMA DOT ASSIGN OPERATOR
  72. %token <token> ROUND_LEFT ROUND_RIGHT
  73. %type <classes> classes
  74. %type <classDefinition> classDefinition
  75. %type <featureDeclaration> featureDeclaration fieldDeclaration methodDefinition
  76. %type <featureList> featureList
  77. %type <argumentList> argumentList
  78. %type <statements> statements
  79. %type <expressionList> expressionList
  80. %type <argumentDeclaration> argumentDeclaration
  81. %type <doEndBlock> doEndBlock
  82. %type <statement> statement
  83. %type <expression> expression operationExpression paranthesesExpression
  84. %type <op> operator
  85. %type <featureCall> featureCall
  86. %type <assignmentStatement> assignmentStatement
  87. %type <newVariableStatement> newVariableStatement
  88. %type <unaryOperation> unaryOperation
  89. %type <binaryOperation> binaryOperation
  90. %left ASTERISK SLASH
  91. %left PLUS MINUS
  92. %start classes
  93. %%
  94. /* possible newline characters
  95. pnl:
  96. {
  97. }
  98. |
  99. pnl NEW_LINE {
  100. };
  101. */
  102. /* list of class definitions */
  103. classes:
  104. /* empty */ {
  105. parsedClasses = std::make_unique<ClassList>();
  106. }
  107. |
  108. classes classDefinition {
  109. parsedClasses->push_back(std::move(std::unique_ptr<Class>($2)));
  110. };
  111. classDefinition:
  112. CLASS IDENTIFIER featureList END {
  113. $$ = new Class(*$2, *$3);
  114. delete $2; delete $3; $2 = 0; $3 = 0;
  115. };
  116. featureList:
  117. /* empty */ {
  118. $$ = new std::vector<std::unique_ptr<FeatureDeclaration>>();
  119. }
  120. |
  121. featureList featureDeclaration {
  122. $$ = $1;
  123. $$->push_back(std::move(std::unique_ptr<FeatureDeclaration>($2)));
  124. };
  125. featureDeclaration:
  126. fieldDeclaration {
  127. $$ = $1;
  128. }
  129. |
  130. methodDefinition {
  131. $$ = $1;
  132. };
  133. fieldDeclaration:
  134. IDENTIFIER COLON IDENTIFIER {
  135. $$ = new FieldDeclaration(*$3, *$1);
  136. delete $3; delete $1; $1 = $3 = 0;
  137. };
  138. methodDefinition:
  139. IDENTIFIER COLON IDENTIFIER doEndBlock {
  140. $$ = new MethodDefinition(*$3, *$1, std::move(std::unique_ptr<DoEndBlock>($4)));
  141. delete $3; delete $1; $1 = $3 = 0;
  142. }
  143. |
  144. IDENTIFIER doEndBlock {
  145. $$ = new MethodDefinition("", *$1, std::move(std::unique_ptr<DoEndBlock>($2)));
  146. delete $1; $1 = 0;
  147. }
  148. |
  149. IDENTIFIER
  150. ROUND_LEFT argumentList ROUND_RIGHT COLON IDENTIFIER doEndBlock {
  151. $$ = new MethodDefinition(*$6, *$1, std::move(*$3), std::move(std::unique_ptr<DoEndBlock>($7)));
  152. delete $6; delete $1; delete $3; $1 = $6 = nullptr; $3 = nullptr;
  153. }
  154. |
  155. IDENTIFIER ROUND_LEFT argumentList ROUND_RIGHT doEndBlock {
  156. $$ = new MethodDefinition("", *$1, std::move(*$3), std::move(std::unique_ptr<DoEndBlock>($5)));
  157. delete $1; delete $3; $1 = nullptr; $3 = nullptr;
  158. };
  159. argumentList:
  160. argumentDeclaration {
  161. $$ = new std::vector<std::unique_ptr<ArgumentDeclaration>>();
  162. $$->push_back(std::unique_ptr<ArgumentDeclaration>($1));
  163. }
  164. |
  165. argumentList COMMA argumentDeclaration {
  166. $$ = $1;
  167. $$->push_back(std::unique_ptr<ArgumentDeclaration>($3));
  168. };
  169. argumentDeclaration:
  170. IDENTIFIER COLON IDENTIFIER {
  171. $$ = new ArgumentDeclaration(*$3, *$1);
  172. delete $3; delete $1; $1 = $3 = 0;
  173. };
  174. doEndBlock:
  175. DO statements END {
  176. $$ = new DoEndBlock(std::move(*$2));
  177. delete $2; $2 = 0;
  178. };
  179. statements:
  180. /* empty */ {
  181. $$ = new std::vector<std::unique_ptr<Statement>>();
  182. }
  183. |
  184. statements statement {
  185. $$ = $1;
  186. $$->push_back(std::move(std::unique_ptr<Statement>($2)));
  187. };
  188. statement:
  189. featureCall {
  190. $$ = $1;
  191. }
  192. |
  193. assignmentStatement {
  194. $$ = $1;
  195. }
  196. |
  197. newVariableStatement {
  198. $$ = $1;
  199. };
  200. featureCall:
  201. IDENTIFIER {
  202. $$ = new FeatureCall(nullptr, *$1);
  203. delete $1; $1 = 0;
  204. }
  205. |
  206. IDENTIFIER ROUND_LEFT expressionList ROUND_RIGHT {
  207. $$ = new FeatureCall(nullptr, *$1, std::move(*$3));
  208. delete $1; delete $3; $1 = 0; $3 = 0;
  209. }
  210. |
  211. expression DOT IDENTIFIER {
  212. $$ = new FeatureCall(std::move(std::unique_ptr<Expression>($1)), *$3);
  213. delete $3; $3 = 0;
  214. }
  215. |
  216. expression DOT IDENTIFIER ROUND_LEFT expressionList ROUND_RIGHT {
  217. $$ = new FeatureCall(std::move(std::unique_ptr<Expression>($1)), *$3,
  218. std::move(*$5));
  219. delete $3; $3 = 0; delete $5; $5 = 0;
  220. };
  221. /* list of effective arguments */
  222. expressionList:
  223. expression {
  224. $$ = new std::vector<std::unique_ptr<Expression>>();
  225. $$->push_back(std::move(std::unique_ptr<Expression>($1)));
  226. }
  227. |
  228. expressionList COMMA expression {
  229. $$ = $1;
  230. $$->push_back(std::move(std::unique_ptr<Expression>($3)));
  231. };
  232. expression:
  233. featureCall {
  234. $$ = $1;
  235. }
  236. |
  237. operationExpression {
  238. $$ = $1;
  239. }
  240. |
  241. paranthesesExpression {
  242. $$ = $1;
  243. };
  244. operationExpression:
  245. binaryOperation {
  246. $$ = $1;
  247. }
  248. |
  249. unaryOperation {
  250. $$ = $1;
  251. };
  252. binaryOperation:
  253. expression operator expression {
  254. $$ = new BinaryOperation(std::unique_ptr<Expression>($1),
  255. std::unique_ptr<Expression>($3), $2);
  256. };
  257. unaryOperation:
  258. expression operator {
  259. $$ = new UnaryOperation(std::unique_ptr<Expression>($1),
  260. UnaryOperation::SUFFIX, $2);
  261. }
  262. |
  263. operator expression {
  264. $$ = new UnaryOperation(std::unique_ptr<Expression>($2),
  265. UnaryOperation::PREFIX, $1);
  266. };
  267. operator:
  268. PLUS { $$ = qlow::ast::Operation::Operator::PLUS; }
  269. |
  270. MINUS { $$ = qlow::ast::Operation::Operator::MINUS; }
  271. |
  272. ASTERISK { $$ = qlow::ast::Operation::Operator::ASTERISK; }
  273. |
  274. SLASH { $$ = qlow::ast::Operation::Operator::SLASH; };
  275. paranthesesExpression:
  276. ROUND_LEFT expression ROUND_RIGHT {
  277. $$ = $2;
  278. };
  279. assignmentStatement:
  280. IDENTIFIER ASSIGN expression {
  281. $$ = new AssignmentStatement(std::move(*$1), std::unique_ptr<Expression>($3));
  282. delete $1; $1 = 0;
  283. };
  284. newVariableStatement:
  285. IDENTIFIER COLON IDENTIFIER {
  286. $$ = new NewVariableStatement(*$3, *$1);
  287. delete $3; delete $1; $3 = 0; $1 = 0;
  288. };
  289. %%