initial commit

This commit is contained in:
me
2024-05-23 15:45:59 +08:00
commit 70275b14e9
55 changed files with 2661 additions and 0 deletions

568
src/main/grammar/main.bnf Normal file
View File

@@ -0,0 +1,568 @@
{
generate=[token-case="as-is" element-case="as-is"]
parserClass="me.zhouxi.slint.lang.parser.SlintParser"
implements="me.zhouxi.slint.lang.psi.SlintPsiElement"
extends="me.zhouxi.slint.lang.psi.SlintPsiElementImpl"
elementTypeHolderClass="me.zhouxi.slint.lang.psi.SlintTypes"
elementTypeClass="me.zhouxi.slint.lang.SlintElementType"
tokenTypeClass="me.zhouxi.slint.lang.SlintTokenType"
psiClassPrefix="Slint"
psiImplClassSuffix="Impl"
psiPackage="me.zhouxi.slint.lang.psi"
psiImplPackage="me.zhouxi.slint.lang.psi.impl"
tokens=[
Comma = ","
FatArrow = "=>"
DoubleArrow = "<=>"
PlusEqual = "+="
MinusEqual = "-="
StarEqual = "*="
DivEqual = "/="
LessEqual = "<="
GreaterEqual = ">="
EqualEqual = "=="
NotEqual = "!="
ColonEqual = ":="
Arrow = "->"
OrOr = "||"
AndAnd = "&&"
LBrace = "{"
RBrace = "}"
LParent = "("
RParent = ")"
LAngle = "<"
RAngle = ">"
LBracket = "["
RBracket = "]"
Plus = "+"
Minus = "-"
Star = "*"
Div = "/"
Equal = "="
Colon = ":"
Comma = ","
Semicolon = ";"
Bang = "!"
Dot = "."
Question = "?"
Dollar = "$"
At = "@"
Pipe = "|"
Percent = "%"
Whitespace = "regexp:(\s+)"
NumberLiteral = "regexp:\d+(\.(\d+)?)?([a-z]+|%)?"
Identifier = "regexp:^[a-zA-Z_][A-Za-z0-9\-_]*"
ColorLiteral = "regexp:#([a-zA-Z0-9]+)"
StringLiteral = 'regexp:(^"[^"\r\n]*")'
LineComment = 'regexp:^//[^\r\n]*'
BlockComment = 'regexp:/\*[\s\S]*?\*/'
]
extends(".*Expression")=Expression
implements(".*Keyword")=[
"me.zhouxi.slint.lang.psi.SlintPsiKeywordIdentifier"
]
}
//
Document ::= DocumentElement*
private recoverTopElement ::= !('component' | 'struct' | 'enum' | 'global'| 'export'|'import' )
private DocumentElement ::= Import | Struct |Export | Enum | GlobalSingleton | Component {
recoverWhile=recoverTopElement
}
GlobalSingleton ::= GlobalKeyword ComponentName ComponentBody {
pin=1
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl"
}
//import 定义
Import ::= ImportKeyword ImportElement? ModuleLocation';'{
pin=1
}
private ImportElement ::= '{' ImportedIdentifier (',' ImportedIdentifier)* ','? '}' FromKeyword {
pin=1
}
// ABc as Def
ImportedIdentifier ::= ReferenceIdentifier ImportAlias?{
pin=1
recoverWhile=AliasNameRecover
}
private AliasNameRecover::=!(','|'}'|';')
private ImportAlias ::= AsKeyword InternalName {
pin=1
}
//Struct 定义
Struct ::= StructKeyword TypeName (':=')? StructBody {
pin=1
}
private StructBody ::= '{' FieldDeclarations? '}'{
pin=1
}
//EnumDeclaration
Enum ::= EnumKeyword EnumName '{' (EnumValue (','EnumValue)*','? )? '}'{
pin=1
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl"
}
//--------------ExportsList -------------------------------------
//ExportsList
Export ::= ExportKeyword ExportElement {
pin=1
}
private ExportElement ::= ExportType | Struct| Component | ExportModule | GlobalSingleton|Enum
ExportType ::= '{' ExportIdentifier (','ExportIdentifier)* ','? '}'{
pin=1
}
ExportIdentifier ::= ReferenceIdentifier ExportAlias?{
}
private ExportAlias ::= AsKeyword ExternalName{
pin=1
}
ExportModule ::= '*' FromKeyword ModuleLocation ';'{
pin=1
}
//---------- component ------------------------------------------------------------
//Component ::= NewComponent
//| LegacyComponent
//Old syntax
//private LegacyComponent ::=(GlobalKeyword ComponentName ':=' ComponentName? ComponentBody)| ('global'? SubComponent)
Component ::= ComponentKeyword ComponentName InheritDeclaration? ComponentBody {
pin=1
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl"
}
//组件定义
//private LegacyComponent ::= (ComponentName|NamedIdentifier ':=' ) ComponentBody
InheritDeclaration ::= InheritsKeyword ReferenceIdentifier {
pin=1
}
ComponentBody ::= '{' ComponentElement* '}'{
pin=1
}
//组件元素定义
private ComponentElement ::=ChildrenPlaceholder| PropertyDeclaration | CallbackDeclaration
| Function | PropertyAnimation | CallbackConnection | Transitions
| PropertyChanged
| States | TwoWayBinding | PropertyBinding | ConditionalElement
| RepetitionElement | SubComponent {
recoverWhile=recoverWhileForComponentBody
}
private recoverWhileForComponentBody::= !(
'property'|'callback'|'changed'
|'states'|'transitions'|'pure'
|'function'|'public'|'protected'|'for'|'if'|'}'|';'|'@'
|GenericIdentifier|PropertyModifier)
ChildrenPlaceholder ::= '@' 'children'{
pin=1
}
//--------------------------------PropertyDeclaration Start----------------------------------------------------
// 属性定义 in property <type> name: value / in property <type> name <=> value
PropertyDeclaration ::= PropertyModifier? PropertyKeyword ('<' Type '>')? PropertyName(PropertyValue|PropertyTwoWayBindingValue|';'){
pin=2
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl"
}
private PropertyModifier ::= InKeyword|OutKeyword|InOutKeyword|PrivateKeyword
private PropertyValue::= ':' BindingStatement {
pin=1
}
private PropertyTwoWayBindingValue ::= '<=>' QualifiedPropertyNameReference ';' {
pin=1
}
//--------------------------------PropertyChanged Start----------------------------------------------------
PropertyChanged ::= ChangedKeyword LocalVariable '=>' CodeBlock{
pin=1
}
//--------------------------------CallbackDeclaration Start----------------------------------------------------
// 回调定义 pure callback abc()->int; callback abc; callback(..);callback()->type;
CallbackDeclaration ::= PureKeyword? CallbackKeyword FunctionName CallbackBinding? ';'{
pin=2
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl"
}
//回调参数定义
CallbackBinding::= CallbackArgument | ('<=>'QualifiedPropertyNameReference)
//入参定义
CallbackArgument ::= '(' (Type (','Type)* ','? )? ')' ReturnType?{
pin=1
}
private ReturnType ::= '->' (NamedType|ArrayType){
pin=1
}
//--------------------------------TwoWayBindingDeclaration Start----------------------------------------------------
//组件双向绑定
TwoWayBinding ::= ReferenceIdentifier '<=>' QualifiedPropertyNameReference ';' {
pin=2
}
//--------------------------------FunctionDeclaration Start----------------------------------------------------
//函数定义 protected? pure? function f()
Function ::= FunctionModifiers? FunctionKeyword FunctionName FunctionArguments ReturnType? CodeBlock{
pin=2
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl"
}
private FunctionModifiers ::= ((PublicKeyword | ProtectedKeyword) PureKeyword?) | (PureKeyword (PublicKeyword | ProtectedKeyword)?)
private FunctionArguments ::= '(' FieldDeclarations* ')'{
pin=1
}
//--------------------------------CallbackConnectionDeclaration Start---------------------------------------------------
//回调绑定定义 abc()=> {}
CallbackConnection ::= FunctionReference CallbackConnectionArguments? '=>' CodeBlock ';'?{
pin=3
}
private CallbackConnectionArguments ::= '(' (LocalVariable (',' LocalVariable)* ','?)? ')'
//--------------------------------ConditionalElementDeclaration Start---------------------------------------------------
ConditionalElement ::= IfKeyword Expression ':' SubComponent{
pin=1
}
RepetitionElement ::= ForKeyword RepetitionVariable InKeyword Expression ':' SubComponent {
pin=1
}
private RepetitionVariable ::= LocalVariable RepetitionIndex?{
pin=1
}
RepetitionIndex ::= '[' LocalVariable ']'{
pin=1
}
//--------------------------------SubElementDeclaration Start---------------------------------------------------
//子组件结构元素定义
SubComponent ::= (PropertyName ':=')? ReferenceIdentifier ComponentBody{
}
//--------------------------------TransitionsDeclaration Start---------------------------------------------------
//过渡绑定
Transitions ::= TransitionsKeyword '[' Transition* ']'{
pin=1
}
//
Transition ::= (InKeyword|OutKeyword) LocalVariable ':' '{' PropertyAnimation* '}'{
pin=1
recoverWhile=recoverForRBracket
}
//--------------------------------TransitionsDeclaration End---------------------------------------------------
// in | out name : { }
States ::= StatesKeyword '[' State* ']'{
pin=1
}
// identifier [when] : { ... }
State ::= LocalVariable StateCondition? ':' '{' StateItem* '}' {
pin=3
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl"
recoverWhile=recoverForRBracket
}
private recoverForRBracket::=!(']'|'}'|';'|GenericIdentifier)
StateCondition ::= WhenKeyword Expression {
pin=1
}
//状态可以由transition propertyBinding 和 animationBinding组成
private StateItem ::= QualifiedNamePropertyBinding | StateTransition
StateTransition ::= (InKeyword|OutKeyword) ':' '{' PropertyAnimation* '}'{
pin=1
}
//------------------------------------------------------------------------------------------
//类型定义
Type ::= NamedType | UnnamedType | ArrayType
private NamedType ::= QualifiedTypeNameReference
ArrayType ::= '[' Type ']'
UnnamedType ::= '{' FieldDeclarations* '}'
private FieldDeclarations ::= FieldDeclaration (',' FieldDeclaration)* ','?
private FieldDeclaration ::= PropertyName ':' Type
//代码块
CodeBlock ::= '{' Statement* '}'{
pin=1
}
private Statement ::= (ReturnStatement|IfElseStatement|ExpressionStatement) ';'?{
recoverWhile=recoverWhileStatement
}
ExpressionStatement ::= Expression (';' &Statement)?
private recoverWhileStatement::=!(GenericIdentifier|';'|'}')
ReturnStatement ::= 'return' (Expression)?{
pin=1
}
private IfElseStatement ::= IfStatement (ElseIfStatement)* ElseStatement?{
pin=1
}
IfStatement ::= IfKeyword Expression CodeBlock {
pin=1
}
ElseIfStatement ::= ElseKeyword IfKeyword Expression CodeBlock{
pin=2
}
ElseStatement ::= ElseKeyword CodeBlock {
pin=1
}
//动画定义
PropertyAnimation ::= AnimateKeyword ('*'| (QualifiedPropertyNameReference (',' QualifiedPropertyNameReference)*)) '{' QualifiedNamePropertyBinding*'}'{
pin=1
}
//组件属性绑定 name: xxx ; name : {}; name : {}
//只有对象定义和表达式需要 ;
private QualifiedNamePropertyBinding::= QualifiedPropertyNameReference ':' BindingStatement{
pin=2
}
PropertyBinding ::= ReferenceIdentifier ':' BindingStatement{
pin=2
}
//优先尝试表达式解析 {}属于代码块 {name:xx}属于表达式那么需要预测后面两个token,第二个token不是':'的情况下才是代码块
//所以优先判断对象创建判断,然后进行代码块判断,最后进行表达式
//代码块分号可选
//表达式需要分号结尾
BindingStatement ::=ObjectCreationExpressionWithSem|(CodeBlock ';'?)| ExpressionWithSem
//用于错误的直观化
private ObjectCreationExpressionWithSem::=ObjectCreationExpression';'{
pin=1
}
private ExpressionWithSem::= Expression ';'{
pin=1
}
//-----------
//////////////////////////////////////////////////////////////////////////////////////////////
//expression
Expression ::= AtExpression
| TernaryExpression
| UnaryExpression
| BinaryExpression
| AdditiveExpression
| MultiplicativeExpression
| ArrayAccessExpression
| ArrayCreationExpression
| ObjectCreationExpression
| AssignmentExpression
| PropertyExpression
| PrimaryExpression
{
recoverWhile=recoverForExpression
}
private recoverForExpression ::= !(Expression|GenericIdentifier|';')
private BinaryExpression ::= SelfAssignExpression | ComparisonExpression | BooleanExpression
//加法表达式
AdditiveExpression ::= Expression ('+'|'-') Expression{
pin=2
}
//乘法表达式
MultiplicativeExpression ::= Expression ('*'|'/')Expression{
pin=2
}
//------------------------------AtExpression---------------------------------------
AtExpression ::= '@' (LineGradient|RadialGradient|ImageUrl|Tr) {
pin=1
}
LineGradient ::= 'linear-gradient' '(' LineGradientArgument ')' {
pin=1
}
private LineGradientArgument ::= Expression (',' ColorStops)? {
pin=1
recoverWhile=recoverForColorStops
}
private recoverForColorStops::=!(Expression|','|')')
RadialGradient ::= 'radial-gradient' '(' RadialGradientArgument ')' {
pin=1
}
private RadialGradientArgument ::= 'circle' (',' ColorStops)?{
pin=1
recoverWhile=recoverForColorStops
}
ImageUrl ::= 'image-url' ImageUrlArgs {
pin=1
}
private ImageUrlArgs ::= '(' RawStringLiteral NineSlice? ')'{
pin=1
recoverWhile=RP
}
NineSlice ::= ',' 'nine-slice' '('Numbers*')'{
// pin=1
}
private RP::=!(';'|'}'|')')
ColorStops ::= ColorStop (','ColorStop)* ','?
ColorStop::= Expression Expression?
Tr::='tr' '(' TrArg (','Expression)* ')'{
pin=2
}
TrArg::= ContextTr | Plurals | SimpleTrText
ContextTr ::= RawStringLiteral '=>' (Plurals|SimpleTrText){
pin=2
}
SimpleTrText::=RawStringLiteral
Plurals ::= RawStringLiteral '|' RawStringLiteral '%' Expression{
pin=2
}
//----------------------------TernaryExpression-----------------------------------------
TernaryExpression ::= Expression '?' Expression ':' Expression
//----------------------------BooleanExpression-----------------------------------------
BooleanExpression ::= Expression ('&&' | '||') Expression{
pin=2
}
ComparisonExpression ::= Expression ('>='|'<='|'=='|'!='|'>'|'<') Expression{
pin=2
}
AssignmentExpression ::= Expression '=' Expression
SelfAssignExpression ::= Expression ('+='|'-='|'/='|'*='|'=') Expression
UnaryExpression ::= ('!' | '+' | '-') Expression{
pin=1
}
private PrimaryExpression::=ParenthesizedExpression|FunctionInvocationExpression|LiteralExpression
ParenthesizedExpression ::= '(' Expression ')'{
pin=2
}
//fake PropertySuffixExpression::= Expression? '.' GenericIdentifier
PropertyExpression ::= Expression '.' GenericIdentifier {
// pin=2 extends=PropertySuffixExpression elementType=PropertySuffixExpression
}
FunctionInvocationExpression ::= Expression '(' InvocationArguments? ')'{
extends=PropertyExpression
}
InvocationArguments ::= Expression (','Expression)* ','?{
recoverWhile=recoverOnRP
}
private recoverOnRP::=!(')')
ArrayAccessExpression ::=Expression '[' Expression ']'
ArrayCreationExpression ::= '[' ArrayElements* ']'{
pin=1
}
private ArrayElements ::= Expression (','Expression)* ','?
LiteralExpression ::= Numbers | RawStringLiteral | GenericIdentifier | RawColorLiteral
//-------------------------------------------------
//-------------------------------------------------
ObjectCreationExpression ::= '{' ObjectPropertyBindings '}'{
pin=2
}
private ObjectPropertyBindings ::= ObjectPropertyBinding (','ObjectPropertyBinding)* ','?{
pin=1
}
private ObjectPropertyBinding ::= PropertyName ':' Expression{
pin=2
recoverWhile=recover
}
private recover::=!(';'|'}'|',')
//-------------------------------For Keyword highlighting------------------------------------
ComponentKeyword ::= 'component'
StructKeyword ::='struct'
EnumKeyword::='enum'
GlobalKeyword::='global'
ExportKeyword::='export'
ImportKeyword::='import'
AsKeyword::='as'
FromKeyword::='from'
InheritsKeyword::='inherits'
PropertyKeyword::='property'
CallbackKeyword::='callback'
StatesKeyword::='states'
TransitionsKeyword::='transitions'
PureKeyword::='pure'
FunctionKeyword::='function'
PublicKeyword::='public'
ProtectedKeyword::='protected'
ForKeyword::='for'
IfKeyword::='if'
ChangedKeyword::='changed'
InKeyword::='in'
WhenKeyword::='when'
ElseKeyword::='else'
AnimateKeyword::='animate'
OutKeyword::='out'
InOutKeyword::='in-out'
PrivateKeyword::='private'
//---------NamedIdentifier ,简化PsiTree-----------------------------------
//noinspection BnfUnusedRule 用于标记命名节点对应的identifier
Named ::= PropertyName | TypeName |ExternalName | InternalName|ComponentName|FunctionName{
pin=1
}
{
extends("PropertyName|TypeName|ComponentName|FunctionName")=Named
}
LocalVariable ::= GenericIdentifier{
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl"
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
}
FunctionName ::= GenericIdentifier
ComponentName ::=GenericIdentifier
InternalName ::= GenericIdentifier{
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl"
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
}
PropertyName ::= GenericIdentifier
TypeName ::= GenericIdentifier
EnumName ::= GenericIdentifier
EnumValue ::=GenericIdentifier
ExternalName ::=GenericIdentifier{
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl"
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
}
ReferenceIdentifier::=GenericIdentifier{
mixin="me.zhouxi.slint.lang.psi.impl.SlintReferencedIdentifierMixinImpl"
}
//----------UnnamedIdentifier------------------
PropertyNameReference ::= GenericIdentifier{
mixin="me.zhouxi.slint.lang.psi.impl.SlintReferencedIdentifierMixinImpl"
}
FunctionReference ::=GenericIdentifier{
}
QualifiedPropertyNameReference ::= PropertyNameReference ('.' PropertyNameReference)*{
extends=PropertyNameReference
}
TypeNameReference::=GenericIdentifier
QualifiedTypeNameReference ::= TypeNameReference ('.' TypeNameReference)*{
extends=TypeNameReference
}
ModuleLocation ::= RawStringLiteral{
mixin="me.zhouxi.slint.lang.psi.impl.SlintReferencedIdentifierMixinImpl"
}
//
//noinspection BnfSuspiciousToken
private RawStringLiteral ::= StringLiteral
//noinspection BnfSuspiciousToken
private Numbers ::= NumberLiteral
//noinspection BnfSuspiciousToken
private GenericIdentifier::= Identifier
//noinspection BnfSuspiciousToken
private RawColorLiteral ::= ColorLiteral