teal-language / tl

The compiler for Teal, a typed dialect of Lua
MIT License
2.03k stars 101 forks source link

Reusing the grammar #704

Closed jorgeleo closed 8 months ago

jorgeleo commented 8 months ago

Hi,

What is the licensing of teal? I am trying to write a typed lua for .net. I want to integrate with monaco editor with better intellisense integration. and i would like to use your grammar.

lenscas commented 8 months ago

https://github.com/teal-language/tl/blob/master/LICENSE

jorgeleo commented 8 months ago

Thank you!

jorgeleo commented 8 months ago

Here is the ANTLR version... just in case:

parser grammar TypedMoon;

start_: chunk EOF;

chunk: block;

block: stat* retstat?;

stat: ';' |
       varlist '=' explist |
       functioncall |
       label |
       'break' |
       'goto' Name |
       'do' block 'end' |
       'while' exp 'do' block 'end' |
       'repeat' block 'until' exp |
       'if' exp 'then' block ('elseif' exp 'then'block)* ('else' block)? 'end' |
       'for' Name '=' exp ',' exp (',' exp)? 'do' block 'end' |
       'for' namelist 'in' explist 'do' block 'end' |
       'function' funcname funcbody |
       'local' attnamelist (':' typelist)? ('=' explist)? |
       'local' 'function' Name funcbody |
       'local' 'record' Name recordbody |
       'local' 'enum' Name enumbody |
       'local' 'type' Name '=' newtype |
       'global' attnamelist ':' typelist ('=' explist)? |
       'global' attnamelist '=' explist |
       'global' 'function' Name funcbody |
       'global' 'record' Name recordbody |
       'global' 'enum' Name enumbody |
       'global' 'type' Name ('=' newtype)?
       ;

attnamelist: Name attrib? (',' Name attrib?)*;

attrib: '<' Name '>';

retstat : 'return' (explist)? (';')?;

label : '::' Name '::';

funcname : Name ('.' Name)* ':' Name | 
            Name ('.' Name)* '.' Name;

varlist : var (',' var)*;

var :  Name | 
        prefixexp '[' exp ']' | 
        prefixexp '.' Name;

namelist : Name (',' Name)*;

explist : exp (',' exp)*;

exp :  'nil' | 
        'false' | 
        'true' | 
        Numeral | 
        LiteralString | 
        '...' | 
        functiondef |
        prefixexp | 
        tableconstructor | 
        exp binop exp | 
        unop exp |
        exp 'as' type | 
        exp 'as' '(' typelist ')' | 
        Name 'is' type;

prefixexp : var | 
            functioncall | 
            '(' exp ')';

functioncall :  prefixexp args | 
                prefixexp ':' Name args;

args :  '(' (explist)? ')' | 
        tableconstructor | 
        LiteralString;

functiondef : 'function' funcbody;

funcbody : (typeargs)? '(' (parlist)? ')' (':' retlist)? block 'end';

parlist : parnamelist (',' '...' (':' type)?)? | 
            '...' (':' type)?;

tableconstructor : '{' (fieldlist)? '}';

fieldlist : field (fieldsep field)* (fieldsep)?;

field : '[' exp ']' '=' exp |
       Name (':' type)? '=' exp |
       exp;

fieldsep : ',' | 
            ';';

binop :  '+' | 
        '-' | 
        '*' | 
        '/' | 
        '//' | 
        '^' | 
        '%' |
        '&' | 
        '~' | 
        '|' | 
        '>>' | 
        '<<' | 
        '..' |
        '<' | 
        '<=' | 
        '>' | 
        '>=' | 
        '==' | 
        '~=' |
        'and' | 
        'or';

unop : '-' | 
        'not' | 
        '#' | 
        '~';

type : '(' type ')' | 
        basetype ('|' basetype)*;

basetype : 'string' | 
            'boolean' | 
            'nil' | 
            'number' |
            '{' type (',' type)* '}' | 
            '{' type ':' type '}' | 
            functiontype
            | Name ('.' Name )* (typeargs)?;

typelist : type (',' type)*;

retlist : '(' (typelist)? ('...')? ')' | 
            typelist ('...')?;

typeargs : '<' Name (',' Name )* '>';

newtype : 'record' recordbody | 
            'enum' enumbody | 
            type;

recordbody : (typeargs)? (recordentry)* 'end';

recordentry : 'userdata' | 
            '{' type '}' |
            'type' Name '=' newtype | 
            ('metamethod')? recordkey ':' type |
            'record' recordbody | 
            'enum' enumbody;

recordkey : Name | 
            '[' LiteralString ']';

enumbody : (LiteralString)* 'end';

functiontype : 'function' (typeargs)? '(' partypelist ')' (':' retlist)?;

partypelist : partype (',' partype)*;

partype : (Name ':')? type;

parnamelist : parname (',' parname)*;

parname : Name (':' type)?;

Name
    : [a-zA-Z_][a-zA-Z_0-9]*
    ;

LiteralString
    : '"' ( EscapeSequence | ~('\\'|'"') )* '"'
    ;

fragment
EscapeSequence
    : '\\' [abfnrtvz"'|$#\\]   // World of Warcraft Lua additionally escapes |$# 
    | '\\' '\r'? '\n'
    | DecimalEscape
    | HexEscape
    | UtfEscape
    ;

fragment
DecimalEscape
    : '\\' Digit
    | '\\' Digit Digit
    | '\\' [0-2] Digit Digit
    ;

fragment
HexEscape
    : '\\' 'x' HexDigit HexDigit
    ;

fragment
UtfEscape
    : '\\' 'u{' HexDigit+ '}'
    ;

fragment
Digit
    : [0-9]
    ;

fragment
HexDigit
    : [0-9a-fA-F]
    ;

Numeral: INT | HEX | FLOAT;

INT
    : Digit+
    ;

HEX
    : '0' [xX] HexDigit+
    ;

FLOAT
    : Digit+ '.' Digit* ExponentPart?
    | '.' Digit+ ExponentPart?
    | Digit+ ExponentPart
    ;

fragment
ExponentPart
    : [eE] [+-]? Digit+
    ;
mingodad commented 8 months ago

Hello Jorge !

I just added a grammar based on the one you've posted to https://mingodad.github.io/parsertl-playground/playground/ an Yacc/Lex compatible online editor/tester (select "Typedmoon parser" from "Examples" then click "Parse" to see a parser tree for the content in "Input source").

It's less forgiving than "ANTLR" but it's good enough to experiment (try to enhance/fix it there).

Any feedback is welcome !

Cheers !