public static void Handle(string timestamp, string data, ParserState state) { data = data.Trim(); var match = Regexes.EntitiesChosenRegex.Match(data); if(match.Success) { /*NOTE: in 10357, "Player" is bugged, it's treating a player ID as an entity ID, resulting in "Player=GameEntity" For our own sanity we keep the old playerID logic from the previous builds, we'll change to "player" when it's fixed.*/ var rawEntity = match.Groups[1].Value; var rawPlayer = match.Groups[2].Value; var count = int.Parse(match.Groups[3].Value); var entity = Helper.ParseEntity(rawEntity, state); var player = Helper.ParseEntity(rawPlayer, state); var cEntities = new ChosenEntities {Entity = entity, PlayerId = player, Count = count, Choices = new List<Choice>(), TimeStamp = timestamp}; state.CurrentGame.Data.Add(cEntities); state.CurrentChosenEntites = cEntities; return; } match = Regexes.EntitiesChosenEntitiesRegex.Match(data); if(match.Success) { var index = int.Parse(match.Groups[1].Value); var rawEntity = match.Groups[2].Value; var entity = Helper.ParseEntity(rawEntity, state); var choice = new Choice {Entity = entity, Index = index}; state.CurrentChosenEntites.Choices.Add(choice); return; } Console.WriteLine("Warning: Unhandled chosen entities: " + data); }
public override ParseTree Parse(Lexer lexer, ParserState state) { lexer.Whitespace(state.RuntimeState); int start = lexer.Position; state.RuntimeState.Runtime.ParseTrace.Enter(this, lexer.CurrentSource(), "[]"); char character = lexer.Peek(); if (character == '\0') { state.RuntimeState.Runtime.ParseTrace.No(this, lexer.SourceFrom(start), "End of source"); return ParseTree.No; } lexer.Read(); state.RuntimeState.Runtime.ParseTrace.Yes(this, lexer.SourceFrom(start), TextEscape.Quote(character)); if (state.BuildTextNodes) return new ParseTree(Convert.ToString(character)); else return ParseTree.Yes; }
private void EndBlock() { AddParameter(parameter); parameter = new Parameter(); PullParent(); parserState = ParserState.BeginParameterName; }
public static void Handle(string timestamp, string data, ParserState state) { data = data.Trim(); var match = Regexes.SendChoicesChoicetypeRegex.Match(data); if(match.Success) { var id = match.Groups[1].Value; var rawType = match.Groups[2].Value; var type = Helper.ParseEnum<ChoiceType>(rawType); state.SendChoices = new SendChoices {Choices = new List<Choice>(), Entity = int.Parse(id), Type = type, TimeStamp = timestamp}; if(state.Node.Type == typeof(Game)) ((Game)state.Node.Object).Data.Add(state.SendChoices); else if(state.Node.Type == typeof(Action)) ((Action)state.Node.Object).Data.Add(state.SendChoices); else throw new Exception("Invalid node " + state.Node.Type + " -- " + data); return; } match = Regexes.SendChoicesEntitiesRegex.Match(data); if(match.Success) { var index = Helper.ParseEntity(match.Groups[1].Value, state); var id = Helper.ParseEntity(match.Groups[2].Value, state); var choice = new Choice {Entity = id, Index = index}; state.SendChoices.Choices.Add(choice); } }
public override ParseTree Parse(Lexer lexer, ParserState state) { state.RuntimeState.Runtime.ParseTrace.Enter(this, lexer.CurrentSource(), "Pattern " + Type.Name); int start = lexer.Position; if (state.Excluded.Contains(this)) { state.RuntimeState.Runtime.ParseTrace.No(this, lexer.CurrentSource(), "Excluded"); return ParseTree.No; } Precedence oldCurrentPrecedence = state.CurrentPrecedence; if (Precedence.Overwrites(state.CurrentPrecedence)) state.CurrentPrecedence = Precedence; ParseTree tree = ParseGraph.Parse(lexer, state); state.CurrentPrecedence = oldCurrentPrecedence; if (tree == ParseTree.No) { state.RuntimeState.Runtime.ParseTrace.No(this, lexer.SourceFrom(start)); return ParseTree.No; } state.RuntimeState.Runtime.ParseTrace.Yes(this, lexer.SourceFrom(start)); return tree; }
// 3.1) scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) private static bool ParseScheme (ref ParserState state) { string part = state.remaining; if (!IsAlpha (part [0])) return part.Length > 0; StringBuilder sb = new StringBuilder (); sb.Append (part [0]); int index; for (index = 1; index < part.Length; index++ ) { char ch = part [index]; if (ch != '.' && ch != '-' && ch != '+' && !IsAlpha (ch)) break; sb.Append (ch); } if (index + 1 <= part.Length && part [index] == ':') { state.elements.scheme = sb.ToString (); state.remaining = part.Substring (index + 1); } return state.remaining.Length > 0; }
private void Reset() { Stack.Reset(); _currentState = Data.InitialState; _currentLine = 0; _tokenCount = 0; _context.Errors.Clear(); }
public override ParseTree Parse(Lexer lexer, ParserState state) { lexer.Whitespace(state.RuntimeState); int start = lexer.Position; state.RuntimeState.Runtime.ParseTrace.Enter(this, lexer.CurrentSource(), range.ToString()); char character = lexer.Peek(); if (!range.Contains(character)) { lexer.ErrorStrings[start].Add(range.ToString()); state.RuntimeState.Runtime.ParseTrace.No(this, lexer.SourceFrom(start), TextEscape.Quote(character)); return ParseTree.No; } lexer.Read(); state.RuntimeState.Runtime.ParseTrace.Yes(this, lexer.SourceFrom(start), TextEscape.Quote(character)); if (state.BuildTextNodes) return new ParseTree(Convert.ToString(character)); else return ParseTree.Yes; }
public SongLineParser(string line) { m_line = line; while (AreData && Char.IsWhiteSpace(CurCh)) m_index++; InitState = State; Read(); }
/// <summary> /// Parses a stream chunking based on STX/ETX framing. Calls are re-entrant and hold state internally. /// </summary> /// <param name="bytes">A byte array of data to append</param> private void Parse(ArraySegment<byte> bytes) { byte[] data = bytes.Array; for (int i = bytes.Offset; i < bytes.Offset + bytes.Count; i++) { if ((data[i] > 3 || data[i] == 1) && _currentState == ParserState.AwaitingEtx) { if (_bufferIndex == _messageBuffer.Length) { var tmp = new byte[_messageBuffer.Length * 2]; Buffer.BlockCopy(_messageBuffer, 0, tmp, 0, _messageBuffer.Length); _messageBuffer = tmp; } _messageBuffer[_bufferIndex] = data[i]; _bufferIndex++; } else if (data[i] == STX) { _currentState = ParserState.AwaitingEtx; _bufferIndex = 0; } else if (data[i] == ETX && _currentState == ParserState.AwaitingEtx) { _currentState = ParserState.AwaitingStx; if (_receivedHandler != null) _receivedHandler(new ArraySegment<byte>(_messageBuffer, 0, _bufferIndex)); _bufferIndex = 0; } } }
public static void Handle(string timestamp, string data, ParserState state) { data = data.Trim(); var match = Regexes.OptionsEntityRegex.Match(data); if(match.Success) { var id = match.Groups[1].Value; state.Options = new Options {Id = int.Parse(id), OptionList = new List<Option>(), TimeStamp = timestamp}; state.UpdateCurrentNode(typeof(Game)); if(state.Node.Type == typeof(Game)) ((Game)state.Node.Object).Data.Add(state.Options); else throw new Exception("Invalid node " + state.Node.Type + " -- " + data); return; } match = Regexes.OptionsOptionRegex.Match(data); if(match.Success) { var index = match.Groups[1].Value; var rawType = match.Groups[2].Value; var rawEntity = match.Groups[3].Value; var entity = Helper.ParseEntity(rawEntity, state); var type = Helper.ParseEnum<OptionType>(rawType); var option = new Option {Entity = entity, Index = int.Parse(index), Type = type, OptionItems = new List<OptionItem>()}; state.Options.OptionList.Add(option); state.CurrentOption = option; state.LastOption = option; return; } match = Regexes.OptionsSuboptionRegex.Match(data); if(match.Success) { var subOptionType = match.Groups[1].Value; var index = match.Groups[2].Value; var rawEntity = match.Groups[3].Value; var entity = Helper.ParseEntity(rawEntity, state); if(subOptionType == "subOption") { var subOption = new SubOption {Entity = entity, Index = int.Parse(index), Targets = new List<Target>()}; state.CurrentOption.OptionItems.Add(subOption); state.LastOption = subOption; } else if(subOptionType == "target") { var target = new Target {Entity = entity, Index = int.Parse(index)}; var lastOption = state.LastOption as Option; if(lastOption != null) { lastOption.OptionItems.Add(target); return; } var lastSubOption = state.LastOption as SubOption; if(lastSubOption != null) lastSubOption.Targets.Add(target); } else throw new Exception("Unexpected suboption type: " + subOptionType); } }
void Parse() { for (var i = 0; i < _data.Length; i++) { var c = _data[i]; if (c == '<' && State == ParserState.None) { State = ParserState.StartElement; _elementNameStart = i + 1; _elementNameEnd = null; } else if (State == ParserState.StartElement && CheckPrev(i, CommentStart)) { State = ParserState.InsideComment; } else if (State == ParserState.InsideComment && CheckPrev(i, CommentEnd)) { State = ParserState.None; } else if (State == ParserState.StartElement && CheckPrev(i, CdataStart)) { State = ParserState.InsideCdata; } else if (State == ParserState.InsideCdata && CheckPrev(i, CdataEnd)) { State = ParserState.None; } else if (State == ParserState.StartElement && char.IsWhiteSpace(c)) { State = ParserState.InsideElement; _attributeNameStart = i; _elementNameEnd = i - 1; } else if ((State == ParserState.InsideElement || State == ParserState.StartElement) && c == '>') { State = ParserState.None; } else if (State == ParserState.InsideElement && (char.IsLetter(c) || c=='_' || c==':')) { State = ParserState.StartAttribute; _attributeNameStart = i; _attributeNameEnd = null; } else if (State == ParserState.StartAttribute && (c == '=' || char.IsWhiteSpace(c))) { State = ParserState.BeforeAttributeValue; _attributeNameEnd = i - 1; } else if (State == ParserState.BeforeAttributeValue && c == '"') { State = ParserState.AttributeValue; _attributeValueStart = i + 1; } else if (State == ParserState.AttributeValue && c == '"') { State = ParserState.InsideElement; } } }
private void BeginBlock() { parameter.Value = new List<Parameter>(); AddParameter(parameter); PushParent(parameter); parameter = new Parameter(); parserState = ParserState.BeginParameterName; }
public TransitionAction(ParserAction action, ParserState nextState) : this(action) { if (action != ParserAction.Shift && action != ParserAction.Goto) throw new Exception("Can only define the next state for the shift or goto actions."); if (nextState == null) throw new ArgumentNullException("nextState"); NextState = nextState; }
public void TestParseErrorGetsReported() { // Create an instance of our language grammar and set handlers for its rules. LanguageGrammar<Expression> g = new LanguageGrammar<Expression>(); g.DivideRule.Action = (e1, e2) => Expression.Divide(e1, e2); g.DoubleLiteralRule.Action = (d) => Expression.Constant(d); g.IntLiteralRule.Action = (i) => Expression.Constant(i); g.StringLiteralRule.Action = (s) => Expression.Constant(s); g.MinusRule.Action = (e1, e2) => Expression.Subtract(e1, e2); g.ModRule.Action = (e1, e2) => Expression.Modulo(e1, e2); g.MultiplyRule.Action = (e1, e2) => Expression.Multiply(e1, e2); g.NegateRule.Action = (e) => Expression.Negate(e); g.PlusRule.Action = (e1, e2) => Expression.Add(e1, e2); g.VariableRefRule.SetStatefulAction<ParserState>((s, name) => s.GetVariable(name)); // Spin up a parser for our language. // TODO: Package this up and simplify it. var expressionHelper = new ExpressionHelper(); var classifierSession = new TerminalClassifierSession<char, ParserState, int>() .AddSkipTerminal(new Terminal<char> { Name = "Whitespace", InitialState = RegexCharNFABuilder.RegexCompiler(@"\s+") }) .CurrentCharExprIs(x => x.CurrentChar()) .GetFromMarkExprIs(x => x.GetFromMarkedPos()) .HasCurrentCharExprIs(x => x.HasCurrentChar()) .MarkPosExprIs(x => x.MarkPos()) .MoveNextCharExprIs(x => x.MoveNextChar()) .GetLocationIs(x=>new ParseLocation {Line = 1, Column = x.GetPos()}) .ErrorCollectionIs(x=>x.Errors) .UnmarkPosExprIs(x => x.UnmarkPos()); var parserGen = new ParserGenerator<char>(expressionHelper); var parseTableBuilder = new LRParseTableBuilder(); var parseTable = parseTableBuilder.BuildParseTable(g); var session = parserGen.NewSession<ParserState>() .NonTerminalValueExprIs<object>(x => x.NonTerminalValue) .TerminalValueExprIs<string>(x => x.TerminalStringValue) .TerminalValueExprIs<int>(x => x.TerminalIntValue) .TerminalValueExprIs<double>(x => x.TerminalDoubleValue) .TerminalIs(x => x.Terminal) .NonTerminalIs(x => x.NonTerminal) .IncludeSymbols(true) .DebugOutputIs(x => Debug.WriteLine(x)) .Generate("LanguageParser", parseTable, classifierSession); // At this point, session is an Expression<ParserState,int> representing our parser. // We can compile it into a delegate or a MethodBuilder. For the examples, we'll use a delegate. var compiler = session.Compile(); // Create a parser state object and initialize it. ParserState ps = new ParserState("x*y +* 2.0"); ps.SetParameters( Expression.Parameter(typeof(double), "x"), Expression.Parameter(typeof(double), "y")); Assert.AreNotEqual(0, compiler(ps)); Assert.AreNotEqual(0, ps.Errors.Count); Assert.Less(ps.Errors.First().ExpectedTerminalNames.Count, g.Terminals.Count); }
public override ParseTree Parse(Lexer lexer, ParserState state) { int start = lexer.Position; ParseTree oldLHS = state.LeftHandSide; bool oldPrecedenceCanEqualCurrent = state.PrecedenceCanEqualCurrent; ConcretePattern oldRecursionExclude = null; ParseTree tree = ParseTree.Yes; for (int n = 0; n < nodes.Count; n++) { ParseGraphNode node = nodes[n]; ParseTree nodeTree = node.Parse(lexer, state); if (nodeTree == ParseTree.No) { state.PrecedenceCanEqualCurrent = oldPrecedenceCanEqualCurrent; state.LeftHandSide = oldLHS; state.RecursionExclude = oldRecursionExclude; if (oldRecursionExclude != null) state.Excluded.Add(oldRecursionExclude); lexer.Position = start; return ParseTree.No; } tree = tree.Extend(nodeTree); if (n == 0) { if (state.RecursionExclude != null) { oldRecursionExclude = state.RecursionExclude; state.Excluded.Remove(state.RecursionExclude); state.RecursionExclude = null; } if (state.RecursionBehaviour == RecursionBehaviour.RightRecursive) state.PrecedenceCanEqualCurrent = true; else if (state.RecursionBehaviour == RecursionBehaviour.LeftRecursive) state.LeftHandSide = null; } } state.PrecedenceCanEqualCurrent = oldPrecedenceCanEqualCurrent; state.LeftHandSide = oldLHS; state.RecursionExclude = oldRecursionExclude; if (oldRecursionExclude != null) state.Excluded.Add(oldRecursionExclude); return tree; }
private string StateToDotString(ParserState state) { var result = new StringBuilder(); foreach (var item in state.Items) { result.Append(item); result.Append("\\l"); } return result.ToString(); }
public RPN_CalculatorEngine() { curr_state = ParserState.ParserState_Ok; op_stack = new Stack<CalculatorToken>(32); output_queue = new Stack<CalculatorToken>(32); func_table_ = new FunctionTable(); input_string = null; input_iter = 0; input_end_marker = 0; }
public void AddTransition(ParserState transitionFrom, GrammarSymbol symbol, ParserState transitionTo) { if(!_stateTransitions.ContainsKey(transitionFrom)) _stateTransitions.Add(transitionFrom, new Dictionary<GrammarSymbol,ParserState>()); if (_stateTransitions[transitionFrom].ContainsKey(symbol)) throw new Exception("State conflict. Trying to add a transition for a state when one already exists for the specified grammar symbol."); _stateTransitions[transitionFrom][symbol] = transitionTo; _states.Add(transitionFrom); _states.Add(transitionTo); }
public void Parse(CompilerContext context) { _context = context; _traceOn = _context.OptionIsSet(CompilerOptions.TraceParser); _currentInput = null; InputStack.Clear(); Stack.Clear(); _currentState = Data.InitialState; //set the current state to InitialState Stack.Push(new ParseTreeNode(Data.InitialState)); //main loop while (ExecuteAction()) {} }//Parse
public ParseTree ParseUsingCompiler(Lexer lexer, ParserState state) { StateForCompiler stateForCompiler = new StateForCompiler(); stateForCompiler.BuildTextNodes = state.BuildTextNodes; stateForCompiler.RecursionBehaviour = state.RecursionBehaviour; stateForCompiler.LeftRecursiveAlts = state.LeftRecursiveAlts; stateForCompiler.Whitespace = lexer.WhitespacePattern; PatternTrampoline trampoline = GetTrampoline(state.RuntimeState.Runtime, stateForCompiler); return trampoline.Implementation(lexer, state); }
public TransitionAction this[ParserState state, GrammarSymbol symbol] { get { if(!_table.ContainsKey(state)) throw new InvalidOperationException("The given state is unknown for this transition table."); var tableEntry = _table[state]; if (!tableEntry.ContainsKey(symbol)) throw new InvalidOperationException("There is no transition from the given state under the given input."); return tableEntry[symbol]; } }
public static bool TryParseComponents (string uri, UriKind kind, out UriElements elements, out string error) { uri = uri.Trim (); ParserState state = new ParserState (uri, kind); elements = state.elements; error = null; if (uri.Length == 0 && (kind == UriKind.Relative || kind == UriKind.RelativeOrAbsolute)){ state.elements.isAbsoluteUri = false; return true; } if (uri.Length <= 1 && kind == UriKind.Absolute) { error = "Absolute URI is too short"; return false; } bool ok = ParseFilePath (state) && ParseScheme (state); var scheme = state.elements.scheme; UriParser parser = null; if (!string.IsNullOrEmpty (scheme)) { parser = UriParser.GetParser (scheme); if (parser != null && !(parser is DefaultUriParser)) return true; } ok = ok && ParseAuthority (state) && ParsePath (state) && ParseQuery (state) && ParseFragment (state); if (string.IsNullOrEmpty (state.elements.host) && (scheme == Uri.UriSchemeHttp || scheme == Uri.UriSchemeGopher || scheme == Uri.UriSchemeNntp || scheme == Uri.UriSchemeHttps || scheme == Uri.UriSchemeFtp)) state.error = "Invalid URI: The Authority/Host could not be parsed."; if (!string.IsNullOrEmpty (state.elements.host) && Uri.CheckHostName (state.elements.host) == UriHostNameType.Unknown) state.error = "Invalid URI: The hostname could not be parsed."; if (!string.IsNullOrEmpty (state.error)) { elements = null; error = state.error; return false; } return true; }
public override ParseTree Parse(Lexer lexer, ParserState state) { lexer.Whitespace(state.RuntimeState); int start = lexer.Position; state.RuntimeState.Runtime.ParseTrace.Enter( this, lexer.CurrentSource(), TextEscape.Quote(text)); for (int n = 0; n < text.Length; n++) { char character = lexer.Peek(n); if (character != text[n]) { string stoppedString; if (character == '\0') stoppedString = "end"; else stoppedString = TextEscape.Quote(character); lexer.ErrorStrings[start + n].Add(TextEscape.Quote(text)); if (n > 0) state.RuntimeState.Runtime.ParseTrace.No( this, lexer.SourceFrom(start), TextEscape.Quote(lexer.Text.Substring(start, n)) + "..." + stoppedString); else state.RuntimeState.Runtime.ParseTrace.No( this, lexer.SourceFrom(start), stoppedString); return ParseTree.No; } } lexer.Skip(text.Length); state.RuntimeState.Runtime.ParseTrace.Yes(this, lexer.SourceFrom(start)); if (state.BuildTextNodes) return new ParseTree(text); else return ParseTree.Yes; }
public override ParseTree Parse(Lexer lexer, ParserState state) { ParseTree bodyTree = body.Parse(lexer, state); if (bodyTree == ParseTree.No) return ParseTree.No; ParseTree labelledTree = new ParseTree(); labelledTree = labelledTree.ExtendFields(bodyTree); labelledTree.Fields[label] = bodyTree.Value; return labelledTree; }
public override ParseTree Parse(Lexer lexer, ParserState state) { int start = lexer.Position; state.RuntimeState.Runtime.ParseTrace.Enter(this, lexer.CurrentSource(), "options"); bool oldBuildTextNodes = state.BuildTextNodes; Pattern oldWhitespace = lexer.WhitespacePattern; Precedence oldCurrentPrecedence = state.CurrentPrecedence; bool oldPrecedenceCanEqualCurrent = state.PrecedenceCanEqualCurrent; if (buildTextNodes.HasValue) state.BuildTextNodes = buildTextNodes.Value; if (whitespace.HasValue) { lexer.Whitespace(state.RuntimeState); lexer.WhitespacePattern = whitespace.Value; } if (exclude.HasValue) state.Excluded.Add(exclude.Value); if (dropPrecedence.HasValue && dropPrecedence.Value) { state.CurrentPrecedence = null; state.PrecedenceCanEqualCurrent = false; } ParseTree tree = body.Parse(lexer, state); state.BuildTextNodes = oldBuildTextNodes; lexer.WhitespacePattern = oldWhitespace; if (exclude.HasValue) state.Excluded.Remove(exclude.Value); state.CurrentPrecedence = oldCurrentPrecedence; state.PrecedenceCanEqualCurrent = oldPrecedenceCanEqualCurrent; if (tree == ParseTree.No) { state.RuntimeState.Runtime.ParseTrace.No(this, lexer.SourceFrom(start)); return ParseTree.No; } state.RuntimeState.Runtime.ParseTrace.Yes(this, lexer.SourceFrom(start)); return tree; }
public static void Handle(string timestamp, string data, ParserState state) { data = data.Trim(); var match = Regexes.ChoicesChoiceRegex.Match(data); if(match.Success) { var rawEntity = match.Groups[1].Value; var playerId = match.Groups[2].Value; var rawType = match.Groups[3].Value; var min = match.Groups[4].Value; var max = match.Groups[5].Value; var entity = Helper.ParseEntity(rawEntity, state); var type = Helper.ParseEnum<CHOICE_TYPE>(rawType); state.Choices = new Choices { ChoiceList = new List<Choice>(), Entity = entity, Max = int.Parse(max), Min = int.Parse(min), PlayerId = int.Parse(playerId), Type = type }; if(state.Node.Type == typeof(Game)) ((Game)state.Node.Object).Data.Add(state.Choices); else if(state.Node.Type == typeof(Action)) ((Action)state.Node.Object).Data.Add(state.Choices); else throw new Exception("Invalid node " + state.Node.Type + " -- " + data); return; } match = Regexes.ChoicesSourceRegex.Match(data); if(match.Success) { var rawEntity = match.Groups[1].Value; var entity = Helper.ParseEntity(rawEntity, state); state.Choices.Source = entity; return; } match = Regexes.ChoicesEntitiesRegex.Match(data); if(match.Success) { var index = match.Groups[1].Value; var rawEntity = match.Groups[2].Value; var entity = Helper.ParseEntity(rawEntity, state); var choice = new Choice {Entity = entity, Index = int.Parse(index)}; state.Choices.ChoiceList.Add(choice); } }
private void ParseFirstHeader() { bool? atBoundary = Client.ReadBuffer.AtBoundary(_firstBoundary, ContentLength); if (atBoundary.HasValue) { if (!atBoundary.Value) throw new ProtocolException("Expected multipart content to start with the boundary"); _state = ParserState.ReadingHeaders; ParseHeaders(); } }
public override ParseTree Parse(Lexer lexer, ParserState state) { // todo traces int start = lexer.Position; ParseTree bodyTree = body.Parse(lexer, state); if (bodyTree == ParseTree.No) return ParseTree.Yes; lexer.Position = start; return ParseTree.No; }
public static UriElements ParseComponents (string uri) { ParserState state = new ParserState (uri); bool ok = ParseScheme (ref state); if (ok) ok = ParseAuthority (ref state); if (ok) ok = ParsePath (ref state); if (ok) ok = ParseQuery (ref state); if (ok) ParseFragment (ref state); return state.elements; }
private static bool ParseFilePath(ParserState state) { return(ParseWindowsFilePath(state) && ParseWindowsUNC(state) && ParseUnixFilePath(state)); }
// 3.1) scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) private static bool ParseScheme(ParserState state) { string part = state.remaining; StringBuilder sb = new StringBuilder(); sb.Append(part [0]); int index; for (index = 1; index < part.Length; index++) { char ch = part [index]; if (ch != '.' && ch != '-' && ch != '+' && !IsAlpha(ch) && !Char.IsDigit(ch)) { break; } sb.Append(ch); } if (index == 0 || index >= part.Length) { if (state.kind == UriKind.Absolute) { state.error = "Invalid URI: The format of the URI could not be determined."; return(false); } state.elements.isAbsoluteUri = false; return(state.remaining.Length > 0); } if (part [index] != ':') { if (state.kind == UriKind.Absolute) { state.error = "Invalid URI: The URI scheme is not valid."; return(false); } state.elements.isAbsoluteUri = false; return(state.remaining.Length > 0); } state.elements.scheme = sb.ToString().ToLowerInvariant(); state.remaining = part.Substring(index); // Check scheme name characters as specified in RFC2396. // Note: different checks in 1.x and 2.0 if (!Uri.CheckSchemeName(state.elements.scheme)) { if (state.kind == UriKind.Absolute) { state.error = "Invalid URI: The URI scheme is not valid."; return(false); } state.elements.isAbsoluteUri = false; return(state.remaining.Length > 0); } return(ParseDelimiter(state)); }
// host = IP-literal / IPv4address / reg-name private static bool ParseHost(ParserState state) { string part = state.remaining; if (state.elements.scheme == Uri.UriSchemeFile && part.Length >= 2 && (part [0] == '\\' || part [0] == '/') && part [1] == part [0]) { part = part.TrimStart(part [0]); state.remaining = part; } if (!ParseWindowsFilePath(state)) { return(false); } StringBuilder sb = new StringBuilder(); var tmpHost = ""; var possibleIpv6 = false; int index; for (index = 0; index < part.Length; index++) { char ch = part [index]; if (ch == '/' || ch == '#' || ch == '?') { break; } // Possible IPv6 if (string.IsNullOrEmpty(tmpHost) && ch == ':') { tmpHost = sb.ToString(); possibleIpv6 = true; } sb.Append(ch); if (possibleIpv6 && ch == ']') { break; } } if (possibleIpv6) { IPv6Address ipv6addr; if (IPv6Address.TryParse(sb.ToString(), out ipv6addr)) { #if NET_4_5 var ipStr = ipv6addr.ToString(false); #else var ipStr = ipv6addr.ToString(true); #endif //remove scope ipStr = ipStr.Split('%') [0]; state.elements.host = "[" + ipStr + "]"; state.elements.scopeId = ipv6addr.ScopeId; state.remaining = part.Substring(sb.Length); return(state.remaining.Length > 0); } state.elements.host = tmpHost; } else { state.elements.host = sb.ToString(); } state.elements.host = state.elements.host.ToLowerInvariant(); state.remaining = part.Substring(state.elements.host.Length); if (state.elements.scheme == Uri.UriSchemeFile && state.elements.host != "") { // under Windows all file://host URI are considered UNC, which is not the case other MacOS (e.g. Silverlight) #if BOOTSTRAP_BASIC state.elements.isUnc = (Path.DirectorySeparatorChar == '\\'); #else state.elements.isUnc = Environment.IsRunningOnWindows; #endif } return(state.remaining.Length > 0); }
public static bool TryParseComponents(string uri, UriKind kind, out UriElements elements, out string error) { uri = uri.Trim(); ParserState state = new ParserState(uri, kind); elements = state.elements; error = null; if (uri.Length == 0 && (kind == UriKind.Relative || kind == UriKind.RelativeOrAbsolute)) { state.elements.isAbsoluteUri = false; return(true); } if (uri.Length <= 1 && kind == UriKind.Absolute) { error = "Absolute URI is too short"; return(false); } bool ok = ParseFilePath(state) && ParseScheme(state); var scheme = state.elements.scheme; UriParser parser = null; if (!string.IsNullOrEmpty(scheme)) { parser = UriParser.GetParser(scheme); if (parser != null && !(parser is DefaultUriParser)) { return(true); } } ok = ok && ParseAuthority(state) && ParsePath(state) && ParseQuery(state) && ParseFragment(state); if (string.IsNullOrEmpty(state.elements.host) && (scheme == Uri.UriSchemeHttp || scheme == Uri.UriSchemeGopher || scheme == Uri.UriSchemeNntp || scheme == Uri.UriSchemeHttps || scheme == Uri.UriSchemeFtp)) { state.error = "Invalid URI: The Authority/Host could not be parsed."; } if (!string.IsNullOrEmpty(state.elements.host) && Uri.CheckHostName(state.elements.host) == UriHostNameType.Unknown) { state.error = "Invalid URI: The hostname could not be parsed."; } if (!string.IsNullOrEmpty(state.error)) { elements = null; error = state.error; return(false); } return(true); }