VimL Grammar - kvmamich/ideavim GitHub Wiki

VimL grammar

Target

File = {Statement};

Statements

Statement = LetStatement| UnletStatement | SetStatement | FunctionDefinition | Conditional;

InFunctionStatement = LetStatement | UnletStatement | SetStatement | InFunctionConditional | ReturnStatement;

AssignmentStatement = ((ListItem | Sublist | DictionaryEntry), '=', Expression) |
                      ((InternalVariable | Option), ('=' | '+=' | '-=' | '.='), Expression) |
                      ((EnvironmentVariable | Register), ('=' | '.='), Expression) |
                      ('[', InternalVariable, {',', InternalVariable}, [';', InternalVariable], ']', 
                                                                ('=' | '+=' | '-=' | '.='), Expression);

LetStatement = 'let', ({Variable} | AssignmentStatement);

UnletStatement = 'unl', ['et'], ['!'], InternalVariable, {InternalVariable}; (* up to 20 variables *)

(* Decimal number in LockVariableStatement and UnlockVariableStatement is: 1 <= n <= 100 *)
LockVariableStatement = 'lockv', ['ar'], ['!'], [Decimal], InternalVariable, {InternalVariable}; (* up to 20 variables *)

UnlockVariableStatement = 'unlo', ['ckvar'], ['!'], [Decimal], InternalVariable, {InternalVariable}; (* up to 20 variables *)

SetStatement = 'se', ['t'], [('all', ['&']) | 'termcap' | {SetOption}];

SetOption = (( 'no' | 'inv' ), Identifier) | 
            (Identifier, [ '?' | '!' | '&' ]) |
            (Identifier, ( '=' | ':' | '+=' | '^=' | '-=' ), Expression);

ReturnStatement = 'retu', ['rn'], Expression;

Definition

FunctionDefinition = 'fu', ['nction'], [!], UserFunctionName, '(', [Variable, {',', Variable}], ')',
                     {InFunctionStatement},
                     'endf', ['unction'];

Conditionals

Conditional = 'if', Condition, {Statement}, 
              [{'elsei', ['f'], Condition, {Statement}}],
              ['el', ['se'], {Statement}],
              'en', ['dif'];

InFunctionConditional = 'if', Condition, {InFunctionStatement}, 
                        [{'elsei', ['f'], Condition, {InFunctionStatement}}],
                        ['el', ['se'], {InFunctionStatement}],
                        'en', ['dif'];

Condition = Expression;

Expressions

(* If ExpressionN cannot be parsed, it must be parsed as ExpressionM, M = N + 1. *)
Expression = Expression1;

Expression1 = Expression2, '?', Expression1, ':', Expression1;

Expression2 = Expression3, LogicalOr, Expression3;

Expression3 = Expression4, LogicalAnd, Expression4;

Expression4 = Expression5, ComparisonOperator, Expression5;

Expression5 = Expression6, ('+' | '-' | '.'), Expression6;

Expression6 = Expression7, ('*' | '/' | '%'), Expression7;

Expression7 = UnaryOperator, Expression7;

Expression8 = ListItem | Sublist | DictionaryEntry;

Expression9 = Value | Variable | NestedExpression | FunctionCall;

NestedExpression = '(', Expression, ')';

FunctionCall = Identifier, '(', [FunctionParameter, {',', FunctionParameter}], ')';

FunctionParameter = Expression;

ListItem = Variable, '[', Expression, ']';

Sublist = Variable, '[', Expression, ':', Expression, ']';

DictionaryEntry = Variable, '.', KeyString;

KeyString = (Letter | DecimalDigit | '_'), {(Letter | DecimalDigit | '_')};

Operators

UnaryOperator = '!' | '-' | '+';

BinaryLogicalOperator = LogicalOr | LogicalAnd;

LogicalOr = '||';

LogicalAnd = '&&';

ComparisonOperator = (('==' | '!=' | '>' | '>=' | '<' | '<=' | '=~' | '!~'), ['#' | '?']) | 'is' | 'isnot';

AssignmentOperator = '=' | '+=' | '-=' | '*=' | '/=';

BinaryArithmeticOperator = '+' | '-' | '.' | '*' | '/' | '%';

Various identifiers

UserFunctionName = UppercaseLetter, {Letter | '_' | DecimalDigit};

BuiltInFunctionName = LowercaseLetter, {Letter | '_' | DecimalDigit};

Identifier = Name;

Variable = EnvironmentVariable | Option | Register | InternalVariable | Identifier;

EnvironmentVariable = '$', Name;

Option = '&', [('g' | 'l'), ':'], Name;

Register = '@', Name;

InternalVariable = ('a' | 'b' | 'g' | 'l' | 's' | 't' | 'v' | 'w' ), ':', Name;

Name = ( Letter | '_' ), { ( Letter | '_' | DecimalDigit ) };

Constants

Value = Number | String | Funcref | List | Dictionary;

Dictionary = '{', [(String | Number), ':', Expression], '}';

List = '[', [Value, {',', Value}], ']';

Funcref = 'function(', String, ')';

String = ('"', {AnyCharacter - '"'}, '"') | ("'", {AnyCharacter - "'"}, "'");

Number = Integer | Float;

Integer = DecimalNumber | HexadecimalNumber | OctalNumber;

Float = [ '-' | '+' ], DecimalNumber, '.', DecimalNumber, [ ( 'e' | 'E' ), [ [ '-' | '+' ], DecimalNumber ];

DecimalNumber = '0' | ( [ '-' | '+' ], ( DecimalDigitExcludingZero, { DecimalDigit } ) );

HexadecimalNumber = '0', ( 'x' | 'X' ), HexadecimalDigit, { HexadecimalDigit };

OctalNumber = '0', OctalDigit, { OctalDigit };

Symbols

DecimalDigitExcludingZero = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';

DecimalDigit = '0' | DecimalDigitExcludingZero;

HexadecimalDigit = DecimalDigit | 'a' | 'A' | 'b' | 'B' | 'c' | 'C' | 'd' | 'D' | 'e' | 'E' | 'f' | 'F';

OctalDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7';

Letter = UppercaseLetter | LowercaseLetter;

UppercaseLetter = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' |
                  'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';

LowercaseLetter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' |
                  'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';

Whitespace = ' ', {' '};

NewlineCharacter = [ '\r' | '\r\n' | '\n' ];

AnyCharacter = ? any visible character ?