scanner.vb
来自「大名鼎鼎的mono是.NET平台的跨平台(支持linux」· VB 代码 · 共 1,307 行 · 第 1/4 页
VB
1,307 行
NextChar() Result = NewToken(KS.Exclamation) Case "&"c Select Case PeekChar()#If EXTENDED Then Case "b"c, "B"c, "h"c, "H"c, "o"c, "O"c, "d"c, "D"c#Else Case "h"c, "H"c, "o"c, "O"c, "d"c, "D"c#End If Result = GetNumber() Case Else 'Not a number, but operator NextChar() EatWhiteSpace() If CurrentChar() = "="c Then Result = NewToken(KS.ConcatAssign) NextChar() Else Result = NewToken(KS.Concat) End If End Select Case "*"c NextChar() EatWhiteSpace() If (CurrentChar() = "="c) Then NextChar() Result = NewToken(KS.MultAssign) Else Result = NewToken(KS.Mult) End If Case "+"c NextChar() EatWhiteSpace() If (CurrentChar() = "="c) Then NextChar() Result = NewToken(KS.AddAssign) Else Result = NewToken(KS.Add) End If Case "-"c NextChar() EatWhiteSpace() If (CurrentChar() = "="c) Then NextChar() Result = NewToken(KS.MinusAssign) Else Result = NewToken(KS.Minus) End If Case "^"c NextChar() EatWhiteSpace() If (CurrentChar() = "="c) Then NextChar() Result = NewToken(KS.PowerAssign) Else Result = NewToken(KS.Power) End If Case "\"c NextChar() EatWhiteSpace() If (CurrentChar() = "="c) Then NextChar() Result = NewToken(KS.IntDivAssign) Else Result = NewToken(KS.IntDivision) End If Case "#"c 'Type characters are already scanned when they appear after a literal. 'If scanning gets here, it is not a type character. If m_TokensSeenOnLine = 0 Then Result = NewToken(KS.Numeral) NextChar() Else Result = GetDate() End If Case "/"c#If SUPPORT_CSTYLE_COMMENTS Then If (PeekChar() = "/"c OrElse PeekChar() = "*"c) Then 'Comment EatComment() Else 'Division#End If NextChar() EatWhiteSpace() If (CurrentChar() = "="c) Then NextChar() Result = NewToken(KS.RealDivAssign) Else Result = NewToken(KS.RealDivision) End If#If SUPPORT_CSTYLE_COMMENTS Then End If#End If Case " "c 'Space NextChar() If (CurrentChar() = "_"c) Then ' Dim i As Integer = 1 Do While IsWhiteSpace(PeekChars(i)) i += 1 Loop If IsNewLine(PeekChars(i)) Then NextChar() EatWhiteSpace() EatNewLine() End If End If Case nlTab ' Tab character NextChar() Case Else If IsWhiteSpace() Then NextChar() ElseIf CanStartIdentifier() Then Result = GetIdentifier() If Result.IsKeyword AndAlso Result.Equals(KS.[REM]) Then EatLine(False) Result = Nothing End If Else Compiler.Report.ShowMessage(Messages.VBNC30037) NextChar() End If End Select Loop While Token.IsSomething(Result) = False If Result.IsEndOfLine = False Then m_TokensSeenOnLine += 1 Else m_TokensSeenOnLine = 0 End If Return Result End Function Function SetMultiKeywords(ByVal current As Token) As Token Dim peeked As Token If current.Equals(KS.ConditionalEnd) Then peeked = Me.PeekExactToken() If peeked.Equals(KS.If) Then peeked = Me.NextExactToken Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalEndIf) End If If Not peeked.IsIdentifier Then Return current If peeked.Equals("Region") Then peeked = Me.NextExactToken Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalEndRegion) ElseIf peeked.Equals("ExternalSource") Then peeked = Me.NextExactToken Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalEndExternalSource) Else Return current End If End If If current.Equals(KS.End) Then peeked = Me.PeekExactToken() If Not peeked.IsKeyword Then Return current Dim attrib As KSEnumStringAttribute attrib = Enums.GetKSStringAttribute(peeked.Keyword) If Not attrib.IsMultiKeyword Then Return current peeked = Me.NextExactToken Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), attrib.MultiKeyword) End If If current.Equals(KS.Numeral) AndAlso m_TokensSeenOnLine = 1 Then peeked = Me.PeekExactToken If peeked.IsKeyword Then Select Case peeked.Keyword Case KS.If peeked = Me.NextExactToken Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalIf) Case KS.Else peeked = Me.NextExactToken Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalElse) Case KS.ElseIf peeked = Me.NextExactToken Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalElseIf) Case KS.Const peeked = Me.NextExactToken Return SetMultiKeywords(Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalConst)) Case KS.End peeked = Me.NextExactToken Return SetMultiKeywords(Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalEnd)) Case KS.End_If peeked = Me.NextExactToken Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalEndIf) Case Else Return current End Select ElseIf peeked.IsIdentifier Then If peeked.Equals("Region") Then peeked = Me.NextExactToken Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalRegion) ElseIf peeked.Equals("ExternalSource") Then peeked = Me.NextExactToken Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.ConditionalExternalSource) Else Return current End If End If End If If current.IsIdentifier AndAlso current.Equals("Custom") Then If Not Me.PeekExactToken.Equals(KS.Event) Then Return current peeked = Me.Next() Return Token.CreateKeywordToken(New Span(current.Location, peeked.Location), KS.CustomEvent) End If Return current End Function Public Sub New(ByVal Compiler As Compiler) m_Compiler = Compiler m_Files = New Generic.Queue(Of CodeFile)(m_Compiler.CommandLine.Files) NextFile() End Sub Public Sub New(ByVal Compiler As Compiler, ByVal Code As String) m_Compiler = Compiler m_Files = New Generic.Queue(Of CodeFile)() Dim cf As New CodeFile("<Internal>", "", Compiler, Code) m_Files.Enqueue(cf) Compiler.CommandLine.Files.Add(cf) NextFile() End Sub Private Sub NextFile() m_TotalLineCount += m_CurrentLine 'm_TotalCharCount += m_Code.Length m_CurrentLine = 1 m_CurrentColumn = 1 m_TokensSeenOnLine = 0 m_CurrentChar = Nothing m_PreviousChar = Nothing m_PeekedChars.Clear() If m_Files.Count > 0 Then m_CodeFile = m_Files.Dequeue() m_CodeFileIndex = CUShort(Compiler.CommandLine.Files.IndexOf(m_CodeFile)) m_Reader = m_CodeFile.CodeStream NextChar() Else m_CodeFile = Nothing 'm_Code = Nothing m_Reader = Nothing End If End Sub Private Function NextExactToken() As Token Dim result As Token If Token.IsSomething(m_PeekedExact) Then result = m_PeekedExact m_PeekedExact = Nothing Return result End If Return GetNextToken() End Function Private Function PeekExactToken() As Token If Token.IsSomething(m_PeekedExact) = False Then m_PeekedExact = NextExactToken() End If Return m_PeekedExact End Function Public Function [Next]() As Token Implements ITokenReader.Next Dim result As Token If Token.IsSomething(m_Peeked) Then m_Current = m_Peeked m_Peeked = Nothing Return m_Current End If If m_CodeFile Is Nothing Then result = Token.CreateEndOfCodeToken m_Current = result Return result End If result = NextExactToken() 'Console.WriteLine("Scanned token: " & result.FriendlyString()) result = SetMultiKeywords(result) If result.IsEndOfLineOnly Then Do While PeekExactToken().IsEndOfLineOnly result = Me.NextExactToken() 'Eat all posterior newlines Loop End If If result.IsEndOfFile() Then If Token.IsSomething(m_Current) AndAlso Not m_Current.IsEndOfLineOnly Then m_Peeked = result result = Token.CreateEndOfLineToken(m_Peeked.Location) End If NextFile() End If m_Current = result 'Console.WriteLine("Returning token: " & result.FriendlyString) Return result End Function Public Function Peek() As Token Implements ITokenReader.Peek If Token.IsSomething(m_Peeked) Then Return m_Peeked m_Peeked = [Next]() Return m_Peeked End Function Public Function Current() As Token Implements ITokenReader.Current Return m_Current End FunctionEnd Class
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?