public ProcedureNode(VBAParser.SubStmtContext context, string scope, string localScope) : this(context, scope, localScope, VBProcedureKind.Sub, context.visibility(), context.ambiguousIdentifier(), null) { _argsListContext = context.argList(); _staticNode = context.STATIC(); _keyword = context.SUB(); }
public IParseTree Parse(string moduleName, string moduleCode, IParseTreeListener[] listeners, out ITokenStream outStream) { var stream = new AntlrInputStream(moduleCode); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); parser.AddErrorListener(new ExceptionErrorListener()); ParserRuleContext tree = null; try { parser.Interpreter.PredictionMode = PredictionMode.Sll; tree = parser.startRule(); } catch (Exception ex) { Logger.Warn(ex, "SLL mode failed in module {0}. Retrying using LL.", moduleName); tokens.Reset(); parser.Reset(); parser.Interpreter.PredictionMode = PredictionMode.Ll; tree = parser.startRule(); } foreach (var listener in listeners) { ParseTreeWalker.Default.Walk(listener, tree); } outStream = tokens; return(tree); }
/// <summary> /// Exports the specified component to a temporary file, loads, and then parses the exported file. /// </summary> /// <param name="component"></param> public IDictionary<Tuple<string, DeclarationType>, Attributes> Parse(VBComponent component) { var path = _exporter.Export(component); if (!File.Exists(path)) { // a document component without any code wouldn't be exported (file would be empty anyway). return new Dictionary<Tuple<string, DeclarationType>, Attributes>(); } var code = File.ReadAllText(path); File.Delete(path); var type = component.Type == vbext_ComponentType.vbext_ct_StdModule ? DeclarationType.Module : DeclarationType.Class; var listener = new AttributeListener(Tuple.Create(component.Name, type)); var stream = new AntlrInputStream(code); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); // parse tree isn't usable for declarations because // line numbers are offset due to module header and attributes // (these don't show up in the VBE, that's why we're parsing an exported file) var tree = parser.startRule(); ParseTreeWalker.Default.Walk(listener, tree); return listener.Attributes; }
/// <summary> /// Parses the given VBA expression. /// </summary> /// <param name="expression">The expression to parse. NOTE: Call statements are not supported.</param> /// <returns>The root of the parse tree.</returns> public ParserRuleContext Parse(string expression) { var stream = new AntlrInputStream(expression); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); parser.AddErrorListener(new ExceptionErrorListener()); ParserRuleContext tree = null; try { parser.Interpreter.PredictionMode = PredictionMode.Sll; tree = parser.expression(); } catch (Exception ex) { Logger.Warn(ex, "SLL mode failed for {0}. Retrying using LL.", expression); tokens.Reset(); parser.Reset(); parser.Interpreter.PredictionMode = PredictionMode.Ll; tree = parser.expression(); } return(tree); }
public IParseTree Parse(string moduleName, CommonTokenStream moduleTokens, IParseTreeListener[] listeners, BaseErrorListener errorListener, out ITokenStream outStream) { moduleTokens.Reset(); var parser = new VBAParser(moduleTokens); parser.AddErrorListener(errorListener); ParserRuleContext tree; try { parser.Interpreter.PredictionMode = PredictionMode.Sll; tree = parser.startRule(); } catch (Exception ex) { Logger.Warn(ex, "SLL mode failed in module {0}. Retrying using LL.", moduleName); moduleTokens.Reset(); parser.Reset(); parser.Interpreter.PredictionMode = PredictionMode.Ll; tree = parser.startRule(); } foreach (var listener in listeners) { ParseTreeWalker.Default.Walk(listener, tree); } outStream = moduleTokens; return(tree); }
public void ParsesEmptyForm() { var code = @" VERSION 5.00 Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} Form1 Caption = ""Form1"" ClientHeight = 2640 ClientLeft = 45 ClientTop = 375 ClientWidth = 4710 OleObjectBlob = ""Form1.frx"":0000 StartUpPosition = 1 'CenterOwner End Attribute VB_Name = ""Form1"" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False "; var stream = new AntlrInputStream(code); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); parser.ErrorListeners.Clear(); parser.ErrorListeners.Add(new ExceptionErrorListener()); var tree = parser.startRule(); Assert.IsNotNull(tree); }
private void AssertTree(VBAParser parser, ParserRuleContext root, string xpath, Predicate <ICollection <IParseTree> > assertion) { var matches = new XPath(parser, xpath).Evaluate(root); var actual = matches.Count; Assert.IsTrue(assertion(matches), string.Format("{0} matches found.", actual)); }
/// <summary> /// Exports the specified component to a temporary file, loads, and then parses the exported file. /// </summary> /// <param name="component"></param> public IDictionary <Tuple <string, DeclarationType>, Attributes> Parse(VBComponent component) { var path = _exporter.Export(component); if (!File.Exists(path)) { // a document component without any code wouldn't be exported (file would be empty anyway). return(new Dictionary <Tuple <string, DeclarationType>, Attributes>()); } var code = File.ReadAllText(path); File.Delete(path); var type = component.Type == vbext_ComponentType.vbext_ct_StdModule ? DeclarationType.ProceduralModule : DeclarationType.ClassModule; var listener = new AttributeListener(Tuple.Create(component.Name, type)); var stream = new AntlrInputStream(code); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); // parse tree isn't usable for declarations because // line numbers are offset due to module header and attributes // (these don't show up in the VBE, that's why we're parsing an exported file) var tree = parser.startRule(); ParseTreeWalker.Default.Walk(listener, tree); return(listener.Attributes); }
public override void EnterICS_S_VariableOrProcedureCall(VBAParser.ICS_S_VariableOrProcedureCallContext context) { if (context.Parent.GetType() != typeof (VBAParser.ICS_S_MemberCallContext)) { _resolver.Resolve(context); } }
public ProcedureNode(VBAParser.PropertyGetStmtContext context, string scope, string localScope) : this(context, scope, localScope, VBProcedureKind.PropertyGet, context.visibility(), context.ambiguousIdentifier(), () => context.asTypeClause()) { _argsListContext = context.argList(); _staticNode = context.STATIC(); _keyword = context.PROPERTY_GET(); _asTypeClauseContext = context.asTypeClause(); }
protected override IParseTree Parse(ITokenStream tokenStream, PredictionMode predictionMode, IParserErrorListener errorListener) { var parser = new VBAParser(tokenStream); parser.Interpreter.PredictionMode = predictionMode; parser.AddErrorListener(errorListener); return(parser.startRule()); }
/// <summary> /// Gets the <c>Accessibility</c> for a procedure member. /// </summary> private Accessibility GetProcedureAccessibility(VBAParser.VisibilityContext visibilityContext) { var visibility = visibilityContext == null ? "Implicit" // "Public" : visibilityContext.GetText(); return (Accessibility)Enum.Parse(typeof(Accessibility), visibility); }
public ProcedureNode(VBAParser.FunctionStmtContext context, string scope, string localScope) : this(context, scope, localScope, VBProcedureKind.Function, context.visibility(), context.ambiguousIdentifier(), () => context.asTypeClause()) { _argsListContext = context.argList(); _staticNode = context.STATIC(); _keyword = context.FUNCTION(); _asTypeClauseContext = context.asTypeClause(); }
private bool HasExplicitCallStatement(VBAParser.ECS_ProcedureCallContext call) { if (call == null) { return false; } var statement = call.CALL(); return statement != null && statement.Symbol.Text == Tokens.Call; }
private string DeclareExplicitVariant(VBAParser.ArgContext context, out string instruction) { if (context == null) { instruction = null; return null; } instruction = context.GetText(); return instruction + ' ' + Tokens.As + ' ' + Tokens.Variant; }
private ProcedureNode GetNode(VBAParser.PropertyGetStmtContext context) { if (context == null) { return null; } var scope = Selection.QualifiedName.ToString(); var localScope = scope + "." + context.ambiguousIdentifier().GetText(); return new ProcedureNode(context, scope, localScope); }
private Tuple <VBAParser, ParserRuleContext> Parse(string code) { var stream = new AntlrInputStream(code); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); //parser.AddErrorListener(new ExceptionErrorListener()); var root = parser.startRule(); // Useful for figuring out what XPath to use for querying the parse tree. var str = root.ToStringTree(parser); return(Tuple.Create <VBAParser, ParserRuleContext>(parser, root)); }
private IParseTree Parse(string code, out TokenStreamRewriter outRewriter) { var input = new AntlrInputStream(code); var lexer = new VBALexer(input); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); parser.AddErrorListener(new ExceptionErrorListener()); outRewriter = new TokenStreamRewriter(tokens); var result = parser.startRule(); return(result); }
private Tuple <VBAParser, ParserRuleContext> Parse(string code) { var stream = new AntlrInputStream(code); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); // Don't remove this line otherwise we won't get notified of parser failures. parser.AddErrorListener(new ExceptionErrorListener()); // If SLL fails we want to get notified ASAP so we can fix it, that's why we don't retry using LL. parser.Interpreter.PredictionMode = PredictionMode.Sll; var tree = parser.startRule(); return(Tuple.Create <VBAParser, ParserRuleContext>(parser, tree)); }
public IAnnotation Create(VBAParser.AnnotationContext context, QualifiedSelection qualifiedSelection) { string annotationName = context.annotationName().GetText(); List<string> parameters = new List<string>(); var argList = context.annotationArgList(); if (argList != null) { parameters.AddRange(argList.annotationArg().Select(arg => arg.GetText())); } Type annotationCLRType = null; if (_creators.TryGetValue(annotationName.ToUpperInvariant(), out annotationCLRType)) { return (IAnnotation)Activator.CreateInstance(annotationCLRType, qualifiedSelection, parameters); } return null; }
private static IParseTree ParseInternal(string code, IParseTreeListener[] listeners, out ITokenStream outStream) { var stream = new AntlrInputStream(code); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); parser.AddErrorListener(new ExceptionErrorListener()); foreach (var l in listeners) { parser.AddParseListener(l); } outStream = tokens; return(parser.startRule()); }
private static void LogAndReset(string logWarnMessage, Exception exception, VBAParser parser, CommonTokenStream tokenStream) { Logger.Warn(logWarnMessage); var message = "Unknown exception"; if (parser.Interpreter.PredictionMode == PredictionMode.Sll) { message = "SLL mode exception"; } else if (parser.Interpreter.PredictionMode == PredictionMode.Ll) { message = "LL mode exception"; } Logger.Debug(exception, message); tokenStream.Reset(); parser.Reset(); }
static void Main(string[] args) { var code = @" Public Sub DoSomething() Debug.Print ""hi from path 1"" If True Then MsgBox ""hello from path 2"" End If Debug.Print ""still in path 1"" End Sub".Trim(); var stream = new AntlrInputStream(code); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); parser.Interpreter.PredictionMode = PredictionMode.Sll; var tree = parser.subStmt(); Console.ReadKey(true); }
private string DeclareExplicitVariant(VBAParser.ConstSubStmtContext context, out string instruction) { if (context == null) { instruction = null; return null; } var parent = (VBAParser.ConstStmtContext) context.Parent; instruction = parent.GetText(); var constant = context.GetText(); var replacement = context.ambiguousIdentifier().GetText() + ' ' + Tokens.As + ' ' + Tokens.Variant + ' ' + context.EQ().GetText() + ' ' + context.valueStmt().GetText(); var result = instruction.Replace(constant, replacement); return result; }
static void Main(string[] args) { var code = @"Public Sub DoSomething() Debug.Print ""hi from path 1"" If True Then MsgBox ""hello from path 2"" End If Debug.Print ""still in path 1"" End Sub"; var stream = new AntlrInputStream(code); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); parser.Interpreter.PredictionMode = PredictionMode.Sll; var tree = parser.subStmt(); var visualizerHost = new VisualizerDevelopmentHost(tree, typeof(Visualizer), typeof(ObjectSource)); visualizerHost.ShowVisualizer(); }
public (IParseTree tree, ITokenStream tokenStream) Parse(string moduleName, CommonTokenStream moduleTokens, IParseTreeListener[] listeners, BaseErrorListener errorListener) { moduleTokens.Reset(); var parser = new VBAParser(moduleTokens); parser.AddErrorListener(errorListener); ParserRuleContext tree; try { parser.Interpreter.PredictionMode = PredictionMode.Sll; tree = parser.startRule(); } catch (ParsePassSyntaxErrorException syntaxErrorException) { var parsePassText = syntaxErrorException.ParsePass == ParsePass.CodePanePass ? "code pane" : "exported"; Logger.Warn($"SLL mode failed while parsing the {parsePassText} version of module {moduleName} at symbol {syntaxErrorException.OffendingSymbol.Text} at L{syntaxErrorException.LineNumber}C{syntaxErrorException.Position}. Retrying using LL."); Logger.Debug(syntaxErrorException, "SLL mode exception"); moduleTokens.Reset(); parser.Reset(); parser.Interpreter.PredictionMode = PredictionMode.Ll; tree = parser.startRule(); } catch (Exception exception) { Logger.Warn($"SLL mode failed while parsing module {moduleName}. Retrying using LL."); Logger.Debug(exception, "SLL mode exception"); moduleTokens.Reset(); parser.Reset(); parser.Interpreter.PredictionMode = PredictionMode.Ll; tree = parser.startRule(); } foreach (var listener in listeners) { ParseTreeWalker.Default.Walk(listener, tree); } return(tree, moduleTokens); }
private ProcedureNode(ParserRuleContext context, string scope, string localScope, VBProcedureKind kind, VBAParser.VisibilityContext visibility, VBAParser.AmbiguousIdentifierContext name, Func<VBAParser.AsTypeClauseContext> asType) : base(context, scope, localScope) { _kind = kind; _name = name.GetText(); _accessibility = visibility.GetAccessibility(); _visibilityContext = visibility; if (asType != null) { var returnTypeClause = asType(); _isImplicitReturnType = returnTypeClause == null; _returnType = returnTypeClause == null ? Tokens.Variant : returnTypeClause.type().GetText(); } }
/// <summary> /// Parses the supplied code. /// </summary> /// <param name="code">The code to parse.</param> /// <param name="startRule">The parser rule to begin the process with.</param> /// <param name="mode">(Optional) The parser mode to run.</param> public static (IParseTree parseTree, TokenStreamRewriter rewriter) Parse(string code, ParserStartRule startRule, ParserMode mode = ParserMode.Default) { var tokenStreamProvider = new SimpleVBAModuleTokenStreamProvider(); var tokenStream = tokenStreamProvider.Tokens(code ?? string.Empty); var parser = new VBAParser(tokenStream); try { return(ParseInternal(ParserMode.Sll, parser, tokenStream, startRule)); } catch (ParsePassSyntaxErrorException exception) { var actualMode = parser.Interpreter.PredictionMode.ToString().ToUpperInvariant(); System.Diagnostics.Debug.Assert(actualMode == ParserMode.Sll.ToString().ToUpperInvariant()); var message = $"{actualMode} mode failed while parsing the code at symbol {exception.OffendingSymbol.Text} at L{exception.LineNumber}C{exception.Position}. Retrying using LL."; LogAndReset(message, exception, parser, tokenStream); if (parser.Interpreter.PredictionMode == PredictionMode.Sll) { return(ParseInternal(ParserMode.Ll, parser, tokenStream, startRule)); } } catch (Exception exception) { var actualMode = parser.Interpreter.PredictionMode.ToString().ToUpperInvariant(); System.Diagnostics.Debug.Assert(actualMode == ParserMode.Sll.ToString().ToUpperInvariant()); var message = $"{actualMode} mode threw an exception. Retrying LL mode."; LogAndReset(message, exception, parser, tokenStream); if (parser.Interpreter.PredictionMode == PredictionMode.Sll) { return(ParseInternal(ParserMode.Ll, parser, tokenStream, startRule)); } } return(null, null); }
public string Format(string code) { var indenter = new Indenter(null, () => new IndenterSettings(true)); var indentedCode = indenter.Indent(code.Split('\n').Select(line => line.Replace("\r", string.Empty))).ToArray(); var builder = new StringBuilder(); var tokens = Tokenize(string.Join("\n", indentedCode)); var parser = new VBAParser(tokens) { Interpreter = { PredictionMode = PredictionMode.Ll } }; var listeners = new IntervalListener[] { new CommentIntervalsListener(), new AnnotationIntervalsListener(), new AttributeIntervalsListener(), new AttributeValueIntervalsListener(), }; foreach (var listener in listeners) { parser.AddParseListener(listener); } parser.startRule(); for (var i = 0; i < tokens.Size; i++) { var token = tokens.Get(i); var listener = listeners .Select(e => new { IsValidInterval = e.IsValidInterval(token, out var interval), Interval = interval, Class = e.Class })
public IParseTree Parse(string code, out ITokenStream outStream) { var input = new AntlrInputStream(code); var lexer = new VBALexer(input); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); parser.AddErrorListener(new ExceptionErrorListener()); outStream = tokens; var result = parser.startRule(); return result; }
public override void EnterAmbiguousIdentifier(VBAParser.AmbiguousIdentifierContext context) { DeclarationType type; if (!ScopingContextTypes.TryGetValue(context.Parent.GetType(), out type)) { return; } _currentScope = Tuple.Create(context.GetText(), type); }
public override void ExitExplicitCallStmt(VBAParser.ExplicitCallStmtContext context) { var procedureCall = context.eCS_ProcedureCall(); if (procedureCall != null) { if (procedureCall.CALL() != null) { _contexts.Add(context); return; } } var memberCall = context.eCS_MemberProcedureCall(); if (memberCall == null) return; if (memberCall.CALL() == null) return; _contexts.Add(context); }
public override void ExitAttributeStmt(VBAParser.AttributeStmtContext context) { var name = context.implicitCallStmt_InStmt().GetText().Trim(); var values = context.literal().Select(e => e.GetText().Replace("\"", string.Empty)).ToList(); _currentScopeAttributes.Add(name, values); }
public override void ExitModuleConfigElement(VBAParser.ModuleConfigElementContext context) { var name = context.ambiguousIdentifier().GetText(); var literal = context.literal(); var values = new[] { literal == null ? string.Empty : literal.GetText()}; _currentScopeAttributes.Add(name, values); }
public override void EnterPropertySetStmt(VBAParser.PropertySetStmtContext context) { _currentScopeAttributes = new Attributes(); _currentScope = Tuple.Create(context.ambiguousIdentifier().GetText(), DeclarationType.PropertySet); }
public override void ExitPropertySetStmt(VBAParser.PropertySetStmtContext context) { if (!string.IsNullOrEmpty(_currentScope.Item1) && _currentScopeAttributes.Any()) { _attributes.Add(_currentScope, _currentScopeAttributes); } }
public override void ExitArgList(VBAParser.ArgListContext context) { if (context.arg() != null && context.arg().Count(a => a.BYREF() != null || (a.BYREF() == null && a.BYVAL() == null)) == 1) { _contexts.Add(context); } }
public override void ExitLiteral(VBAParser.LiteralContext context) { var literal = context.STRINGLITERAL(); if (literal != null && literal.GetText() == "\"\"") { _contexts.Add(context); } }
public override void ExitLetStmt(VBAParser.LetStmtContext context) { if (context.LET() != null) { _contexts.Add(context); } }
private void AssertTree(VBAParser parser, ParserRuleContext root, string xpath, Predicate <ICollection <IParseTree> > assertion) { var matches = new XPath(parser, xpath).Evaluate(root); Assert.IsTrue(assertion(matches)); }
private static (IParseTree parseTree, TokenStreamRewriter rewriter) ParseInternal(ParserMode mode, VBAParser parser, CommonTokenStream tokenStream, ParserStartRule startRule) { if (mode == ParserMode.Ll) { parser.Interpreter.PredictionMode = PredictionMode.Ll; } else { parser.Interpreter.PredictionMode = PredictionMode.Sll; } var tree = startRule.Invoke(parser); return(tree, new TokenStreamRewriter(tokenStream)); }
private void AssertTree(VBAParser parser, ParserRuleContext root, string xpath) { AssertTree(parser, root, xpath, matches => matches.Count >= 1); }
public override void ExitModuleAttributes(VBAParser.ModuleAttributesContext context) { _attributes.Add(_currentScope, _currentScopeAttributes); }
public override void EnterWithStmt(VBAParser.WithStmtContext context) { _resolver.EnterWithBlock(context); }
private Tuple<VBAParser, ParserRuleContext> Parse(string code) { var stream = new AntlrInputStream(code); var lexer = new VBALexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new VBAParser(tokens); //parser.AddErrorListener(new ExceptionErrorListener()); var root = parser.startRule(); // Useful for figuring out what XPath to use for querying the parse tree. var str = root.ToStringTree(parser); return Tuple.Create<VBAParser, ParserRuleContext>(parser, root); }
public override void ExitWithStmt(VBAParser.WithStmtContext context) { _resolver.ExitWithBlock(); }
private void AssertTree(VBAParser parser, ParserRuleContext root, string xpath, Predicate<ICollection<IParseTree>> assertion) { var matches = new XPath(parser, xpath).Evaluate(root); Assert.IsTrue(assertion(matches)); }
public override void EnterICS_B_MemberProcedureCall(VBAParser.ICS_B_MemberProcedureCallContext context) { _resolver.Resolve(context); }