private new LexerToken ScanIdentifierOrKeyword(string line, ref int startAt) { var token = Lexer_Base.ScanIdentifierOrKeyword(line, ref startAt); if (token != null && token.tokenKind == LexerToken.Kind.Keyword && !IsKeyword(token.text) && !IsBuiltInType(token.text)) { token.tokenKind = LexerToken.Kind.Identifier; } return(token); }
private void Preprocess(string sData, ref int iIndex, FormatedLine formatedLine) { TryScan_Whitespace(sData, ref iIndex, formatedLine); var error = false; var commentsOnly = false; int iLength = sData.Length; List <LexerToken> tokens = formatedLine.tokens; LexerToken token = ScanWord(sData, ref iIndex); if (!preprocessorKeywords.Contains(token.text)) { token.tokenKind = LexerToken.Kind.PreprocessorDirectiveExpected; tokens.Add(token); token.formatedLine = formatedLine; error = true; } else { token.tokenKind = LexerToken.Kind.Preprocessor; tokens.Add(token); token.formatedLine = formatedLine; TryScan_Whitespace(sData, ref iIndex, formatedLine); switch (token.text) { case "if": if (ParsePPOrExpression(sData, formatedLine, ref iIndex) && formatedLine.regionTree.kind <= RegionTree.Kind.LastActive) { OpenRegion(formatedLine, RegionTree.Kind.If); } else { OpenRegion(formatedLine, RegionTree.Kind.InactiveIf); } commentsOnly = true; break; case "elif": bool active = ParsePPOrExpression(sData, formatedLine, ref iIndex); switch (formatedLine.regionTree.kind) { case RegionTree.Kind.If: case RegionTree.Kind.Elif: case RegionTree.Kind.InactiveElif: OpenRegion(formatedLine, RegionTree.Kind.InactiveElif); break; case RegionTree.Kind.InactiveIf: if (active && formatedLine.regionTree.kind <= RegionTree.Kind.LastActive) { OpenRegion(formatedLine, RegionTree.Kind.Elif); } else { OpenRegion(formatedLine, RegionTree.Kind.InactiveElif); } break; default: token.tokenKind = LexerToken.Kind.PreprocessorUnexpectedDirective; break; } break; case "else": if (formatedLine.regionTree.kind == RegionTree.Kind.If || formatedLine.regionTree.kind == RegionTree.Kind.Elif) { OpenRegion(formatedLine, RegionTree.Kind.InactiveElse); } else if (formatedLine.regionTree.kind == RegionTree.Kind.InactiveIf || formatedLine.regionTree.kind == RegionTree.Kind.InactiveElif) { if (formatedLine.regionTree.parent.kind > RegionTree.Kind.LastActive) { OpenRegion(formatedLine, RegionTree.Kind.InactiveElse); } else { OpenRegion(formatedLine, RegionTree.Kind.Else); } } else { token.tokenKind = LexerToken.Kind.PreprocessorUnexpectedDirective; } break; case "endif": if (formatedLine.regionTree.kind == RegionTree.Kind.If || formatedLine.regionTree.kind == RegionTree.Kind.Elif || formatedLine.regionTree.kind == RegionTree.Kind.Else || formatedLine.regionTree.kind == RegionTree.Kind.InactiveIf || formatedLine.regionTree.kind == RegionTree.Kind.InactiveElif || formatedLine.regionTree.kind == RegionTree.Kind.InactiveElse) { CloseRegion(formatedLine); } else { token.tokenKind = LexerToken.Kind.PreprocessorUnexpectedDirective; } break; case "define": case "undef": { var symbol = Lexer_Base.ScanIdentifierOrKeyword(sData, ref iIndex); if (symbol != null && symbol.text != "true" && symbol.text != "false") { symbol.tokenKind = LexerToken.Kind.PreprocessorSymbol; formatedLine.tokens.Add(symbol); symbol.formatedLine = formatedLine; scriptDefinesChanged = true; var inactive = formatedLine.regionTree.kind > RegionTree.Kind.LastActive; if (!inactive) { if (token.text == "define") { if (!CompilationDefines.Contains(symbol.text)) { CompilationDefines.Add(symbol.text); } } else if (CompilationDefines.Contains(symbol.text)) { CompilationDefines.Remove(symbol.text); } } } } break; case "region": if (formatedLine.regionTree.kind > RegionTree.Kind.LastActive) { OpenRegion(formatedLine, RegionTree.Kind.InactiveRegion); } else { OpenRegion(formatedLine, RegionTree.Kind.Region); } break; case "endregion": if (formatedLine.regionTree.kind == RegionTree.Kind.Region || formatedLine.regionTree.kind == RegionTree.Kind.InactiveRegion) { CloseRegion(formatedLine); } else { token.tokenKind = LexerToken.Kind.PreprocessorUnexpectedDirective; } break; case "error": case "warning": break; } } switch (token.text) { case "region": case "endregion": case "error": case "warning": TryScan_Whitespace(sData, ref iIndex, formatedLine); if (iIndex < iLength) { var textArgument = sData.Substring(iIndex); textArgument.TrimEnd(new[] { ' ', '\t' }); tokens.Add(new LexerToken(LexerToken.Kind.PreprocessorArguments, textArgument) { formatedLine = formatedLine }); iIndex = iLength - textArgument.Length; if (iIndex < iLength) { tokens.Add(new LexerToken(LexerToken.Kind.Whitespace, sData.Substring(iIndex)) { formatedLine = formatedLine }); } } return; } while (iIndex < iLength) { if (TryScan_Whitespace(sData, ref iIndex, formatedLine)) { continue; } var firstChar = sData[iIndex]; if (iIndex < iLength - 1 && firstChar == '/' && sData[iIndex + 1] == '/') { tokens.Add(new LexerToken(LexerToken.Kind.Comment, sData.Substring(iIndex)) { formatedLine = formatedLine }); break; } else if (commentsOnly) { tokens.Add(new LexerToken(LexerToken.Kind.PreprocessorCommentExpected, sData.Substring(iIndex)) { formatedLine = formatedLine }); break; } if (char.IsLetterOrDigit(firstChar) || firstChar == '_') { token = ScanWord(sData, ref iIndex); token.tokenKind = LexerToken.Kind.PreprocessorArguments; tokens.Add(token); token.formatedLine = formatedLine; } else if (firstChar == '"') { token = ScanStringLiteral(sData, ref iIndex); token.tokenKind = LexerToken.Kind.PreprocessorArguments; tokens.Add(token); token.formatedLine = formatedLine; } else if (firstChar == '\'') { token = ScanCharLiteral(sData, ref iIndex); token.tokenKind = LexerToken.Kind.PreprocessorArguments; tokens.Add(token); token.formatedLine = formatedLine; } else { token = new LexerToken(LexerToken.Kind.PreprocessorArguments, firstChar.ToString()) { formatedLine = formatedLine }; tokens.Add(token); ++iIndex; } if (error) { token.tokenKind = LexerToken.Kind.PreprocessorDirectiveExpected; } } }