polserver/lib/Parser/EscriptGrammar/EscriptLexer.g4

263 lines
6.6 KiB
Text
Raw Permalink Normal View History

lexer grammar EscriptLexer;
channels { COMMENTS }
Add support for interpolated strings ("interstrings") (#369) * Update grammar to support interpolated strings * Struct initializers, case switchs are regular strings * Initial stub for interpolated string in AST This splits the previous STRING_LITERAL terminal into a production, stringLiteral, to handle REGULAR_STRING terminal and interpolatedString production. * Change interpolated strings to expressions * Fix mode handling in grammar * Grammar fixes - Fix mode handling in lexer - Interpolated strings only have one expression * Can successfully parse, stub compile interstrings $"He {there + print("hello")}"; * Add formatting string to grammar * Fix tests, and add test stubs * Rename curleys to brace; better AST generation * initial work interstring instruction * Initial work on formatted string instruction: emit * Formatted string instruction: execution * Add simple formatted string test * Add formatted string test src * Review changes #1 - Rename `FormattedString` to `FormatExpression` - Rename overloaded `try_to_format()` to `get_formatted()` * Review changes part 2 - Rename `InterpolatedString` ast node to `InterpolateString` * Review changes part 3 - Modify `ins_interpolate_string` * Review changes part 4 - Remove unused formal parameter * Add negative tests * Spruce up positive tests * Fix braces, escape chars inside interstring * Fix, add tests for escaped char and double brace * Address differences for new lines in tests * Update Escript version * Make empty expression an error * Add documentation for interpolated strings * Quick touchup on docs
2021-03-11 22:48:16 +01:00
@lexer::members
{
int interpolatedStringLevel = 0;
std::stack<int> curlyLevels;
}
// Keywords
IF: 'if';
THEN: 'then';
ELSEIF: 'elseif';
ENDIF: 'endif';
ELSE: 'else';
// '_OptionBracketed';
GOTO: 'goto';
// GOSUB: 'gosub'; // not used??
RETURN: 'return';
TOK_CONST: 'const';
VAR: 'var';
DO: 'do';
DOWHILE: 'dowhile';
WHILE: 'while';
ENDWHILE: 'endwhile';
EXIT: 'exit';
FUNCTION: 'function';
ENDFUNCTION: 'endfunction';
EXPORTED: 'exported';
USE: 'use';
INCLUDE: 'include';
BREAK: 'break';
CONTINUE: 'continue';
FOR: 'for';
ENDFOR: 'endfor';
TO: 'to';
// NEXT: 'next'; // not used?
FOREACH: 'foreach';
ENDFOREACH: 'endforeach';
REPEAT: 'repeat';
UNTIL: 'until';
PROGRAM: 'program';
ENDPROGRAM: 'endprogram';
CASE: 'case';
DEFAULT: 'default';
ENDCASE: 'endcase';
ENUM: 'enum';
ENDENUM: 'endenum';
// Reserved words (future)
DOWNTO: 'downto';
STEP: 'step';
REFERENCE: 'reference';
TOK_OUT: 'out';
INOUT: 'inout';
BYVAL: 'ByVal';
STRING: 'string';
TOK_LONG: 'long';
INTEGER: 'integer';
UNSIGNED: 'unsigned';
SIGNED: 'signed';
REAL: 'real';
FLOAT: 'float';
DOUBLE: 'double';
AS: 'as';
IS: 'is';
// Operators
AND_A: '&&';
AND_B: 'and';
fragment AND: '&&' | 'and';
OR_A: '||';
OR_B: 'or';
fragment OR: '||' | 'or';
BANG_A: '!';
BANG_B: 'not';
fragment BANG: '!' | 'not';
BYREF: 'byref';
UNUSED: 'unused';
TOK_ERROR: 'error';
HASH: 'hash';
DICTIONARY: 'dictionary';
STRUCT: 'struct';
ARRAY: 'array';
STACK: 'stack';
TOK_IN: 'in';
UNINIT: 'uninit';
BOOL_TRUE: 'true';
BOOL_FALSE: 'false';
// Literals
DECIMAL_LITERAL: ('0' | [1-9] Digits?);
HEX_LITERAL: '0' [xX] HexDigits;
OCT_LITERAL: '0' [0-7]+;
BINARY_LITERAL: '0' [bB] [01]+;
FLOAT_LITERAL: (Digits '.' Digits? | '.' Digits) ExponentPart?
| Digits ExponentPart
;
HEX_FLOAT_LITERAL: '0' [xX] (HexDigits '.'? | HexDigits? '.' HexDigits) [pP] [+-]? Digits;
STRING_LITERAL: '"' (~[\\"] | EscapeSequence)* '"';
Add support for interpolated strings ("interstrings") (#369) * Update grammar to support interpolated strings * Struct initializers, case switchs are regular strings * Initial stub for interpolated string in AST This splits the previous STRING_LITERAL terminal into a production, stringLiteral, to handle REGULAR_STRING terminal and interpolatedString production. * Change interpolated strings to expressions * Fix mode handling in grammar * Grammar fixes - Fix mode handling in lexer - Interpolated strings only have one expression * Can successfully parse, stub compile interstrings $"He {there + print("hello")}"; * Add formatting string to grammar * Fix tests, and add test stubs * Rename curleys to brace; better AST generation * initial work interstring instruction * Initial work on formatted string instruction: emit * Formatted string instruction: execution * Add simple formatted string test * Add formatted string test src * Review changes #1 - Rename `FormattedString` to `FormatExpression` - Rename overloaded `try_to_format()` to `get_formatted()` * Review changes part 2 - Rename `InterpolatedString` ast node to `InterpolateString` * Review changes part 3 - Modify `ins_interpolate_string` * Review changes part 4 - Remove unused formal parameter * Add negative tests * Spruce up positive tests * Fix braces, escape chars inside interstring * Fix, add tests for escaped char and double brace * Address differences for new lines in tests * Update Escript version * Make empty expression an error * Add documentation for interpolated strings * Quick touchup on docs
2021-03-11 22:48:16 +01:00
INTERPOLATED_STRING_START: '$"'
{ interpolatedStringLevel++; } -> pushMode(INTERPOLATION_STRING);
// Separators
LPAREN: '(';
RPAREN: ')';
LBRACK: '[';
RBRACK: ']';
Add support for interpolated strings ("interstrings") (#369) * Update grammar to support interpolated strings * Struct initializers, case switchs are regular strings * Initial stub for interpolated string in AST This splits the previous STRING_LITERAL terminal into a production, stringLiteral, to handle REGULAR_STRING terminal and interpolatedString production. * Change interpolated strings to expressions * Fix mode handling in grammar * Grammar fixes - Fix mode handling in lexer - Interpolated strings only have one expression * Can successfully parse, stub compile interstrings $"He {there + print("hello")}"; * Add formatting string to grammar * Fix tests, and add test stubs * Rename curleys to brace; better AST generation * initial work interstring instruction * Initial work on formatted string instruction: emit * Formatted string instruction: execution * Add simple formatted string test * Add formatted string test src * Review changes #1 - Rename `FormattedString` to `FormatExpression` - Rename overloaded `try_to_format()` to `get_formatted()` * Review changes part 2 - Rename `InterpolatedString` ast node to `InterpolateString` * Review changes part 3 - Modify `ins_interpolate_string` * Review changes part 4 - Remove unused formal parameter * Add negative tests * Spruce up positive tests * Fix braces, escape chars inside interstring * Fix, add tests for escaped char and double brace * Address differences for new lines in tests * Update Escript version * Make empty expression an error * Add documentation for interpolated strings * Quick touchup on docs
2021-03-11 22:48:16 +01:00
LBRACE: '{'
{
if ( interpolatedStringLevel > 0 )
{
auto currentLevel = curlyLevels.top();
curlyLevels.pop();
curlyLevels.push( currentLevel + 1 );
}
};
RBRACE: '}'
{
if ( interpolatedStringLevel > 0 )
{
auto currentLevel = curlyLevels.top();
curlyLevels.pop();
curlyLevels.push( currentLevel - 1 );
if ( curlyLevels.top() == 0 )
{
curlyLevels.pop();
skip();
popMode();
}
}
};
DOT: '.';
ARROW: '->';
MUL: '*';
DIV: '/';
MOD: '%';
ADD: '+';
SUB: '-';
ADD_ASSIGN: '+=';
SUB_ASSIGN: '-=';
MUL_ASSIGN: '*=';
DIV_ASSIGN: '/=';
MOD_ASSIGN: '%=';
LE: '<=';
LT: '<';
GE: '>=';
GT: '>';
RSHIFT: '>>';
LSHIFT: '<<';
BITAND: '&';
CARET: '^';
BITOR: '|';
NOTEQUAL_A: '<>';
NOTEQUAL_B: '!=';
fragment NOTEQUAL: '<>' | '!=';
EQUAL_DEPRECATED: '=';
EQUAL: '==';
// && covered above
// || covered above
ASSIGN: ':=';
ADDMEMBER: '.+';
DELMEMBER: '.-';
CHKMEMBER: '.?';
SEMI: ';';
COMMA: ',';
TILDE: '~';
AT: '@';
COLONCOLON: '::';
Add support for interpolated strings ("interstrings") (#369) * Update grammar to support interpolated strings * Struct initializers, case switchs are regular strings * Initial stub for interpolated string in AST This splits the previous STRING_LITERAL terminal into a production, stringLiteral, to handle REGULAR_STRING terminal and interpolatedString production. * Change interpolated strings to expressions * Fix mode handling in grammar * Grammar fixes - Fix mode handling in lexer - Interpolated strings only have one expression * Can successfully parse, stub compile interstrings $"He {there + print("hello")}"; * Add formatting string to grammar * Fix tests, and add test stubs * Rename curleys to brace; better AST generation * initial work interstring instruction * Initial work on formatted string instruction: emit * Formatted string instruction: execution * Add simple formatted string test * Add formatted string test src * Review changes #1 - Rename `FormattedString` to `FormatExpression` - Rename overloaded `try_to_format()` to `get_formatted()` * Review changes part 2 - Rename `InterpolatedString` ast node to `InterpolateString` * Review changes part 3 - Modify `ins_interpolate_string` * Review changes part 4 - Remove unused formal parameter * Add negative tests * Spruce up positive tests * Fix braces, escape chars inside interstring * Fix, add tests for escaped char and double brace * Address differences for new lines in tests * Update Escript version * Make empty expression an error * Add documentation for interpolated strings * Quick touchup on docs
2021-03-11 22:48:16 +01:00
COLON: ':'
{
if (interpolatedStringLevel > 0)
{
int ind = 1;
bool switchToFormatString = true;
Add support for interpolated strings ("interstrings") (#369) * Update grammar to support interpolated strings * Struct initializers, case switchs are regular strings * Initial stub for interpolated string in AST This splits the previous STRING_LITERAL terminal into a production, stringLiteral, to handle REGULAR_STRING terminal and interpolatedString production. * Change interpolated strings to expressions * Fix mode handling in grammar * Grammar fixes - Fix mode handling in lexer - Interpolated strings only have one expression * Can successfully parse, stub compile interstrings $"He {there + print("hello")}"; * Add formatting string to grammar * Fix tests, and add test stubs * Rename curleys to brace; better AST generation * initial work interstring instruction * Initial work on formatted string instruction: emit * Formatted string instruction: execution * Add simple formatted string test * Add formatted string test src * Review changes #1 - Rename `FormattedString` to `FormatExpression` - Rename overloaded `try_to_format()` to `get_formatted()` * Review changes part 2 - Rename `InterpolatedString` ast node to `InterpolateString` * Review changes part 3 - Modify `ins_interpolate_string` * Review changes part 4 - Remove unused formal parameter * Add negative tests * Spruce up positive tests * Fix braces, escape chars inside interstring * Fix, add tests for escaped char and double brace * Address differences for new lines in tests * Update Escript version * Make empty expression an error * Add documentation for interpolated strings * Quick touchup on docs
2021-03-11 22:48:16 +01:00
while (_input->LA(ind) != '}')
{
if (_input->LA(ind) == ':' || _input->LA(ind) == ')')
{
switchToFormatString = false;
break;
}
ind++;
}
if (switchToFormatString)
{
setMode( INTERPOLATION_FORMAT );
}
}
};
INC: '++';
DEC: '--';
ELVIS: '?:';
QUESTION: '?';
// Whitespace and comments
WS: [ \t\r\n\u000C]+ -> channel(HIDDEN);
COMMENT: '/*' .*? '*/' -> channel(COMMENTS);
LINE_COMMENT: '//' ~[\r\n]* -> channel(COMMENTS);
// Identifiers
IDENTIFIER: Letter LetterOrDigit*;
// Fragment rules
fragment ExponentPart
: [eE] [+-]? Digits
;
// We currently allow all escapes, as they are checked during semantic analysis.
fragment EscapeSequence
: '\\' [xX] HexDigit HexDigit
| '\\' .
;
fragment HexDigits
: HexDigit HexDigit*
;
fragment HexDigit
: [0-9a-fA-F]
;
fragment Digits
: [0-9] [0-9]*
;
fragment LetterOrDigit
: Letter
| [0-9]
;
fragment Letter
: [a-zA-Z$_]
| ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate
| [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
;
Add support for interpolated strings ("interstrings") (#369) * Update grammar to support interpolated strings * Struct initializers, case switchs are regular strings * Initial stub for interpolated string in AST This splits the previous STRING_LITERAL terminal into a production, stringLiteral, to handle REGULAR_STRING terminal and interpolatedString production. * Change interpolated strings to expressions * Fix mode handling in grammar * Grammar fixes - Fix mode handling in lexer - Interpolated strings only have one expression * Can successfully parse, stub compile interstrings $"He {there + print("hello")}"; * Add formatting string to grammar * Fix tests, and add test stubs * Rename curleys to brace; better AST generation * initial work interstring instruction * Initial work on formatted string instruction: emit * Formatted string instruction: execution * Add simple formatted string test * Add formatted string test src * Review changes #1 - Rename `FormattedString` to `FormatExpression` - Rename overloaded `try_to_format()` to `get_formatted()` * Review changes part 2 - Rename `InterpolatedString` ast node to `InterpolateString` * Review changes part 3 - Modify `ins_interpolate_string` * Review changes part 4 - Remove unused formal parameter * Add negative tests * Spruce up positive tests * Fix braces, escape chars inside interstring * Fix, add tests for escaped char and double brace * Address differences for new lines in tests * Update Escript version * Make empty expression an error * Add documentation for interpolated strings * Quick touchup on docs
2021-03-11 22:48:16 +01:00
mode INTERPOLATION_STRING;
DOUBLE_LBRACE_INSIDE: '{{';
LBRACE_INSIDE: '{' { curlyLevels.push(1); } -> pushMode(DEFAULT_MODE);
REGULAR_CHAR_INSIDE: EscapeSequence;
DOUBLE_QUOTE_INSIDE: '"' { interpolatedStringLevel--; } -> popMode;
DOUBLE_RBRACE: '}}';
STRING_LITERAL_INSIDE: ~('{' | '}' | '\\' | '"')+;
Add support for interpolated strings ("interstrings") (#369) * Update grammar to support interpolated strings * Struct initializers, case switchs are regular strings * Initial stub for interpolated string in AST This splits the previous STRING_LITERAL terminal into a production, stringLiteral, to handle REGULAR_STRING terminal and interpolatedString production. * Change interpolated strings to expressions * Fix mode handling in grammar * Grammar fixes - Fix mode handling in lexer - Interpolated strings only have one expression * Can successfully parse, stub compile interstrings $"He {there + print("hello")}"; * Add formatting string to grammar * Fix tests, and add test stubs * Rename curleys to brace; better AST generation * initial work interstring instruction * Initial work on formatted string instruction: emit * Formatted string instruction: execution * Add simple formatted string test * Add formatted string test src * Review changes #1 - Rename `FormattedString` to `FormatExpression` - Rename overloaded `try_to_format()` to `get_formatted()` * Review changes part 2 - Rename `InterpolatedString` ast node to `InterpolateString` * Review changes part 3 - Modify `ins_interpolate_string` * Review changes part 4 - Remove unused formal parameter * Add negative tests * Spruce up positive tests * Fix braces, escape chars inside interstring * Fix, add tests for escaped char and double brace * Address differences for new lines in tests * Update Escript version * Make empty expression an error * Add documentation for interpolated strings * Quick touchup on docs
2021-03-11 22:48:16 +01:00
mode INTERPOLATION_FORMAT;
DOUBLE_RBRACE_INSIDE: '}}' -> type(FORMAT_STRING);
CLOSE_RBRACE_INSIDE: '}' { curlyLevels.pop(); } -> skip, popMode;
FORMAT_STRING: ~'}'+;