/// <summary> /// Returns Scope of the given line /// </summary> /// <returns></returns> public static ParsedScopeItem GetScopeOfLine(int line) { ParsedScopeItem output = null; DoInLock(() => { output = _lineInfo != null && _lineInfo.ContainsKey(line) ? _lineInfo[line].Scope : null; }); return(output); }
/// <summary> /// Parses a file. /// Remarks : it doesn't parse the document against known words since this is only useful for /// the CURRENT document and not for the others /// </summary> private static ParserVisitor ParseFile(string filePath, ParsedScopeItem scopeItem) { ParserVisitor parserVisitor; // did we already parsed this file in a previous parse session? (if we are in CodeExplorerDisplayExternalItems mode we need to parse it again anyway) if (SavedPersistent.ContainsKey(filePath)) { parserVisitor = SavedPersistent[filePath]; } else { // Parse it var ablParser = new Parser(Utils.ReadAllText(filePath), filePath, scopeItem, false); parserVisitor = new ParserVisitor(false); ablParser.Accept(parserVisitor); } return(parserVisitor); }
/// <summary> /// Parses a file. /// Remarks : it doesn't parse the document against known words since this is only useful for /// the CURRENT document and not for the others /// </summary> private static ParserVisitor ParseFile(string fileName, ParsedScopeItem scopeItem) { ParserVisitor parserVisitor; // did we already parsed this file in a previous parse session? if (_savedParserVisitors.ContainsKey(fileName)) { parserVisitor = _savedParserVisitors[fileName]; } else { // Parse it var ablParser = new Parser(Utils.ReadAllText(fileName), fileName, scopeItem); parserVisitor = new ParserVisitor(false, Path.GetFileName(fileName), ablParser.LineInfo); ablParser.Accept(parserVisitor); // save it for future uses _savedParserVisitors.Add(fileName, parserVisitor); } return(parserVisitor); }
/// <summary> /// Parses given file and load its function + procedures has persistent so they are /// accessible from the autocompletion list /// Set runPersistentIsInFile = false (default) to add items only to the completion list, /// set to true to also display proc/func in the code explorer tree if asked /// </summary> private void LoadProcPersistent(string fileName, ParsedScopeItem scopeItem) { ParserVisitor parserVisitor = ParseFile(fileName, scopeItem); // add info to the completion list var listToAdd = parserVisitor.ParsedCompletionItemsList.Where(data => data is FunctionCompletionItem || data is ProcedureCompletionItem).ToList(); foreach (var completionData in listToAdd) { completionData.Flags = completionData.Flags | ParseFlag.Persistent; } _parsedCompletionItemsList.AddRange(listToAdd); // add info to the code explorer if (Config.Instance.CodeExplorerDisplayPersistentItems) { foreach (var codeExplorerItem in parserVisitor.ParsedExplorerItemsList.SelectMany(item => item.Children ?? new List <FilteredTypeTreeListItem>()).Cast <CodeItem>().Where(item => item is FunctionCodeItem || item is ProcedureCodeItem)) { codeExplorerItem.Flags = codeExplorerItem.Flags | ParseFlag.Persistent; PushToCodeExplorer(codeExplorerItem is FunctionCodeItem ? GetExplorerListNode("Functions", CodeExplorerIconType.Function) : GetExplorerListNode("Procedures", CodeExplorerIconType.Procedure), codeExplorerItem); } } }
/// <summary> /// Parses given file and load its function + procedures has persistent so they are /// accessible from the autocompletion list /// Set runPersistentIsInFile = false (default) to add items only to the completion list, /// set to true to also display proc/func in the code explorer tree if asked /// </summary> public void LoadProcPersistent(string fileName, ParsedScopeItem scopeItem) { ParserVisitor parserVisitor = ParseFile(fileName, scopeItem); // add info to the completion list var listToAdd = parserVisitor._parsedCompletionItemsList.Where(data => (data.Type == CompletionType.Function || data.Type == CompletionType.Procedure)).ToList(); foreach (var completionData in listToAdd) { completionData.Flag = completionData.Flag | ParseFlag.Persistent; } _parsedCompletionItemsList.AddRange(listToAdd); // add info to the code explorer if (Config.Instance.CodeExplorerDisplayExternalItems) { var listExpToAdd = parserVisitor._parsedExplorerItemsList.Where(item => item.Branch == CodeExplorerBranch.Procedure || item.Branch == CodeExplorerBranch.Function).ToList(); foreach (var codeExplorerItem in listExpToAdd) { codeExplorerItem.Flag = codeExplorerItem.Flag | CodeExplorerFlag.Persistent; } _parsedExplorerItemsList.AddRange(listExpToAdd); } }
/// <summary> /// Parses a text into a list of parsedItems /// </summary> public Parser(ProLexer proLexer, string filePathBeingParsed, ParsedScopeItem defaultScope, bool matchKnownWords) { // process inputs _filePathBeingParsed = filePathBeingParsed; _matchKnownWords = matchKnownWords && KnownStaticItems != null; // the first of this list represents the file currently being parsed _parsedIncludes.Add( new ParsedIncludeFile( "root", new TokenEos(null, 0, 0, 0, 0), // the preprocessed variable {0} equals to the filename... new Dictionary <string, List <Token> >(StringComparer.CurrentCultureIgnoreCase) { { "0", new List <Token> { new TokenWord(Path.GetFileName(FilePathBeingParsed), 0, 0, 0, 0) } } }, _filePathBeingParsed, null) ); // init context _context = new ParseContext { BlockStack = new Stack <BlockInfo>(), PreProcIfStack = new Stack <ParsedPreProcBlock>(), UibBlockStack = new Stack <ParsedPreProcBlock>() }; // create root item if (defaultScope == null) { var rootToken = new TokenEos(null, 0, 0, 0, 0); rootToken.OwnerNumber = 0; _rootScope = new ParsedFile("Root", rootToken); AddParsedItem(_rootScope, rootToken.OwnerNumber); } else { _rootScope = defaultScope; } _context.Scope = _rootScope; // Analyze _tokenList = proLexer.GetTokensList; _tokenCount = _tokenList.Count; ReplacePreProcVariablesAhead(1); // replaces a preproc var {&x} at token position 0 ReplacePreProcVariablesAhead(2); // replaces a preproc var {&x} at token position 1 while (MoveNext()) { try { Analyze(); } catch (Exception e) { ErrorHandler.LogError(e, "Error while parsing the following file : " + filePathBeingParsed); } } // add missing values to the line dictionary var current = new LineInfo(GetCurrentDepth(), _rootScope); for (int i = proLexer.MaxLine; i >= 0; i--) { if (_lineInfo.ContainsKey(i)) { current = _lineInfo[i]; } else { _lineInfo.Add(i, current); } } // check that we match an &ENDIF for each &IF if (_context.PreProcIfStack.Count > 0) { _parserErrors.Add(new ParserError(ParserErrorType.MismatchNumberOfIfEndIf, PeekAt(0), _context.PreProcIfStack.Count, _parsedIncludes)); } // dispose _context.BlockStack.Clear(); _context.PreProcIfStack.Clear(); _context.UibBlockStack.Clear(); _context = null; _tokenList = null; // if we are parsing an include file that was saved for later use, update it if (SavedLexerInclude.ContainsKey(filePathBeingParsed)) { SavedLexerInclude.Remove(filePathBeingParsed); } }
/// <summary> /// Constructor with a string instead of a proLexer /// </summary> public Parser(string data, string filePathBeingParsed, ParsedScopeItem defaultScope, bool matchKnownWords) : this(NewLexerFromData(data), filePathBeingParsed, defaultScope, matchKnownWords) { }
public LineInfo(int blockDepth, ParsedScopeItem scope) { BlockDepth = blockDepth; Scope = scope; }
/// <summary> /// Parses a text into a list of parsedItems /// </summary> public Parser(Lexer lexer, string filePathBeingParsed, ParsedScopeItem defaultScope, bool matchKnownWords = false) { // process inputs _filePathBeingParsed = filePathBeingParsed; _matchKnownWords = matchKnownWords && _knownStaticItems != null; // init context _context = new ParseContext { BlockStack = new Stack<BlockInfo>(), PreProcIfStack = new Stack<ParsedPreProcBlock>(), UibBlockStack = new Stack<ParsedPreProcBlock>() }; // create root item if (defaultScope == null) { _rootScope = new ParsedFile("Root", new TokenEos(null, 0, 0, 0, 0)); AddParsedItem(_rootScope); } else _rootScope = defaultScope; _context.Scope = _rootScope; // parse _lexer = lexer; while (MoveNext()) { Analyze(); } // add missing values to the line dictionnary var current = new LineInfo(GetCurrentDepth(), _rootScope); for (int i = _lexer.MaxLine - 1; i >= 0; i--) { if (_lineInfo.ContainsKey(i)) current = _lineInfo[i]; else _lineInfo.Add(i, current); } // check that we match an &ENDIF for each &IF if (_context.PreProcIfStack.Count > 0) _parserErrors.Add(new ParserError(ParserErrorType.MismatchNumberOfIfEndIf, PeekAt(0), _context.PreProcIfStack.Count)); // dispose _context.BlockStack.Clear(); _context.PreProcIfStack.Clear(); _context.UibBlockStack.Clear(); _context = null; _lexer = null; }
/// <summary> /// Constructor with a string instead of a lexer /// </summary> public Parser(string data, string filePathBeingParsed, ParsedScopeItem defaultScope, bool matchKnownWords = false) : this(NewLexerFromData(data), filePathBeingParsed, defaultScope, matchKnownWords) { }