Move rules from lexer to parser. Fix some bugs found in manual testing. Add bugs found via manual testing to new lua test file.

This commit is contained in:
Matt Hargett 2022-09-07 19:29:55 -07:00
parent c59ee1d55d
commit 026015954a
3 changed files with 128 additions and 67 deletions

View File

@ -91,7 +91,7 @@ stat
| 'function' funcname funcbody
| 'local' 'function' NAME funcbody
| 'local' bindinglist ('=' explist)?
| ('export')? 'type' NAME ('<' GenericTypeParameterList '>')? '=' Type
| ('export')? 'type' NAME ('<' genericTypeParameterList '>')? '=' type
;
attnamelist
@ -115,7 +115,7 @@ funcname
;
funcbody
: ('<' GenericTypeParameterList '>')? '(' parlist? ')' (':' '...'? ReturnType ) block 'end' // GenericTypeParameterList and ReturnType
: ('<' genericTypeParameterList '>')? '(' parlist? ')' (':' '...'? returnType ) block 'end' // genericTypeParameterList and returnType
;
parlist
@ -131,7 +131,7 @@ namelist
;
binding
: NAME (':' Type ('?')?)?
: NAME (':' type ('?')?)?
;
bindinglist: binding (',' bindinglist)?;
@ -158,10 +158,10 @@ exp
ifelseexp: 'if' exp 'then' exp ('elseif' exp 'then' exp)* 'else' exp;
asexp: simpleexp ('::' Type)?;
asexp: simpleexp ('::' type)?;
simpleexp
: 'nil' | 'false' | 'true'
: NIL | BOOLEAN
| number
| string
| '...'
@ -242,73 +242,81 @@ number
;
string
: NORMALSTRING | CHARSTRING | LONGSTRING
: NORMALSTRING | LONGSTRING
;
SimpleType
: 'nil'
| SingletonType
| NAME /* ('.' NAME)? */ ('<' TypeParams '>')?
simpleType
: NIL
| singletonType
| NAME ('.' NAME)? ('<' typeParams '>')?
| 'typeof' '(' NAME ('(' ')')? | '...' ')' // can't use `exp`, manually handle common cases
| TableType
| FunctionType
| tableType
| functionType
;
SingletonType
: NORMALSTRING | CHARSTRING
| 'true'
| 'false'
singletonType
: NORMALSTRING | BOOLEAN
;
Type
: SimpleType ('?')?
| SimpleType ('?')? ('|' Type) // can't use Type because it's mutually left-recursive
| SimpleType ('?')? ('&' Type) // can't use Type because it's mutually left-recursive
type
: simpleType ('?')?
| simpleType ('?')? ('|' type) // can't use type because it's mutually left-recursive
| simpleType ('?')? ('&' type) // can't use type because it's mutually left-recursive
;
GenericTypePackParameter: NAME '...' ('=' (('(' (TypeList)? ')') | VariadicTypePack | GenericTypePack))?; // TypePack must be inlined here
genericTypePackParameter: NAME '...' ('=' (('(' (typeList)? ')') | variadicTypePack | genericTypePack))?; // typePack must be inlined here
GenericTypeParameterList: NAME ('=' Type)? (',' GenericTypeParameterList)? | GenericTypePackParameter (',' GenericTypePackParameter)*;
genericTypeParameterList: NAME ('=' type)? (',' genericTypeParameterList)? | genericTypePackParameter (',' genericTypePackParameter)*;
TypeList: Type (',' Type)? | VariadicTypePack;
typeList: type (',' type)? | variadicTypePack;
TypeParams: (Type | VariadicTypePack | GenericTypePack) (',' TypeParams)?; // had to remove TypePack
typeParams: (type | variadicTypePack | genericTypePack) (',' typeParams)?; // had to remove typePack
// TypePack: inlined everywhere to avoid overly greedy match when out-of-context
// typePack: inlined everywhere to avoid overly greedy match when out-of-context
GenericTypePack: NAME '...';
genericTypePack: NAME '...';
VariadicTypePack: '...' Type;
variadicTypePack: '...' type;
ReturnType: Type | '(' Type ',' Type ')' | '(' ')'; // can't use TypePack, inline common cases
returnType: variadicTypePack | '(' typeList ')' | '(' ')'; // can't use typePack, inline common cases
TableIndexer: '[' Type ']' ':' Type;
tableIndexer: '[' type ']' ':' type;
TableProp: NAME ':' Type;
tableProp: NAME ':' type;
TablePropOrIndexer
: TableProp | TableIndexer;
tablePropOrIndexer
: tableProp | tableIndexer;
PropList
: TablePropOrIndexer ((','|';') TablePropOrIndexer)* (','|';')?;
propList
: tablePropOrIndexer ((','|';') tablePropOrIndexer)* (','|';')?;
TableType
: '{' PropList '}';
tableType
: '{' propList '}';
functionType: ('<' genericTypeParameterList '>')? '(' (typeList)? ')' '->' returnType;
require
: 'require' '(' (NAME ('.' NAME)*) | NORMALSTRING ')' ('::' type)?
;
FunctionType: ('<' GenericTypeParameterList '>')? '(' (TypeList)? ')' '->' (Type | '(' ')' | '(' (TypeList) ')'); // inline ReturnType to avoid greediness
// LEXER
NIL
: 'nil'
;
BOOLEAN
: 'true' | 'false'
;
NAME
: [a-zA-Z_][a-zA-Z_0-9]*
;
NORMALSTRING
: '"' ( EscapeSequence | ~('\\'|'"') )* '"'
;
CHARSTRING
: '\'' ( EscapeSequence | ~('\''|'\\') )* '\''
| '\'' ( EscapeSequence | ~('\\'|'\'') )* '\''
;
LONGSTRING
@ -401,7 +409,7 @@ LINE_COMMENT
;
WS
: [ \t\u000C\r\n]+ -> skip
: [ \n\r\t\u000B\u000C\u0000]+ -> channel(HIDDEN)
;
SHEBANG

View File

@ -7,6 +7,10 @@ local _notLiteral = not true
local _notVariable = not x
local _length = #{x}
export type Function<T... = ...any> = (...any) -> T...
local _PlatformService = nil
local game = require(script.Parent.game) :: any
pcall(function() _PlatformService = game:GetService('PlatformService') end)
return function <T>(req, ...: boolean): ({[string|number]: T}, string, Function<...any>)
local body = string.format("%s %s\n", req.method, req.path)

View File

@ -53,18 +53,56 @@ L9
[type] 8 11
[Function] 13 20
[<] 21 21
[T...] 22 25
[T] 22 22
[...] 23 25
[=] 27 27
[...any] 29 34
[...] 29 31
[any] 32 34
[>] 35 35
[=] 37 37
[(] 39 39
[...any] 40 45
[...] 40 42
[any] 43 45
[)] 46 46
[-] 48 48
[>] 49 49
[T...] 51 54
[->] 48 49
[T] 51 51
[...] 52 54
L10
[local] 1 5
[_PlatformService] 7 22
[=] 24 24
[nil] 26 28
L11
[local] 1 5
[game] 7 10
[=] 12 12
[require] 14 20
[(] 21 21
[script] 22 27
[.] 28 28
[Parent] 29 34
[.] 35 35
[game] 36 39
[)] 40 40
[::] 42 43
[any] 45 47
L12
[pcall] 1 5
[(] 6 6
[function] 7 14
[(] 15 15
[)] 16 16
[_PlatformService] 18 33
[=] 35 35
[game] 37 40
[:] 41 41
[GetService] 42 51
[(] 52 52
['PlatformService'] 53 69
[)] 70 70
[end] 72 74
[)] 75 75
L15
[return] 1 6
[function] 8 15
[<] 17 17
@ -81,7 +119,9 @@ L11
[(] 41 41
[{] 42 42
[\[] 43 43
[string|number] 44 56
[string] 44 49
[|] 50 50
[number] 51 56
[\]] 57 57
[:] 58 58
[T] 60 60
@ -89,9 +129,13 @@ L11
[,] 62 62
[string] 64 69
[,] 70 70
[Function<...any>] 72 87
[Function] 72 79
[<] 80 80
[...] 81 83
[any] 84 86
[>] 87 87
[)] 88 88
L12
L16
[local] 3 7
[body] 9 12
[=] 14 14
@ -109,24 +153,24 @@ L12
[.] 56 56
[path] 57 60
[)] 61 61
L13
L17
[local] 3 7
[res] 9 11
[=] 13 13
[{] 15 15
L14
L18
[code] 5 8
[=] 10 10
[200] 12 14
[,] 15 15
L15
L19
[{] 5 5
["Content-Type"] 7 20
[,] 21 21
["text/plain"] 23 34
[}] 36 36
[,] 37 37
L16
L20
[{] 5 5
["Content-Length"] 7 22
[,] 23 23
@ -134,9 +178,12 @@ L16
[body] 26 29
[}] 31 31
[::] 33 34
[Array<any>] 36 45
[Array] 36 40
[<] 41 41
[any] 42 44
[>] 45 45
[,] 46 46
L17
L21
[}] 3 3
[::] 5 6
[{] 8 8
@ -153,7 +200,7 @@ L17
[boolean] 41 47
[>] 48 48
[}] 50 50
L18
L22
[if] 3 4
[(] 6 6
[req] 7 9
@ -163,7 +210,7 @@ L18
[.] 18 18
[keepAlive] 19 27
[then] 29 32
L19
L23
[local] 5 9
[socketType] 11 20
[:] 21 21
@ -176,13 +223,13 @@ L19
[""] 56 57
[::] 59 60
[""] 62 63
L20
L24
[socketType] 5 14
[=] 16 16
["Connection"] 18 29
[::] 31 32
["Connection"] 34 45
L21
L25
[res] 5 7
[\[] 8 8
[#] 9 9
@ -198,7 +245,7 @@ L21
[,] 43 43
["Keep-Alive"] 45 56
[}] 58 58
L22
L26
[res] 5 7
[\[] 8 8
[#] 9 9
@ -210,9 +257,9 @@ L22
[{] 21 21
[...] 23 25
[}] 27 27
L23
L27
[end] 3 5
L25
L29
[return] 3 8
[(] 10 10
[res] 11 13
@ -228,12 +275,14 @@ L25
[,] 37 37
[function] 39 46
[(] 47 47
[...)] 48 51
[...] 48 50
[)] 51 51
[:] 52 52
[...any] 54 59
[...] 54 56
[any] 57 59
[return] 61 66
[...] 68 70
[end] 72 74
L26
L30
[end] 1 3
EOF