private TomlTable GetTableOrCreateIfAbsent(String name, TomlTable parentTable) { TomlTable table; if (parentTable.Contains(name)) { if (parentTable[name] is TomlTable tomlTable) { table = tomlTable; } else if (parentTable[name] is TomlArrayOfTables tomlArrayOfTables) { return(tomlArrayOfTables.Value[tomlArrayOfTables.Value.Count - 1] as TomlTable); } else { throw new TomlSemanticException($"value with key '{parentTable.Name}.{name}' is already exists and it is not ITomlOpenTable", this.currentFile, this.currentLine); } } else { if (!(parentTable is TomlDottedTable) && parentTable.IsClosed) { throw new TomlSemanticException($"table '{parentTable.Name}' is closed ", this.currentFile, this.currentLine); } table = new TomlTable(name); parentTable[name] = table; } return(table); }
private void ParseArrayOfTables(TomlTable rootTable) { this.Match(TokenType.LBRACKET); this.Match(TokenType.LBRACKET); String key; TomlTable table = rootTable; while (this.LookMatch(1, TokenType.DOT)) { key = this.Consume(TokenType.BAREKEY).Text; table = this.GetTableOrCreateIfAbsent(key, table); this.Match(TokenType.DOT); } key = this.Consume(TokenType.BAREKEY).Text; this.Consume(TokenType.RBRACKET); this.Consume(TokenType.RBRACKET); this.Match(TokenType.NL); TomlTable newTable = new TomlTable(null); while (!this.LookMatch(0, TokenType.LBRACKET) && !this.LookMatch(0, TokenType.EOF)) { if (this.LookMatch(1, TokenType.DOT)) { this.ParseDottedKeyValuePair(newTable); } else { this.ParseKeyValuePair(newTable); } } if (table.Contains(key)) { if (table[key] is TomlArrayOfTables arrayOfTables) { arrayOfTables.Value.Add(newTable); } else { throw new TomlSemanticException($"key '{key}' is already exists and it is not an array of tables", this.currentFile, this.currentLine); } } else { table[key] = new TomlArrayOfTables(key, new List <TomlValue> { newTable }); } }
private TomlValue ParseInineTable() { TomlTable inlineTable = new TomlInlineTable(); while (!this.Match(TokenType.RBRACE)) { // If there is no key if (!this.LookMatch(0, TokenType.BAREKEY)) { throw new TomlSyntaxException($"expected key, got '{GetToken(0)}'", this.currentFile, this.currentLine); } String key; TomlTable table = inlineTable; while (this.LookMatch(1, TokenType.DOT)) { key = this.Consume(TokenType.BAREKEY).Text; table = this.GetTableOrCreateDottedIfAbsent(key, table); this.Match(TokenType.DOT); } key = this.Consume(TokenType.BAREKEY).Text; this.Consume(TokenType.ASSIGNMENT); // There is no value if (this.Match(TokenType.NL) || this.Match(TokenType.EOF) || this.Match(TokenType.RBRACE)) { throw new TomlSyntaxException("unspecified value", this.currentFile, this.currentLine); } var value = this.ParseValue(); if (table.Contains(key)) { throw new TomlSemanticException($"key {key} is already defined in this table", this.currentFile, this.currentLine); } table[key] = value; this.Match(TokenType.SPLIT); } return(inlineTable); }
private void ParseDottedKeyValuePair(TomlTable parentTable) { String key; TomlTable table = parentTable; while (this.LookMatch(1, TokenType.DOT)) { key = this.Consume(TokenType.BAREKEY).Text; table = this.GetTableOrCreateDottedIfAbsent(key, table); this.Match(TokenType.DOT); } key = this.Consume(TokenType.BAREKEY).Text; this.Consume(TokenType.ASSIGNMENT); // There is no value if (this.Match(TokenType.NL) || this.Match(TokenType.EOF)) { throw new TomlSyntaxException("unspecified value", this.currentFile, this.currentLine); } TomlValue value = this.ParseValue(); if (!this.Match(TokenType.NL) && !this.LookMatch(0, TokenType.EOF)) { throw new TomlSyntaxException("there must be a newline or end of file after a key/value pair", this.currentFile, this.currentLine); } if (parentTable.Contains(key)) { throw new TomlSemanticException($"key '{key}' is already defined in this table", this.currentFile, this.currentLine); } if (table.IsClosed) { throw new TomlSemanticException($"table '{table.Name}' is closed ", this.currentFile, this.currentLine); } table[key] = value; }
private void ParseKeyValuePair(TomlTable parentTable) { // If there is no key if (this.Match(TokenType.ASSIGNMENT)) // generalize it on any token except barekey { throw new TomlSyntaxException("expected key, got '='", this.currentFile, this.currentLine); } String key = this.Consume(TokenType.BAREKEY).Text; this.Consume(TokenType.ASSIGNMENT); // There is no value if (this.Match(TokenType.NL) || this.Match(TokenType.EOF)) { throw new TomlSyntaxException("unspecified value", this.currentFile, this.currentLine); } var value = this.ParseValue(); if (!this.Match(TokenType.NL) && !this.LookMatch(0, TokenType.EOF)) { throw new TomlSyntaxException("there must be a newline or end of file after a key/value pair", this.currentFile, this.currentLine); } if (parentTable.IsClosed) { throw new TomlSemanticException($"table '{parentTable.Name}' is closed ", this.currentFile, this.currentLine); } if (parentTable.Contains(key)) { throw new TomlSemanticException($"key '{key}' is already defined in this table", this.currentFile, this.currentLine); } parentTable[key] = value; }