Updated kn translations
[gcalctool.git] / src / equation-parser.vala
blob2410d7bb6e032cf323748c94a3437fb9b5eaf81e
1 /*
2 * Copyright (C) 2012 Arth Patel
3 * Copyright (C) 2012 Robert Ancell
5 * This program is free software: you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation, either version 2 of the License, or (at your option) any later
8 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
9 * license.
12 /* Operator Associativity. */
13 public enum Associativity
15 LEFT,
16 RIGHT
19 /* Operator Precedence. */
20 private enum Precedence
22 UNKNOWN = 0,
23 ADD_SUBTRACT = 1,
24 MULTIPLY = 2,
25 MOD = 3,
26 DIVIDE = 4,
27 NOT = 5,
28 ROOT = 6,
29 FUNCTION = 7,
30 BOOLEAN = 8,
31 PERCENTAGE = 9,
32 /* UNARY_MINUS and POWER must have same precedence. */
33 UNARY_MINUS = 10,
34 POWER = 10,
35 FACTORIAL = 11,
36 NUMBER_VARIABLE = 12,
37 /* DEPTH should be always at the bottom. It stops node jumping off the current depth level. */
38 DEPTH
41 /* ParseNode structure for parse tree. */
42 public class ParseNode
44 public Parser parser;
45 public ParseNode? parent = null;
46 public ParseNode? left = null;
47 public ParseNode? right = null;
48 public LexerToken token;
49 public uint precedence;
50 public Associativity associativity;
51 public string? value;
53 public ParseNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity, string? value = null)
55 this.parser = parser;
56 this.token = token;
57 this.precedence = precedence;
58 this.associativity = associativity;
59 this.value = value;
62 public virtual Number? solve ()
64 return null;
68 public abstract class RNode : ParseNode
70 public RNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
72 base (parser, token, precedence, associativity);
75 public override Number? solve ()
77 var r = right.solve ();
78 if (r == null)
79 return null;
80 return solve_r (r);
83 public abstract Number solve_r (Number r);
86 public abstract class LRNode : ParseNode
88 public LRNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
90 base (parser, token, precedence, associativity);
93 public override Number? solve ()
95 var l = left.solve ();
96 var r = right.solve ();
97 if (l == null || r == null)
98 return null;
99 return solve_lr (l, r);
102 public abstract Number solve_lr (Number left, Number r);
105 public class ConstantNode : ParseNode
107 public ConstantNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
109 base (parser, token, precedence, associativity);
112 public override Number? solve ()
114 return mp_set_from_string (token.text, parser.number_base);
118 public class AssignNode : RNode
120 public AssignNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
122 base (parser, token, precedence, associativity);
125 public override Number solve_r (Number r)
127 parser.set_variable (left.token.text, r);
128 return r;
132 public class NameNode : ParseNode
134 public NameNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity, string? text = null)
136 base (parser, token, precedence, associativity, text);
140 public class VariableNode : ParseNode
142 public VariableNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
144 base (parser, token, precedence, associativity);
147 public override Number? solve ()
149 /* If defined, then get the variable */
150 var ans = parser.get_variable (token.text);
151 if (ans != null)
152 return ans;
154 /* If has more than one character then assume a multiplication of variables */
155 // FIXME: Do this in the lexer
156 var value = new Number.integer (1);
157 var index = 0;
158 unichar c;
159 while (token.text.get_next_char (ref index, out c))
161 var t = parser.get_variable (c.to_string ());
162 if (t == null)
164 parser.set_error (ErrorCode.UNKNOWN_VARIABLE, token.text, token.start_index, token.end_index);
165 return null;
167 value = value.multiply (t);
170 return value;
174 public class VariableWithPowerNode : ParseNode
176 public VariableWithPowerNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity, string text)
178 base (parser, token, precedence, associativity, text);
181 public override Number? solve ()
183 var pow = super_atoi (value);
185 value = null;
187 /* If defined, then get the variable */
188 var ans = parser.get_variable (token.text);
189 if (ans != null)
190 return ans.xpowy_integer (pow);
192 /* If has more than one character then assume a multiplication of variables */
193 // FIXME: Do in lexer
194 var value = new Number.integer (1);
195 var index = 0;
196 unichar c;
197 while (token.text.get_next_char (ref index, out c))
199 var t = parser.get_variable (c.to_string ());
200 if (t == null)
202 parser.set_error (ErrorCode.UNKNOWN_VARIABLE, token.text, token.start_index, token.end_index);
203 return null;
206 /* If last term do power */
207 var i = index;
208 unichar next;
209 if (!token.text.get_next_char (ref i, out next))
210 t = t.xpowy_integer (pow);
211 value = value.multiply (t);
214 return value;
218 public class FunctionNode : RNode
220 public FunctionNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
222 base (parser, token, precedence, associativity);
225 public override Number solve_r (Number r)
227 var ans = parser.get_function (token.text, r);
228 if (ans == null)
229 parser.set_error (ErrorCode.UNKNOWN_FUNCTION, token.text, token.start_index, token.end_index);
231 return ans;
235 public class FunctionWithPowerNode : ParseNode
237 public FunctionWithPowerNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity, string text)
239 base (parser, token, precedence, associativity, text);
242 public override Number? solve ()
244 var val = right.solve ();
245 if (val == null)
247 value = null;
248 return null;
250 var tmp = parser.get_function (token.text, val);
251 if (tmp == null)
253 value = null;
254 parser.set_error (ErrorCode.UNKNOWN_FUNCTION, token.text, token.start_index, token.end_index);
255 return null;
258 var pow = super_atoi (value);
259 value = null;
261 return tmp.xpowy_integer (pow);
265 public class FunctionWithNegativePowerNode : ParseNode
267 public FunctionWithNegativePowerNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity, string text)
269 base (parser, token, precedence, associativity, text);
272 public override Number? solve ()
274 var val = right.solve ();
275 if (val == null)
277 value = null;
278 return null;
280 var inv_name = token.text + "⁻¹";
281 var tmp = parser.get_function (inv_name, val);
282 if (tmp == null)
284 value = null;
285 parser.set_error (ErrorCode.UNKNOWN_FUNCTION, token.text, token.start_index, token.end_index);
286 return null;
289 var pow = super_atoi (value);
290 value = null;
292 return tmp.xpowy_integer (-pow);
296 public class UnaryMinusNode : RNode
298 public UnaryMinusNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
300 base (parser, token, precedence, associativity);
303 public override Number solve_r (Number r)
305 return r.invert_sign ();
309 public class AbsoluteValueNode : RNode
311 public AbsoluteValueNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
313 base (parser, token, precedence, associativity);
316 public override Number solve_r (Number r)
318 return r.abs ();
322 public class FloorNode : RNode
324 public FloorNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
326 base (parser, token, precedence, associativity);
329 public override Number solve_r (Number r)
331 return r.floor ();
335 public class CeilingNode : RNode
337 public CeilingNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
339 base (parser, token, precedence, associativity);
342 public override Number solve_r (Number r)
344 return r.ceiling ();
348 public class FractionalComponentNode : RNode
350 public FractionalComponentNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
352 base (parser, token, precedence, associativity);
355 public override Number solve_r (Number r)
357 return r.fractional_part ();
361 public class RoundNode : RNode
363 public RoundNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
365 base (parser, token, precedence, associativity);
368 public override Number solve_r (Number r)
370 return r.round ();
374 public class PercentNode : RNode
376 public PercentNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
378 base (parser, token, precedence, associativity);
381 public override Number solve_r (Number r)
383 return r.divide_integer (100);
387 public class FactorialNode : RNode
389 public FactorialNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
391 base (parser, token, precedence, associativity);
394 public override Number solve_r (Number r)
396 return r.factorial ();
400 public class AddNode : LRNode
402 public bool do_percentage = false;
404 public AddNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
406 base (parser, token, precedence, associativity);
409 public override Number solve_lr (Number l, Number r)
411 if (do_percentage)
413 var per = r.add (new Number.integer (100));
414 per = per.divide_integer (100);
415 return l.multiply (per);
417 else
418 return l.add (r);
422 public class SubtractNode : LRNode
424 public bool do_percentage = false;
426 public SubtractNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
428 base (parser, token, precedence, associativity);
431 public override Number solve_lr (Number l, Number r)
433 if (do_percentage)
435 var per = r.add (new Number.integer (-100));
436 per = per.divide_integer (-100);
437 return l.multiply (per);
439 else
440 return l.subtract (r);
444 public class MultiplyNode : LRNode
446 public MultiplyNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
448 base (parser, token, precedence, associativity);
451 public override Number solve_lr (Number l, Number r)
453 return l.multiply (r);
457 public class DivideNode : LRNode
459 public DivideNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
461 base (parser, token, precedence, associativity);
464 public override Number solve_lr (Number l, Number r)
466 return l.divide (r);
470 public class ModulusDivideNode : LRNode
472 public ModulusDivideNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
474 base (parser, token, precedence, associativity);
477 public override Number solve_lr (Number l, Number r)
479 return l.modulus_divide (r);
483 public class RootNode : RNode
485 private int n;
487 public RootNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity, int n)
489 base (parser, token, precedence, associativity);
490 this.n = n;
493 public override Number solve_r (Number r)
495 return r.root (n);
499 public class XPowYNode : LRNode
501 public XPowYNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
503 base (parser, token, precedence, associativity);
506 public override Number solve_lr (Number l, Number r)
508 return l.xpowy (r);
512 public class XPowYIntegerNode : ParseNode
514 public XPowYIntegerNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
516 base (parser, token, precedence, associativity);
519 public override Number? solve ()
521 var val = left.solve ();
522 var pow = super_atoi (right.token.text);
523 if (val == null)
524 return null;
526 return val.xpowy_integer (pow);
530 public class NotNode : RNode
532 public NotNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
534 base (parser, token, precedence, associativity);
537 public override Number solve_r (Number r)
539 if (!mp_is_overflow (r, parser.wordlen))
541 parser.set_error (ErrorCode.OVERFLOW);
542 return new Number.integer (0);
545 return r.not (parser.wordlen);
549 public class AndNode : LRNode
551 public AndNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
553 base (parser, token, precedence, associativity);
556 public override Number solve_lr (Number l, Number r)
558 return l.and (r);
562 public class OrNode : LRNode
564 public OrNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
566 base (parser, token, precedence, associativity);
569 public override Number solve_lr (Number l, Number r)
571 return l.or (r);
575 public class XorNode : LRNode
577 public XorNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
579 base (parser, token, precedence, associativity);
582 public override Number solve_lr (Number l, Number r)
584 return l.xor (r);
588 public class ConvertNode : LRNode
590 public ConvertNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
592 base (parser, token, precedence, associativity);
595 public override Number solve_lr (Number l, Number r)
597 string from;
598 if (left.value != null)
600 from = left.value;
601 left.value = null;
603 else
604 from = left.token.text;
606 string to;
607 if (right.value != null)
609 to = right.value;
610 right.value = null;
612 else
613 to = right.token.text;
615 var tmp = new Number.integer (1);
617 var ans = parser.convert (tmp, from, to);
618 if (ans == null)
619 parser.set_error (ErrorCode.UNKNOWN_CONVERSION);
621 return ans;
625 public class ConvertNumberNode : ParseNode
627 public ConvertNumberNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
629 base (parser, token, precedence, associativity);
632 public override Number? solve ()
634 string from;
635 if (left.value != null)
637 from = left.value;
638 left.value = null;
640 else
641 from = left.token.text;
643 string to;
644 if (right.value != null)
646 to = right.value;
647 right.value = null;
649 else
650 to = right.token.text;
652 var tmp = mp_set_from_string (left.left.token.text, parser.number_base);
653 if (tmp == null)
654 return null;
656 var ans = parser.convert (tmp, from, to);
657 if (ans == null)
658 parser.set_error (ErrorCode.UNKNOWN_CONVERSION);
660 return ans;
664 public class Parser
666 private string input;
667 private ParseNode root;
668 private ParseNode right_most;
669 private Lexer lexer;
670 public int number_base;
671 public int wordlen;
672 private uint depth_level;
673 private ErrorCode error;
674 private string error_token;
675 private int error_token_start;
676 private int error_token_end;
678 public Parser (string input, int number_base, int wordlen)
680 this.input = input;
681 lexer = new Lexer (input, this, number_base);
682 root = null;
683 depth_level = 0;
684 right_most = null;
685 this.number_base = number_base;
686 this.wordlen = wordlen;
687 error = ErrorCode.NONE;
688 error_token = null;
689 error_token_start = 0;
690 error_token_end = 0;
693 public void set_error (ErrorCode errorno, string? token = null, uint token_start = 0, uint token_end = 0)
695 error = errorno;
696 error_token = token;
697 error_token_start = input.char_count (token_start);
698 error_token_end = input.char_count (token_end);
701 public virtual bool variable_is_defined (string name)
703 return false;
706 public virtual Number? get_variable (string name)
708 return null;
711 public virtual void set_variable (string name, Number x)
715 public virtual bool function_is_defined (string name)
717 return false;
720 public virtual Number? get_function (string name, Number x)
722 return null;
725 public virtual Number? convert (Number x, string x_units, string z_units)
727 return null;
730 /* Start parsing input string. And call evaluate on success. */
731 public Number? parse (out ErrorCode error_code, out string? error_token, out uint error_start, out uint error_end)
733 /* Scan string and split into tokens */
734 lexer.scan ();
736 /* Parse tokens */
737 var ret = statement ();
739 var token = lexer.get_next_token ();
740 if (token.type == LexerTokenType.ASSIGN)
742 token = lexer.get_next_token ();
743 if (token.type != LexerTokenType.PL_EOS)
745 /* Full string is not parsed. */
746 if (error == 0)
747 set_error (ErrorCode.INVALID, token.text, token.start_index, token.end_index);
749 error_code = error;
750 error_token = this.error_token;
751 error_start = error_token_start;
752 error_end = error_token_end;
753 return null;
756 if (token.type != LexerTokenType.PL_EOS)
758 /* Full string is not parsed. */
759 if (error == 0)
760 set_error (ErrorCode.INVALID, token.text, token.start_index, token.end_index);
762 error_code = error;
763 error_token = this.error_token;
764 error_start = error_token_start;
765 error_end = error_token_end;
766 return null;
769 /* Input can't be parsed with grammar. */
770 if (!ret)
772 error_code = error;
773 error_token = this.error_token;
774 error_start = error_token_start;
775 error_end = error_token_end;
776 return null;
778 var ans = root.solve ();
779 if (ans == null)
781 error_code = ErrorCode.INVALID;
782 error_token = null;
783 error_start = error_token_start;
784 error_end = error_token_end;
785 return null;
788 error_code = ErrorCode.NONE;
789 error_token = null;
790 error_start = 0;
791 error_end = 0;
792 return ans;
795 /* Converts LexerTokenType to Precedence value. */
796 private Precedence get_precedence (LexerTokenType type)
798 /* WARNING: This function doesn't work for Unary Plus and Unary Minus. Use their precedence directly while inserting them in tree. */
799 if (type == LexerTokenType.ADD || type == LexerTokenType.SUBTRACT)
800 return Precedence.ADD_SUBTRACT;
801 if (type == LexerTokenType.MULTIPLY)
802 return Precedence.MULTIPLY;
803 if (type == LexerTokenType.MOD)
804 return Precedence.MOD;
805 if (type == LexerTokenType.DIVIDE)
806 return Precedence.DIVIDE;
807 if (type == LexerTokenType.NOT)
808 return Precedence.NOT;
809 if (type == LexerTokenType.ROOT || type == LexerTokenType.ROOT_3 || type == LexerTokenType.ROOT_4)
810 return Precedence.ROOT;
811 if (type == LexerTokenType.FUNCTION)
812 return Precedence.FUNCTION;
813 if (type == LexerTokenType.AND || type == LexerTokenType.OR || type == LexerTokenType.XOR)
814 return Precedence.BOOLEAN;
815 if (type == LexerTokenType.PERCENTAGE)
816 return Precedence.PERCENTAGE;
817 if (type == LexerTokenType.POWER)
818 return Precedence.POWER;
819 if (type == LexerTokenType.FACTORIAL)
820 return Precedence.FACTORIAL;
821 if (type == LexerTokenType.NUMBER || type == LexerTokenType.VARIABLE)
822 return Precedence.NUMBER_VARIABLE;
823 return Precedence.UNKNOWN;
826 /* Return associativity of specific token type from precedence. */
827 private Associativity get_associativity_p (Precedence type)
829 if (type == Precedence.BOOLEAN || type == Precedence.DIVIDE || type == Precedence.MOD || type == Precedence.MULTIPLY || type == Precedence.ADD_SUBTRACT)
830 return Associativity.LEFT;
831 if (type == Precedence.POWER)
832 return Associativity.RIGHT;
833 /* For all remaining / non-associative operators, return Left Associativity. */
834 return Associativity.LEFT;
837 /* Return associativity of specific token by converting it to precedence first. */
838 private Associativity get_associativity (LexerToken token)
840 return get_associativity_p (get_precedence (token.type));
843 /* Generate precedence for a node from precedence value. Includes depth_level. */
844 private uint make_precedence_p (Precedence p)
846 return p + (depth_level * Precedence.DEPTH);
849 /* Generate precedence for a node from lexer token type. Includes depth_level. */
850 private uint make_precedence_t (LexerTokenType type)
852 return get_precedence (type) + (depth_level * Precedence.DEPTH);
855 /* Compares two nodes to decide, which will be parent and which will be child. */
856 private bool cmp_nodes (ParseNode? left, ParseNode? right)
858 /* Return values:
859 * true = right goes up (near root) in parse tree.
860 * false = left goes up (near root) in parse tree.
862 if (left == null)
863 return false;
864 if (left.precedence > right.precedence)
865 return true;
866 else if (left.precedence < right.precedence)
867 return false;
868 else
869 return right.associativity != Associativity.RIGHT;
872 /* Unified interface (unary and binary nodes) to insert node into parse tree. */
873 private void insert_into_tree_all (ParseNode node, bool unary_function)
875 if (root == null)
877 root = node;
878 right_most = root;
879 return;
881 ParseNode tmp = right_most;
882 while (cmp_nodes (tmp, node))
883 tmp = tmp.parent;
885 if (unary_function)
887 /* If tmp is null, that means, we have to insert new node at root. */
888 if (tmp == null)
890 node.right = root;
891 node.right.parent = node;
893 root = node;
895 else
897 node.right = tmp.right;
898 if (node.right != null)
899 node.right.parent = node;
901 tmp.right = node;
902 if (tmp.right != null)
903 tmp.right.parent = tmp;
906 right_most = node;
907 while (right_most.right != null)
908 right_most = right_most.right;
910 else
912 /* If tmp is null, that means, we have to insert new node at root. */
913 if (tmp == null)
915 node.left = root;
916 node.left.parent = node;
918 root = node;
920 else
922 node.left = tmp.right;
923 if (node.left != null)
924 node.left.parent = node;
926 tmp.right = node;
927 if (tmp.right != null)
928 tmp.right.parent = tmp;
931 right_most = node;
935 /* Insert binary node into the parse tree. */
936 private void insert_into_tree (ParseNode node)
938 insert_into_tree_all (node, false);
941 /* Insert unary node into the parse tree. */
942 private void insert_into_tree_unary (ParseNode node)
944 insert_into_tree_all (node, true);
947 /* Recursive call to free every node of parse-tree. */
948 private void destroy_all_nodes (ParseNode node)
950 if (node == null)
951 return;
953 destroy_all_nodes (node.left);
954 destroy_all_nodes (node.right);
955 /* Don't call free for tokens, as they are allocated and freed in lexer. */
956 /* WARNING: If node.value is freed elsewhere, please assign it null before calling destroy_all_nodes (). */
959 /* LL (*) parser. Lookahead count depends on tokens. Handle with care. :P */
961 /* Check if string "name" is a valid variable for given Parser. It is the same code, used to get the value of variable in parserfunc.c. */
962 private bool check_variable (string name)
964 /* If defined, then get the variable */
965 if (variable_is_defined (name))
966 return true;
968 /* If has more than one character then assume a multiplication of variables */
969 var index = 0;
970 unichar c;
971 while (name.get_next_char (ref index, out c))
973 if (!variable_is_defined (c.to_string ()))
974 return false;
977 return true;
980 private bool statement ()
982 var token = lexer.get_next_token ();
983 if (token.type == LexerTokenType.VARIABLE)
985 var token_old = token;
986 token = lexer.get_next_token ();
987 if (token.type == LexerTokenType.ASSIGN)
989 insert_into_tree (new NameNode (this, token_old, make_precedence_p (Precedence.NUMBER_VARIABLE), get_associativity (token_old)));
990 insert_into_tree (new AssignNode (this, token, 0, get_associativity (token)));
992 if (!expression ())
993 return false;
995 return true;
997 else if (token.type == LexerTokenType.IN)
999 lexer.roll_back ();
1000 lexer.roll_back ();
1002 if (!unit ())
1003 return false;
1004 lexer.get_next_token ();
1006 insert_into_tree (new ConvertNode (this, token, 0, get_associativity (token)));
1008 if (!unit ())
1009 return false;
1011 return true;
1013 else if (token.type == LexerTokenType.SUP_NUMBER)
1015 token = lexer.get_next_token ();
1016 if (token.type == LexerTokenType.IN)
1018 lexer.roll_back ();
1019 lexer.roll_back ();
1020 lexer.roll_back ();
1021 if (!unit ())
1022 return false;
1023 lexer.get_next_token ();
1025 insert_into_tree (new ConvertNode (this, token, 0, get_associativity (token)));
1027 if (!unit ())
1028 return false;
1030 return true;
1032 else
1034 lexer.roll_back ();
1035 lexer.roll_back ();
1036 lexer.roll_back ();
1038 if (!expression ())
1039 return false;
1041 return true;
1044 else
1046 lexer.roll_back ();
1047 lexer.roll_back ();
1049 if (!expression ())
1050 return false;
1052 return true;
1055 else if (token.type == LexerTokenType.NUMBER)
1057 var token_old = token;
1058 token = lexer.get_next_token ();
1059 if (token.type == LexerTokenType.VARIABLE)
1061 token = lexer.get_next_token ();
1062 if (token.type == LexerTokenType.IN)
1064 lexer.roll_back ();
1065 lexer.roll_back ();
1067 insert_into_tree (new ConstantNode (this, token_old, make_precedence_t (token_old.type), get_associativity (token)));
1069 if (!unit ())
1070 return false;
1072 token = lexer.get_next_token ();
1073 insert_into_tree (new ConvertNumberNode (this, token, 0, get_associativity (token)));
1075 if (!unit ())
1076 return false;
1078 return true;
1080 else if (token.type == LexerTokenType.SUP_NUMBER)
1082 token = lexer.get_next_token ();
1083 if (token.type == LexerTokenType.IN)
1085 lexer.roll_back ();
1086 lexer.roll_back ();
1087 lexer.roll_back ();
1089 insert_into_tree (new ConstantNode (this, token_old, make_precedence_t (token_old.type), get_associativity (token)));
1091 if (!unit ())
1092 return false;
1093 token = lexer.get_next_token ();
1095 insert_into_tree (new ConvertNumberNode (this, token, 0, get_associativity (token)));
1097 if (!unit ())
1098 return false;
1099 return true;
1101 else
1103 lexer.roll_back ();
1104 lexer.roll_back ();
1105 lexer.roll_back ();
1106 lexer.roll_back ();
1107 if (!expression ())
1108 return false;
1109 return true;
1112 else
1114 lexer.roll_back ();
1115 lexer.roll_back ();
1116 lexer.roll_back ();
1117 if (!expression ())
1118 return false;
1119 return true;
1122 else
1124 lexer.roll_back ();
1125 lexer.roll_back ();
1126 if (!expression ())
1127 return false;
1128 return true;
1131 else
1133 lexer.roll_back ();
1134 if (!expression ())
1135 return false;
1136 return true;
1140 private bool unit ()
1142 var token = lexer.get_next_token ();
1143 if (token.type == LexerTokenType.VARIABLE)
1145 var token_old = token;
1146 token = lexer.get_next_token ();
1147 if (token.type == LexerTokenType.SUP_NUMBER)
1149 insert_into_tree (new NameNode (this, token_old, make_precedence_t (token_old.type), get_associativity (token_old), token_old.text + token.text));
1150 return true;
1152 else
1154 lexer.roll_back ();
1155 insert_into_tree (new NameNode (this, token_old, make_precedence_t (token_old.type), get_associativity (token_old)));
1156 return true;
1159 else
1161 lexer.roll_back ();
1162 return false;
1166 private bool expression ()
1168 if (!expression_1 ())
1169 return false;
1170 if (!expression_2 ())
1171 return false;
1173 return true;
1176 private bool expression_1 ()
1178 var token = lexer.get_next_token ();
1180 if (token.type == LexerTokenType.PL_EOS || token.type == LexerTokenType.ASSIGN)
1182 lexer.roll_back ();
1183 return false;
1186 if (token.type == LexerTokenType.L_R_BRACKET)
1188 depth_level++;
1190 if (!expression ())
1191 return false;
1193 token = lexer.get_next_token ();
1194 if (token.type == LexerTokenType.R_R_BRACKET)
1196 depth_level--;
1197 return true;
1199 //Expected ")" here...
1200 else
1201 return false;
1203 else if (token.type == LexerTokenType.L_S_BRACKET)
1205 depth_level++;
1207 /* Give round, preference of Precedence.UNKNOWN aka 0, to keep it on the top of expression. */
1209 insert_into_tree_unary (new RoundNode (this, token, make_precedence_p (Precedence.UNKNOWN), get_associativity (token)));
1211 if (!expression ())
1212 return false;
1214 token = lexer.get_next_token ();
1215 if (token.type == LexerTokenType.R_S_BRACKET)
1217 depth_level--;
1218 return true;
1220 else
1221 //Expected "]" here...
1222 return false;
1224 else if (token.type == LexerTokenType.L_C_BRACKET)
1226 depth_level++;
1228 /* Give fraction, preference of Precedence.UNKNOWN aka 0, to keep it on the top of expression. */
1230 insert_into_tree_unary (new FractionalComponentNode (this, token, make_precedence_p (Precedence.UNKNOWN), get_associativity (token)));
1232 if (!expression ())
1233 return false;
1235 token = lexer.get_next_token ();
1236 if (token.type == LexerTokenType.R_C_BRACKET)
1238 depth_level--;
1239 return true;
1241 //Expected "}" here...
1242 else
1243 return false;
1245 else if (token.type == LexerTokenType.ABS)
1247 depth_level++;
1249 /* Give abs, preference of Precedence.UNKNOWN aka 0, to keep it on the top of expression. */
1251 insert_into_tree_unary (new AbsoluteValueNode (this, token, make_precedence_p (Precedence.UNKNOWN), get_associativity (token)));
1253 if (!expression ())
1254 return false;
1256 token = lexer.get_next_token ();
1257 if (token.type == LexerTokenType.ABS)
1259 depth_level--;
1260 return true;
1262 //Expected "|" here...
1263 else
1264 return false;
1266 else if (token.type == LexerTokenType.NOT)
1268 insert_into_tree_unary (new NotNode (this, token, make_precedence_p (Precedence.NOT), get_associativity (token)));
1270 if (!expression ())
1271 return false;
1273 return true;
1275 else if (token.type == LexerTokenType.NUMBER)
1277 insert_into_tree (new ConstantNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1279 token = lexer.get_next_token ();
1280 lexer.roll_back ();
1282 if (token.type == LexerTokenType.FUNCTION || token.type == LexerTokenType.VARIABLE || token.type == LexerTokenType.SUB_NUMBER || token.type == LexerTokenType.ROOT || token.type == LexerTokenType.ROOT_3 || token.type == LexerTokenType.ROOT_4)
1284 insert_into_tree (new MultiplyNode (this, null, make_precedence_p (Precedence.MULTIPLY), get_associativity_p (Precedence.MULTIPLY)));
1286 if (!variable ())
1287 return false;
1288 else
1289 return true;
1291 else
1292 return true;
1294 else if (token.type == LexerTokenType.L_FLOOR)
1296 depth_level++;
1297 /* Give floor, preference of Precedence.UNKNOWN aka 0, to keep it on the top of expression. */
1299 insert_into_tree_unary (new FloorNode (this, null, make_precedence_p (Precedence.UNKNOWN), get_associativity_p (Precedence.UNKNOWN)));
1301 if (!expression ())
1302 return false;
1304 token = lexer.get_next_token ();
1305 if (token.type == LexerTokenType.R_FLOOR)
1307 depth_level--;
1308 return true;
1310 //Expected ⌋ here...
1311 else
1312 return false;
1314 else if (token.type == LexerTokenType.L_CEILING)
1316 depth_level++;
1317 /* Give ceiling, preference of Precedence.UNKNOWN aka 0, to keep it on the top of expression. */
1319 insert_into_tree_unary (new CeilingNode (this, null, make_precedence_p (Precedence.UNKNOWN), get_associativity_p (Precedence.UNKNOWN)));
1321 if (!expression ())
1322 return false;
1324 token = lexer.get_next_token ();
1325 if (token.type == LexerTokenType.R_CEILING)
1327 depth_level--;
1328 return true;
1330 //Expected ⌉ here...
1331 else
1332 return false;
1334 else if (token.type == LexerTokenType.SUBTRACT)
1336 insert_into_tree_unary (new UnaryMinusNode (this, token, make_precedence_p (Precedence.UNARY_MINUS), get_associativity_p (Precedence.UNARY_MINUS)));
1338 if (!expression_1 ())
1339 return false;
1341 return true;
1343 else if (token.type == LexerTokenType.ADD)
1345 token = lexer.get_next_token ();
1346 if (token.type == LexerTokenType.NUMBER)
1348 /* Ignore ADD. It is not required. */
1349 insert_into_tree (new ConstantNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1350 return true;
1352 else
1353 return false;
1355 else
1357 lexer.roll_back ();
1358 if (!variable ())
1359 return false;
1360 else
1361 return true;
1365 private bool expression_2 ()
1367 var token = lexer.get_next_token ();
1368 if (token.type == LexerTokenType.L_R_BRACKET)
1370 insert_into_tree (new MultiplyNode (this, null, make_precedence_p (Precedence.MULTIPLY), get_associativity_p (Precedence.MULTIPLY)));
1372 depth_level++;
1373 if (!expression ())
1374 return false;
1375 token = lexer.get_next_token ();
1376 if (token.type == LexerTokenType.R_R_BRACKET)
1378 depth_level--;
1380 if (!expression_2 ())
1381 return false;
1383 return true;
1385 else
1386 return false;
1388 else if (token.type == LexerTokenType.POWER)
1390 insert_into_tree (new XPowYNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1392 if (!expression_1 ())
1393 return false;
1394 if (!expression_2 ())
1395 return false;
1397 return true;
1399 else if (token.type == LexerTokenType.SUP_NUMBER)
1401 insert_into_tree (new XPowYIntegerNode (this, null, make_precedence_p (Precedence.POWER), get_associativity_p (Precedence.POWER)));
1402 insert_into_tree (new NameNode (this, token, make_precedence_p (Precedence.NUMBER_VARIABLE), get_associativity_p (Precedence.NUMBER_VARIABLE)));
1404 if (!expression_2 ())
1405 return false;
1407 return true;
1409 else if (token.type == LexerTokenType.NSUP_NUMBER)
1411 insert_into_tree (new XPowYIntegerNode (this, null, make_precedence_p (Precedence.POWER), get_associativity_p (Precedence.POWER)));
1412 insert_into_tree (new NameNode (this, token, make_precedence_p (Precedence.NUMBER_VARIABLE), get_associativity_p (Precedence.NUMBER_VARIABLE)));
1414 if (!expression_2 ())
1415 return false;
1417 return true;
1419 else if (token.type == LexerTokenType.FACTORIAL)
1421 insert_into_tree_unary (new FactorialNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1423 if (!expression_2 ())
1424 return false;
1426 return true;
1428 else if (token.type == LexerTokenType.MULTIPLY)
1430 insert_into_tree (new MultiplyNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1432 if (!expression_1 ())
1433 return false;
1434 if (!expression_2 ())
1435 return false;
1437 return true;
1439 else if (token.type == LexerTokenType.PERCENTAGE)
1441 insert_into_tree_unary (new PercentNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1443 if (!expression_2 ())
1444 return false;
1446 return true;
1448 else if (token.type == LexerTokenType.AND)
1450 insert_into_tree (new AndNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1452 if (!expression_1 ())
1453 return false;
1454 if (!expression_2 ())
1455 return false;
1457 return true;
1459 else if (token.type == LexerTokenType.OR)
1461 insert_into_tree (new OrNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1463 if (!expression_1 ())
1464 return false;
1465 if (!expression_2 ())
1466 return false;
1468 return true;
1470 else if (token.type == LexerTokenType.XOR)
1472 insert_into_tree (new XorNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1474 if (!expression_1 ())
1475 return false;
1476 if (!expression_2 ())
1477 return false;
1479 return true;
1481 else if (token.type == LexerTokenType.DIVIDE)
1483 insert_into_tree (new DivideNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1485 if (!expression_1 ())
1486 return false;
1487 if (!expression_2 ())
1488 return false;
1490 return true;
1492 else if (token.type == LexerTokenType.MOD)
1494 insert_into_tree (new ModulusDivideNode (this, token, make_precedence_t (token.type), get_associativity (token)));
1496 if (!expression_1 ())
1497 return false;
1498 if (!expression_2 ())
1499 return false;
1501 return true;
1503 else if (token.type == LexerTokenType.ADD)
1505 var node = new AddNode (this, token, make_precedence_t (token.type), get_associativity (token));
1506 insert_into_tree (node);
1508 if (!expression_1 ())
1509 return false;
1511 token = lexer.get_next_token ();
1512 if (token.type == LexerTokenType.PERCENTAGE)
1514 //FIXME: This condition needs to be verified for all cases.. :(
1515 if (node.right.precedence > Precedence.PERCENTAGE)
1517 node.precedence = Precedence.PERCENTAGE;
1518 node.do_percentage = true;
1519 return true;
1521 else
1523 /* Assume '%' to be part of 'expression PERCENTAGE' statement. */
1524 lexer.roll_back ();
1525 if (!expression_2 ())
1526 return true;
1529 else
1530 lexer.roll_back ();
1532 if (!expression_2 ())
1533 return false;
1535 return true;
1537 else if (token.type == LexerTokenType.SUBTRACT)
1539 var node = new SubtractNode (this, token, make_precedence_t (token.type), get_associativity (token));
1540 insert_into_tree (node);
1542 if (!expression_1 ())
1543 return false;
1544 token = lexer.get_next_token ();
1545 if (token.type == LexerTokenType.PERCENTAGE)
1547 //FIXME: This condition needs to be verified for all cases.. :(
1548 if (node.right.precedence > Precedence.PERCENTAGE)
1550 node.precedence = Precedence.PERCENTAGE;
1551 node.do_percentage = true;
1552 return true;
1554 else
1556 /* Assume '%' to be part of 'expression PERCENTAGE' statement. */
1557 lexer.roll_back ();
1558 if (!expression_2 ())
1559 return true;
1562 else
1563 lexer.roll_back ();
1565 if (!expression_2 ())
1566 return false;
1568 return true;
1570 else
1572 lexer.roll_back ();
1573 return true;
1577 private bool variable ()
1579 var token = lexer.get_next_token ();
1580 if (token.type == LexerTokenType.FUNCTION)
1582 var token_old = token;
1583 token = lexer.get_next_token ();
1584 if (token.type == LexerTokenType.SUP_NUMBER)
1586 /* Pass power as void * value. That will be taken care in pf_apply_func_with_power. */
1588 insert_into_tree_unary (new FunctionWithPowerNode (this, token_old, make_precedence_t (token_old.type), get_associativity (token_old), token.text));
1589 if (!expression ())
1590 return false;
1592 return true;
1594 else if (token.type == LexerTokenType.NSUP_NUMBER)
1596 /* Pass power as void * value. That will be taken care in pf_apply_func_with_npower. */
1598 insert_into_tree_unary (new FunctionWithNegativePowerNode (this, token_old, make_precedence_t (token_old.type), get_associativity (token_old), token.text));
1599 if (!expression ())
1600 return false;
1602 return true;
1604 else
1606 lexer.roll_back ();
1607 insert_into_tree_unary (new FunctionNode (this, token_old, make_precedence_t (token_old.type), get_associativity (token_old)));
1608 if (!expression ())
1609 return false;
1611 return true;
1614 else if (token.type == LexerTokenType.SUB_NUMBER)
1616 var token_old = token;
1617 token = lexer.get_next_token ();
1618 if (token.type == LexerTokenType.ROOT)
1620 insert_into_tree_unary (new RootNode (this, token, make_precedence_t (token.type), get_associativity (token), sub_atoi (token_old.text)));
1621 if (!expression ())
1622 return false;
1624 return true;
1626 else
1627 return false;
1629 else if (token.type == LexerTokenType.ROOT)
1631 insert_into_tree_unary (new RootNode (this, token, make_precedence_t (token.type), get_associativity (token), 2));
1633 if (!expression ())
1634 return false;
1636 return true;
1638 else if (token.type == LexerTokenType.ROOT_3)
1640 insert_into_tree_unary (new RootNode (this, token, make_precedence_t (token.type), get_associativity (token), 3));
1642 if (!expression ())
1643 return false;
1645 return true;
1647 else if (token.type == LexerTokenType.ROOT_4)
1649 insert_into_tree_unary (new RootNode (this, token, make_precedence_t (token.type), get_associativity (token), 4));
1651 if (!expression ())
1652 return false;
1654 return true;
1656 else if (token.type == LexerTokenType.VARIABLE)
1658 lexer.roll_back ();
1659 //TODO: unknown function ERROR for (VARIABLE SUP_NUMBER expression).
1660 if (!term ())
1661 return false;
1663 return true;
1665 else
1666 return false;
1669 private bool term ()
1671 var token = lexer.get_next_token ();
1673 if (token.type == LexerTokenType.VARIABLE)
1675 var token_old = token;
1676 /* Check if the token is a valid variable or not. */
1677 if (!check_variable (token.text))
1679 set_error (ErrorCode.UNKNOWN_VARIABLE, token.text, token.start_index, token.end_index);
1680 return false;
1682 token = lexer.get_next_token ();
1683 if (token.type == LexerTokenType.SUP_NUMBER)
1684 insert_into_tree (new VariableWithPowerNode (this, token_old, make_precedence_t (token_old.type), get_associativity (token_old), token.text));
1685 else
1687 lexer.roll_back ();
1688 insert_into_tree (new VariableNode (this, token_old, make_precedence_t (token_old.type), get_associativity (token_old)));
1691 if (!term_2 ())
1692 return false;
1694 return true;
1696 else
1697 return false;
1700 private bool term_2 ()
1702 var token = lexer.get_next_token ();
1703 lexer.roll_back ();
1705 if (token.type == LexerTokenType.PL_EOS || token.type == LexerTokenType.ASSIGN)
1706 return true;
1708 if (token.type == LexerTokenType.VARIABLE)
1710 /* Insert multiply in between two distinct (variable). */
1711 insert_into_tree (new MultiplyNode (this, null, make_precedence_p (Precedence.MULTIPLY), get_associativity_p (Precedence.MULTIPLY)));
1713 if (!term ())
1714 return false;
1716 return true;
1718 else
1719 return true;