grammar Meow; file : importStatement* topLevelDeclaration* EOF ; importStatement : ImportKeyword importpath=StringLiteral (AsKeyword importname=Identifier)? ';' ; topLevelDeclaration : unterminatedTopLevelDeclaration ';'? ; unterminatedTopLevelDeclaration : function | constraintDeclaration | structDeclaration | enumDeclaration | tupleDeclaration | typeAlias | topLevelStatement ; topLevelStatement : constantDeclarationStatement ; structDeclaration : attribute* pub=PubKeyword? StructKeyword name=Identifier (genericParameters constraint*)? structType ; enumDeclaration : attribute* pub=PubKeyword? EnumKeyword name=Identifier (genericParameters constraint*)? enumType ; tupleDeclaration : attribute* pub=PubKeyword? TupleKeyword name=Identifier (genericParameters constraint*)? tupleType ; typeAlias : attribute* pub=PubKeyword? TypeKeyword name=Identifier genericParameters? '=' typeReference ; constraintDeclaration : attribute* pub=PubKeyword? ConstraintKeyword name=Identifier types+=Identifier+ '{' constraintRule* '}' ; constraintRule : embedConstraintRule | functionConstraintRule ; embedConstraintRule : ConstraintKeyword name=Identifier types+=typeReference+ ';' ; functionConstraintRule : name=Identifier constraintFunctionParameters functionReturn? ';' ; constraintFunctionParameters : '(' (typeReference (',' typeReference)*)? ')' ; function : attribute* pub=PubKeyword? FnKeyword name=Identifier functionParameters functionReturn? body=blockExpression | attribute* pub=PubKeyword? FnKeyword name=Identifier genericParameters functionParameters functionReturn? constraint* body=blockExpression ; attribute : '[' name=Identifier ('(' (attributeValue (',' attributeValue)*)? ')')? ']' ; attributeValue : literal | id=Identifier ; literal : stringLiteral | numericLiteral | boolLiteral | characterLiteral ; stringLiteral: val=StringLiteral; numericLiteral: val=NumericLiteral; boolLiteral: val=BoolLiteral; characterLiteral: val=CharacterLiteral; genericParameters : '<' (name+=Identifier (',' name+=Identifier)*) '>' ; functionParameters : '(' (functionParameter (',' functionParameter)*)? ')' ; functionParameter : name=Identifier ':' typeReference ; functionReturn : ':' (typeReference (',' typeReference)*) ; constraint : WhereKeyword name=Identifier typenames+=Identifier+ ; typeReference : nonPointerTypeReference pointer='*'? ; nonPointerTypeReference : typeName | arrayType | tupleType | StructKeyword structType | EnumKeyword enumType ; typeName : identifierName ('<' genericType+=typeName (',' genericType+=typeName)* '>')? ('@' name+=Identifier)* ; identifierName : (importName=Identifier ':')? name=Identifier ; arrayType : '[' typeReference (';' length=NumericLiteral)? ']' ; tupleType : '(' typeReference (',' typeReference)* ')' ; structType : '{' structMember+ '}' ; structMember : name=Identifier ':' typeReference ';' ; enumType : '{' enumMember (',' enumMember)* ','? '}' ; enumMember : name=Identifier ('(' typeReference ')')? ; terminatedStatement : statement ';' | blockStatement ; statement : breakStatement | continueStatement | returnStatement | expressionStatement | variableDeclarationStatement | constantDeclarationStatement ; blockStatement : ifExpression | switchExpression | blockExpression | loopStatement ; breakStatement : BreakKeyword label=Identifier? ; variableDeclarationStatement : 'let' name+=Identifier (',' name+= Identifier)* '=' expression ; constantDeclarationStatement : 'const' Identifier (',' name+= Identifier)* '=' expression ; continueStatement : ContinueKeyword label=Identifier? ; returnStatement : ReturnKeyword expression? ; loopStatement : (label=Identifier ':')? LoopKeyword '{' terminatedStatement* '}' | (label=Identifier ':')? LoopKeyword condition=expression '{' terminatedStatement* '}' | (label=Identifier ':')? LoopKeyword (initExpression=expression|initDeclaration=variableDeclarationStatement)? forIndicator=';' condition=expression? ';' increment=expression? '{' terminatedStatement* '}' ; expressionStatement : expression ; expression : assignmentExpression ; assignmentExpression : pattern op=AssignmentOperator logicalOrExpression | logicalOrExpression ; pattern : pointerDereferenceExpression (',' pointerDereferenceExpression)* ; logicalOrExpression : logicalXorExpression ('||' logicalXorExpression)* ; logicalXorExpression : logicalAndExpression ('^^' logicalAndExpression)* ; logicalAndExpression : bitwiseOrExpression ('&&' bitwiseOrExpression)* ; bitwiseOrExpression : bitwiseXorExpression ('|' bitwiseXorExpression)* ; bitwiseXorExpression : bitwiseAndExpression ('^' bitwiseAndExpression)* ; bitwiseAndExpression : equalityExpression ('&' equalityExpression)* ; equalityExpression : relationalExpression ((op+='=='|op+='!=') relationalExpression)* ; relationalExpression : shiftExpression ((op+='<'|op+='>'|op+='<='|op+='>=') shiftExpression)* ; shiftExpression : addExpression ((op+='<<'|op+='>' '>') addExpression)* ; addExpression : multExpression ((op+='+'|op+='-') multExpression)* ; multExpression : unaryExpression ((op+='*'|op+='/'|op+='%') unaryExpression)* ; unaryExpression : (op+='!'|op+='~'|op+='-'|op+='&')* pointerDereferenceExpression ; pointerDereferenceExpression : op+='*'* accessExpression ; accessExpression : terminalExpression accessExpression1? ; accessExpression1 : '[' subscript=expression end=']' accessExpression1? | '.' (name=Identifier|name=NumericLiteral) accessExpression1? ; terminalExpression : literalExpression | nameExpression | structConstructor | arrayConstructor | enumConstructor | tupleConstructor | functionCall | ifExpression | switchExpression | blockExpression | parenthesisExpression ; literalExpression : literal ; nameExpression : identifierName ; structConstructor : typeName? '{' structConstructorMember (',' structConstructorMember)* ','? '}' ; structConstructorMember : name=Identifier ':' expression ; arrayConstructor : (arrayType | typeName? '[' ']') '{' (expression (',' expression)* ','?)? '}' ; enumConstructor : typeName? '\'' name=Identifier ; tupleConstructor : '(' ')' | '(' expression ',' ')' | '(' expression (',' expression)+ ','? ')' ; functionCall : identifierName '(' (expression (',' expression)*)? ')' ; ifExpression : IfKeyword cond=expression then=blockExpression elseIfExpression* (ElseKeyword else=blockExpression)? ; elseIfExpression : ElseKeyword IfKeyword cond=expression then=blockExpression ; switchExpression : SwitchKeyword expression '{' (switchDefault ','?)? '}' | SwitchKeyword expression '{' switchCase (',' switchCase)* (',' switchDefault ','?)? '}' ; switchCase : CaseKeyword literal ':' (expression|FallthroughKeyword) ; switchDefault : DefaultKeyword ':' expression ; blockExpression : '{' terminatedStatement* expression? '}' ; parenthesisExpression : '(' expression ')' ; /////////////////////////// MeowKeyword: 'm' 'e'+ 'o'* 'w' -> channel(HIDDEN); // ignores all me+o*ws in the code NyaKeyword: '-ny' 'a'+ -> channel(HIDDEN); // ignores all -nya+s in the code ImportKeyword: 'import'; AsKeyword: 'as'; PubKeyword: 'pub'; FnKeyword: 'fn'; WhereKeyword: 'where'; ConstraintKeyword: 'constraint'; StructKeyword: 'struct'; EnumKeyword: 'enum'; TupleKeyword: 'tuple'; TypeKeyword: 'type'; BreakKeyword: 'break'; ContinueKeyword: 'continue'; ReturnKeyword: 'return'; LoopKeyword: 'loop'; IfKeyword: 'if'; ElseKeyword: 'else'; SwitchKeyword: 'switch'; CaseKeyword: 'case'; FallthroughKeyword: 'fallthrough'; DefaultKeyword: 'default'; AssignmentOperator: '='|'+='|'-='|'*='|'/='|'%='|'&='|'|='|'^='|'<<='|'>>='; // start with letters (upper or lower case) followed by any alphanumeric symbol Identifier: [a-zA-Z_][a-zA-Z_0-9]*; NumericLiteral: DecimalNumberLiteral /*| HexadecimalNumberLiteral | OctalNumberLiteral | BinaryNumberLiteral*/; fragment DecimalNumberLiteral: '-'? DecimalNumberPart ('.' DecimalNumberPart)? | '.' DecimalNumberPart; fragment DecimalNumberPart: [0-9] [0-9_]*; BoolLiteral: 'true' | 'false' ; CharacterLiteral: '\'' (CharacterEscape | ~['\\]) '\''; fragment CharacterEscape: '\\\'' | '\\\\'; StringLiteral: '"' (StringEscape | ~[\\"])*? '"'; fragment StringEscape: '\\"' | '\\\\'; // comments and white space -> ignored BLOCK_COMMENT: '/*' .*? '*/' -> channel(HIDDEN); LINE_COMMENT: '//' ~[\n]* -> channel(HIDDEN); WS: [ \t\r\n\f]+ -> channel(HIDDEN);