public static TomlTableArray TryApply(ITomlRoot root, TokenBuffer tokens) { if (!tokens.TryExpectAt(0, TokenType.LBrac)) { return null; } if (!tokens.TryExpectAt(1, TokenType.LCurly)) { return null; } return Apply(root, tokens); }
private static TomlTableArray Apply(ITomlRoot root, TokenBuffer tokens) { tokens.ExpectAndConsume(TokenType.LBrac); tokens.ConsumeAllNewlines(); var arr = new TomlTableArray(root); TomlTable tbl = null; while ((tbl = InlineTableProduction.TryApply(root, tokens)) != null) { arr.Add(tbl); if (tokens.TryExpect(TokenType.Comma)) { tokens.Consume(); tokens.ConsumeAllNewlines(); } else { tokens.ConsumeAllNewlines(); tokens.Expect(TokenType.RBrac); } } tokens.ConsumeAllNewlines(); tokens.ExpectAndConsume(TokenType.RBrac); return arr; }
private static TomlString ParseLiteralString(ITomlRoot root, LookaheadBuffer<Token> tokens) { var t = tokens.Consume(); Debug.Assert(t.type == TokenType.LiteralString); var s = t.value.TrimNChars(1); return new TomlString(root, s, TomlString.TypeOfString.Literal); }
public TomlTableArray(ITomlRoot root, IEnumerable<TomlTable> enumerable) : base(root) { if (enumerable != null) { foreach (var e in enumerable) { this.Add(e); } } }
public object Convert(ITomlRoot root, object value, Type targetType) { Assert( targetType != typeof(Dictionary<string, object>), $"Ensure '{nameof(TomlTableToDictionaryConverter)}' converter registered before this one."); var valueType = targetType.GetGenericArguments()[1]; var target = (IDictionary)Activator.CreateInstance(targetType); TomlTable table = (TomlTable)value; foreach (var r in table.Rows) { target[r.Key] = r.Value.Get(valueType); } return target; }
public static Tuple<string, TomlObject> Apply(ITomlRoot root, TokenBuffer tokens) { var key = KeyProduction.Apply(tokens); tokens.ExpectAndConsume(TokenType.Assign); var inlineTableArray = InlineTableArrayProduction.TryApply(root, tokens); if (inlineTableArray != null) { return new Tuple<string, TomlObject>(key, inlineTableArray); } var inlineTable = InlineTableProduction.TryApply(root, tokens); if (inlineTable != null) { return new Tuple<string, TomlObject>(key, inlineTable); } var value = ValueProduction.Apply(root, tokens); return Tuple.Create(key, value); }
public static TomlObject Apply(ITomlRoot root, TokenBuffer tokens) { var value = ParseTomlValue(root, tokens); if (value == null) { var t = tokens.Peek(); if (t.IsEmpty || t.IsEof || t.IsNewLine) { throw Parser.CreateParseError(t, "Value is missing."); } else { string msg = $"Expected a TOML value while parsing key value pair." + $" Token of type '{t.type}' with value '{t.value}' is invalid."; throw Parser.CreateParseError(t, msg); } } return value; }
public static TomlTable Apply(ITomlRoot root, TokenBuffer tokens) { TomlTable inlineTable = new TomlTable(root, TomlTable.TableTypes.Inline); tokens.ExpectAndConsume(TokenType.LCurly); if (!tokens.TryExpect(TokenType.RBrac)) { var kvp = KeyValuePairProduction.Apply(root, tokens); inlineTable.Add(kvp.Item1, kvp.Item2); while (tokens.TryExpect(TokenType.Comma)) { tokens.Consume(); kvp = KeyValuePairProduction.Apply(root, tokens); inlineTable.Add(kvp.Item1, kvp.Item2); } } tokens.ExpectAndConsume(TokenType.RCurly); return inlineTable; }
private static TomlInt ParseTomlInt(ITomlRoot root, LookaheadBuffer<Token> tokens) { var token = tokens.Consume(); if (token.value.Length > 1 && token.value[0] == '0') { throw new Exception($"Failed to parse TOML int with '{token.value}' because it has a leading '0' which is not allowed by the TOML specification."); } return new TomlInt(root, long.Parse(token.value.Replace("_", string.Empty))); }
private static TomlString ParseStringValue(ITomlRoot root, LookaheadBuffer<Token> tokens) { var t = tokens.Consume(); Debug.Assert(t.type == TokenType.String); if (t.value.Contains("\n")) { throw Parser.CreateParseError(t, $"String '{t.value}' is invalid because it contains newlines."); } var s = t.value.TrimNChars(1).Unescape(t); return new TomlString(root, s, TomlString.TypeOfString.Normal); }
public static TomlTable TryApply(ITomlRoot root, TokenBuffer tokens) => tokens.TryExpect(TokenType.LCurly) ? Apply(root, tokens) : null;
internal override TomlObject WithRoot(ITomlRoot root) => this.DateTimeWithRoot(root);
public TomlValue(ITomlRoot root) : base(root) { }
internal override TomlObject WithRoot(ITomlRoot root) { throw new NotImplementedException(); }
internal override TomlObject WithRoot(ITomlRoot root) => this.BoolWithRoot(root);
internal override TomlValue ValueWithRoot(ITomlRoot root) => this.BoolWithRoot(root);
public TomlSource(ITomlRoot root, IConfigSource source) : base(root) { this.Value = source; }
internal override TomlObject WithRoot(ITomlRoot root) { root.CheckNotNull(nameof(root)); return(new TomlSource(root, this.Value)); }
internal override TomlObject CloneFor(ITomlRoot root) => CopyComments(new TomlSource(root, this.Value), this);
public object Convert(ITomlRoot root, object value, Type targetType) { var converter = new ConvertTomlTableToDictionaryConversionVisitor(); return(converter.Convert((TomlTable)value)); }
internal TomlDateTime DateTimeWithRoot(ITomlRoot root) { root.CheckNotNull(nameof(root)); return(new TomlDateTime(root, this.Value)); }
internal TomlDateTime CloneDateTimeFor(ITomlRoot root) => CopyComments(new TomlDateTime(root, this.Value), this);
internal TomlDateTime(ITomlRoot root, DateTimeOffset value) : base(root, value) { }
internal TomlBool CloneBoolFor(ITomlRoot root) => CopyComments(new TomlBool(root, this.Value), this);
internal override TomlObject WithRoot(ITomlRoot root) { root.CheckNotNull(nameof(root)); return new TomlSource(root, this.Value); }
internal TomlBool BoolWithRoot(ITomlRoot root) { root.CheckNotNull(nameof(root)); return(new TomlBool(root, this.Value)); }
private static TomlObject ToTomlValue(ITomlRoot root, ValueNode node) { switch (node.Value.SyntaxNode()) { case TerminalNode tn: return(CreateValue(tn)); case ArrayNode an: return(CreateArrayOrTableArray(an)); case InlineTableNode it: return(CreateInlineTable(it)); default: throw new Exception($"Cannot create TomlValue from node with type '{node.GetType()}'."); } TomlValue CreateValue(TerminalNode tn) { var val = CreateValueFromTerminal(tn.Terminal); if (node.Unit.HasNode) { val.Unit = node.Unit.SyntaxNodeOrDefault().Terminal.Value; } return(val); } TomlValue CreateValueFromTerminal(Token terminal) { switch (terminal.Type) { case TokenType.Integer: return(new TomlInt(root, Convert.ToInt64(Cleanup(terminal.Value, 0)), TomlInt.IntTypes.Decimal)); case TokenType.HexInteger: return(new TomlInt(root, Convert.ToInt64(Cleanup(terminal.Value, 2), 16), TomlInt.IntTypes.Hex)); case TokenType.BinaryInteger: return(new TomlInt(root, Convert.ToInt64(Cleanup(terminal.Value, 2), 2), TomlInt.IntTypes.Binary)); case TokenType.OctalInteger: return(new TomlInt(root, Convert.ToInt64(Cleanup(terminal.Value, 2), 8), TomlInt.IntTypes.Octal)); case TokenType.Bool: return(new TomlBool(root, Convert.ToBoolean(terminal.Value))); case TokenType.String: return(new TomlString(root, terminal.Value.Unescape(terminal))); case TokenType.LiteralString: return(new TomlString(root, terminal.Value, TomlString.TypeOfString.Literal)); case TokenType.MultilineLiteralString: return(new TomlString(root, terminal.Value, TomlString.TypeOfString.MultilineLiteral)); case TokenType.MultilineString: return(new TomlString(root, terminal.Value, TomlString.TypeOfString.Multiline)); case TokenType.Float: return(TomlFloat.FromTerminal(root, terminal)); case TokenType.OffsetDateTime: return(TomlOffsetDateTime.Parse(root, terminal.Value)); case TokenType.LocalTime: return(TomlLocalTime.Parse(root, terminal.Value)); case TokenType.Duration: return(TomlDuration.Parse(root, terminal.Value)); case TokenType.LocalDate: return(TomlLocalDate.Parse(root, terminal.Value)); case TokenType.LocalDateTime: return(TomlLocalDateTime.Parse(root, terminal.Value)); default: throw new NotSupportedException(); } string Cleanup(string s, int sub) => s.Substring(sub).Replace("_", string.Empty); } TomlObject CreateArrayOrTableArray(ArrayNode array) { var values = CreateValues(array.GetValues()).ToList(); var tables = values.OfType <TomlTable>().ToList(); if (tables.Count > 0 && tables.Count == values.Count) { var ta = new TomlTableArray(root, tables); ta.AddComments(array); return(ta); } else if (tables.Count == 0) { var arr = new TomlArray(root, values.Cast <TomlValue>().ToArray()); arr.AddComments(array); return(arr); } else { throw new InvalidOperationException("Array is a mixture of a value array and a TOML table array."); } IEnumerable <TomlObject> CreateValues(IEnumerable <ValueNode> nodes) { var linked = nodes.Select(n => Tuple.Create(n, ToTomlValue(root, n))).ToList(); var expectedType = linked.DistinctBy(n => n.Item2.GetType()).FirstOrDefault(); var wrongType = linked.DistinctBy(n => n.Item2.GetType()).Skip(1).FirstOrDefault(); if (wrongType != null) { string msg = $"Expected array value of type '{expectedType.Item2.ReadableTypeName}' " + $"but value of type '{wrongType.Item2.ReadableTypeName}' was found.'"; throw ParseException.MessageForNode(wrongType.Item1, msg); } return(linked.Select(l => l.Item2)); } } TomlTable CreateInlineTable(InlineTableNode it) { TomlTable table = new TomlTable(root, TomlTable.TableTypes.Inline); table.AddComments(it); System.Collections.Generic.IEnumerable <KeyValueExpressionNode> expressions = it.GetExpressions(); foreach (KeyValueExpressionNode e in expressions) { table.AddRow(e.Key.SyntaxNode().ExpressionKey(), ToTomlValue(root, e.Value.SyntaxNode())); } return(table); } }
internal TomlBool(ITomlRoot root, bool value) : base(root, value) { }
public object Convert(ITomlRoot root, object value, Type targetType) { var converter = new ConvertTomlTableToDictionaryConversionVisitor(); return converter.Convert((TomlTable)value); }
internal override TomlObject WithRoot(ITomlRoot root) => this.TableArrayWithRoot(root);
internal TomlTableArray(ITomlRoot root) : this(root, null) { }
internal override TomlObject CloneFor(ITomlRoot root) => this.CloneArrayFor(root);
private static TomlArray ParseTomlArray(ITomlRoot root, TokenBuffer tokens) { TomlArray a; tokens.ExpectAndConsume(TokenType.LBrac); tokens.ConsumeAllNewlines(); if (tokens.TryExpect(TokenType.RBrac)) { // Empty array handled inside this if, else part can assume the array has values tokens.Consume(); return new TomlArray(root); } else { List<TomlValue> values = new List<TomlValue>(); var errPos = tokens.Peek(); var v = ParseTomlValue(root, tokens); if (v == null) { throw Parser.CreateParseError(errPos, $"Array value is missing."); } values.Add(v); while (!tokens.TryExpect(TokenType.RBrac)) { if (!tokens.TryExpectAndConsume(TokenType.Comma)) { throw Parser.CreateParseError(tokens.Peek(), "Array not closed."); } tokens.ConsumeAllNewlines(); values.Last().Comments.AddRange(CommentProduction.TryParseComments(tokens, CommentLocation.Append)); if (!tokens.TryExpect(TokenType.RBrac)) { var et = tokens.Peek(); v = ParseTomlValue(root, tokens); if (v == null) { throw Parser.CreateParseError(et, $"Array value is missing."); } if (v.GetType() != values[0].GetType()) { throw Parser.CreateParseError(et, $"Expected value of type '{values[0].ReadableTypeName}' but value of type '{v.ReadableTypeName}' was found."); } values.Add(v); tokens.ConsumeAllNewlines(); } } a = new TomlArray(root, values.ToArray()); } a.Last().Comments.AddRange(CommentProduction.TryParseComments(tokens, CommentLocation.Append)); tokens.ExpectAndConsume(TokenType.RBrac); return a; }
internal TomlTableArray CloneArrayFor(ITomlRoot root) => CopyComments(new TomlTableArray(root, this.items.Select(i => i.CloneTableFor(root))), this);
private static TomlFloat ParseTomlFloat(ITomlRoot root, LookaheadBuffer<Token> tokens) { var floatToken = tokens.Consume(); var check = floatToken.value; int startToCheckForZeros = check[0] == '+' || check[0] == '-' ? 1 : 0; if (check[startToCheckForZeros] == '0' && check[startToCheckForZeros + 1] != '.') { throw new Exception($"Failed to parse TOML float with '{floatToken.value}' because it has a leading '0' which is not allowed by the TOML specification."); } return new TomlFloat(root, double.Parse(floatToken.value.Replace("_", string.Empty), CultureInfo.InvariantCulture)); }
public object Convert(ITomlRoot root, object value, Type targetType) => new TomlString(root, value.ToString());
private static TomlValue ParseTomlValue(ITomlRoot root, TokenBuffer tokens) { if (tokens.TryExpect(TokenType.Integer)) { return ParseTomlInt(root, tokens); } else if (tokens.TryExpect(TokenType.Float)) { return ParseTomlFloat(root, tokens); } else if (tokens.TryExpect(TokenType.DateTime)) { return TomlDateTime.Parse(root, tokens.Consume().value); } else if (tokens.TryExpect(TokenType.Timespan)) { return new TomlTimeSpan(root, TimeSpan.Parse(tokens.Consume().value, CultureInfo.InvariantCulture)); } else if (tokens.TryExpect(TokenType.String)) { return ParseStringValue(root, tokens); } else if (tokens.TryExpect(TokenType.LiteralString)) { return ParseLiteralString(root, tokens); } else if (tokens.TryExpect(TokenType.MultilineString)) { return ParseMultilineString(root, tokens); } else if (tokens.TryExpect(TokenType.MultilineLiteralString)) { return ParseMultilineLiteralString(root, tokens); } else if (tokens.TryExpect(TokenType.Bool)) { return new TomlBool(root, bool.Parse(tokens.Consume().value)); } else if (tokens.TryExpect(TokenType.LBrac)) { return ParseTomlArray(root, tokens); } return null; }
public object Convert(ITomlRoot root, object value, Type targetType) => Enum.Parse(targetType, ((TomlString)value).Value);
private static TomlString ParseMultilineLiteralString(ITomlRoot root, LookaheadBuffer<Token> tokens) { var t = tokens.Consume(); Debug.Assert(t.type == TokenType.MultilineLiteralString); var s = t.value.TrimNChars(3); // Trim newline following the """ tag immediate if (s.Length > 0 && s[0] == '\r') { s = s.Substring(1); } if (s.Length > 0 && s[0] == '\n') { s = s.Substring(1); } return new TomlString(root, s, TomlString.TypeOfString.MultilineLiteral); }
internal TomlTable(ITomlRoot root, TableTypes tableType = TableTypes.Default) : base(root) { this.TableType = tableType; }
private static TomlValue ParseTomlValue(ITomlRoot root, TokenBuffer tokens) { if (tokens.TryExpect(TokenType.Integer)) { return(ParseTomlInt(root, tokens, long.TryParse)); } else if (tokens.TryExpect(TokenType.HexInteger)) { return(ParseTomlInt(root, tokens, TryParseHexInt)); } else if (tokens.TryExpect(TokenType.OctalInteger)) { return(ParseTomlInt(root, tokens, TryParseOctInt)); } else if (tokens.TryExpect(TokenType.BinaryInteger)) { return(ParseTomlInt(root, tokens, TryParseBinInt)); } else if (tokens.TryExpect(TokenType.Float)) { return(ParseTomlFloat(root, tokens)); } else if (tokens.TryExpect(TokenType.DateTime)) { return(TomlDateTime.Parse(root, tokens.Consume().value)); } else if (tokens.TryExpect(TokenType.LocalTime)) { return(ParseLocalDateTime(root, tokens.Consume().value)); } else if (tokens.TryExpect(TokenType.Duration)) { return(TomlDuration.Parse(root, tokens.Consume().value)); } else if (tokens.TryExpect(TokenType.String)) { return(ParseStringValue(root, tokens)); } else if (tokens.TryExpect(TokenType.LiteralString)) { return(ParseLiteralString(root, tokens)); } else if (tokens.TryExpect(TokenType.MultilineString)) { return(ParseMultilineString(root, tokens)); } else if (tokens.TryExpect(TokenType.MultilineLiteralString)) { return(ParseMultilineLiteralString(root, tokens)); } else if (tokens.TryExpect(TokenType.Bool)) { return(new TomlBool(root, bool.Parse(tokens.Consume().value))); } else if (tokens.TryExpect(TokenType.LBrac)) { return(ParseTomlArray(root, tokens)); } return(null); }
internal TomlTableArray TableArrayWithRoot(ITomlRoot root) { root.CheckNotNull(nameof(root)); var a = new TomlTableArray(root, this.Items.Select(t => t.TableWithRoot(root))); return a; }
internal override TomlObject CloneFor(ITomlRoot root) => this.CloneDateTimeFor(root);
internal abstract TomlValue ValueWithRoot(ITomlRoot root);
private static TomlArray ParseTomlArray(ITomlRoot root, TokenBuffer tokens) { TomlArray a; var prep = CommentProduction.TryParseComments(tokens, CommentLocation.Prepend).ToList(); tokens.ExpectAndConsume(TokenType.LBrac); using (tokens.UseIgnoreNewlinesContext()) { prep.AddRange(CommentProduction.TryParseComments(tokens, CommentLocation.Prepend)); if (tokens.TryExpect(TokenType.RBrac)) { // Empty array handled inside this if, else part can assume the array has values // Comments in an empty array are moved before the array at the moment. // There currently does not exist a comment location that will allow to write this comments correctly // => Parse the real items correctly and do not create a parse error, but the comment will get lost // on the next write. tokens.Consume(); a = new TomlArray(root); a.AddComments(prep); a.AddComments(CommentProduction.TryParseComments(tokens, CommentLocation.Append)); return(a); } else { List <TomlValue> values = new List <TomlValue>(); // Parse first !required! array value var v = ParseArrayValue(); v.AddComments(prep); values.Add(v); while (!tokens.TryExpect(TokenType.RBrac)) { if (!tokens.TryExpectAndConsume(TokenType.Comma)) { throw Parser.CreateParseError(tokens.Peek(), "Array not closed."); } // This comment is misplaced as we simply append it to the last value, but it does not belong to it // Comments processing needs some tweaking/redesign in the future. v.AddComments(CommentProduction.TryParseComments(tokens, CommentLocation.Append)); if (!tokens.TryExpect(TokenType.RBrac)) { var et = tokens.Peek(); v = ParseArrayValue(); if (v.GetType() != values[0].GetType()) { throw Parser.CreateParseError(et, $"Expected array value of type '{values[0].ReadableTypeName}' but value of type '{v.ReadableTypeName}' was found."); } values.Add(v); } } a = new TomlArray(root, values.ToArray()); } a.Last().AddComments(CommentProduction.TryParseComments(tokens, CommentLocation.Append)); tokens.ExpectAndConsume(TokenType.RBrac); a.AddComments(CommentProduction.TryParseComments(tokens, CommentLocation.Append)); TomlValue ParseArrayValue() { var prepComments = CommentProduction.TryParseComments(tokens, CommentLocation.Prepend); var valueParseErrorPos = tokens.Peek(); var value = ParseTomlValue(root, tokens); if (value == null) { throw Parser.CreateParseError(valueParseErrorPos, $"Array value is missing."); } value.AddComments(prepComments); value.AddComments(CommentProduction.TryParseComments(tokens, CommentLocation.Append)); return(value); } } return(a); }
internal override TomlValue ValueWithRoot(ITomlRoot root) => this.DateTimeWithRoot(root);