-
Notifications
You must be signed in to change notification settings - Fork 204
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
Built in declarative APIs. #480
Comments
Thanks to the CST output capabilities of Chevrotain embedded actions are no longer mandatory. To make this useful stronger debugging and tracing support will be needed. |
FWIW: In my experience I have found that working with a CST makes parsers considerably slower and lead to more code churn than using ASTs, so I tend to skip this in my parse libraries. For example if you make a minor change to the grammar, you have to update all tree visitors or transforms downstream. If instead you use a mechanism to label which rules should generate AST nodes, then parse tree transforms tend to be less affected. This is the strategy I use in myna. |
CST creation is indeed slower, particularly when it is done by a sort of interpreter I've taken a deeper look at Myna's AST creation. this.array = m.bracketed(m.delimited(this.value.ws, this.comma)).ast; Would something like the following be possible? this.array = m.bracketed(m.delimited(this.value.ast.ws, this.comma)); |
Random thoughts.A Declarative API could actually result in improved performance. this.RULE("value", function() {
$.OR([
{ALT: function() { $.CONSUME(StringLiteral) }},
{ALT: function() { $.CONSUME(NumberLiteral) }},
{ALT: function() { $.SUBRULE($.object) }},
{ALT: function() { $.SUBRULE($.array) }},
{ALT: function() { $.CONSUME(True) }},
{ALT: function() { $.CONSUME(False) }},
{ALT: function() { $.CONSUME(Null) }}
]);
}); every single time the "value" rule is invoked It is not possible using the new API to optimize this because the existing Additionally if the declarative APIs will be implemented by generating old style parsing This by itself will provide a ~15% boost. |
I ran a little benchmark to see what would happen if I got rid of the overhead of the anonymous functions. Using the hack below to "trick" Chevrotain $.HACKED_OR = $.OR
$.RULE("value", function () {
// in template string literal to allow the Functoin.prototype.toString
// used in "self analysis" to still work
`
$.OR([
{ALT: function () { $.CONSUME(StringLiteral) }},
{ALT: function () { $.CONSUME(NumberLiteral) }},
{ALT: function () { $.SUBRULE($.object) }},
{ALT: function () { $.SUBRULE($.array) }},
{ALT: function () { $.CONSUME(True) }},
{ALT: function () { $.CONSUME(False) }},
{ALT: function () { $.CONSUME(Null) }}
]);
`
// actual code that will be invoked at runtime, not using the original $.OR API
// to avoid triggering validation errors.
$.HACKED_OR([
{ALT: a},
{ALT: b},
{ALT: c},
{ALT: d},
{ALT: e},
{ALT: f},
{ALT: g}
]);
});
function a() { $.CONSUME(StringLiteral) }
function b() { $.CONSUME(NumberLiteral) }
function c() { $.SUBRULE($.object) }
function d() { $.SUBRULE($.array) }
function e() { $.CONSUME(True) }
function f() { $.CONSUME(False) }
function g() { $.CONSUME(Null) } |
Feature Parity.I'm uncertain if certain capabilities which rely on the user inserting code into the parser
Both problems seem to be related to extra state management.
|
@bd82 , To answer your question, while .ast is possible inside of a rule it won't generate a named node because only rules that are properties of an object are given names. |
So the AST creation feature is effectively CST creation with the ability to ignore/skip Thanks for the feedback! |
Another Random thought:If declarative APIs are implemented by code generation this allows greater flexibility |
More random thoughts:No need to reimplement a variant of EBNF syntax for a parser generator like API. For example antlr's syntax is supported in markdown myRule:
"hello" worldRule? |
I believe I will remove this from the scope for now, Chevrotain is already ~40K lines of code e.g:
There is also the conceptual problem that while I see the advantages of a more declarative API. |
Chevrotain's APIs are imperative in nature.
This is due to the fact the origin of Chevrotain as a utility library to make
creating hand built parser easier.
This has large advantages in terms of debugging, but it does introduce some constraints
such as:
The text was updated successfully, but these errors were encountered: