private int GetRestartStateIndex(ScannerState state, int stateIndex) { ScannerRestartState restartState = new ScannerRestartState(); this.scanner.InitializeRestartState(restartState); restartState.State = state; for (int i = stateIndex - 1; i >= 0; i--) { ScannerRestartState rstate = (ScannerRestartState)this.stateList[i]; if (rstate == restartState) { return(i); } } int n = this.stateList.Count; for (int i = stateIndex + 1; i < n; i++) { ScannerRestartState rstate = (ScannerRestartState)this.stateList[i]; if (rstate == restartState) { return(i); } } this.stateList.Add(restartState); return(n); }
private ScannerRestartState GetRestartStateFor(int stateIndex) { if (stateIndex < 0) { Debug.Assert(false); stateIndex = 0; } if (this.stateList.Count <= stateIndex) { Debug.Assert(stateIndex == 0); ScannerRestartState restartState = new ScannerRestartState(); this.stateList.Add(restartState); this.scanner.InitializeRestartState(restartState); return(restartState); } return((ScannerRestartState)this.stateList[stateIndex]); }
public virtual bool ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo, ref int stateIndex) { ScannerRestartState restartState = this.GetRestartStateFor(stateIndex); restartState.EndPos = this.scanner.endPos; this.scanner.Restart(restartState); bool noMemberSelection = this.scanner.state == ScannerState.LastTokenDisablesMemberSelection; if (noMemberSelection) { this.scanner.state = ScannerState.Code; this.scanner.RestartStateHasChanged = true; } SpecSharpTokenInfo specSharpTokenInfo = tokenInfo as SpecSharpTokenInfo; tokenInfo.trigger = TokenTrigger.None; Token tok; this.scanner.stillInsideToken = false; ScannerState state = this.scanner.state; switch (state) { case ScannerState.CData: if (this.scanner.endPos >= this.scanner.maxPos) { return(false); } this.scanner.ScanXmlCharacterData(); if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; } else { state = ScannerState.XML; } tok = Token.CharacterData; break; case ScannerState.MLComment: if (this.scanner.endPos >= this.scanner.maxPos) { return(false); } this.scanner.SkipMultiLineComment(); if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; } else { state = ScannerState.Code; } tok = Token.MultiLineComment; break; case ScannerState.MLString: if (this.scanner.endPos >= this.scanner.maxPos) { return(false); } this.scanner.ScanVerbatimString(); if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; } else { state = ScannerState.Code; } tok = Token.LiteralContentString; break; case ScannerState.PI: if (this.scanner.endPos >= this.scanner.maxPos) { return(false); } this.scanner.ScanXmlProcessingInstructionsTag(); if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; } else { state = ScannerState.XML; } tok = Token.ProcessingInstructions; break; case ScannerState.Text: if (this.scanner.endPos >= this.scanner.maxPos) { return(false); } this.scanner.ScanXmlText(); if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; } else { state = ScannerState.XML; } tok = Token.LiteralContentString; break; case ScannerState.LiteralComment: if (this.scanner.endPos >= this.scanner.maxPos) { return(false); } this.scanner.ScanXmlComment(); if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; } else { state = ScannerState.XML; } tok = Token.LiteralComment; break; case ScannerState.XmlAttr1: case ScannerState.XmlAttr2: if (this.scanner.endPos >= this.scanner.maxPos) { return(false); } this.scanner.ScanXmlString(state == ScannerState.XmlAttr1 ? '"' : '\''); if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; } else { state = ScannerState.Tag; } tok = Token.StringLiteral; break; default: tok = this.scanner.GetNextToken(); if (tok != Token.LeftBrace) { state = this.scanner.state; } break; } if (specSharpTokenInfo != null) { specSharpTokenInfo.extendedType = tok; } switch (tok) { case Token.AddAssign: case Token.AddOne: case Token.Arrow: case Token.BitwiseAnd: case Token.BitwiseAndAssign: case Token.BitwiseNot: case Token.BitwiseOr: case Token.BitwiseOrAssign: case Token.BitwiseXor: case Token.BitwiseXorAssign: case Token.Divide: case Token.DivideAssign: case Token.Equal: case Token.GreaterThan: case Token.GreaterThanOrEqual: case Token.Iff: case Token.Implies: case Token.LeftShift: case Token.LeftShiftAssign: case Token.LessThanOrEqual: case Token.LogicalAnd: case Token.LogicalNot: case Token.LogicalOr: case Token.Maplet: case Token.Multiply: case Token.MultiplyAssign: case Token.NotEqual: case Token.Plus: case Token.Remainder: case Token.RemainderAssign: case Token.RightShift: case Token.RightShiftAssign: case Token.Subtract: case Token.SubtractAssign: case Token.SubtractOne: tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.Operator; break; case Token.Assign: if (state == ScannerState.Tag) { tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; } else { tokenInfo.color = TokenColor.Text; } tokenInfo.type = TokenType.Operator; break; case Token.Abstract: case Token.Acquire: case Token.Add: case Token.Additive: case Token.Alias: case Token.As: case Token.Assert: case Token.Assume: case Token.Base: case Token.Bool: case Token.Break: case Token.Byte: case Token.Case: case Token.Catch: case Token.Char: case Token.Checked: case Token.Class: case Token.Const: case Token.Continue: case Token.Count: case Token.Decimal: case Token.Default: case Token.Delegate: case Token.Do: case Token.Double: case Token.ElementsSeen: case Token.Else: case Token.Ensures: case Token.Enum: case Token.Event: case Token.Exists: case Token.Explicit: case Token.Expose: case Token.Extern: case Token.False: case Token.Finally: case Token.Fixed: case Token.Float: case Token.For: case Token.Forall: case Token.Foreach: case Token.Get: case Token.Goto: case Token.If: case Token.Implicit: case Token.In: case Token.Invariant: case Token.Int: case Token.Interface: case Token.Internal: case Token.Is: case Token.Lock: case Token.Long: case Token.Max: case Token.Min: case Token.Model: case Token.Namespace: case Token.New: case Token.Modifies: case Token.Object: case Token.Old: case Token.Operator: case Token.Out: case Token.Otherwise: case Token.Override: case Token.Params: case Token.Partial: case Token.Private: case Token.Product: case Token.Protected: case Token.Public: case Token.Read: case Token.Readonly: case Token.Ref: case Token.Remove: case Token.Requires: case Token.Return: case Token.Satisfies: case Token.Sbyte: case Token.Sealed: case Token.Set: case Token.Short: case Token.Sizeof: case Token.Stackalloc: case Token.Static: case Token.String: case Token.Struct: case Token.Sum: case Token.Switch: case Token.This: case Token.Throw: case Token.Throws: case Token.True: case Token.Try: case Token.Typeof: case Token.Uint: case Token.Ulong: case Token.Unchecked: case Token.Unique: case Token.Unsafe: case Token.Ushort: case Token.Using: case Token.Value: case Token.Virtual: case Token.Void: case Token.Volatile: case Token.Witness: case Token.Where: case Token.While: case Token.Write: case Token.Yield: tokenInfo.color = TokenColor.Keyword; tokenInfo.type = TokenType.Keyword; break; case Token.CharacterData: tokenInfo.color = (TokenColor)SpecSharpTokenColor.CData; tokenInfo.type = TokenType.Literal; if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; state = ScannerState.CData; } break; case Token.Comma: tokenInfo.trigger = TokenTrigger.ParamNext; tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.Delimiter; break; case Token.Conditional: case Token.Colon: case Token.Semicolon: tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.Delimiter; break; case Token.DoubleColon: case Token.Dot: if (!noMemberSelection) { tokenInfo.trigger = TokenTrigger.MemberSelect; } tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.Delimiter; break; case Token.EndOfSimpleTag: state = ScannerState.XML; tokenInfo.trigger = TokenTrigger.MatchBraces; tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; tokenInfo.type = TokenType.Delimiter; break; case Token.EndOfTag: state = ScannerState.XML; tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; tokenInfo.type = TokenType.Delimiter; break; case Token.HexLiteral: case Token.IntegerLiteral: case Token.RealLiteral: state = ScannerState.LastTokenDisablesMemberSelection; tokenInfo.color = TokenColor.Number; tokenInfo.type = TokenType.Literal; break; case Token.Identifier: if (state == ScannerState.Code) { //if (this.scanner.startPos + 1 == this.scanner.endPos) { // if (noMemberSelection) // state = ScannerState.LastTokenDisablesMemberSelection; // else // tokenInfo.trigger = TokenTrigger.MemberSelect; //} tokenInfo.color = TokenColor.Identifier; } else { tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; } tokenInfo.type = TokenType.Identifier; break; case Token.LeftBrace: tokenInfo.trigger = TokenTrigger.MatchBraces; tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.Delimiter; break; case Token.LeftBracket: case Token.LeftParenthesis: tokenInfo.trigger = TokenTrigger.ParamStart | TokenTrigger.MatchBraces; tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.Delimiter; break; case Token.LessThan: tokenInfo.trigger = TokenTrigger.ParamStart; tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.Delimiter; break; case Token.MultiLineComment: tokenInfo.color = TokenColor.Comment; tokenInfo.type = TokenType.Comment; if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; state = ScannerState.MLComment; } break; case Token.Null: state = ScannerState.LastTokenDisablesMemberSelection; tokenInfo.color = TokenColor.Keyword; tokenInfo.type = TokenType.Keyword; break; case Token.PreProcessorDirective: tokenInfo.color = TokenColor.Keyword; tokenInfo.type = TokenType.Delimiter; if (this.scanner.state == ScannerState.ExcludedCode) { this.startExcludingAfterEndOfLine = true; state = ScannerState.Code; } break; case Token.PreProcessorExcludedBlock: tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; tokenInfo.type = TokenType.Literal; break; case Token.ProcessingInstructions: tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; tokenInfo.type = TokenType.Literal; if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; state = ScannerState.PI; } break; case Token.RightBrace: tokenInfo.trigger = TokenTrigger.MatchBraces; tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.Delimiter; break; case Token.RightBracket: case Token.RightParenthesis: tokenInfo.trigger = TokenTrigger.ParamEnd | TokenTrigger.MatchBraces; tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.Delimiter; break; case Token.SingleLineComment: tokenInfo.color = TokenColor.Comment; tokenInfo.type = TokenType.LineComment; break; case Token.SingleLineDocCommentStart: tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; tokenInfo.type = TokenType.LineComment; break; case Token.StartOfClosingTag: state = ScannerState.Tag; tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; tokenInfo.type = TokenType.Delimiter; break; case Token.StartOfTag: state = ScannerState.Tag; tokenInfo.trigger = TokenTrigger.MemberSelect; tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; tokenInfo.type = TokenType.Delimiter; break; case Token.StringLiteral: if (state == ScannerState.Code || state == ScannerState.MLString) { tokenInfo.color = TokenColor.String; } else { tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; } tokenInfo.type = TokenType.String; break; case Token.LiteralComment: tokenInfo.color = TokenColor.Comment; tokenInfo.type = TokenType.Comment; if (this.scanner.stillInsideToken) { this.scanner.stillInsideToken = false; state = ScannerState.LiteralComment; } break; case Token.LiteralContentString: tokenInfo.color = TokenColor.Comment; tokenInfo.type = TokenType.String; break; case Token.MultiLineDocCommentStart: tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; tokenInfo.type = TokenType.Delimiter; break; case Token.ObjectLiteralStart: // this is a code to object literal switch by definition state = ScannerState.XML; tokenInfo.color = TokenColor.Keyword; tokenInfo.type = TokenType.Delimiter; break; case Token.DocCommentEnd: tokenInfo.color = (TokenColor)SpecSharpTokenColor.ProcessingInstruction; tokenInfo.type = TokenType.Delimiter; state = ScannerState.Code; break; case Token.EndOfFile: if (this.startExcludingAfterEndOfLine) { this.startExcludingAfterEndOfLine = false; stateIndex = this.GetRestartStateIndex(ScannerState.ExcludedCode, stateIndex); } else if (this.scanner.state == ScannerState.XML && this.scanner.docCommentStart == Token.SingleLineDocCommentStart) { stateIndex = this.GetRestartStateIndex(ScannerState.Code, stateIndex); } return(false); case Token.WhiteSpace: tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.WhiteSpace; break; default: tokenInfo.color = TokenColor.Text; tokenInfo.type = TokenType.Delimiter; break; } tokenInfo.startIndex = this.scanner.startPos; tokenInfo.endIndex = this.scanner.endPos - 1; if (state != this.scanner.state || this.scanner.RestartStateHasChanged) { stateIndex = this.GetRestartStateIndex(state, stateIndex); } return(true); }