private HierarchicalExpression(string[] segments, Reflection.MemberPathSegment[] members) { _segments = segments ?? new string[0]; _members = members ?? new Reflection.MemberPathSegment[0]; _anchor = IO.PathAnchor.None; _path = string.Empty; if (segments.Length > 0) { switch (segments[0]) { case "": _anchor = IO.PathAnchor.Root; break; case ".": _anchor = IO.PathAnchor.Current; break; case "..": _anchor = IO.PathAnchor.Parent; break; } if (segments.Length == 1 && segments[0].Length == 0) { _path = "/"; } else { _path = string.Join("/", segments); } } }
public StateContext(ReadOnlySpan <char> data) { _data = data; _anchorPosition = -1; _cursorPosition = -1; _whitespaces = 0; this.State = State.None; this.Character = '\0'; this.Anchor = IO.PathAnchor.None; }
private static void ParsePath(TextReader reader, out IO.PathAnchor anchor, out string name, out string path) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } var state = CommandPathState.None; var parts = new List <string>(); var valueRead = 0; //设置输出参数的默认值 anchor = IO.PathAnchor.None; name = string.Empty; path = string.Empty; while ((valueRead = reader.Read()) > 0) { var chr = (char)valueRead; //首先对位于路径中间的点号进行转换,以方便后续的处理 if (chr == '.' && state == CommandPathState.Part) { chr = '/'; } if (chr == '.') { switch (state) { case CommandPathState.None: state = CommandPathState.Dot; anchor = IO.PathAnchor.Current; break; case CommandPathState.Dot: state = CommandPathState.DoubleDot; anchor = IO.PathAnchor.Parent; break; default: throw new CommandExpressionException("Invalid anchor of command path."); } } else if (chr == '/') { if (state == CommandPathState.Slash) { throw new CommandExpressionException("Duplicate '/' slash characters."); } if (state == CommandPathState.None) { anchor = IO.PathAnchor.Root; } else if (state == CommandPathState.Part) { parts.Add(name); name = string.Empty; } state = CommandPathState.Slash; } else if (Char.IsLetterOrDigit(chr) || chr == '_') { if (state == CommandPathState.Dot || state == CommandPathState.DoubleDot) { throw new CommandExpressionException("Missing '/' slash character between dot and letter or digit."); } name += chr; state = CommandPathState.Part; } else if (Char.IsWhiteSpace(chr)) { if (state == CommandPathState.None) { continue; } else { break; } } else { throw new CommandExpressionException($"Contains '{chr}' illegal character(s) in the command path."); } } //如果路径以斜杠符结尾,即为非法路径格式 if (state == CommandPathState.Slash && ((parts != null && parts.Count > 0) || anchor != IO.PathAnchor.Root)) { throw new CommandExpressionException("The command path can not at the end of '/' character."); } if (parts != null && parts.Count > 0) { path = string.Join(".", parts); } else if (string.IsNullOrEmpty(name)) { switch (anchor) { case IO.PathAnchor.Root: name = "/"; break; case IO.PathAnchor.Current: name = "."; break; case IO.PathAnchor.Parent: name = ".."; break; } anchor = IO.PathAnchor.None; } }