Giter Site home page Giter Site logo

Comments (6)

MikePopoloski avatar MikePopoloski commented on May 24, 2024 1

Yeah, it's on my list to write some higher level documentation for the AST constructs. The key points to get you going:

  • SyntaxTree represents a "parse tree" or a "concrete syntax tree". It wraps up a lexer / preprocessor / parser for a single compilation unit. Parsing does not involve name resolution, just creating a data structure that mirrors the syntactic structure of the source.
  • The AST / "abstract syntax tree" is represented by the Compilation object, symbols, expressions, statements, etc.
  • AST nodes are lazily elaborated, so if you just call getRoot() it constructs the top level and returns immediately without creating all child nodes. In order to get all diagnostics you have to visit the whole design, which is what getAllDiagnostics() does. At that point the design is fully elaborated and subsequent visits just reuse the elaborated tree. I don't consider this step parsing; it's doing name resolution, type checking, elaborating generate loops, etc.

from slang.

udif avatar udif commented on May 24, 2024

For the sake of completeness, I edited the original issue to include the expected output when the bug is not triggered, which I forgot to include earlier.

from slang.

MikePopoloski avatar MikePopoloski commented on May 24, 2024

This is essentially an API bug; the API should not allow you to access the parameter list before the instance body has been elaborated, but currently it does. If you do something like call .members() prior to accessing the parameters things will work correctly. I'll add an accessor that enforces this.

from slang.

udif avatar udif commented on May 24, 2024

I am confused.
I was using the code below, and assumed that by the time driver.createCompilation() returns, everything is elaborated, and I'm merely traversing an already elaborated tree.

    bool ok = driver.parseAllSources();
    auto compilation = driver.createCompilation();
    auto instances = compilation->getRoot().topInstances;
    for (auto& i : instances) {
        i->visit(makeVisitor([&](auto& visitor, const InstanceSymbol& type) {...}));
    }
...

The truth is, I couldn't find any document/tutorial that explains how to use slang as a parser. I could only rely on the tools directory as examples, but apparently that's not enoug.

In sv-lang.com, you have several sections:
User Manual, which more-or-less only talks about using the slang executable, perhaps as a simple syntax checker.
Developer Guide, that has 5 sub-sections. The first is a technical build/install section, the next deal with some subclasses you don't need to know about if you use the driver. only in the last sub-section you mention the SyntaxTree class.
And finally, the API Reference which is way too low level and only serves as a reference material if you already knows what each class does and just needs a reference.

I'm left with so many questions:

  1. What is the different between a SyntaxTree and the AST Classes? When do I use one or the other?
  2. How do I just parse source, where everything is only compiled and checked for syntax correctness but not fully elaborated yet?
  3. And in contrast to the previous section, what do I need to do to start parsing an elaborated tree? Looking at the AST JSON output from slang I see that a fully elaborated design includes both final parameter values, and the expression used to derive it. How does this work for other stuff such as if/for generate? do I see both code paths, those covered by if/generate and the else branch that is not?

from slang.

udif avatar udif commented on May 24, 2024

I just independently confirmed this.

For the sake of the test, I added an additional silent driver.reportCompilation(*compilation, /* quiet */ true); call before my code, and the problems went away (I left the original reportCompilation at the end.
When you look at repotCompilation, you see that when it is in quiet mode, all it does is this code:

    for (auto& diag : compilation.getAllDiagnostics())
        diagEngine.issue(diag);

    bool succeeded = diagEngine.getNumErrors() == 0;

    std::string diagStr = diagClient->getString();
    OS::printE(fmt::format("{}", diagStr));

Apparently, as you wrote, it does more work as it gets the diagnostics messages.
My permanent solution is simply to call it once before my code.

from slang.

MikePopoloski avatar MikePopoloski commented on May 24, 2024

Fixed in b9d5423

from slang.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.