Class: CFG::Parser
- Inherits:
-
Object
- Object
- CFG::Parser
- Defined in:
- lib/CFG/config.rb
Constant Summary collapse
- EXPRESSION_STARTERS =
- VALUE_STARTERS =
- COMPARISON_OPERATORS =
Instance Attribute Summary collapse
-
#next_token ⇒ Object
readonly
Returns the value of attribute next_token.
-
#tokenizer ⇒ Object
readonly
Returns the value of attribute tokenizer.
Instance Method Summary collapse
- #_get_slice_element ⇒ Object
- #_invalid_index(num, pos) ⇒ Object
- #_try_get_step ⇒ Object
- #add_expr ⇒ Object
- #advance ⇒ Object
- #and_expr ⇒ Object
- #at_end ⇒ Object
- #atom ⇒ Object
- #bitand_expr ⇒ Object
- #bitor_expr ⇒ Object
- #bitxor_expr ⇒ Object
- #comp_op ⇒ Object
- #comparison ⇒ Object
- #consume_newlines ⇒ Object
- #container ⇒ Object
- #expect(kind) ⇒ Object
- #expr ⇒ Object
-
#initialize(stream) ⇒ Parser
constructor
A new instance of Parser.
- #list ⇒ Object
- #list_body ⇒ Object
- #mapping ⇒ Object
- #mapping_body ⇒ Object
- #mul_expr ⇒ Object
- #not_expr ⇒ Object
- #object_key ⇒ Object
- #power ⇒ Object
- #primary ⇒ Object
- #shift_expr ⇒ Object
- #strings ⇒ Object
- #trailer ⇒ Object
- #unary_expr ⇒ Object
- #value ⇒ Object
Constructor Details
Instance Attribute Details
#next_token ⇒ Object (readonly)
Returns the value of attribute next_token.
844 845 846 |
# File 'lib/CFG/config.rb', line 844 def next_token @next_token end |
#tokenizer ⇒ Object (readonly)
Returns the value of attribute tokenizer.
843 844 845 |
# File 'lib/CFG/config.rb', line 843 def tokenizer @tokenizer end |
Instance Method Details
#_get_slice_element ⇒ Object
969 970 971 972 973 974 975 |
# File 'lib/CFG/config.rb', line 969 def _get_slice_element lb = list_body size = lb.elements.length _invalid_index(size, lb.start) unless size == 1 lb.elements[0] end |
#_invalid_index(num, pos) ⇒ Object
963 964 965 966 967 |
# File 'lib/CFG/config.rb', line 963 def _invalid_index(num, pos) e = ParserError.new "Invalid index at #{pos}: expected 1 expression, found #{num}" e.location = pos raise e end |
#_try_get_step ⇒ Object
977 978 979 980 |
# File 'lib/CFG/config.rb', line 977 def _try_get_step kind = advance kind == :RIGHT_BRACKET ? nil : _get_slice_element end |
#add_expr ⇒ Object
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 |
# File 'lib/CFG/config.rb', line 1174 def add_expr result = mul_expr kind = @next_token.kind while %i[PLUS MINUS].include? kind advance result = BinaryNode.new kind, result, mul_expr kind = @next_token.kind end result end |
#advance ⇒ Object
855 856 857 858 |
# File 'lib/CFG/config.rb', line 855 def advance @next_token = @tokenizer.get_token @next_token.kind end |
#and_expr ⇒ Object
1266 1267 1268 1269 1270 1271 1272 1273 |
# File 'lib/CFG/config.rb', line 1266 def and_expr result = not_expr while @next_token.kind == :AND advance result = BinaryNode.new :AND, result, not_expr end result end |
#at_end ⇒ Object
851 852 853 |
# File 'lib/CFG/config.rb', line 851 def at_end @next_token.kind == :EOF end |
#atom ⇒ Object
935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 |
# File 'lib/CFG/config.rb', line 935 def atom kind = @next_token.kind case kind when :LEFT_CURLY result = mapping when :LEFT_BRACKET result = list when :DOLLAR expect :DOLLAR expect :LEFT_CURLY spos = @next_token.start result = UnaryNode.new :DOLLAR, primary result.start = spos expect :RIGHT_CURLY when :WORD, :INTEGER, :FLOAT, :COMPLEX, :STRING, :BACKTICK, :TRUE, :FALSE, :NONE result = value when :LEFT_PARENTHESIS expect :LEFT_PARENTHESIS result = expr expect :RIGHT_PARENTHESIS else e = ParserError.new "Unexpected: #{kind}" e.location = @next_token.start raise e end result end |
#bitand_expr ⇒ Object
1198 1199 1200 1201 1202 1203 1204 1205 1206 |
# File 'lib/CFG/config.rb', line 1198 def bitand_expr result = shift_expr while @next_token.kind == :BITWISE_AND advance result = BinaryNode.new :BITWISE_AND, result, shift_expr end result end |
#bitor_expr ⇒ Object
1218 1219 1220 1221 1222 1223 1224 1225 1226 |
# File 'lib/CFG/config.rb', line 1218 def bitor_expr result = bitxor_expr while @next_token.kind == :BITWISE_OR advance result = BinaryNode.new :BITWISE_OR, result, bitxor_expr end result end |
#bitxor_expr ⇒ Object
1208 1209 1210 1211 1212 1213 1214 1215 1216 |
# File 'lib/CFG/config.rb', line 1208 def bitxor_expr result = bitand_expr while @next_token.kind == :BITWISE_XOR advance result = BinaryNode.new :BITWISE_XOR, result, bitand_expr end result end |
#comp_op ⇒ Object
1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 |
# File 'lib/CFG/config.rb', line 1228 def comp_op result = @next_token.kind should_advance = false advance if result == :IS && @next_token.kind == :NOT result = :IS_NOT should_advance = true elsif result == :NOT && @next_token.kind == :IN result = :NOT_IN should_advance = true end advance if should_advance result end |
#comparison ⇒ Object
1248 1249 1250 1251 1252 1253 1254 1255 |
# File 'lib/CFG/config.rb', line 1248 def comparison result = bitor_expr while COMPARISON_OPERATORS.include? @next_token.kind op = comp_op result = BinaryNode.new op, result, bitor_expr end result end |
#consume_newlines ⇒ Object
872 873 874 875 876 877 |
# File 'lib/CFG/config.rb', line 872 def consume_newlines result = @next_token.kind result = advance while result == :NEWLINE result end |
#container ⇒ Object
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 |
# File 'lib/CFG/config.rb', line 1120 def container kind = consume_newlines case kind when :LEFT_CURLY result = mapping when :LEFT_BRACKET result = list when :WORD, :STRING, :EOF result = mapping_body else e = ParserError.new "Unexpected type for container: #{kind}" e.location = @next_token.start raise e end consume_newlines result end |
#expect(kind) ⇒ Object
860 861 862 863 864 865 866 867 868 869 870 |
# File 'lib/CFG/config.rb', line 860 def expect(kind) if @next_token.kind != kind e = ParserError.new "Expected #{kind} but got #{@next_token.kind}" e.location = @next_token.start # require 'byebug'; byebug raise e end result = @next_token advance result end |
#expr ⇒ Object
1275 1276 1277 1278 1279 1280 1281 1282 |
# File 'lib/CFG/config.rb', line 1275 def expr result = and_expr while @next_token.kind == :OR advance result = BinaryNode.new :OR, result, and_expr end result end |
#list ⇒ Object
1113 1114 1115 1116 1117 1118 |
# File 'lib/CFG/config.rb', line 1113 def list expect :LEFT_BRACKET result = list_body expect :RIGHT_BRACKET result end |
#list_body ⇒ Object
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 |
# File 'lib/CFG/config.rb', line 1096 def list_body result = [] kind = consume_newlines spos = @next_token.start while EXPRESSION_STARTERS.include? kind result.push(expr) kind = @next_token.kind break unless %i[NEWLINE COMMA].include? kind advance kind = consume_newlines end result = ListNode.new result result.start = spos result end |
#mapping ⇒ Object
1089 1090 1091 1092 1093 1094 |
# File 'lib/CFG/config.rb', line 1089 def mapping expect :LEFT_CURLY result = mapping_body expect :RIGHT_CURLY result end |
#mapping_body ⇒ Object
1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 |
# File 'lib/CFG/config.rb', line 1054 def mapping_body result = [] kind = consume_newlines spos = @next_token.start if kind != :RIGHT_CURLY && kind != :EOF if kind != :WORD && kind != :STRING e = ParserError.new "Unexpected type for key: #{kind}" e.location = @next_token.start raise e end while %i[WORD STRING].include? kind key = object_key kind = @next_token.kind if kind != :COLON && kind != :ASSIGN e = ParserError.new "Expected key-value separator, found: #{kind}" e.location = @next_token.start raise e end advance consume_newlines result.push [key, expr] kind = @next_token.kind if %i[NEWLINE COMMA].include? kind advance kind = consume_newlines end end end result = MappingNode.new result result.start = spos result end |
#mul_expr ⇒ Object
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 |
# File 'lib/CFG/config.rb', line 1162 def mul_expr result = unary_expr kind = @next_token.kind while %i[STAR SLASH SLASH_SLASH MODULO].include? kind advance result = BinaryNode.new kind, result, unary_expr kind = @next_token.kind end result end |
#not_expr ⇒ Object
1257 1258 1259 1260 1261 1262 1263 1264 |
# File 'lib/CFG/config.rb', line 1257 def not_expr if @next_token.kind != :NOT comparison else advance UnaryNode.new :NOT, not_expr end end |
#object_key ⇒ Object
1044 1045 1046 1047 1048 1049 1050 1051 1052 |
# File 'lib/CFG/config.rb', line 1044 def object_key if @next_token.kind == :STRING result = strings else result = @next_token advance end result end |
#power ⇒ Object
1140 1141 1142 1143 1144 1145 1146 1147 |
# File 'lib/CFG/config.rb', line 1140 def power result = primary while @next_token.kind == :POWER advance result = BinaryNode.new :POWER, result, unary_expr end result end |
#primary ⇒ Object
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 |
# File 'lib/CFG/config.rb', line 1033 def primary result = atom kind = @next_token.kind while %i[DOT LEFT_BRACKET].include? kind op, rhs = trailer result = BinaryNode.new op, result, rhs kind = @next_token.kind end result end |
#shift_expr ⇒ Object
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 |
# File 'lib/CFG/config.rb', line 1186 def shift_expr result = add_expr kind = @next_token.kind while %i[LEFT_SHIFT RIGHT_SHIFT].include? kind advance result = BinaryNode.new kind, result, add_expr kind = @next_token.kind end result end |
#strings ⇒ Object
891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 |
# File 'lib/CFG/config.rb', line 891 def strings result = @next_token if advance == :STRING all_text = '' all_value = '' t = result.text v = result.value start = result.start endpos = result.end loop do all_text += t all_value += v t = @next_token.text v = @next_token.value endpos = @next_token.end kind = advance break if kind != :STRING end all_text += t # the last one all_value += v result = Token.new :STRING, all_text, all_value result.start = start result.end = endpos end result end |
#trailer ⇒ Object
982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 |
# File 'lib/CFG/config.rb', line 982 def trailer op = @next_token.kind if op != :LEFT_BRACKET expect :DOT result = expect :WORD else kind = advance is_slice = false start_index = nil stop_index = nil step = nil if kind == :COLON # it's a slice like [:xyz:abc] is_slice = true else elem = _get_slice_element kind = @next_token.kind if kind != :COLON result = elem else start_index = elem is_slice = true end end if is_slice op = :COLON # at this point startIndex is either nil (if foo[:xyz]) or a # value representing the start. We are pointing at the COLON # after the start value kind = advance if kind == :COLON # no stop, but there might be a step s = _try_get_step step = s unless s.nil? elsif kind != :RIGHT_BRACKET stop_index = _get_slice_element kind = @next_token.kind if kind == :COLON s = _try_get_step step = s unless s.nil? end end result = SliceNode.new start_index, stop_index, step end expect :RIGHT_BRACKET end [op, result] end |
#unary_expr ⇒ Object
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 |
# File 'lib/CFG/config.rb', line 1149 def unary_expr kind = @next_token.kind spos = @next_token.start result = if !%i[PLUS MINUS BITWISE_COMPLEMENT AT].include? kind power else advance UnaryNode.new kind, unary_expr end result.start = spos result end |
#value ⇒ Object
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 |
# File 'lib/CFG/config.rb', line 919 def value kind = @next_token.kind unless VALUE_STARTERS.include? kind e = ParserError.new "Unexpected when looking for value: #{kind}" e.location = @next_token.start raise e end if kind == :STRING result = strings else result = @next_token advance end result end |