meowlang/parser/Meow.g4

413 lines
9.1 KiB
Plaintext
Raw Normal View History

2022-02-12 02:29:25 +01:00
grammar Meow;
file
2022-02-12 18:30:04 +01:00
: importStatement* topLevelDeclaration* EOF
2022-02-12 02:29:25 +01:00
;
importStatement
: ImportKeyword importpath=StringLiteral (AsKeyword importname=Identifier)? ';'
;
2022-02-12 18:30:04 +01:00
topLevelDeclaration
: unterminatedTopLevelDeclaration ';'?
;
unterminatedTopLevelDeclaration
: function
| constraintDeclaration
| structDeclaration
| enumDeclaration
| tupleDeclaration
| typeAlias
| topLevelStatement
;
topLevelStatement
: constantDeclarationStatement
;
2022-02-12 02:29:25 +01:00
structDeclaration
2022-02-12 18:30:04 +01:00
: attribute* pub=PubKeyword? StructKeyword name=Identifier (genericParameters constraint*)? structType
2022-02-12 02:29:25 +01:00
;
enumDeclaration
2022-02-12 18:30:04 +01:00
: attribute* pub=PubKeyword? EnumKeyword name=Identifier (genericParameters constraint*)? enumType
2022-02-12 02:29:25 +01:00
;
tupleDeclaration
2022-02-12 18:30:04 +01:00
: attribute* pub=PubKeyword? TupleKeyword name=Identifier (genericParameters constraint*)? tupleType
2022-02-12 02:29:25 +01:00
;
typeAlias
2022-02-12 18:30:04 +01:00
: attribute* pub=PubKeyword? TypeKeyword name=Identifier genericParameters? '=' typeReference
2022-02-12 02:29:25 +01:00
;
constraintDeclaration
2022-02-12 18:30:04 +01:00
: attribute* pub=PubKeyword? ConstraintKeyword name=Identifier types+=Identifier+ '{' constraintRule* '}'
2022-02-12 02:29:25 +01:00
;
constraintRule
: embedConstraintRule
| functionConstraintRule
;
embedConstraintRule
: ConstraintKeyword name=Identifier types+=typeReference+ ';'
;
functionConstraintRule
: name=Identifier constraintFunctionParameters functionReturn? ';'
;
constraintFunctionParameters
: '(' (typeReference (',' typeReference)*)? ')'
;
function
2022-02-12 18:30:04 +01:00
: attribute* pub=PubKeyword? FnKeyword name=Identifier functionParameters functionReturn? body=blockExpression
| attribute* pub=PubKeyword? FnKeyword name=Identifier genericParameters functionParameters functionReturn? constraint* body=blockExpression
2022-02-12 02:29:25 +01:00
;
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
2022-02-12 18:30:04 +01:00
: name=Identifier ':' typeReference
2022-02-12 02:29:25 +01:00
;
functionReturn
2022-02-12 18:30:04 +01:00
: ':' (typeReference (',' typeReference)*)
2022-02-12 02:29:25 +01:00
;
constraint
: WhereKeyword name=Identifier typenames+=Identifier+
;
typeReference
: nonPointerTypeReference pointer='*'?
;
nonPointerTypeReference
: typeName
| arrayType
| tupleType
| StructKeyword structType
| EnumKeyword enumType
;
2022-02-12 18:30:04 +01:00
2022-02-12 02:29:25 +01:00
typeName
2022-02-12 18:30:04 +01:00
: identifierName ('<' genericType+=typeName (',' genericType+=typeName)* '>')? ('@' name+=Identifier)*
;
identifierName
: (importName=Identifier ':')? name=Identifier
2022-02-12 02:29:25 +01:00
;
arrayType
: '[' typeReference (';' length=NumericLiteral)? ']'
;
tupleType
: '(' typeReference (',' typeReference)* ')'
;
structType
2022-02-12 18:30:04 +01:00
: '{' structMember+ '}'
2022-02-12 02:29:25 +01:00
;
structMember
2022-02-12 18:30:04 +01:00
: name=Identifier ':' typeReference ';'
2022-02-12 02:29:25 +01:00
;
enumType
: '{' enumMember (',' enumMember)* ','? '}'
;
enumMember
: name=Identifier ('(' typeReference ')')?
;
2022-02-12 18:30:04 +01:00
terminatedStatement
: statement ';'
| blockStatement
;
2022-02-12 02:29:25 +01:00
statement
: breakStatement
| continueStatement
| returnStatement
| expressionStatement
2022-02-12 18:30:04 +01:00
| variableDeclarationStatement
| constantDeclarationStatement
;
blockStatement
: ifExpression
| switchExpression
| blockExpression
| loopStatement
2022-02-12 02:29:25 +01:00
;
breakStatement
2022-02-12 18:30:04 +01:00
: BreakKeyword label=Identifier?
;
variableDeclarationStatement
: 'let' name+=Identifier (',' name+= Identifier)* '=' expression
;
constantDeclarationStatement
: 'const' Identifier (',' name+= Identifier)* '=' expression
2022-02-12 02:29:25 +01:00
;
2022-02-12 18:30:04 +01:00
2022-02-12 02:29:25 +01:00
continueStatement
2022-02-12 18:30:04 +01:00
: ContinueKeyword label=Identifier?
2022-02-12 02:29:25 +01:00
;
returnStatement
2022-02-12 18:30:04 +01:00
: ReturnKeyword expression?
2022-02-12 02:29:25 +01:00
;
loopStatement
2022-02-12 18:30:04 +01:00
: (label=Identifier ':')? LoopKeyword '{' terminatedStatement* '}'
| (label=Identifier ':')? LoopKeyword condition=expression '{' terminatedStatement* '}'
| (label=Identifier ':')? LoopKeyword (initExpression=expression|initDeclaration=variableDeclarationStatement)? forIndicator=';' condition=expression? ';' increment=expression? '{' terminatedStatement* '}'
2022-02-12 02:29:25 +01:00
;
expressionStatement
2022-02-12 18:30:04 +01:00
: expression
;
2022-02-12 02:29:25 +01:00
expression
2022-02-12 18:30:04 +01:00
: assignmentExpression
;
assignmentExpression
: pattern op=AssignmentOperator logicalOrExpression
| logicalOrExpression
2022-02-12 02:29:25 +01:00
;
2022-02-12 18:30:04 +01:00
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)*
;
2022-02-12 02:29:25 +01:00
addExpression
2022-02-12 18:30:04 +01:00
: multExpression ((op+='+'|op+='-') multExpression)*
2022-02-12 02:29:25 +01:00
;
multExpression
2022-02-12 18:30:04 +01:00
: unaryExpression ((op+='*'|op+='/'|op+='%') unaryExpression)*
;
unaryExpression
: (op+='!'|op+='~'|op+='-'|op+='&')* pointerDereferenceExpression
;
pointerDereferenceExpression
: op+='*'* accessExpression
2022-02-12 02:29:25 +01:00
;
2022-02-12 18:30:04 +01:00
accessExpression
: terminalExpression accessExpression1?
;
accessExpression1
: '[' subscript=expression end=']' accessExpression1?
| '.' (name=Identifier|name=NumericLiteral) accessExpression1?
;
2022-02-12 02:29:25 +01:00
terminalExpression
2022-02-12 18:30:04 +01:00
: literalExpression
| nameExpression
2022-02-12 02:29:25 +01:00
| structConstructor
| arrayConstructor
| enumConstructor
2022-02-12 18:30:04 +01:00
| tupleConstructor
2022-02-12 02:29:25 +01:00
| functionCall
| ifExpression
| switchExpression
| blockExpression
| parenthesisExpression
;
2022-02-12 18:30:04 +01:00
literalExpression
: literal
;
2022-02-12 02:29:25 +01:00
2022-02-12 18:30:04 +01:00
nameExpression
: identifierName
;
structConstructor
: typeName? '{' structConstructorMember (',' structConstructorMember)* ','? '}'
;
structConstructorMember
: name=Identifier ':' expression
;
arrayConstructor
: (arrayType | typeName? '[' ']') '{' (expression (',' expression)* ','?)? '}'
;
enumConstructor
: typeName? '\'' name=Identifier
;
tupleConstructor
: '(' ')'
| '(' expression ',' ')'
| '(' expression (',' expression)+ ','? ')'
;
2022-02-12 02:29:25 +01:00
2022-02-12 18:30:04 +01:00
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
2022-02-12 02:29:25 +01:00
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';
2022-02-12 18:30:04 +01:00
IfKeyword: 'if';
ElseKeyword: 'else';
SwitchKeyword: 'switch';
CaseKeyword: 'case';
FallthroughKeyword: 'fallthrough';
DefaultKeyword: 'default';
AssignmentOperator: '='|'+='|'-='|'*='|'/='|'%='|'&='|'|='|'^='|'<<='|'>>=';
2022-02-12 02:29:25 +01:00
// 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;
2022-02-12 02:29:25 +01:00
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);