Skip to content

Commit d13f7c7

Browse files
committed
Fix parsing ambiguity between ternary expressions and lambdas
Improve nullable access syntax Fix declaration syntax details Standardize variable target naming Fix interpolated-brace token length
1 parent 244b24d commit d13f7c7

3 files changed

Lines changed: 34 additions & 19 deletions

File tree

.github/workflows/build-and-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
fetch-depth: 0
1919

2020
- name: Use Node.js
21-
uses: actions/setup-node@v6
21+
uses: actions/setup-node@v7
2222
with:
2323
# Examples: 20, 18.19, >=16.20.2, lts/Iron, lts/Hydrogen, *, latest, current, node
2424
# Ref: https://github.com/actions/setup-node#supported-version-syntax

src/syntax.grammar

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@
214214
'!'[@name=Not, group=Operator] '~'[group=Operator]
215215
'<<='[group=Operator] '<<'[group=Operator] '<='[group=Operator] '>='[group=Operator] '<'[group=Operator] '>'[group=Operator]
216216
'=='[group=Operator] '!='[@name=NotEq, group=Operator] '&&'[group=Operator] '||'[group=Operator] '&'[group=Operator] '|'[group=Operator] '^'[group=Operator]
217-
'??='[group=Operator] '??'[group=Operator] '?'[group=Operator]
217+
'??='[group=Operator] '??'[group=Operator] '?.'[group=Operator] '?[' '?'[group=Operator]
218218
'='[group=Operator] '+='[group=Operator] '-='[group=Operator] '*='[group=Operator] '/='[@name=SlashEq, group=Operator] '%='[group=Operator] '&='[group=Operator] '|='[group=Operator] '^='[group=Operator]
219219
'->'[group=Operator] '=>'[group=Operator]
220220
'$"'[group=String] '@$"'[group=String] '$@"'[group=String]
@@ -529,7 +529,7 @@ simpleName { identifier typeArgumentList? }
529529

530530
// Paren/Tuple expressions
531531

532-
ParenOrTupleExpr[@dynamicPrecedence=-1, group=Expression] { parens<~tuple csep1<ArgumentName? expr>> }
532+
ParenOrTupleExpr[@dynamicPrecedence=1, group=Expression] { parens<~tuple csep1<ArgumentName? expr>> }
533533

534534

535535
// Member access
@@ -547,10 +547,12 @@ memberCall { '.' MethodName typeArgumentList? !memberCall arguments }
547547

548548

549549
nullableMemberAccess {
550-
PrimaryExpr !memberAccess '?' '.' VarName dependentAccess*
551-
| PrimaryExpr !memberAccess '?' memberCall dependentAccess*
550+
PrimaryExpr !memberAccess '?.' VarName dependentAccess*
551+
| PrimaryExpr !memberAccess nullableMemberCall dependentAccess*
552552
}
553553

554+
nullableMemberCall { '?.' MethodName typeArgumentList? !memberCall arguments }
555+
554556

555557
dependentAccess {
556558
!memberAccess '.' VarName
@@ -575,7 +577,7 @@ elementAccess {
575577
}
576578

577579
nullableElementAccess {
578-
PrimaryNoArrayCreationExpr !elementAccess '?' brackets<argumentList> dependentAccess*
580+
PrimaryNoArrayCreationExpr !elementAccess delim<'?[' argumentList ']', 'BracketsDelim'> dependentAccess*
579581
}
580582

581583

@@ -628,7 +630,7 @@ objectInit {
628630
memberInit { InitializerTarget !assign '=' ref? initializerValue }
629631

630632
InitializerTarget[@dynamicPrecedence=1] {
631-
identifier ~id
633+
VarName
632634
| brackets<argumentList>
633635
}
634636

@@ -673,7 +675,7 @@ memberDeclarator {
673675
| memberAccess
674676
| PrimaryExpr !memberAccess '?' '.' simpleName
675677
| baseAccess
676-
| identifier !assign '=' ref? expr
678+
| VarName !assign '=' ref? expr
677679
}
678680

679681

@@ -801,7 +803,10 @@ BinaryExpr[group=Expression] {
801803
| expr !c_and '&&' expr
802804
| expr !c_or '||' expr
803805
| expr !nullcoal '??' expr
804-
| expr !ternary '?' expr ':' expr
806+
}
807+
808+
ConditionalExpr[group=Expression] {
809+
expr !ternary '?' expr ':' expr
805810
}
806811

807812

@@ -813,8 +818,17 @@ RangeExpr[group=Expression] {
813818

814819
// Lambda expr
815820

816-
LambdaExpr[@dynamicPrecedence=1, group=Expression] {
817-
(kw<'async'> | kw<'static'>)? type? anonFuncSignature !arrow '=>' anonFuncBody
821+
LambdaExpr[@dynamicPrecedence=-1, group=Expression] {
822+
parenthesizedLambdaExpr
823+
| simpleLambdaExpr
824+
}
825+
826+
parenthesizedLambdaExpr {
827+
(kw<'async'> | kw<'static'>)? type parens<csep1<ParamName ~id>> !arrow '=>' anonFuncBody
828+
}
829+
830+
simpleLambdaExpr {
831+
(kw<'async'> | kw<'static'>)? anonFuncSignature !arrow '=>' anonFuncBody
818832
}
819833

820834
AnonMethodExpr[group=Expression] {
@@ -905,6 +919,7 @@ nonAssignmentExpr {
905919
PrimaryExpr
906920
| UnaryExpr
907921
| BinaryExpr
922+
| ConditionalExpr
908923
| RangeExpr
909924
| LambdaExpr
910925
| QueryExpr
@@ -1272,9 +1287,9 @@ JumpStmt[group=Statement] {
12721287
| ThrowStmt
12731288
}
12741289

1275-
BreakStmt[group=Statement] { kw<'break'> identifier ';' }
1290+
BreakStmt[group=Statement] { kw<'break'> identifier? ';' }
12761291

1277-
ContinueStmt[group=Statement] { kw<'continue'> identifier ';' }
1292+
ContinueStmt[group=Statement] { kw<'continue'> identifier? ';' }
12781293

12791294
GotoStmt[group=Statement] {
12801295
kw<'goto'> identifier ';'
@@ -1655,7 +1670,7 @@ accessorBody {
16551670

16561671
EventDecl[group=Declaration] {
16571672
attrs? modifier* kw<'event'> type
1658-
( csep1<varDeclarator>
1673+
( csep1<varDeclarator> ';'
16591674
| memberTypeName<PropertyName> braces<eventAccessorDecls>
16601675
)
16611676
}
@@ -1729,7 +1744,7 @@ CtorDecl[group=Declaration] {
17291744
}
17301745

17311746
ctorDeclarator {
1732-
TypeIdentifier formalParams ctorInit
1747+
TypeIdentifier formalParams ctorInit?
17331748
}
17341749

17351750
ctorInit { ':' (kw<'base'> | kw<'this'>) arguments }

src/tokens.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { ExternalTokenizer, ContextTracker } from "@lezer/lr";
22
import {
3-
DocComment,
43
interpStringContent,
54
interpStringBrace,
65
interpStringEnd,
@@ -14,7 +13,8 @@ import {
1413
interpRawStringContent,
1514
interpRawStringBraceStart,
1615
interpRawStringBraceEnd,
17-
interpRawStringEnd
16+
interpRawStringEnd,
17+
DocComment
1818
} from "./syntax.grammar.terms";
1919

2020
const
@@ -91,7 +91,7 @@ export const interpString = new ExternalTokenizer(input => {
9191

9292
case braceL:
9393
if (input.peek(1) === braceL) { input.acceptToken(interpStringContent, 2); }
94-
else { input.acceptToken(interpStringBrace); }
94+
else { input.acceptToken(interpStringBrace, 1); }
9595
return;
9696

9797
case braceR:
@@ -125,7 +125,7 @@ export const interpVString = new ExternalTokenizer(input => {
125125

126126
case braceL:
127127
if (input.peek(1) === braceL) { input.acceptToken(interpVStringContent, 2); }
128-
else { input.acceptToken(interpVStringBrace); }
128+
else { input.acceptToken(interpVStringBrace, 1); }
129129
return;
130130

131131
case braceR:

0 commit comments

Comments
 (0)