Conversation
|
wondering about the common lexical scope and an option to have a lexer per entry rule |
78988e1 to
9f6d652
Compare
There was a problem hiding this comment.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.
| Benchmark suite | Current: 40d792c | Previous: d803417 | Ratio |
|---|---|---|---|
BenchmarkWorkspaceCycle (typefox.dev/fastbelt/examples/statemachine) - MB/s |
13.16 MB/s |
5.21 MB/s |
2.53 |
This comment was automatically generated by workflow using github-action-benchmark.
|
@cdietrich Thanks for the input. I plan to finish implementing this once #127 lands, since it refactors a lot of the lexer infrastructure. |
ssmifi
left a comment
There was a problem hiding this comment.
Looks solid, thanks. I have a couple of questions to get a better understanding before merging and some documentation seems to be stale.
| @@ -55,7 +55,7 @@ func runGenerateCLI(opts generateOptions) error { | |||
| } | |||
|
|
|||
| sc := grammar.CreateServices() | |||
There was a problem hiding this comment.
Nice separation.
Question: The following lines are conceptionally doing for one file what parseAndMerge and reportDiagnostic do generically now. I was wondering if we can de-duplicate some code here and use come common helper?
|
|
||
| type DocumentMatcher func(uri URI) bool | ||
|
|
||
| // DocumentFilter matches a document by LSP language id and/or a glob over the |
| "typefox.dev/fastbelt/util/service" | ||
| ) | ||
|
|
||
| type DocumentMatcher func(uri URI) bool |
There was a problem hiding this comment.
As this is an exported symbol, it should probably get a doc, even if self-explanatory.
| // documents. | ||
| type Language struct { | ||
| Entry string | ||
| LanguageID string |
There was a problem hiding this comment.
Or combine it within the syntax of the entry rule:
entry XRule on mode YMode: ...
Omitting on mode YMode falls back to the default mode.
There was a problem hiding this comment.
Agree with @Lotes.
However, this idea mixes concepts that don't belong together:
entry XRule on mode YMode: ...
I don't support this proposal.
There was a problem hiding this comment.
Yes, I would keep the entry lexer mode local to the Language struct value.
| @@ -0,0 +1,15 @@ | |||
| grammar MultilangModel | |||
There was a problem hiding this comment.
I thought this PR is also about multi file support.
But yes, this might be a smaller step towards this direction.
| DocStateLocalSymbols // 0x0010 | ||
| // DocStateLinked marks that cross-references were linked. | ||
| DocStateLinked // 0x0010 | ||
| DocStateLinked // 0x0020 |
There was a problem hiding this comment.
Why the comment "//0x0001" ...? Who needs it?
The only reason in my eyes: to not forget the flag nature of this constant group.
Alternative: Rename the constants to reflect the flag nature.
- DocStateFlagLinked
- DocStateBitMaskLinked
sailingKieler
left a comment
There was a problem hiding this comment.
Thanks @msujew for this effort! Great step forward.
Actually, I doubt the necessity and benefit for the additional language build customization for the multi language aspect. Other concerns might justify that.
I left some comments inline.
The other aspect is the documentation of impact of multiple entry rules on the lexer.
That is something I didn't expect in the first place, and others (newbies) probably also don't. See also below.
|
|
||
| // LanguageSelector resolves a document URI to the index of the owning language | ||
| // (into the configured languages), or -1 if none match. | ||
| type LanguageSelector interface { |
There was a problem hiding this comment.
On the first impression this felt a bit over engineered to me.
After thinking about it for a moment or tow, I came to the conclusion that this mainly bridges the lack of multi-bindings in our dependency container, here, multiple DocumentSelectors, correct?
I would appreciate a corresponding hint on that here in the docs.
| } | ||
| if err := ctx.Build(); err != nil { | ||
| log.Fatalf("multilang generation failed: %v", err) | ||
| } |
There was a problem hiding this comment.
Is this route really needed for the multi lange setup?
Why not having it configured manually in the scaffold provided services.go, as you did in this language impl? Coding agents will be able to do that shortly.
Hence, I'm favor of skipping the generation in service_generator.go.
| @@ -55,7 +55,7 @@ func runGenerateCLI(opts generateOptions) error { | |||
| } | |||
|
|
|||
| sc := grammar.CreateServices() | |||
| n.AppendLine(")") | ||
| }) | ||
| n.AppendLine("}") | ||
| } |
There was a problem hiding this comment.
I don't see the need/benefit of this, see also my remark in languages/multilang/gen/main.go.
Having it codified in services.go based on an initial template should be fine IMHO.
The single rule validation in cmd/fastbelt/generator.go could be suppressed by a cmd line switch that is to be added in the // go:generate ... config.
| // documents. | ||
| type Language struct { | ||
| Entry string | ||
| LanguageID string |
There was a problem hiding this comment.
Agree with @Lotes.
However, this idea mixes concepts that don't belong together:
entry XRule on mode YMode: ...
I don't support this proposal.
| } | ||
| } | ||
| }) | ||
| nn.AppendLine("},") |
There was a problem hiding this comment.
uuuhhh this is sophisticated.
This should be documented very prominently, specifically the fact parser (entry) rule names/ids are used in the lexer setup.
| // Grammars with multiple configured languages use [NewMultiLanguageLexer] | ||
| // instead, passing one token type list per language; at lex time the document | ||
| // is routed to its language's token set via [core.LanguageSelector], mirroring | ||
| // the generated parser's entry rule dispatch. |
There was a problem hiding this comment.
I lexer_gen.go I asked for prominent documentation of this fact.
Okay, it is already stated here but I didn't get the consequences of this fairly compact statement.
I strongly advocate to extend it, explicit state that reachable token sets from each entry rules are determined.
That this way ambiguities among the entire token definitions set are tolerated as long the sets reachable from the entry rules a unambiguous (enough).
And that this is also beneficial performance wise (less dispatches)
There was a problem hiding this comment.
Let's adhere the common pattern of naming this file doc.go.
//go:generate go run ./gen
can go to services.go, like in the other languages.
Closes #96
Does as the title says, similar to how it is outlined in the issue:
fastbelt/cmdpackage adopters can use to write their own CLIs to generate Fastbelt code.LanguageSelectorservice that is used to determine during runtime what language a URI/document belongs to.multilangexample that shows that this is working as expected (including parser, lexer and completion tests).FYI, while this has a
Pluginsfield in the API, plugins aren't actually supported in this PR. This will need a follow-up.