New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Produce typed output from the parser #11
Comments
The TS compiler already does it by default. |
This is actually really easy to do. Please don't close this It's literally just a string injection |
Can you provide a sample to illustrate your idea? |
a minimal garbage implementation would accept |
I see your point and I, like you would love to have a typed grammar parser generator. Moreover, I am not big fan to encode semantics in comments (did it several times before and paid the penality of technical debt). I think it makes more sense to create something like |
it's really unfortunate that you're declining an easy immediate fix in hope of figuring out whether to create a whole new tool |
i'm confused why a plugin for peg "to generate typescript parsers" answers to the request "please give this basic typescript functionality" is "this targets javascript, not typescript" it's an easy one-off regular expression targeting the first closed parenthesis |
if i produce a patch that does the job without causing a bad software situation, will it be considered? |
Maybe I was not clear enough on my comments:
|
i don't see any need for that type to come from the markup (in fact i see a lot of reasons that it shouldn't) i think it should come from an argument to the compile call that in turn suggests it can just be dropped into the tspegjs options object as a voluntary |
would you consider an interface like this acceptable? var parser = pegjs.generate("pos_integer = sint:[0-9]+ { return Number(sint); }", {
plugins: [tspegjs]
"tspegjs": {
"noTslint": false,
"tsReturnType": "number",
"tslintIgnores": "rule1,rule2",
"customHeader": "// import lib\nimport { Lib } from 'mylib';"
}
}); |
the germane bit being the new |
Yes, options would be a suitable workaround solution if we cannot augment the base DSL.
|
individual rules don't need to be typed, as the only thing that's ever exposed to the outside is there's no circumstance under which they would ever be checked |
Sorry to disagree. Type checking if introduced, is useful for all productions: to find errors as soon as possible and not only in the top level rule. Having a unique entry point is a valid use case. But consider, there are more use cases: several entrypoint rules for parsing. If you only want to type the top level rule, consider wrapping the parse function inside another and you are done. |
So, wrapping it in a typecasting function is what I recommended in my other ticket about this, and what everyone does to cope, right now. It's very obvious. It's not the same thing, though. And it's not as good. It's not an adequate replacement. You can't use the module production; you have to wrap or edit the module. You can't call parse; you have to either wrap every parser, or make sure everything has the same wrapper even if unnecessary, or you have to monkey-patch the module. None of those are acceptable under definitely typed. At this time, I can't register A wrapper typecast isn't the same thing, and isn't as good. .
I didn't know this was possible. How does one do this? I can easily support both the single and multiple entrypoints simultaneously. I just didn't realize this was a practical use case. |
I've wanted this for a very long time, and thought PEG didn't do this. This has the potential to radically change how I use the library |
You can enable multiple entry point rules with the option |
has that been there a long time? at any rate, my new opinion is that the object member should be either a string or an object if a string, apply it to would that fit your preferences? |
wait, this just means there are more than one start rule i thought you meant this exposed more signatures than if it's still just |
Yes: that option is there for a long time. When you use that option, you use it with const res = <number> parse(inputString, { startRule: 'Integer' }); You are right, the output type of parse/2 will be the union of all types of the allowed rule start collection. And the TS compiler infers the type when possible. If we go, one step further and type intermediate production rules we are helping the type checker and finding errors faster. If we add the type info for all the needed rules, we can still generate typed wrappers per entry rule like: parseInteger(inputString: string, options: any): number {
options = options || {};
options.startRule = 'Integer';
return <number> parse(inputString, options);
}
parseBool(inputString: string, options: any): boolean {
options = options || {};
options.startRule = 'Bool';
return <boolean> parse(inputString, options);
} I usually do the following: I use to generate Abstract Syntact Trees (AST), and everything returned by rules inherits from a base class: |
oh wow, so you can explicitly specify which rule it is, and it's just not by the signature lol holy crap i've been re-hacking that on from the outside in a far less good way i'm so glad you told me about that 😅 |
this would be more powerful if it actually exposed new methods rather than just decorating the call inbound, as i don't think typescript knows about conflicting return types but also it's equally powerful to the thing i was asking for, so i'm not complaining fundamentally, if given it's still worth writing that way to skip human maintenance of the union; just making sure we're on the same page about this also i'm going to sleep after posting this; it's 2:30am here |
OK. Take a rest. Tomorrow morning take look to PR #16 |
Yes, your conclusions seems ok for me too:
|
nice this is better than the implementation i had in mind the only thing i would change - and it's fine without the change too - would be to accept either a string or an object, and if it's a string, to use the string as the return for parse but that's no big deal and i can definitely just use tyvm for sticking with this and implementing this :) |
Sorry: cannot change that. Options object is already an extension object in |
It would be nice if my typescript parser had typescript annotations on what it produced.
Consider the following toy parser example.
Dumb bad code
This allows three legal documents. It would be useful to be able to tell the plugin "announce that the result of this parse will be
number | string
."Obviously in this case this is silly, but for something that returns highly typed content, that would actually be pretty powerful.
The text was updated successfully, but these errors were encountered: