Giter Site home page Giter Site logo

AST validation [Question] about parsica HOT 7 CLOSED

parsica-php avatar parsica-php commented on June 29, 2024
AST validation [Question]

from parsica.

Comments (7)

turanct avatar turanct commented on June 29, 2024

Currently not really.

At the point that you want to map, you have a ParseResult. There you have the parsed data (the AST in your case) and the "remainder" of the input that you're parsing. Based on that remainder you can do some kind of positioning, but only if you compare it to the original input. You could make some kind of error like MySQL does:

SELECT * FROM `users` HERE `age` > 21;

would result in an error somewhat like

MySQL parse error at "HERE `age` > 21;"

which is basically the remainder.

However. Parsica knows how to make better error messages, so if you make a Parser that validates the Parsed map, you can make it fail like any other parser, and the error message will be something like

            <input>:5:10
              |
            5 | ...bcd
              |    ^— column 10
            Unexpected 'b'
            Expecting 'a'

where the "unexpected" and "expected" input indications are based on the parser's label

from parsica.

zim32 avatar zim32 commented on June 29, 2024

Thanks for reply

from parsica.

zim32 avatar zim32 commented on June 29, 2024

Unfortunately if I try to print remainder I got error: Can't read the remainder of a failed ParseResult.

from parsica.

turanct avatar turanct commented on June 29, 2024

Correct, I forgot about that.

The return value of a parser is a ParseResult, which is either a Success or a Failure. In case of a Success we have a value and a remainder, in case of a Failure we have an error message.

something like this

ParseResult a = Succeed<a, Stream> | Fail<string>

Isn't the error message what you need?

from parsica.

zim32 avatar zim32 commented on June 29, 2024

F.e. I have AST node which handles function call. f.e. sum(1,2). It is represented by FunctionCallAstNode class. This class has validate() method where it checks whether function name is valid. And I need to display some error message that this function is invalid and point to position

from parsica.

turanct avatar turanct commented on June 29, 2024

so you're doing something like this?

$functionParser = ...;

map(
    $functionParser,
    function(array $parsedValues) {
        $name = $parsedValues[0];
        $parameters = $parsedValues[1];

        return new FunctionCallAstNode($name, $parameters);
    }
);

but you want to be able to let the parser fail if the FunctionCallAstNode throws or if you call a validation method on it and it fails?

Let's first look at the types:

map :: Parser<T1> -> (T1 -> T2) -> Parser<T2>

This means that it takes a Parser that will try to parse something of type T1 and a function from T1 to T2, and it will return a Parser of type T2.

However if i'm understanding you correctly, what you're trying to accomplish is that within the mapping function, you can still decide that you're not succeeding the parse, which is not possible with map, according to the type signature.

The function that allows us to do something similar is the bind function. Let's take a look at the type signature:

bind :: Parser<T1> -> (T1 -> Parser<T2>) -> Parser<T2>

This means that bind takes a Parser that will try to parse something of type T1 and a function from T1 to a Parser (!) that will try to parse a T2, and it will return a Parser of type T2.

Which as a result means that you can "replace" the outcome of your parser based on the function you passed.

Something like this:

$functionParser = ...;

bind(
    $functionParser,
    function(array $parsedValues) {
        $name = $parsedValues[0];
        $parameters = $parsedValues[1];

        try {
            $astNode = new FunctionCallAstNode($name, $parameters);
            $astNode->validate(); // <-- this validate call should probably happen in the constructor of `FunctionCallAstNode`
        } catch (Exception $e) {
            return fail(); // <-- this will return a parser that will always fail
        }

        return pure($astNode)->label('Function Call AST Node'); // <-- this will return a parser that returns the AST Node
    }
);

does that help you?

from parsica.

zim32 avatar zim32 commented on June 29, 2024

Yeas, I think this is what I need. Thanks.
Yeas.my goal and question was how to validate something already parsed and fail it

from parsica.

Related Issues (17)

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.