deploy: v0.12 存档迁移+考古日志滚动条

This commit is contained in:
2026-06-24 03:04:38 +00:00
parent 4831505ef9
commit b4c6111516
58986 changed files with 7569452 additions and 31667 deletions
+75
View File
@@ -0,0 +1,75 @@
## 1.0.2 (2023-12-28)
### Bug fixes
Tag comments and strings as isolating for the purpose of bidirectional text.
## 1.0.1 (2023-07-03)
### Bug fixes
Make the package work with new TS resolution styles.
## 1.0.0 (2022-06-06)
### New features
First stable version.
## 0.16.1 (2022-04-26)
### Bug fixes
Allow arbitrary bracketed token trees to appear after attribute names
## 0.16.0 (2022-04-20)
### Breaking changes
Move to 0.16 serialized parser format.
### New features
The parser now includes syntax highlighting information in its node types.
## 0.15.1 (2022-03-21)
### Bug fixes
Allow arbitrary token trees after `=` in attributes.
## 0.15.0 (2021-08-11)
### Breaking changes
The module's name changed from `lezer-rust` to `@lezer/rust`.
Upgrade to the 0.15.0 lezer interfaces.
## 0.13.1 (2020-12-04)
### Bug fixes
Fix versions of lezer packages depended on.
## 0.13.0 (2020-12-04)
## 0.12.0 (2020-10-23)
### Breaking changes
Adjust to changed serialized parser format.
## 0.11.1 (2020-10-01)
### New features
Expression statements are now wrapped in an `ExpressionStatement` node.
The package now provides TypeScript type definitions.
## 0.11.0 (2020-09-29)
### Breaking changes
First numbered release.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (C) 2018 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+9
View File
@@ -0,0 +1,9 @@
# @lezer/rust
This is a Rust grammar for the
[Lezer](https://lezer.codemirror.net/) parser system.
The grammar used is based in part on the corresponding
[tree-sitter grammar](https://github.com/tree-sitter/tree-sitter-rust).
The code is licensed under an MIT license.
+155
View File
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
import {LRParser} from "@lezer/lr"
export const parser: LRParser
+3
View File
@@ -0,0 +1,3 @@
import {LRParser} from "@lezer/lr"
export const parser: LRParser
+151
View File
File diff suppressed because one or more lines are too long
+36
View File
@@ -0,0 +1,36 @@
{
"name": "@lezer/rust",
"version": "1.0.2",
"description": "Lezer-based Rust grammar",
"main": "dist/index.cjs",
"type": "module",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"module": "dist/index.js",
"types": "dist/index.d.ts",
"author": "Marijn Haverbeke <marijn@haverbeke.berlin>",
"license": "MIT",
"devDependencies": {
"@lezer/generator": "^1.0.0",
"mocha": "^10.2.0",
"rollup": "^2.52.2",
"@rollup/plugin-node-resolve": "^9.0.0"
},
"dependencies": {
"@lezer/common": "^1.2.0",
"@lezer/lr": "^1.0.0",
"@lezer/highlight": "^1.0.0"
},
"repository": {
"type" : "git",
"url" : "https://github.com/lezer-parser/rust.git"
},
"scripts": {
"build": "lezer-generator src/rust.grammar -o src/parser && rollup -c",
"build-debug": "lezer-generator src/rust.grammar --names -o src/parser && rollup -c",
"prepare": "npm run build",
"test": "mocha test/test-*.js"
}
}
+16
View File
@@ -0,0 +1,16 @@
import {nodeResolve} from "@rollup/plugin-node-resolve"
export default {
input: "./src/parser.js",
output: [{
format: "cjs",
file: "./dist/index.cjs"
}, {
format: "es",
file: "./dist/index.js"
}],
external(id) { return !/^[\.\/]/.test(id) },
plugins: [
nodeResolve()
]
}
+46
View File
@@ -0,0 +1,46 @@
import {styleTags, tags as t} from "@lezer/highlight"
export const rustHighlighting = styleTags({
"const macro_rules struct union enum type fn impl trait let static": t.definitionKeyword,
"mod use crate": t.moduleKeyword,
"pub unsafe async mut extern default move": t.modifier,
"for if else loop while match continue break return await": t.controlKeyword,
"as in ref": t.operatorKeyword,
"where _ crate super dyn": t.keyword,
"self": t.self,
String: t.string,
Char: t.character,
RawString: t.special(t.string),
Boolean: t.bool,
Identifier: t.variableName,
"CallExpression/Identifier": t.function(t.variableName),
BoundIdentifier: t.definition(t.variableName),
"FunctionItem/BoundIdentifier": t.function(t.definition(t.variableName)),
LoopLabel: t.labelName,
FieldIdentifier: t.propertyName,
"CallExpression/FieldExpression/FieldIdentifier": t.function(t.propertyName),
Lifetime: t.special(t.variableName),
ScopeIdentifier: t.namespace,
TypeIdentifier: t.typeName,
"MacroInvocation/Identifier MacroInvocation/ScopedIdentifier/Identifier": t.macroName,
"MacroInvocation/TypeIdentifier MacroInvocation/ScopedIdentifier/TypeIdentifier": t.macroName,
"\"!\"": t.macroName,
UpdateOp: t.updateOperator,
LineComment: t.lineComment,
BlockComment: t.blockComment,
Integer: t.integer,
Float: t.float,
ArithOp: t.arithmeticOperator,
LogicOp: t.logicOperator,
BitOp: t.bitwiseOperator,
CompareOp: t.compareOperator,
"=": t.definitionOperator,
".. ... => ->": t.punctuation,
"( )": t.paren,
"[ ]": t.squareBracket,
"{ }": t.brace,
". DerefOp": t.derefOperator,
"&": t.operator,
", ; ::": t.separator,
"Attribute/...": t.meta,
})
+27
View File
File diff suppressed because one or more lines are too long
+68
View File
@@ -0,0 +1,68 @@
// This file was generated by lezer-generator. You probably shouldn't edit it.
export const
closureParamDelim = 1,
tpOpen = 2,
tpClose = 3,
RawString = 4,
Float = 5,
LineComment = 6,
BlockComment = 7,
SourceFile = 8,
InnerAttribute = 10,
MetaItem = 13,
Metavariable = 15,
Identifier = 18,
QualifiedScope = 21,
TypeIdentifier = 26,
ScopeIdentifier = 28,
TypeArgList = 29,
TypeBinding = 30,
Lifetime = 32,
String = 33,
Escape = 34,
Char = 35,
Integer = 37,
Block = 40,
Vis = 43,
BoundIdentifier = 49,
IfExpression = 56,
FieldPattern = 70,
FieldIdentifier = 73,
ParenthesizedTokens = 85,
tokenIdentifier = 87,
UpdateOp = 92,
CompareOp = 93,
BracketedTokens = 97,
BracedTokens = 98,
Attribute = 105,
Guard = 106,
BinaryExpression = 113,
ArgList = 129,
FieldExpression = 132,
LoopLabel = 136,
ClosureParamList = 145,
FieldInitializerList = 150,
MacroInvocationSemi = 161,
MacroRule = 164,
DeclarationList = 168,
AttributeItem = 169,
TypeParamList = 174,
ConstrainedTypeParameter = 175,
TraitBounds = 176,
HigherRankedTraitBound = 177,
RemovedTraitBound = 178,
OptionalTypeParameter = 179,
ConstParameter = 180,
WhereClause = 181,
LifetimeClause = 183,
TypeBoundClause = 184,
FieldDeclarationList = 185,
FieldDeclaration = 186,
OrderedFieldDeclarationList = 187,
EnumVariant = 193,
ParamList = 199,
Parameter = 200,
SelfParameter = 201,
UseList = 214,
GenericType = 222,
FunctionType = 223
+616
View File
@@ -0,0 +1,616 @@
@precedence {
preferGenerics
try
implFor
implBang
deref
call
params
macroRules
macroSemi
macro
unary
mult @left
add @left
shift @left
bitAnd @left
bitXor @left
bitOr @left
compare @left
and @left
or @left
assign @right
else @right
range @left
cast
return
typeArgs
block
bind
plusSep
bound @left
scope
crateVis
selfParam
mut @cut
statement
}
@skip { whitespace | LineComment | BlockComment }
@top SourceFile {
InnerAttribute*
statement*
}
statement[@isGroup=Statement] {
declarationStatement |
AttributeItem |
ExpressionStatement {
blockExpression !statement |
nonBlockExpression ";"
}
}
AttributeItem { Attribute+ declarationStatement }
declarationStatement {
ConstItem {
Vis? kw<"const"> BoundIdentifier ":" type ("=" expression)? ";"
} |
MacroInvocationSemi |
MacroDefinition {
ckw<"macro_rules"> !macroRules "!" Identifier (
"(" (MacroRule ";")* MacroRule? ")" ";" |
"{" (MacroRule ";")* MacroRule? "}"
)
} |
EmptyStatement { ";" } |
ModItem {
Vis? kw<"mod"> BoundIdentifier (";" | DeclarationList)
} |
ForeignModItem {
Vis? externModifier (";" | DeclarationList)
} |
StructItem {
Vis? kw<"struct">
TypeIdentifier TypeParamList?
(WhereClause? FieldDeclarationList | OrderedFieldDeclarationList WhereClause? ";" | ";")
} |
UnionItem {
Vis? ckw<"union">
TypeIdentifier TypeParamList? WhereClause? FieldDeclarationList
} |
EnumItem {
Vis? kw<"enum"> TypeIdentifier TypeParamList? WhereClause?
EnumVariantList { "{" commaSep<Attribute* EnumVariant> "}" }
} |
TypeItem {
Vis? kw<"type"> TypeIdentifier TypeParamList? "=" type ";"
} |
FunctionItem {
Vis? functionModifier* kw<"fn">
(BoundIdentifier | Metavariable) TypeParamList? ParamList ("->" type)?
WhereClause?
(Block | ";")
} |
ImplItem {
kw<"unsafe">? kw<"impl"> TypeParamList?
((!implBang "!")? type !implFor kw<"for">)? type
WhereClause? DeclarationList
} |
TraitItem {
Vis? kw<"unsafe">? kw<"trait"> TypeIdentifier TypeParamList? TraitBounds? WhereClause? DeclarationList
} |
AssociatedType {
kw<"type"> TypeIdentifier TraitBounds? ";"
} |
LetDeclaration {
kw<"let"> (!mut kw<"mut">)? pattern (":" type)? ("=" expression)? ";"
} |
UseDeclaration {
Vis? kw<"use"> useClause ";"
} |
ExternCrateDeclaration {
Vis? kw<"extern"> kw<"crate"> (BoundIdentifier | Identifier kw<"as"> BoundIdentifier) ";"
} |
StaticItem {
Vis? kw<"static"> kw<"ref">? kw<"mut">? BoundIdentifier ":" type ("=" expression)? ";"
}
}
delimitedTokenTree { ParenthesizedTokens | BracketedTokens | BracedTokens }
MacroRule { tokenTree "=>" delimitedTokenTree }
tokenTree {
delimitedTokenTree |
TokenBinding {
Metavariable !bind ":" tokenIdentifier
} |
TokenRepetition {
"$" "(" tokenTree* ")" separatorToken? ("+" | "*" | "?")
} |
ArithOp { "*" | "+" } |
"?" |
separatorToken
}
separatorToken {
String |
RawString |
Char |
Integer |
Float |
tokenIdentifier |
Lifetime |
Metavariable |
ArithOp { "-" | "/" } |
BitOp { "<<" | ">>" | "&" | "|" | "^" } |
LogicOp { "||" | "&&" } |
UpdateOp | CompareOp |
"." | "," | ";" | ":" | "=" | "->" | "=>" | ".." | "..." | "::" | "#" | "!"
}
ParenthesizedTokens { "(" tokenTree* ")" }
BracketedTokens { "[" tokenTree* "]" }
BracedTokens { "{" tokenTree* "}" }
Attribute {
"#" "[" MetaItem "]"
}
InnerAttribute {
"#" "!" "[" MetaItem "]"
}
MetaItem {
path ("=" tokenTree | delimitedTokenTree)?
}
DeclarationList {
"{" InnerAttribute* (declarationStatement | AttributeItem)* "}"
}
EnumVariant {
Vis? Identifier (FieldDeclarationList | OrderedFieldDeclarationList)? ("=" expression)?
}
FieldDeclarationList {
"{" commaSep<Attribute* FieldDeclaration> "}"
}
FieldDeclaration {
Vis? FieldIdentifier ":" type
}
OrderedFieldDeclarationList {
"(" commaSep<Attribute* Vis? type> ")"
}
functionModifier {
kw<"async"> | ckw<"default"> | kw<"const"> | kw<"unsafe"> | externModifier
}
WhereClause {
kw<"where"> commaSep<LifetimeClause | TypeBoundClause>
}
LifetimeClause { Lifetime ":" plusSep<Lifetime> }
TypeBoundClause { (HigherRankedTraitBound | type) TraitBounds }
TraitBounds {
":" plusSep<type | Lifetime | HigherRankedTraitBound | RemovedTraitBound>
}
HigherRankedTraitBound {
kw<"for"> TypeParamList type
}
RemovedTraitBound {
"?" type
}
typeParam[@inline] {
Lifetime |
Metavariable |
TypeIdentifier |
ConstrainedTypeParameter |
OptionalTypeParameter |
ConstParameter
}
TypeParamList {
tpOpen !preferGenerics (typeParam !preferGenerics ("," typeParam? !preferGenerics)*)? tpClose
}
ConstParameter {
kw<"const"> BoundIdentifier ":" type
}
ConstrainedTypeParameter {
(Lifetime | TypeIdentifier) TraitBounds
}
OptionalTypeParameter {
(TypeIdentifier | ConstrainedTypeParameter) "=" type
}
useClause {
pathIdent<BoundIdentifier> |
ScopedIdentifier { simplePathPrefix BoundIdentifier } |
UseAsClause { simplePath kw<"as"> BoundIdentifier } |
UseList |
ScopedUseList { simplePathPrefix UseList } |
UseWildcard { simplePathPrefix? "*" }
}
UseList {
"{" commaSep<useClause> "}"
}
ParamList {
"(" commaSep<Attribute* (Parameter | SelfParameter | VariadicParameter { "..." } | kw<"_">)> ")"
}
SelfParameter {
"&"? Lifetime? (!mut kw<"mut">)? !selfParam kw<"self">
}
Parameter {
(!mut kw<"mut">)? pattern ":" type
}
externModifier {
kw<"extern"> String?
}
Vis {
kw<"pub"> (!call "(" (kw<"self"> | kw<"super"> | kw<"crate"> | kw<"in"> path) ")")? |
kw<"crate"> !crateVis
}
type[@isGroup=Type] {
AbstractType { kw<"impl"> (typePath | GenericType | FunctionType) } |
ReferenceType { "&" Lifetime? kw<"mut">? type } |
PointerType { "*" (kw<"const"> | kw<"mut">) type } |
typePath |
GenericType |
TupleType { "(" commaSep1<type> ")" } |
UnitType { "(" ")" } |
ArrayType { "[" type (";" expression)? "]" } |
FunctionType |
MacroInvocation { typePath !macro "!" delimitedTokenTree } |
EmptyType { "!" } |
DynamicType { kw<"dyn"> (typePath | GenericType | FunctionType) } |
BoundedType { Lifetime !bound "+" type | type !bound "+" type | type !bound "+" Lifetime }
}
FunctionType {
ForLifetimes { kw<"for"> tpOpen commaSep<Lifetime> tpClose }?
(typePath | functionModifier* kw<"fn">)
!params ParamList {
"(" commaSep<Attribute* SelfParameter | VariadicParameter { "..." } | kw<"_"> | Parameter { type }> ")"
}
("->" type)?
}
GenericType {
typePath !typeArgs TypeArgList
}
TypeArgList {
tpOpen commaSep1<type | TypeBinding | Lifetime | literal | Block> tpClose
}
TypeBinding {
TypeIdentifier "=" type
}
expression[@isGroup=Expression] { blockExpression | nonBlockExpression }
nonBlockExpression {
UnaryExpression { (ArithOp { "-" } | DerefOp { "*" } | LogicOp { "!" }) !unary expression } |
ReferenceExpression { "&" kw<"mut">? expression } |
TryExpression { expression !try "?" } |
BinaryExpression |
AssignmentExpression { expression !assign ("=" | UpdateOp) expression } |
TypeCastExpression { expression !cast kw<"as"> type } |
ReturnExpression { kw<"return"> (!return expression)? } |
RangeExpression { expression? !range (".." | "..." | "..=") expression? } |
CallExpression { expression !call ArgList } |
literal |
path |
AwaitExpression { expression !deref "." kw<"await"> } |
FieldExpression |
GenericFunction { (path | FieldExpression) !scope "::" TypeArgList } |
BreakExpression { kw<"break"> LoopLabel? (!return expression)? } |
ContinueExpression { kw<"continue"> LoopLabel? } |
IndexExpression { expression !deref "[" expression "]" } |
ArrayExpression { "[" InnerAttribute* (expression ";" expression | commaSep1<expression>)? "]" } |
TupleExpression { "(" InnerAttribute* expression ("," expression?)+ ")" } |
MacroInvocation { macroInvocation } |
UnitExpression { "(" ")" } |
ClosureExpression { kw<"move">? ClosureParamList (("->" type)? !statement Block | expression) } |
ParenthesizedExpression { "(" InnerAttribute* expression ")" } |
StructExpression { structName FieldInitializerList }
}
FieldExpression { expression !deref "." (FieldIdentifier | Integer) }
blockExpression {
UnsafeBlock { kw<"unsafe"> Block } |
AsyncBlock { kw<"async"> kw<"move">? Block } |
Block |
IfExpression |
MatchExpression {
kw<"match"> expression MatchBlock { "{" InnerAttribute* (MatchArm<",">* MatchArm<","?>)? "}" }
} |
WhileExpression {
(LoopLabel ":")? kw<"while"> cond Block
} |
LoopExpression {
(LoopLabel ":")? kw<"loop"> Block
} |
ForExpression {
(LoopLabel ":")? kw<"for"> pattern kw<"in"> expression Block
}
}
macroInvocation {
path !macro "!" delimitedTokenTree
}
MacroInvocationSemi[@name=MacroInvocation] {
path !macro "!" ((ParenthesizedTokens | BracketedTokens) !macroSemi ";" | BracedTokens !macroSemi)
}
QualifiedScope { tpOpen type (kw<"as"> type)? tpClose }
pathIdent<and> {
kw<"self"> |
Metavariable |
kw<"super"> |
kw<"crate"> |
and
}
pathSegment {
pathIdent<ScopeIdentifier> ~path !scope "::" (TypeArgList "::")?
}
path {
pathIdent<Identifier> ~path |
ScopedIdentifier {
(("::" | QualifiedScope !scope "::") pathSegment* | pathSegment+) pathIdent<Identifier> ~path
}
}
typePathSegment {
pathIdent<ScopeIdentifier> ~path ((!scope "::")? TypeArgList)? !scope "::"
}
typePath {
SelfType { kw<"self"> } ~path |
MetaType { Metavariable } ~path |
TypeIdentifier ~path |
ScopedTypeIdentifier {
(("::" | QualifiedScope !scope "::") typePathSegment* | typePathSegment+) pathIdent<TypeIdentifier> ~path
}
}
simplePathPrefix[@inline] {
"::" (pathIdent<ScopeIdentifier> ~path !scope "::")* |
(pathIdent<ScopeIdentifier> ~path !scope "::")+
}
simplePath {
pathIdent<Identifier> ~path |
ScopedIdentifier { simplePathPrefix pathIdent<Identifier> ~path }
}
structName {
pathIdent<TypeIdentifier> ~path |
ScopedTypeIdentifier {
(("::" | QualifiedScope !scope "::") pathSegment* | pathSegment+) pathIdent<TypeIdentifier> ~path
}
}
patternPath {
MetaPattern { Metavariable ~path } |
BoundIdentifier ~path |
SelfPattern { kw<"self"> ~path } |
ScopedIdentifier {
(("::" | QualifiedScope !scope "::") pathSegment* | pathSegment+) pathIdent<Identifier> ~path
}
}
BinaryExpression {
expression !add ArithOp { "+" | "-" } expression |
expression !mult ArithOp { "*" | "/" | "%" } expression |
expression !shift BitOp { "<<" | ">>" } expression |
expression !bitAnd BitOp { "&" } expression |
expression !bitXor BitOp { "^" } expression |
expression !bitOr BitOp { "|" } expression |
expression !compare CompareOp expression |
expression !and LogicOp { "&&" } expression |
expression !or LogicOp { "||" } expression
}
ArgList {
"(" commaSep<Attribute* expression> ")"
}
FieldInitializerList {
"{" commaSep<fieldInitializer> "}"
}
fieldInitializer {
ShorthandFieldInitializer { Attribute* Identifier } |
FieldInitializer { Attribute* FieldIdentifier ":" expression } |
BaseFieldInitializer { ".." expression }
}
IfExpression {
kw<"if"> cond Block (!else kw<"else"> (Block | IfExpression))?
}
cond {
expression |
LetDeclaration { kw<"let"> pattern "=" expression }
}
Guard { kw<"if"> expression }
MatchArm<after> {
Attribute* pattern Guard?
"=>" (nonBlockExpression after | !block blockExpression)
}
ClosureParamList[@name=ParamList] {
closureParamDelim commaSep<Parameter { (!mut kw<"mut">)? pattern (":" type)?}> closureParamDelim
}
Block {
"{"
InnerAttribute*
statement*
ExpressionStatement { expression }?
"}"
}
pattern[@isGroup=Pattern] {
LiteralPattern { literalPattern } |
patternPath |
TuplePattern { structName? "(" commaSep<pattern> ")" } |
StructPattern {
structName
FieldPatternList { "{" commaSep<FieldPattern | ".."> "}" }
} |
RefPattern { kw<"ref"> !unary pattern } |
SlicePattern { "[" commaSep<pattern> "]" } |
CapturedPattern { BoundIdentifier "@" pattern } |
ReferencePattern { "&" !unary (!mut kw<"mut">)? pattern } |
".." |
MutPattern { kw<"mut"> !unary pattern } |
RangePattern { (literalPattern | path) ("..." | "..=") (literalPattern | path) } |
OrPattern { pattern !or "|" pattern } |
MacroPattern { macroInvocation } |
kw<"_">
}
FieldPattern {
kw<"ref">? (!mut kw<"mut">)? (BoundIdentifier | FieldIdentifier ":" pattern)
}
literal {
String |
RawString |
Char |
boolean |
Integer |
Float
}
literalPattern {
literal |
ArithOp { "-" } (Integer | Float)
}
boolean { @specialize[@name=Boolean]<identifier, "true" | "false"> }
@skip {} {
BlockComment[isolate] { "/*" (BlockComment | blockCommentContent)* blockCommentEnd }
String[isolate] { stringStart (Escape | stringContent)* stringEnd }
}
Identifier { identifier }
TypeIdentifier { identifier }
FieldIdentifier { identifier }
ScopeIdentifier { identifier }
BoundIdentifier { identifier }
LoopLabel { quoteIdentifier }
Lifetime { quoteIdentifier }
kw<term> { @specialize[@name={term}]<identifier, term> }
ckw<term> { @extend[@name={term}]<identifier, term> }
commaSep<expr> { commaSep1<expr>? }
commaSep1<expr> { expr ("," expr?)* }
plusSep<expr> { expr (!plusSep "+" expr)* }
@external tokens closureParam from "./tokens" { closureParamDelim[@name="|"] }
@external tokens tpDelim from "./tokens" { tpOpen[@name="<"], tpClose[@name=">"] }
@external tokens literalTokens from "./tokens" { RawString[isolate], Float }
@tokens {
whitespace { $[ \t\r\n] }
UpdateOp { ($[+\-*/%^&|] | "<<" | ">>") "=" }
CompareOp { $[<>] "="? | $[!=] "=" }
Integer {
($[0-9] $[0-9_]* |
"0x" $[0-9a-fA-F_]+ |
"0b" $[01_]+ |
"0o" $[0-7_]+)
(("u" | "i") ("8" | "16" | "32" | "64" | "128" | "size"))?
}
hex { $[0-9a-fA-F] }
Escape { "\\" (![xu] | "u" hex hex hex hex | "u{" hex+ "}" | "x" hex hex) }
Char { "b"? "'" (Escape | ![\\'])? "'" }
LineComment[isolate] { "//" ![\n]* }
@precedence { LineComment, "/" }
blockCommentContent { ![*/] blockCommentContent? | "*" blockCommentStar | "/" blockCommentSlash }
blockCommentStar { ![/*] blockCommentContent | "*" blockCommentStar }
blockCommentSlash { ![/*] blockCommentContent | "/" blockCommentSlash }
blockCommentEnd { ![*/] blockCommentEnd | "*" blockCommentEndStar | "/" blockCommentEndSlash }
blockCommentEndStar { "/" | ![/*] blockCommentEnd | "*" blockCommentEndStar }
blockCommentEndSlash { ![/*] blockCommentEnd | "/" blockCommentSlash }
@precedence { blockCommentEnd, blockCommentContent }
stringStart { "b"? '"' }
stringContent { !["\\\n]* "\n" | !["\\\n]+ }
stringEnd { '"' }
identBase { $[a-zA-Zα-ωΑ-Ωµ_] $[a-zA-Zα-ωΑ-Ωµ0-9_]* }
identifier { ("r#")? identBase }
tokenIdentifier[@name=Identifier] { identBase }
quoteIdentifier { "'" identBase }
Metavariable { "$" identBase }
@precedence { stringStart, Char, identifier }
@precedence { stringStart, Char, tokenIdentifier }
@precedence { Char, quoteIdentifier }
@precedence { Metavariable, "$" }
"[" "]" "{" "}" "(" ")"
";" ":" "::" ","
"=" "->" "=>" ".." "..."
"&" "!"
}
@external propSource rustHighlighting from "./highlight"
@detectDelim
+72
View File
@@ -0,0 +1,72 @@
import {ExternalTokenizer} from "@lezer/lr"
import {Float, RawString, closureParamDelim, tpOpen, tpClose} from "./parser.terms"
const _b = 98, _e = 101, _f = 102, _r = 114, _E = 69, Zero = 48,
Dot = 46, Plus = 43, Minus = 45, Hash = 35, Quote = 34, Pipe = 124, LessThan = 60, GreaterThan = 62
function isNum(ch) { return ch >= 48 && ch <= 57 }
function isNum_(ch) { return isNum(ch) || ch == 95 }
export const literalTokens = new ExternalTokenizer((input, stack) => {
if (isNum(input.next)) {
let isFloat = false
do { input.advance() } while (isNum_(input.next))
if (input.next == Dot) {
isFloat = true
input.advance()
if (isNum(input.next)) {
do { input.advance() } while (isNum_(input.next))
} else if (input.next == Dot || input.next > 0x7f || /\w/.test(String.fromCharCode(input.next))) {
return
}
}
if (input.next == _e || input.next == _E) {
isFloat = true
input.advance()
if (input.next == Plus || input.next == Minus) input.advance()
if (!isNum_(input.next)) return
do { input.advance() } while (isNum_(input.next))
}
if (input.next == _f) {
let after = input.peek(1)
if (after == Zero + 3 && input.peek(2) == Zero + 2 ||
after == Zero + 6 && input.peek(2) == Zero + 4) {
input.advance(3)
isFloat = true
} else {
return
}
}
if (isFloat) input.acceptToken(Float)
} else if (input.next == _b || input.next == _r) {
if (input.next == _b) input.advance()
if (input.next != _r) return
input.advance()
let count = 0
while (input.next == Hash) { count++; input.advance() }
if (input.next != Quote) return
input.advance()
content: for (;;) {
if (input.next < 0) return
let isQuote = input.next == Quote
input.advance()
if (isQuote) {
for (let i = 0; i < count; i++) {
if (input.next != Hash) continue content
input.advance()
}
input.acceptToken(RawString)
return
}
}
}
})
export const closureParam = new ExternalTokenizer(input => {
if (input.next == Pipe) input.acceptToken(closureParamDelim, 1)
})
export const tpDelim = new ExternalTokenizer(input => {
if (input.next == LessThan) input.acceptToken(tpOpen, 1)
else if (input.next == GreaterThan) input.acceptToken(tpClose, 1)
})
+59
View File
@@ -0,0 +1,59 @@
# Async function
async fn abc() {}
async fn main() {
let x = futures.await?;
}
==>
SourceFile(
FunctionItem(async, fn,
BoundIdentifier,
ParamList,
Block),
FunctionItem(async, fn, BoundIdentifier, ParamList,
Block(
LetDeclaration(let,BoundIdentifier, TryExpression(
AwaitExpression(Identifier, await))))))
# Await expression
futures.await;
futures.await?;
futures.await?.await?;
futures.await?.function().await?;
==>
SourceFile(
ExpressionStatement(AwaitExpression(Identifier, await)),
ExpressionStatement(TryExpression(
AwaitExpression(Identifier, await))),
ExpressionStatement(TryExpression(
AwaitExpression(
TryExpression(
AwaitExpression(Identifier, await)), await))),
ExpressionStatement(TryExpression(
AwaitExpression(
CallExpression(
FieldExpression(
TryExpression(
AwaitExpression(Identifier, await)),
FieldIdentifier),
ArgList), await))))
# Async Block
async {}
async { let x = 10; }
async move {}
==>
SourceFile(
ExpressionStatement(AsyncBlock(async, Block)),
ExpressionStatement(AsyncBlock(async, Block(LetDeclaration(let, BoundIdentifier, Integer)))),
ExpressionStatement(AsyncBlock(async, move, Block)))
+52
View File
@@ -0,0 +1,52 @@
# Block comments
/*
* Block comments
*/
/* Comment with asterisks **/
==>
SourceFile(
BlockComment,
BlockComment)
# Nested block comments
/* /* double nested */ */
// ---
/*/*/* triple nested */*/*/
// ---
/****
/****
nested with extra stars
****/
****/
// ---
==>
SourceFile(
BlockComment(BlockComment),
LineComment,
BlockComment(BlockComment(BlockComment)),
LineComment,
BlockComment(BlockComment),
LineComment)
# Line comments
// Comment
==>
SourceFile(
LineComment)
+1295
View File
File diff suppressed because it is too large Load Diff
+704
View File
@@ -0,0 +1,704 @@
# Identifiers
fn main() {
abc;
}
==>
SourceFile(
FunctionItem(fn,BoundIdentifier, ParamList, Block(
ExpressionStatement(Identifier))))
# Raw identifiers
fn main() {
(r#abc as r#Def).r#ghi;
}
==>
SourceFile(
FunctionItem(fn,
BoundIdentifier,
ParamList,
Block(
ExpressionStatement(FieldExpression(
ParenthesizedExpression(
TypeCastExpression(Identifier, as, TypeIdentifier)),
FieldIdentifier)))))
# Unary operator expressions
-num;
!bits;
*boxed_thing;
==>
SourceFile(
ExpressionStatement(UnaryExpression(ArithOp, Identifier)),
ExpressionStatement(UnaryExpression(LogicOp, Identifier)),
ExpressionStatement(UnaryExpression(DerefOp, Identifier)))
# Reference expressions
&a;
&mut self.name;
==>
SourceFile(
ExpressionStatement(ReferenceExpression(Identifier)),
ExpressionStatement(ReferenceExpression(mut, FieldExpression(self, FieldIdentifier))))
# Try expressions
a.unwrap()?;
==>
SourceFile(
ExpressionStatement(TryExpression(CallExpression(FieldExpression(Identifier, FieldIdentifier), ArgList))))
# Binary operator expressions
a * b;
a / b;
a % b;
a + b;
a - b;
a >> b;
a << b;
a == b;
a && b;
a || b;
==>
SourceFile(
ExpressionStatement(BinaryExpression(Identifier, ArithOp, Identifier)),
ExpressionStatement(BinaryExpression(Identifier, ArithOp, Identifier)),
ExpressionStatement(BinaryExpression(Identifier, ArithOp, Identifier)),
ExpressionStatement(BinaryExpression(Identifier, ArithOp, Identifier)),
ExpressionStatement(BinaryExpression(Identifier, ArithOp, Identifier)),
ExpressionStatement(BinaryExpression(Identifier, BitOp, Identifier)),
ExpressionStatement(BinaryExpression(Identifier, BitOp, Identifier)),
ExpressionStatement(BinaryExpression(Identifier, CompareOp, Identifier)),
ExpressionStatement(BinaryExpression(Identifier, LogicOp, Identifier)),
ExpressionStatement(BinaryExpression(Identifier, LogicOp, Identifier)))
# Grouped expressions
(0);
(2 * (3 + 4));
==>
SourceFile(
ExpressionStatement(ParenthesizedExpression(Integer)),
ExpressionStatement(ParenthesizedExpression(BinaryExpression(
Integer,
ArithOp,
ParenthesizedExpression(BinaryExpression(Integer, ArithOp, Integer))))))
# Range expressions
1..2;
3..;
..4;
..;
1..b;
a..b;
==>
SourceFile(
ExpressionStatement(RangeExpression(Integer, Integer)),
ExpressionStatement(RangeExpression(Integer)),
ExpressionStatement(RangeExpression(Integer)),
ExpressionStatement(RangeExpression),
ExpressionStatement(RangeExpression(Integer, Identifier)),
ExpressionStatement(RangeExpression(Identifier, Identifier)))
# Assignment expressions
x = y;
==>
SourceFile(
ExpressionStatement(AssignmentExpression(
Identifier,
Identifier)))
# Compound assignment expressions
x += 1;
x += y;
==>
SourceFile(
ExpressionStatement(AssignmentExpression(Identifier, UpdateOp, Integer)),
ExpressionStatement(AssignmentExpression(Identifier, UpdateOp, Identifier)))
# Type cast expressions
1000 as u8;
let character = integer as char;
let size: f64 = len(values) as f64;
==>
SourceFile(
ExpressionStatement(TypeCastExpression(
Integer,
as,
TypeIdentifier)),
LetDeclaration(let,
BoundIdentifier,
TypeCastExpression(
Identifier,
as,
TypeIdentifier)),
LetDeclaration(let,
BoundIdentifier,
TypeIdentifier,
TypeCastExpression(
CallExpression(
Identifier,
ArgList(Identifier)),
as,
TypeIdentifier)))
# Call expressions
foo();
add(1i32, 2i32);
add(
1i32,
2i32,
);
==>
SourceFile(
ExpressionStatement(CallExpression(
Identifier,
ArgList)),
ExpressionStatement(CallExpression(
Identifier,
ArgList(Integer, Integer))),
ExpressionStatement(CallExpression(
Identifier,
ArgList(Integer, Integer))))
# Array expressions
[];
[1, 2, 3];
["a", "b", "c"];
[0; 128];
==>
SourceFile(
ExpressionStatement(ArrayExpression),
ExpressionStatement(ArrayExpression(
Integer,
Integer,
Integer)),
ExpressionStatement(ArrayExpression(
String,
String,
String)),
ExpressionStatement(ArrayExpression(
Integer,
Integer)))
# Tuple expressions
();
(0,);
let (x, y, z) = (1, 2, 3);
==>
SourceFile(
ExpressionStatement(UnitExpression),
ExpressionStatement(TupleExpression(Integer)),
LetDeclaration(let,
TuplePattern(BoundIdentifier, BoundIdentifier, BoundIdentifier),
TupleExpression(Integer, Integer, Integer)))
# Struct expressions
NothingInMe {};
Point {x: 10.0, y: 20.0};
let a = SomeStruct { field1, field2: expression, field3, };
let u = game::User {name: "Joe", age: 35, score: 100_000};
==>
SourceFile(
ExpressionStatement(StructExpression(TypeIdentifier,
FieldInitializerList)),
ExpressionStatement(StructExpression(TypeIdentifier,
FieldInitializerList(
FieldInitializer(FieldIdentifier, Float),
FieldInitializer(FieldIdentifier, Float)))),
LetDeclaration(let,
BoundIdentifier,
StructExpression(
TypeIdentifier,
FieldInitializerList(
ShorthandFieldInitializer(
Identifier),
FieldInitializer(FieldIdentifier, Identifier),
ShorthandFieldInitializer(
Identifier)))),
LetDeclaration(let,
BoundIdentifier,
StructExpression(
ScopedTypeIdentifier(ScopeIdentifier, TypeIdentifier),
FieldInitializerList(
FieldInitializer(FieldIdentifier, String),
FieldInitializer(FieldIdentifier, Integer),
FieldInitializer(FieldIdentifier, Integer)))))
# Struct expressions with update initializers
let u = User{name, ..current_user()};
==>
SourceFile(
LetDeclaration(let,
BoundIdentifier,
StructExpression(
TypeIdentifier,
FieldInitializerList(
ShorthandFieldInitializer(
Identifier),
BaseFieldInitializer(CallExpression(Identifier, ArgList))))))
# If expressions
fn main() {
if n == 1 {
} else if n == 2 {
} else {
}
}
let y = if x == 5 { 10 } else { 15 };
==>
SourceFile(
FunctionItem(fn,
BoundIdentifier,
ParamList,
Block(
ExpressionStatement(IfExpression(if,
BinaryExpression(
Identifier,
CompareOp,
Integer),
Block,
else,
IfExpression(if,
BinaryExpression(
Identifier,
CompareOp,
Integer),
Block,
else,
Block))))),
LetDeclaration(let,
BoundIdentifier,
IfExpression(if,
BinaryExpression(
Identifier,
CompareOp,
Integer),
Block(ExpressionStatement(Integer)),
else,
Block(ExpressionStatement(Integer)))))
# If let expressions
if let ("Bacon", b) = dish {
}
==>
SourceFile(
ExpressionStatement(IfExpression(if, LetDeclaration(let, TuplePattern(LiteralPattern(String), BoundIdentifier), Identifier),
Block)))
# While let expressions
while let ("Bacon", b) = dish {
}
==>
SourceFile(
ExpressionStatement(WhileExpression(while,
LetDeclaration(let, TuplePattern(LiteralPattern(String), BoundIdentifier), Identifier),
Block)))
# Match expressions
match x {
1 => { "one" }
2 => "two",
-1 => 1,
-3.14 => 3,
#[attr1]
3 => "three",
macro!(4) => "four",
_ => "something else",
}
let msg = match x {
0 | 1 | 10 => "one of zero, one, or ten",
y if y < 20 => "less than 20, but not zero, one, or ten",
y if y == 200 =>
if a {
"200 (but this is not very stylish)"
}
_ => "something else",
};
==>
SourceFile(
ExpressionStatement(MatchExpression(match,
Identifier,
MatchBlock(
MatchArm(
LiteralPattern(Integer),
Block(
ExpressionStatement(String))),
MatchArm(
LiteralPattern(Integer),
String),
MatchArm(
LiteralPattern(ArithOp, Integer),
Integer),
MatchArm(
LiteralPattern(ArithOp, Float),
Integer),
MatchArm(
Attribute(
MetaItem(
Identifier)),
LiteralPattern(Integer),
String),
MatchArm(
MacroPattern(
Identifier,
ParenthesizedTokens(
Integer)),
String),
MatchArm(_, String)))),
LetDeclaration(let,
BoundIdentifier,
MatchExpression(match,
Identifier,
MatchBlock(
MatchArm(
OrPattern(OrPattern(LiteralPattern(Integer), LiteralPattern(Integer)), LiteralPattern(Integer)),
String),
MatchArm(
BoundIdentifier,
Guard(if,
BinaryExpression(
Identifier,
CompareOp,
Integer)),
String),
MatchArm(
BoundIdentifier,
Guard(if,
BinaryExpression(
Identifier,
CompareOp,
Integer)),
IfExpression(if,
Identifier,
Block(
ExpressionStatement(String)))),
MatchArm(
_,
String)))))
# While expressions
while !done {
done = true;
}
==>
SourceFile(
ExpressionStatement(WhileExpression(while,
UnaryExpression(LogicOp, Identifier),
Block(
ExpressionStatement(AssignmentExpression(
Identifier,
Boolean))))))
# Loop expressions
'outer: loop {
'inner: loop {
break 'outer;
break true;
}
}
==>
SourceFile(
ExpressionStatement(LoopExpression(LoopLabel, loop, Block(
ExpressionStatement(LoopExpression(LoopLabel, loop, Block(
ExpressionStatement(BreakExpression(break,LoopLabel)),
ExpressionStatement(BreakExpression(break,Boolean)))))))))
# For expressions
for e in v {
bar(e);
}
for i in 0..256 {
bar(i);
}
'outer: for x in 0..10 {
'inner: for y in 0..10 {
if x % 2 == 0 { continue 'outer; }
if y % 2 == 0 { continue 'inner; }
}
}
==>
SourceFile(
ExpressionStatement(ForExpression(for,BoundIdentifier, in, Identifier, Block(
ExpressionStatement(CallExpression(Identifier, ArgList(Identifier)))))),
ExpressionStatement(ForExpression(for,BoundIdentifier, in, RangeExpression(Integer, Integer), Block(
ExpressionStatement(CallExpression(Identifier, ArgList(Identifier)))))),
ExpressionStatement(ForExpression(LoopLabel, for, BoundIdentifier, in, RangeExpression(Integer, Integer), Block(
ExpressionStatement(ForExpression(LoopLabel, for, BoundIdentifier, in, RangeExpression(Integer, Integer), Block(
ExpressionStatement(IfExpression(if,BinaryExpression(BinaryExpression(Identifier, ArithOp, Integer), CompareOp, Integer),
Block(ExpressionStatement(ContinueExpression(continue,LoopLabel))))),
ExpressionStatement(IfExpression(if,BinaryExpression(BinaryExpression(Identifier, ArithOp, Integer), CompareOp, Integer),
Block(ExpressionStatement(ContinueExpression(continue,LoopLabel))))))))))))
# Field expressions
mystruct.myfield;
foo().x;
value.0.1.iter();
1.max(2);
==>
SourceFile(
ExpressionStatement(FieldExpression(Identifier, FieldIdentifier)),
ExpressionStatement(FieldExpression(CallExpression(Identifier, ArgList), FieldIdentifier)),
ExpressionStatement(CallExpression(
FieldExpression(
FieldExpression(FieldExpression(Identifier, Integer), Integer),
FieldIdentifier),
ArgList)),
ExpressionStatement(CallExpression(
FieldExpression(Integer, FieldIdentifier), ArgList(Integer))))
# Method call expressions
mystruct.foo();
==>
SourceFile(ExpressionStatement(CallExpression(FieldExpression(Identifier, FieldIdentifier), ArgList)))
# Index expressions
([1, 2, 3, 4])[0];
arr[10];
arr[n];
==>
SourceFile(
ExpressionStatement(IndexExpression(
ParenthesizedExpression(
ArrayExpression(Integer, Integer, Integer, Integer)),
Integer)),
ExpressionStatement(IndexExpression(Identifier, Integer)),
ExpressionStatement(IndexExpression(Identifier, Identifier)))
# Scoped functions
a::b();
C::<D>::e();
::f();
::g::h();
==>
SourceFile(
ExpressionStatement(CallExpression(
ScopedIdentifier(ScopeIdentifier, Identifier),
ArgList)),
ExpressionStatement(CallExpression(
ScopedIdentifier(
ScopeIdentifier, TypeArgList(TypeIdentifier),
Identifier),
ArgList)),
ExpressionStatement(CallExpression(ScopedIdentifier(Identifier), ArgList)),
ExpressionStatement(CallExpression(ScopedIdentifier(ScopeIdentifier, Identifier), ArgList)))
# Scoped functions with fully qualified syntax
<Dog as Animal>::eat(d);
==>
SourceFile(
ExpressionStatement(CallExpression(
ScopedIdentifier(
QualifiedScope(TypeIdentifier, as, TypeIdentifier),
Identifier),
ArgList(Identifier))))
# Scoped functions with macros as types
<Token![]>::foo();
==>
SourceFile(
ExpressionStatement(CallExpression(
ScopedIdentifier(
QualifiedScope(MacroInvocation(TypeIdentifier, BracketedTokens)),
Identifier),
ArgList)))
# Generic functions
std::sizeof::<u32>();
foo::<8>();
==>
SourceFile(
ExpressionStatement(CallExpression(
GenericFunction(
ScopedIdentifier(
ScopeIdentifier,
Identifier),
TypeArgList(
TypeIdentifier)),
ArgList)),
ExpressionStatement(CallExpression(
GenericFunction(
Identifier,
TypeArgList(
Integer)),
ArgList)))
# Closures
a.map(|(b, c)| b.push(c));
d.map(move |mut e| {
f(e);
g(e)
});
h(|| -> i { j });
==>
SourceFile(
ExpressionStatement(CallExpression(
FieldExpression(Identifier, FieldIdentifier),
ArgList(
ClosureExpression(
ParamList(Parameter(TuplePattern(BoundIdentifier, BoundIdentifier))),
CallExpression(
FieldExpression(Identifier, FieldIdentifier),
ArgList(Identifier)))))),
ExpressionStatement(CallExpression(
FieldExpression(Identifier, FieldIdentifier),
ArgList(
ClosureExpression(move,
ParamList(Parameter(mut, BoundIdentifier)),
Block(
ExpressionStatement(CallExpression(Identifier, ArgList(Identifier))),
ExpressionStatement(CallExpression(Identifier, ArgList(Identifier)))))))),
ExpressionStatement(CallExpression(
Identifier,
ArgList(
ClosureExpression(
ParamList,
TypeIdentifier,
Block(ExpressionStatement(Identifier)))))))
# Closures with typed parameteres
a.map(|b: usize| b.push(c));
==>
SourceFile(
ExpressionStatement(CallExpression(
FieldExpression(Identifier, FieldIdentifier),
ArgList(ClosureExpression(
ParamList(Parameter(BoundIdentifier, TypeIdentifier)),
CallExpression(FieldExpression(Identifier, FieldIdentifier), ArgList(Identifier)))))))
# Unsafe blocks
const a : A = unsafe { foo() };
==>
SourceFile(
ConstItem(const,
BoundIdentifier,
TypeIdentifier,
UnsafeBlock(unsafe, Block(ExpressionStatement(CallExpression(Identifier, ArgList))))))
+135
View File
@@ -0,0 +1,135 @@
# Integer literals
0;
0___0;
123;
0usize;
123i32;
123u32;
123_u32;
0xff_u8;
0o70_i16;
0b1111_1111_1001_0000_i32;
1u128;
==>
SourceFile(
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer))
# Floating-point literals
123.123;
2.;
123.0f64;
0.1f64;
0.1f32;
12E+99_f64;
==>
SourceFile(
ExpressionStatement(Float),
ExpressionStatement(Float),
ExpressionStatement(Float),
ExpressionStatement(Float),
ExpressionStatement(Float),
ExpressionStatement(Float))
# String literals
"";
"abc";
b"foo\nbar";
"foo\
bar";
"\"foo\"";
"/* foo bar */ foo bar";
"foo\x42\x43bar";
"foo \x42 \x43 bar";
==>
SourceFile(
ExpressionStatement(String),
ExpressionStatement(String),
ExpressionStatement(String(Escape)),
ExpressionStatement(String(Escape)),
ExpressionStatement(String(Escape, Escape)),
ExpressionStatement(String),
ExpressionStatement(String(Escape, Escape)),
ExpressionStatement(String(Escape, Escape)))
# Raw string literals
r#"abc"#; r##"ok"##;
r##"foo #"# bar"##;
r###"foo ##"## bar"###;
r######"foo ##### bar"######;
==>
SourceFile(
ExpressionStatement(RawString),
ExpressionStatement(RawString),
ExpressionStatement(RawString),
ExpressionStatement(RawString),
ExpressionStatement(RawString))
# Raw byte string literals
br#"abc"#;
br##"abc"##;
==>
SourceFile(
ExpressionStatement(RawString),
ExpressionStatement(RawString))
# Character literals
'a';
'\'';
'\0';
b'x';
'\t';
'\xff';
'\\';
==>
SourceFile(
ExpressionStatement(Char),
ExpressionStatement(Char),
ExpressionStatement(Char),
ExpressionStatement(Char),
ExpressionStatement(Char),
ExpressionStatement(Char),
ExpressionStatement(Char))
# Boolean literals
true;
false;
==>
SourceFile(ExpressionStatement(Boolean), ExpressionStatement(Boolean))
+148
View File
@@ -0,0 +1,148 @@
# Macro invocation - no arguments
a!();
b![];
c!{}
d::e!();
f::g::h!{}
==>
SourceFile(
MacroInvocation(Identifier, ParenthesizedTokens),
MacroInvocation(Identifier, BracketedTokens),
MacroInvocation(Identifier, BracedTokens),
MacroInvocation(ScopedIdentifier(ScopeIdentifier, Identifier), ParenthesizedTokens),
MacroInvocation(ScopedIdentifier(ScopeIdentifier, ScopeIdentifier, Identifier), BracedTokens))
# Macro invocation - arbitrary tokens
a!(* a *);
a!(& a &);
a!(- a -);
a!(b + c + +);
a!('a'..='z');
a!('\u{0}'..='\u{2}');
a!('lifetime);
==>
SourceFile(
MacroInvocation(
Identifier,
ParenthesizedTokens(ArithOp, Identifier, ArithOp)),
MacroInvocation(
Identifier,
ParenthesizedTokens(BitOp, Identifier, BitOp)),
MacroInvocation(
Identifier,
ParenthesizedTokens(ArithOp, Identifier, ArithOp)),
MacroInvocation(
Identifier,
ParenthesizedTokens(Identifier, ArithOp, Identifier, ArithOp, ArithOp)),
MacroInvocation(
Identifier,
ParenthesizedTokens(Char, Char)),
MacroInvocation(
Identifier,
ParenthesizedTokens(Char, Char)),
MacroInvocation(
Identifier,
ParenthesizedTokens(Lifetime)))
# Macro definition
macro_rules! say_hello {
() => (
println!("Hello!");
)
}
macro_rules! four {
() => {1 + 3};
}
macro_rules! foo {
(x => $e:expr) => (println!("mode X: {}", $e));
(y => $e:expr) => (println!("mode Y: {}", $e))
}
macro_rules! o_O {
(
$($x:expr; [ $( $y:expr ),* ]);*
) => {
$($($x + $e),*),*
}
}
macro_rules! zero_or_one {
($($e:expr),?) => {
$($e),?
};
}
==>
SourceFile(
MacroDefinition(macro_rules,
Identifier,
MacroRule(
ParenthesizedTokens,
ParenthesizedTokens(
Identifier,
ParenthesizedTokens(String)))),
MacroDefinition(macro_rules,
Identifier,
MacroRule(
ParenthesizedTokens,
BracedTokens(Integer, ArithOp, Integer))),
MacroDefinition(macro_rules,
Identifier,
MacroRule(
ParenthesizedTokens(
Identifier,
TokenBinding(
Metavariable,
Identifier)),
ParenthesizedTokens(
Identifier,
ParenthesizedTokens(
String,
Metavariable))),
MacroRule(
ParenthesizedTokens(
Identifier,
TokenBinding(
Metavariable,
Identifier)),
ParenthesizedTokens(
Identifier,
ParenthesizedTokens(
String,
Metavariable)))),
MacroDefinition(macro_rules,
Identifier,
MacroRule(
ParenthesizedTokens(
TokenRepetition(
TokenBinding(
Metavariable,
Identifier),
BracketedTokens(
TokenRepetition(
TokenBinding(
Metavariable,
Identifier))))),
BracedTokens(
TokenRepetition(
TokenRepetition(Metavariable, ArithOp, Metavariable))))),
MacroDefinition(macro_rules,
Identifier,
MacroRule(
ParenthesizedTokens(
TokenRepetition(
TokenBinding(Metavariable, Identifier))),
BracedTokens(
TokenRepetition(Metavariable)))))
+221
View File
@@ -0,0 +1,221 @@
# Tuple struct patterns
match x {
Some(x) => "some",
std::None() => "none"
}
==>
SourceFile(
ExpressionStatement(MatchExpression(match,Identifier, MatchBlock(
MatchArm(
TuplePattern(TypeIdentifier, BoundIdentifier),
String),
MatchArm(
TuplePattern(ScopedTypeIdentifier(ScopeIdentifier, TypeIdentifier)),
String)))))
# Reference patterns
match x {
A(ref x) => x.0,
ref mut y => y,
& mut z => z,
}
==>
SourceFile(
ExpressionStatement(MatchExpression(match,Identifier, MatchBlock(
MatchArm(
TuplePattern(TypeIdentifier, RefPattern(ref, BoundIdentifier)),
FieldExpression(Identifier, Integer)),
MatchArm(
RefPattern(ref, MutPattern(mut, BoundIdentifier)),
Identifier),
MatchArm(
ReferencePattern(mut, BoundIdentifier),
Identifier)))))
# Struct patterns
match x {
Person{name, age} if age < 5 => ("toddler", name),
Person{name: adult_name, age: _} => ("adult", adult_name),
}
==>
SourceFile(
ExpressionStatement(MatchExpression(match,Identifier, MatchBlock(
MatchArm(
StructPattern(
TypeIdentifier,
FieldPatternList(FieldPattern(BoundIdentifier), FieldPattern(BoundIdentifier))),
Guard(if, BinaryExpression(Identifier, CompareOp, Integer)),
TupleExpression(String, Identifier)),
MatchArm(
StructPattern(
TypeIdentifier,
FieldPatternList(
FieldPattern(FieldIdentifier, BoundIdentifier),
FieldPattern(FieldIdentifier, _))),
TupleExpression(String, Identifier))))))
# Ignored patterns
match x {
(a, ..) => a,
B(..) => c,
D::E{f: g, ..} => g
}
==>
SourceFile(
ExpressionStatement(MatchExpression(match,Identifier, MatchBlock(
MatchArm(
TuplePattern(BoundIdentifier),
Identifier),
MatchArm(
TuplePattern(TypeIdentifier),
Identifier),
MatchArm(
StructPattern(
ScopedTypeIdentifier(ScopeIdentifier, TypeIdentifier),
FieldPatternList(FieldPattern(FieldIdentifier, BoundIdentifier))),
Identifier)))))
# Captured patterns
match x {
a @ A(_) | b @ B(..) => a,
a @ 1 ... 5 => a,
Some(1 ... 5) => a,
a @ b...c => a,
a @ b..=c => a,
}
==>
SourceFile(
ExpressionStatement(MatchExpression(match,
Identifier,
MatchBlock(
MatchArm(
OrPattern(
CapturedPattern(
BoundIdentifier,
TuplePattern(TypeIdentifier, _)),
CapturedPattern(
BoundIdentifier,
TuplePattern(TypeIdentifier))),
Identifier),
MatchArm(
CapturedPattern(
BoundIdentifier,
RangePattern(Integer, Integer)),
Identifier),
MatchArm(
TuplePattern(
TypeIdentifier,
RangePattern(Integer, Integer)),
Identifier),
MatchArm(
CapturedPattern(
BoundIdentifier,
RangePattern(Identifier, Identifier)),
Identifier),
MatchArm(
CapturedPattern(
BoundIdentifier,
RangePattern(Identifier, Identifier)),
Identifier)))))
# Or patterns
if let A(x) | B(x) = expr {
do_stuff_with(x);
}
while let A(x) | B(x) = expr {
do_stuff_with(x);
}
let Ok(index) | Err(index) = slice.binary_search(&x);
for ref a | b in c {}
let Ok(x) | Err(x) = binary_search(x);
for A | B | C in c {}
|(Ok(x) | Err(x))| expr();
let ref mut x @ (A | B | C);
fn foo((1 | 2 | 3): u8) {}
==>
SourceFile(
ExpressionStatement(IfExpression(if,
LetDeclaration(let,
OrPattern(
TuplePattern(TypeIdentifier, BoundIdentifier),
TuplePattern(TypeIdentifier, BoundIdentifier)),
Identifier),
Block(
ExpressionStatement(CallExpression(Identifier, ArgList(Identifier)))))),
ExpressionStatement(WhileExpression(while,
LetDeclaration(let,
OrPattern(
TuplePattern(TypeIdentifier, BoundIdentifier),
TuplePattern(TypeIdentifier, BoundIdentifier)),
Identifier),
Block(
ExpressionStatement(CallExpression(Identifier,ArgList(Identifier)))))),
LetDeclaration(let,
OrPattern(
TuplePattern(TypeIdentifier, BoundIdentifier),
TuplePattern(TypeIdentifier, BoundIdentifier)),
CallExpression(FieldExpression(Identifier, FieldIdentifier),
ArgList(ReferenceExpression(Identifier)))),
ExpressionStatement(ForExpression(for,
OrPattern(RefPattern(ref, BoundIdentifier), BoundIdentifier),
in, Identifier,
Block)),
LetDeclaration(let,
OrPattern(
TuplePattern(TypeIdentifier, BoundIdentifier),
TuplePattern(TypeIdentifier, BoundIdentifier)),
CallExpression(Identifier, ArgList(Identifier))),
ExpressionStatement(ForExpression(for,
OrPattern(OrPattern(BoundIdentifier, BoundIdentifier), BoundIdentifier),
in, Identifier,
Block)),
ExpressionStatement(ClosureExpression(
ParamList(Parameter(TuplePattern(
OrPattern(
TuplePattern(TypeIdentifier, BoundIdentifier),
TuplePattern(TypeIdentifier, BoundIdentifier))))),
CallExpression(Identifier, ArgList))),
LetDeclaration(let,
RefPattern(ref,
MutPattern(
mut,
CapturedPattern(
BoundIdentifier,
TuplePattern(
OrPattern(OrPattern(BoundIdentifier, BoundIdentifier), BoundIdentifier)))))),
FunctionItem(fn,
BoundIdentifier,
ParamList(
Parameter(
TuplePattern(
OrPattern(OrPattern(LiteralPattern(Integer), LiteralPattern(Integer)), LiteralPattern(Integer))),
TypeIdentifier)),
Block))
+16
View File
@@ -0,0 +1,16 @@
import {parser} from "../dist/index.js"
import {fileTests} from "@lezer/generator/dist/test"
import * as fs from "fs"
import * as path from "path"
import {fileURLToPath} from "url"
let caseDir = path.dirname(fileURLToPath(import.meta.url))
for (let file of fs.readdirSync(caseDir)) {
if (!/\.txt$/.test(file)) continue
let name = /^[^\.]*/.exec(file)[0]
describe(name, () => {
for (let {name, run} of fileTests(fs.readFileSync(path.join(caseDir, file), "utf8"), file))
it(name, () => run(parser))
})
}
+231
View File
@@ -0,0 +1,231 @@
# The unit type
type A = ();
==>
SourceFile(
TypeItem(type,TypeIdentifier, UnitType))
# Tuple types
type A = (i32, String);
==>
SourceFile(
TypeItem(type,TypeIdentifier, TupleType(TypeIdentifier, TypeIdentifier)))
# Reference types
type A = &B;
type C = &'a str;
type D = &'a mut str;
==>
SourceFile(
TypeItem(type,TypeIdentifier, ReferenceType(TypeIdentifier)),
TypeItem(type,TypeIdentifier, ReferenceType(Lifetime, TypeIdentifier)),
TypeItem(type,TypeIdentifier, ReferenceType(Lifetime, mut, TypeIdentifier)))
# Raw pointer types
type A = *mut B;
type C = *const str;
==>
SourceFile(
TypeItem(type,TypeIdentifier, PointerType(mut, TypeIdentifier)),
TypeItem(type,TypeIdentifier, PointerType(const, TypeIdentifier)))
# Generic types
type A = B<C>;
type D = E<F, str>;
type G = H<'a, I>;
type J = H<K=L>;
==>
SourceFile(
TypeItem(type,
TypeIdentifier,
GenericType(TypeIdentifier, TypeArgList(TypeIdentifier))),
TypeItem(type,
TypeIdentifier,
GenericType(TypeIdentifier, TypeArgList(TypeIdentifier, TypeIdentifier))),
TypeItem(type,
TypeIdentifier,
GenericType(TypeIdentifier, TypeArgList(Lifetime, TypeIdentifier))),
TypeItem(type,
TypeIdentifier,
GenericType(TypeIdentifier, TypeArgList(TypeBinding(TypeIdentifier, TypeIdentifier)))))
# Scoped types
type A = B::C;
type D = E::F::G;
type H = I::J<K>;
type L = M<N>::O;
==>
SourceFile(
TypeItem(type,
TypeIdentifier,
ScopedTypeIdentifier(ScopeIdentifier, TypeIdentifier)),
TypeItem(type,
TypeIdentifier,
ScopedTypeIdentifier(ScopeIdentifier, ScopeIdentifier, TypeIdentifier)),
TypeItem(type,
TypeIdentifier,
GenericType(
ScopedTypeIdentifier(ScopeIdentifier, TypeIdentifier),
TypeArgList(TypeIdentifier))),
TypeItem(type,
TypeIdentifier,
ScopedTypeIdentifier(
ScopeIdentifier,
TypeArgList(TypeIdentifier),
TypeIdentifier)))
# Array types
type A = [B; 4];
type C = &[D];
==>
SourceFile(
TypeItem(type,TypeIdentifier, ArrayType(TypeIdentifier, Integer)),
TypeItem(type,TypeIdentifier, ReferenceType(ArrayType(TypeIdentifier))))
# Function types
fn high_order1(value: i32, f: fn(i32)) -> i32 {}
fn high_order2(value: i32, f: fn(i32) -> i32) -> i32 {
f(value)
}
fn high_order3(value: i32, f: &FnOnce(i32) -> i32) -> i32 {
f(value)
}
type F = for<'a, 'b> fn(&'a A, &'a B<'i, 't>,) -> C;
==>
SourceFile(
FunctionItem(fn,
BoundIdentifier,
ParamList(
Parameter(BoundIdentifier, TypeIdentifier),
Parameter(BoundIdentifier, FunctionType(fn, ParamList(Parameter(TypeIdentifier))))),
TypeIdentifier,
Block),
FunctionItem(fn,
BoundIdentifier,
ParamList(
Parameter(BoundIdentifier, TypeIdentifier),
Parameter(BoundIdentifier, FunctionType(fn, ParamList(Parameter(TypeIdentifier)), TypeIdentifier))),
TypeIdentifier,
Block(ExpressionStatement(CallExpression(Identifier, ArgList(Identifier))))),
FunctionItem(fn,
BoundIdentifier,
ParamList(
Parameter(BoundIdentifier, TypeIdentifier),
Parameter(BoundIdentifier,
ReferenceType(FunctionType(TypeIdentifier, ParamList(Parameter(TypeIdentifier)), TypeIdentifier)))),
TypeIdentifier, Block(ExpressionStatement(CallExpression(Identifier, ArgList(Identifier))))),
TypeItem(type,
TypeIdentifier,
FunctionType(
ForLifetimes(for, Lifetime, Lifetime),
fn,
ParamList(
Parameter(ReferenceType(Lifetime, TypeIdentifier)),
Parameter(ReferenceType(Lifetime, GenericType(TypeIdentifier, TypeArgList(Lifetime, Lifetime))))),
TypeIdentifier)))
# Unsafe and extern function types
type a = extern "C" fn(*mut c_void);
type b = unsafe extern "C" fn() -> *mut c_void;
==>
SourceFile(
TypeItem(type,
TypeIdentifier,
FunctionType(
extern, String, fn,
ParamList(Parameter(PointerType(mut, TypeIdentifier))))),
TypeItem(type,
TypeIdentifier,
FunctionType(
unsafe, extern, String, fn,
ParamList,
PointerType(mut, TypeIdentifier))))
# Trait objects
type a = Box<Something + 'a>;
type b = Rc<dyn Something>;
type c = A<&dyn Fn(&B) -> C>;
==>
SourceFile(
TypeItem(type,
TypeIdentifier,
GenericType(
TypeIdentifier,
TypeArgList(BoundedType(TypeIdentifier, Lifetime)))),
TypeItem(type,
TypeIdentifier,
GenericType(
TypeIdentifier,
TypeArgList(DynamicType(dyn, TypeIdentifier)))),
TypeItem(type,
TypeIdentifier,
GenericType(
TypeIdentifier,
TypeArgList(
ReferenceType(
DynamicType(dyn, FunctionType(TypeIdentifier, ParamList(Parameter(ReferenceType(TypeIdentifier))), TypeIdentifier)))))))
# Type cast expressions with generics
a as B<C>;
d as *mut E<<F as E>::G>;
==>
SourceFile(
ExpressionStatement(TypeCastExpression(
Identifier,
as,
GenericType(TypeIdentifier, TypeArgList(TypeIdentifier)))),
ExpressionStatement(TypeCastExpression(
Identifier,
as,
PointerType(
mut,
GenericType(
TypeIdentifier,
TypeArgList(
ScopedTypeIdentifier(
QualifiedScope(TypeIdentifier,as,TypeIdentifier), TypeIdentifier)))))))