private IReq <ValueNode> Value(ICommentsContext cctx) { var value = SimpleValue() .Or(Array) .Or(InlineTable) .OrNode(() => SyntaxErrorNode.Unexpected("Expected TOML value", this.input.Current)); if (this.settings.IsFeautureEnabled(ExperimentalFeature.ValueWithUnit) && value.HasNode) { var unit = this.input.Accept(t => t.Type == TokenType.BareKey || t.Type == TokenType.Unit) .CreateNode(t => new TerminalNode(t.Trimmed()).Opt()); if (unit.HasNode) { return(value.SyntaxNode().WithUnitAttached(unit)); } } return(value); IOpt <ValueNode> SimpleValue() => this.input .Accept(t => t.Type == TokenType.Float || t.Type == TokenType.Integer || t.Type == TokenType.HexInteger || t.Type == TokenType.BinaryInteger || t.Type == TokenType.OctalInteger || t.Type == TokenType.Bool || t.Type == TokenType.LocalDate || t.Type == TokenType.OffsetDateTime || t.Type == TokenType.LocalTime || t.Type == TokenType.LocalDateTime || t.Type == TokenType.Duration || t.Type == TokenType.String || t.Type == TokenType.LiteralString || t.Type == TokenType.MultilineString || t.Type == TokenType.MultilineLiteralString) .CreateNode(t => ValueNode.CreateTerminalValue(t).Opt()); IOpt <ValueNode> Array() => this.input .Accept(t => t.Type == TokenType.LBrac) .CreateNode(t => ValueNode.CreateNonTerminalValue(this.Array(t)).Opt()); IOpt <ValueNode> InlineTable() { return(this.input .Accept(t => t.Type == TokenType.LCurly) .CreateNode(t => ValueNode.CreateNonTerminalValue(this.InlineTable(t, cctx.Consume())).Opt())); } }
private IOpt <ArraySeparatorNode> ArraySeparator() { if (Epsilon()) { return(Opt <ArraySeparatorNode> .None); } return(this.input.Expect(t => t.Type == TokenType.Comma) .CreateNode( onSuccess: t => new ArraySeparatorNode(t, this.ArrayValue(out var _), this.AppComment()).Opt(), onError: ut => SyntaxErrorNode.Unexpected("Array value is missing", ut))); bool Epsilon() => this.input.Peek(t => t.Type == TokenType.RBrac); }
private IReq <ExpressionNode> Expression() { using (var cctx = this.input.CreateConsumeCommentContext()) { if (this.input.Peek(t => t.Type == TokenType.Eof)) { return(new CommentExpressionNode(cctx.Consume()).Req()); } return(KeyValueExpression() .Or <ExpressionNode>(Table) .OrNode(() => SyntaxErrorNode.Unexpected("Expected TOML table or row key", this.input.Current))); IOpt <KeyValueExpressionNode> KeyValueExpression() { var key = this.input.Accept(IsKey) .CreateNode(t => new KeyNode(t, this.KeySeparator()).Opt()); if (key.HasNode) { var comments = cctx.Consume(); return(this.input.Expect(t => t.Type == TokenType.Assign) .CreateNode( assignToken => new KeyValueExpressionNode( key.AsReq(), assignToken, this.Value(NoCommentsHere.Instance), comments, this.AppComment()).Opt(), t => new SyntaxErrorNode("Key value expression's '=' is missing.", t.Location))); } else { return(Opt <KeyValueExpressionNode> .None); } } IOpt <TableNode> Table() => this.input .Accept(t => t.Type == TokenType.LBrac) .CreateNode(lbrac => this.Table(lbrac, cctx.Consume()).AsOpt()); } }
private IReq <ValueNode> Value(ICommentsContext cctx) { return(SimpleValue() .Or(Array) .Or(InlineTable) .OrNode(() => SyntaxErrorNode.Unexpected("Expected TOML value", this.input.Current))); IOpt <ValueNode> SimpleValue() => this.input .Accept(t => t.Type == TokenType.Float || t.Type == TokenType.Integer || t.Type == TokenType.HexInteger || t.Type == TokenType.BinaryInteger || t.Type == TokenType.OctalInteger || t.Type == TokenType.Bool || t.Type == TokenType.LocalDate || t.Type == TokenType.OffsetDateTime || t.Type == TokenType.LocalTime || t.Type == TokenType.LocalDateTime || t.Type == TokenType.Duration || t.Type == TokenType.String || t.Type == TokenType.LiteralString || t.Type == TokenType.MultilineString || t.Type == TokenType.MultilineLiteralString) .CreateNode(t => ValueNode.CreateTerminalValue(t).Opt()); IOpt <ValueNode> Array() => this.input .Accept(t => t.Type == TokenType.LBrac) .CreateNode(t => ValueNode.CreateNonTerminalValue(this.Array(t)).Opt()); IOpt <ValueNode> InlineTable() { return(this.input .Accept(t => t.Type == TokenType.LCurly) .CreateNode(t => ValueNode.CreateNonTerminalValue(this.InlineTable(t, cctx.Consume())).Opt())); } }
public SyntaxErrorNode CreateErrorNode() => this.Current.TokenError() ?? SyntaxErrorNode.Unexpected(this.CurrentToken);
private SyntaxErrorNode GetError(Func <Token, SyntaxErrorNode> customHandler) => customHandler?.Invoke(this.errorToken) ?? SyntaxErrorNode.Unexpected(this.errorToken);