Advertisement
Guest User

Untitled

a guest
Oct 30th, 2014
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.09 KB | None | 0 0
  1. public class Parser {
  2. private static final APValueNum NEGATIVE_ONE = new APValueNum(
  3. new BigDecimal("-1"));
  4. LinkedList<Token> tokens = new LinkedList<>();
  5. Token lookahead;
  6.  
  7. public Parser(final List<Token> tokens) {
  8. this.tokens.addAll(tokens);
  9. if (tokens.isEmpty()) {
  10. throw new ParserException("Cannot parse an empty file!");
  11. }
  12. }
  13.  
  14. private void nextToken() {
  15. try {
  16. tokens.pop();
  17. } catch (final NoSuchElementException e) {
  18. throw new ParserException("Ran out of characters!", e);
  19. }
  20. // at the end of input we return an epsilon token
  21. if (tokens.isEmpty()) {
  22. lookahead = new Token(TokenType.EOF, "<EOF>");
  23. } else {
  24. lookahead = tokens.getFirst();
  25. }
  26. }
  27.  
  28. public List<ExpressionNode> parse(final Context context) {
  29.  
  30. final List<ExpressionNode> expressions = new ArrayList<>();
  31.  
  32. lookahead = tokens.getFirst();
  33.  
  34. while (lookahead.getType() != TokenType.EOF) {
  35. expressions.add(statement(context));
  36. }
  37. return expressions;
  38. }
  39.  
  40. private ExpressionNode statement(final Context context) {
  41. final ExpressionNode.VariableNode expr = identifier();
  42. nextToken();
  43. if (lookahead.getType() == TokenType.EQUAL) {
  44. final ExpressionNode assignment = assignment(context, expr);
  45. return assignment;
  46. } else if (lookahead.getType() == TokenType.IDENTIFIER) {
  47. // we have a parameter
  48. nextToken();
  49. if (lookahead.getType() == TokenType.IDENTIFIER
  50. || lookahead.getType() == TokenType.EQUAL) {
  51. final List<VariableNode> variables = new ArrayList<>();
  52. while (lookahead.getType() == TokenType.IDENTIFIER) {
  53. variables.add(identifier());
  54. nextToken();
  55. }
  56. if (lookahead.getType() == TokenType.EQUAL) {
  57. nextToken();
  58. final ExpressionNode expression = expression(context);
  59. final Function function = new Function(expr.getName(),
  60. variables, expression);
  61. context.putFunction(expr.getName(), function);
  62. nextToken();
  63. return ExpressionNode.VOID;
  64. } else {
  65. throw new ParserException(
  66. "Expected parameter list or equal (function def)");
  67. }
  68. } else {
  69. throw new ParserException("Expected EQUAL");
  70. }
  71. } else if (lookahead.getType() == TokenType.OPEN_PARENS) {
  72. final ExpressionNode node = functionParameters(context, expr);
  73. nextToken();
  74. return node;
  75. } else {
  76. throw new ParserException(
  77. "Non function call, assignment, or function def statement");
  78. }
  79.  
  80. }
  81.  
  82. private ExpressionNode assignment(final Context context,
  83. final ExpressionNode.VariableNode expr) {
  84. nextToken();
  85. final ExpressionNode assigned = expression(context);
  86. final ExpressionNode assignment = new ExpressionNode.AssignmentNode(
  87. expr, assigned);
  88. if (lookahead.getType() != TokenType.SEMI) {
  89. throw new ParserException("Expected semicolon, got "
  90. + lookahead.getText());
  91. }
  92. nextToken();
  93. return assignment;
  94. }
  95.  
  96. private ExpressionNode expression(final Context context) {
  97. if (lookahead.getType() == TokenType.IF) {
  98. return ifExpr(context);
  99. }
  100.  
  101. final ExpressionNode expr = signedTerm(context);
  102. return lowOp(expr, context);
  103. }
  104.  
  105. private ExpressionNode ifExpr(final Context context) {
  106. assert lookahead.getType() == TokenType.IF;
  107. nextToken();
  108. final ExpressionNode ifExpr = expression(context);
  109. final ExpressionNode thenExpr = expression(context);
  110. if (lookahead.getType() != TokenType.ELSE) {
  111. throw new ParserException("Needs else after if, was " + lookahead);
  112. }
  113. nextToken();
  114. final ExpressionNode elseExpr = expression(context);
  115. return new ExpressionNode.IfNode(ifExpr, thenExpr, elseExpr);
  116. }
  117.  
  118. /*
  119. * Lower level precedence operations: +, -, ||
  120. */
  121. private ExpressionNode lowOp(final ExpressionNode expr,
  122. final Context context) {
  123. if (lookahead.getType() == TokenType.PLUSMINUS) {
  124. // sum_op -> PLUSMINUS term sum_op
  125. ExpressionNode sum;
  126. final boolean positive = lookahead.getText().equals("+");
  127. nextToken();
  128. final ExpressionNode t = signedTerm(context);
  129. if (positive) {
  130. sum = new ExpressionNode.AdditionNode(expr, t);
  131. } else {
  132. sum = new ExpressionNode.SubtractionNode(expr, t);
  133. }
  134.  
  135. return lowOp(sum, context);
  136. } else if (lookahead.getType() == TokenType.OR) {
  137. nextToken();
  138. return lowOp(new ExpressionNode.OrNode(expr, term(context)),
  139. context);
  140. } else if (lookahead.getType() == TokenType.LESS_THAN) {
  141. nextToken();
  142. return lowOp(new ExpressionNode.LessThanNode(expr, term(context)),
  143. context);
  144. } else if (lookahead.getType() == TokenType.GREATER_THAN) {
  145. nextToken();
  146. return lowOp(
  147. new ExpressionNode.GreaterThanNode(expr, term(context)),
  148. context);
  149. } else if (lookahead.getType() == TokenType.LESS_THAN_EQUAL) {
  150. nextToken();
  151. return lowOp(new ExpressionNode.LessThanEqualNode(expr,
  152. term(context)), context);
  153. } else if (lookahead.getType() == TokenType.GREATER_THAN_EQUAL) {
  154. nextToken();
  155. return lowOp(new ExpressionNode.GreaterThanEqualNode(expr,
  156. term(context)), context);
  157. } else {
  158. // sum_op -> EPSILON
  159. return expr;
  160. }
  161. }
  162.  
  163. private ExpressionNode term(final Context context) {
  164. // term -> factor term_op
  165. return highOp(factor(context), context);
  166. }
  167.  
  168. /*
  169. * High precedence operations: *, /, &&
  170. */
  171. private ExpressionNode highOp(final ExpressionNode expr,
  172. final Context context) {
  173. if (lookahead.getType() == TokenType.MULDIV) {
  174. // term_op -> MULTDIV factor term_op
  175. ExpressionNode prod;
  176.  
  177. final boolean positive = lookahead.getText().equals("*");
  178. nextToken();
  179. final ExpressionNode f = signedFactor(context);
  180.  
  181. if (positive) {
  182. prod = new ExpressionNode.MultiplicationNode(expr, f);
  183. } else {
  184. prod = new ExpressionNode.DivisionNode(expr, f);
  185. }
  186.  
  187. return highOp(prod, context);
  188. } else if (lookahead.getType() == TokenType.AND) {
  189. nextToken();
  190. return highOp(new ExpressionNode.AndNode(expr, value(context)),
  191. context);
  192. } else {
  193. // term_op -> EPSILON
  194. return expr;
  195. }
  196.  
  197. }
  198.  
  199. private ExpressionNode signedFactor(final Context context) {
  200. if (lookahead.getType() == TokenType.PLUSMINUS) {
  201. final boolean positive = lookahead.getText().equals("+");
  202. nextToken();
  203. final ExpressionNode t = factor(context);
  204. if (positive) {
  205. return t;
  206. } else {
  207. return new ExpressionNode.ConstantNode(
  208. ((APValueNum) t.getValue(context)).callMethod(
  209. Methods.MULTIPLY, NEGATIVE_ONE));
  210. }
  211. } else {
  212. // signed_factor -> factor
  213. return factor(context);
  214. }
  215. }
  216.  
  217. private ExpressionNode factor(final Context context) {
  218. // factor -> argument factor_op
  219. return factorOp(argument(context), context);
  220. }
  221.  
  222. private ExpressionNode factorOp(final ExpressionNode expression,
  223. final Context context) {
  224. if (lookahead.getType() == TokenType.RAISED) {
  225. // factor_op -> RAISED expression
  226. nextToken();
  227. final ExpressionNode exponent = signedFactor(context);
  228. return new ExpressionNode.ExponentiationNode(expression, exponent);
  229.  
  230. } else {
  231. // factor_op -> EPSILON
  232. return expression;
  233. }
  234. }
  235.  
  236. private ExpressionNode argument(final Context context) {
  237. if (lookahead.getType() == TokenType.OPEN_PARENS) {
  238. // argument -> OPEN_BRACKET sum CLOSE_BRACKET
  239. nextToken();
  240. final ExpressionNode node = expression(context);
  241.  
  242. if (lookahead.getType() != TokenType.CLOSE_PARENS) {
  243. throw new ParserException("Closing brackets expected and "
  244. + lookahead.getText() + " found instead");
  245. }
  246.  
  247. nextToken();
  248. return node;
  249. } else {
  250. // argument -> value
  251. return value(context);
  252. }
  253. }
  254.  
  255. private ExpressionNode signedTerm(final Context context) {
  256. if (lookahead.getType() == TokenType.PLUSMINUS) {
  257. // signed_term -> PLUSMINUS term
  258. final boolean positive = lookahead.getText().equals("+");
  259. nextToken();
  260. final ExpressionNode t = term(context);
  261. if (positive) {
  262. return t;
  263. } else {
  264. return new ExpressionNode.ConstantNode(t.getValue(context)
  265. .callMethod(Methods.MULTIPLY, NEGATIVE_ONE));
  266. }
  267. } else {
  268. // signed_term -> term
  269. return term(context);
  270. }
  271. }
  272.  
  273. private ExpressionNode value(final Context context) {
  274. if (lookahead.getType() == TokenType.NUMBER) {
  275. final ExpressionNode.ConstantNode expr = new ExpressionNode.ConstantNode(
  276. new APValueNum(new BigDecimal(lookahead.getText())));
  277. nextToken();
  278. return expr;
  279. } else if (lookahead.getType() == TokenType.BOOLEAN) {
  280. final ExpressionNode.ConstantNode expr = new ExpressionNode.ConstantNode(
  281. new APValueBool(Boolean.parseBoolean(lookahead.getText())));
  282. nextToken();
  283. return expr;
  284. }
  285.  
  286. else if (lookahead.getType() == TokenType.IDENTIFIER) {
  287.  
  288. final ExpressionNode.VariableNode expr = identifier();
  289. nextToken();
  290. if (lookahead.getType() == TokenType.OPEN_PARENS) {
  291. return functionParameters(context, expr);
  292. }
  293. return expr;
  294. } else {
  295. throw new ParserException("Unexpected token " + lookahead
  296. + " found");
  297. }
  298. }
  299.  
  300. /**
  301. * @param context
  302. * @param expr
  303. * @return
  304. */
  305. private ExpressionNode functionParameters(final Context context,
  306. final ExpressionNode.VariableNode expr) {
  307. final List<ExpressionNode> parameters = new ArrayList<>();
  308. nextToken();
  309. if (lookahead.getType() == TokenType.CLOSE_PARENS) {
  310. // No params
  311. final ExpressionNode.FunctionCallNode node = new ExpressionNode.FunctionCallNode(
  312. expr, parameters);
  313. nextToken();
  314. return node;
  315. }
  316.  
  317. parameters.add(expression(context));
  318. if (lookahead.getType() == TokenType.CLOSE_PARENS) {
  319. // One parameter
  320. final ExpressionNode.FunctionCallNode node = new ExpressionNode.FunctionCallNode(
  321. expr, parameters);
  322. nextToken();
  323. return node;
  324. }
  325.  
  326. while (lookahead.getType() != TokenType.CLOSE_PARENS) {
  327. if (lookahead.getType() != TokenType.COMMA) {
  328. throw new ParserException("Expected comma, got " + lookahead);
  329. }
  330. nextToken();
  331. parameters.add(expression(context));
  332. }
  333. nextToken();
  334.  
  335. return new ExpressionNode.FunctionCallNode(expr, parameters);
  336. }
  337.  
  338. private ExpressionNode.VariableNode identifier() {
  339. return new ExpressionNode.VariableNode(lookahead.getText());
  340. }
  341. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement