Files
intellij-slint/src/main/grammar/main.bnf
2024-05-26 15:15:34 +08:00

576 lines
19 KiB
BNF
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
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.impl.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.keyword.SlintPsiKeywordIdentifier"]
mixin(".*Keyword")="me.zhouxi.slint.lang.psi.keyword.SlintPsiKeywordIdentifierImpl"
}
//
Document ::= DocumentElement*
private recoverTopElement ::= !('component' | 'struct' | 'enum' | 'global'| 'export'|'import' )
private DocumentElement ::= Import | Struct | Enum | GlobalSingleton | Component | Export {
recoverWhile=recoverTopElement
}
GlobalSingleton ::= ExportKeyword? GlobalKeyword ComponentName ComponentBody {
pin=2
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
}
//import 定义
Import ::= ImportKeyword (ImportElement|ImportResource)';'{
pin=1
elementTypeFactory="me.zhouxi.slint.lang.psi.stubs.types.SlintStubTypes.slintImport"
stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintImportStub"
extends="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiElementImpl<?>"
}
ImportElement ::= '{' ImportSpecifier (',' ImportSpecifier)* ','? '}' FromKeyword ModuleLocation{
pin=1
}
ImportResource ::= ModuleLocation
// ABc as Def
ImportSpecifier ::= ReferenceIdentifier ImportAlias?{
pin=1
elementTypeFactory="me.zhouxi.slint.lang.psi.stubs.types.SlintStubTypes.importSpecifier"
stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintImportSpecifierStub"
extends="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiElementImpl<?>"
}
private AliasNameRecover::=!(','|'}'|';')
ImportAlias ::= AsKeyword InternalName {
pin=1
recoverWhile=AliasNameRecover
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
}
//Struct 定义
Struct ::= ExportKeyword? StructKeyword TypeName (':=')? StructBody {
pin=2
}
private StructBody ::= '{' FieldDeclarations? '}'{
pin=1
}
//EnumDeclaration
Enum ::= ExportKeyword? EnumKeyword EnumName '{' (EnumValue (','EnumValue)*','? )? '}'{
pin=2
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
}
//--------------ExportsList -------------------------------------
//ExportsList
Export ::= ExportKeyword (ExportType | ExportModule) {
pin=1
}
ExportType ::= '{' ExportSpecifier (','ExportSpecifier)* ','? '}'{
pin=1
}
ExportSpecifier::= ReferenceIdentifier ExportAlias?{
recoverWhile=AliasNameRecover
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
}
ExportAlias ::= AsKeyword ExternalName{
pin=1
}
ExportModule ::= '*' FromKeyword ModuleLocation ';'{
pin=1
}
Component ::= ExportKeyword? ComponentKeyword ComponentName InheritDeclaration? ComponentBody {
pin=2
implements=[
"me.zhouxi.slint.lang.psi.SlintPsiNamedElement"
]
elementTypeFactory="me.zhouxi.slint.lang.psi.stubs.types.SlintStubTypes.component"
stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintComponentStub"
extends="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiNamedElementImpl<?>"
}
//组件定义
//private LegacyComponent ::= (ComponentName|NamedIdentifier ':=' ) ComponentBody
InheritDeclaration ::= InheritsKeyword ReferenceIdentifier {
pin=1
}
ComponentBody ::= '{' ComponentElement* '}'{
pin=1
recoverWhile=recoverWhileForComponentBody
}
//组件元素定义
private ComponentElement ::=ChildrenPlaceholder| Property | Callback
| Function | PropertyAnimation | CallbackConnection | Transitions
| PropertyChanged
| States | TwoWayBinding | PropertyBinding | ConditionalElement
| RepetitionElement | SubComponent {
recoverWhile(".*")=recoverWhileForComponentBody
}
private recoverWhileForComponentBody::= !('{'|';'|'}'|'@'|GenericIdentifier)
ChildrenPlaceholder ::= '@' 'children'{
pin=1
}
//--------------------------------PropertyDeclaration Start----------------------------------------------------
// 属性定义 in property <type> name: value / in property <type> name <=> value
Property ::= PropertyModifier? PropertyKeyword ('<' Type '>')? PropertyName(PropertyValue|PropertyTwoWayBindingValue|';'){
pin=2
implements=[
"me.zhouxi.slint.lang.psi.SlintPsiNamedElement"
]
elementTypeFactory="me.zhouxi.slint.lang.psi.stubs.types.SlintStubTypes.property"
stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintPropertyStub"
extends="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiNamedElementImpl<?>"
}
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;
Callback ::= PureKeyword? CallbackKeyword FunctionName CallbackBinding? ';'{
pin=2
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
}
//回调参数定义
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"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
}
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{
pin=3
recoverWhile=recoverWhileForComponentBody
}
//--------------------------------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"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
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=recoverWhileForComponentBody
}
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
}
private WhileIdentifier::=!('}'|GenericIdentifier)
//优先尝试表达式解析 {}属于代码块 {name:xx}属于表达式那么需要预测后面两个token,第二个token不是':'的情况下才是代码块
//所以优先判断对象创建判断,然后进行代码块判断,最后进行表达式
//代码块分号可选
//表达式需要分号结尾
BindingStatement ::=ObjectCreationExpressionWithSem|(CodeBlock ';'?)| ExpressionWithSem{
recoverWhile=WhileIdentifier
}
//用于错误的直观化
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|InternalName|ExternalName")=Named
}
LocalVariable ::= GenericIdentifier{
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
}
FunctionName ::= GenericIdentifier
ComponentName ::=GenericIdentifier
InternalName ::= GenericIdentifier
PropertyName ::= GenericIdentifier
TypeName ::= GenericIdentifier
EnumName ::= GenericIdentifier
EnumValue ::=GenericIdentifier
ExternalName ::=GenericIdentifier
ReferenceIdentifier::=GenericIdentifier{
extends="me.zhouxi.slint.lang.psi.impl.SlintReferencedIdentifierImpl"
}
//----------UnnamedIdentifier------------------
PropertyNameReference ::= GenericIdentifier{
extends="me.zhouxi.slint.lang.psi.impl.SlintReferencedIdentifierImpl"
}
FunctionReference ::=GenericIdentifier{
}
QualifiedPropertyNameReference ::= PropertyNameReference ('.' PropertyNameReference)*{
extends=PropertyNameReference
}
TypeNameReference::=GenericIdentifier
QualifiedTypeNameReference ::= TypeNameReference ('.' TypeNameReference)*{
extends=TypeNameReference
}
ModuleLocation ::= RawStringLiteral{
extends="me.zhouxi.slint.lang.psi.impl.SlintReferencedIdentifierImpl"
}
//
//noinspection BnfSuspiciousToken
private RawStringLiteral ::= StringLiteral
//noinspection BnfSuspiciousToken
private Numbers ::= NumberLiteral
//noinspection BnfSuspiciousToken
private GenericIdentifier::= Identifier
//noinspection BnfSuspiciousToken
private RawColorLiteral ::= ColorLiteral