Open mingodad opened 2 years ago
Nice tool indeed. I didn't take the time to check if all the EBNF is right but I will for sure add railroad diagrams to the documentation when I have time to revise it.
Regards
Maurizio
https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=icon Virus-free. www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=link <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
On Mon, Apr 4, 2022 at 10:22 PM Domingo Alvarez Duarte < @.***> wrote:
Using a parser generator to produce an EBNF understood by https://www.bottlecaps.de/rr/ui and following the code flow in https://github.com/mdegirolami/sing/blob/master/compiler/src/Parser.cpp, we can have a nice railroad diagram ( https://en.wikipedia.org/wiki/Syntax_diagram) .
Copy and paste the EBNF shown bellow at https://www.bottlecaps.de/rr/ui on the tab "Edit Grammar" then click on the tab "View Diagram".
// // EBNF generated by CocoR parser generator to be viewed with https://www.bottlecaps.de/rr/ui //
// // productions //
Sing ::= ParseNamespace? ParseDependency ParseDeclaration EOF ParseNamespace ::= TOKEN_NAMESPACE TOKEN_NAME ( TOKEN_DOT TOKEN_NAME ) TOKEN_SEMICOLON ParseDependency ::= TOKEN_REQUIRES TOKEN_LITERAL_STRING ( TOKEN_COMMA TOKEN_NAME )? TOKEN_SEMICOLON ParseDeclaration ::= TOKEN_PUBLIC? ( ParseType | ParseVar | ParseConst | ParseFunctionDeclaration | ParseEnum | ParseInterface | ParseClass ) ParseType ::= TOKEN_TYPE TOKEN_NAME ParseTypeSpecification TOKEN_SEMICOLON ParseVar ::= TOKEN_VAR TOKEN_NAME ( TOKEN_ASSIGN ParseIniter )? TOKEN_SEMICOLON ParseConst ::= TOKEN_LET TOKEN_NAME ParseTypeSpecification? TOKEN_ASSIGN ParseIniter TOKEN_SEMICOLON ParseFunctionDeclaration ::= TOKEN_FUNC TOKEN_NAME ( TOKEN_DOT TOKEN_NAME )? ParseFunctionType ( TOKEN_SEMICOLON | ParseBlock ) ParseEnum ::= TOKEN_ENUM TOKEN_NAME TOKEN_CURLY_OPEN ParseEnumElement ( TOKEN_COMMA ParseEnumElement ) TOKEN_CURLY_CLOSE ParseInterface ::= TOKEN_INTERFACE TOKEN_NAME ( TOKEN_COLON ParseNamedType ( TOKEN_COMMA ParseNamedType ) )? TOKEN_CURLY_OPEN ( TOKEN_FUNC TOKEN_MUT? ParseFunctionType TOKEN_SEMICOLON ) TOKEN_NAME TOKEN_CURLY_CLOSE ParseClass ::= TOKEN_CLASS TOKEN_NAME ( TOKEN_COLON ParseNamedType ( TOKEN_BY TOKEN_NAME )? ( TOKEN_COMMA ParseNamedType ( TOKEN_BY TOKEN_NAME )? ) )? ParseTypeSpecification ::= ( TOKEN_INT8 | TOKEN_INT16 | TOKEN_INT32 | TOKEN_INT64 | TOKEN_UINT8 | TOKEN_UINT16 | TOKEN_UINT32 | TOKEN_UINT64 | TOKEN_FLOAT32 | TOKEN_FLOAT64 | TOKEN_COMPLEX64 | TOKEN_COMPLEX128 | TOKEN_STRING | TOKEN_BOOL | TOKEN_VOID ) | ParseNamedType | TOKEN_MAP TOKEN_ROUND_OPEN ParseTypeSpecification TOKEN_ROUND_CLOSE ParseTypeSpecification | ParseIndices | ( TOKEN_CONST | TOKEN_WEAK )? TOKEN_MPY ParseTypeSpecification | ParseFunctionType ParseIniter ::= ( TOKEN_CURLY_OPEN ParseIniter ( TOKEN_COMMA ParseIniter ) TOKEN_CURLY_CLOSE )? ParseExpression ParseFunctionType ::= TOKEN_PURE? ParseArgsDef ParseTypeSpecification ParseBlock ::= TOKEN_CURLY_OPEN ParseStatement TOKEN_CURLY_CLOSE ParseStatement ::= ParseVar | ParseConst | ParseBlock | ParseWhile | ParseIf | ParseFor | ParseSwitch | ParseTypeSwitch | ( TOKEN_BREAK | TOKEN_CONTINUE ) TOKEN_SEMICOLON | TOKEN_RETURN ( TOKEN_ROUND_OPEN ParseExpression TOKEN_ROUND_CLOSE )? TOKEN_SEMICOLON | ( TOKEN_INC | TOKEN_DEC ) ParsePrefixExpression TOKEN_SEMICOLON | TOKEN_SWAP TOKEN_ROUND_OPEN ParsePrefixExpression TOKEN_COMMA ParsePrefixExpression TOKEN_ROUND_CLOSE TOKEN_SEMICOLON | ParseLeftTermStatement ParseWhile ::= TOKEN_WHILE TOKEN_ROUND_OPEN ParseExpression TOKEN_ROUND_CLOSE ParseBlock ParseIf ::= TOKEN_IF TOKEN_ROUND_OPEN ParseExpression TOKEN_ROUND_CLOSE ParseBlock ( TOKEN_ELSE ( ParseIf | ParseBlock ) )? ParseFor ::= TOKEN_FOR TOKEN_ROUND_OPEN TOKEN_NAME ( TOKEN_COMMA TOKEN_NAME ) TOKEN_IN ParseExpression ( TOKEN_COLON ParseExpression ( TOKEN_STEP ParseExpression )? )? TOKEN_ROUND_CLOSE ParseBlock ParseSwitch ::= TOKEN_SWITCH TOKEN_ROUND_OPEN ParseExpression TOKEN_ROUND_CLOSE TOKEN_CURLY_OPEN ParseSwitchCase ( TOKEN_DEFAULT TOKEN_COLON ParseStatement )? TOKEN_CURLY_CLOSE ParseTypeSwitch ::= TOKEN_TYPESWITCH TOKEN_ROUND_OPEN TOKEN_NAME TOKEN_ASSIGN ParseExpression TOKEN_ROUND_CLOSE TOKEN_CURLY_OPEN TOKEN_CURLY_CLOSE ParseExpression ::= ParsePrefixExpression ParsePrefixExpression ::= TOKEN_MINUS | TOKEN_PLUS | TOKEN_AND | TOKEN_NOT | TOKEN_LOGICAL_NOT | TOKEN_MPY | ParsePostfixExpression ParseLeftTermStatement ::= ParsePrefixExpression ( ( TOKEN_ASSIGN | TOKEN_UPD_PLUS | TOKEN_UPD_MINUS | TOKEN_UPD_MPY | TOKEN_UPD_DIVIDE | TOKEN_UPD_XOR | TOKEN_UPD_MOD | TOKEN_UPD_SHR | TOKEN_UPD_SHL | TOKEN_UPD_AND | TOKEN_UPD_OR ) ParseExpression | ( TOKEN_INC | TOKEN_DEC ) ) TOKEN_SEMICOLON ParseSwitchCase ::= ParseCase ParseCase ParseStatement ParseCase ::= TOKEN_CASE ParseExpression TOKEN_COLON ParseTypeSwitchCase ::= ParseTypeCase ParseTypeCase ParseStatement ParseTypeCase ::= TOKEN_CASE ParseTypeSpecification TOKEN_COLON ParseEnumElement ::= TOKEN_NAME ( TOKEN_ASSIGN ParseExpression )? ParseNamedType ::= TOKEN_NAME ParseIndices ::= ParseOneIndice ParseOneIndice ParseOneIndice ::= TOKEN_SQUARE_OPEN ( ParseOneIndixeExpr ( TOKEN_COMMA ParseOneIndixeExpr ) )? TOKEN_SQUARE_CLOSE ParseTypeSpecification ParseOneIndixeExpr ::= ParseExpression | TOKEN_MPY ParseArgsDef ::= TOKEN_ROUND_OPEN ( TOKEN_ETC | ParseSingleArgDef ( TOKEN_COMMA ParseSingleArgDef ) )? TOKEN_ROUND_CLOSE ParseSingleArgDef ::= ( TOKEN_IN | TOKEN_OUT | TOKEN_IO )? TOKEN_NAME ParseTypeSpecification ( TOKEN_ASSIGN ParseIniter )? ParsePostfixExpression ::= ParseRangesOrIndices | TOKEN_DOT | ParseArguments ParseRangesOrIndices ::= TOKEN_SQUARE_OPEN ParseArguments ::= TOKEN_ROUND_OPEN
// // tokens //
TOKEN_NULL ::= "null" TOKEN_TRUE ::= "true" TOKEN_FALSE ::= "false" TOKEN_VOID ::= "void" TOKEN_MUT ::= "mut" TOKEN_REQUIRES ::= "requires" TOKEN_NAMESPACE ::= "namespace" TOKEN_VAR ::= "var" TOKEN_CONST ::= "const" TOKEN_TYPE ::= "type" TOKEN_MAP ::= "map" TOKEN_WEAK ::= "weak" TOKEN_INT8 ::= "i8" TOKEN_INT16 ::= "i16" TOKEN_INT32 ::= "i32" TOKEN_INT64 ::= "i64" TOKEN_UINT8 ::= "u8" TOKEN_UINT16 ::= "u16" TOKEN_UINT32 ::= "u32" TOKEN_UINT64 ::= "u64" TOKEN_FLOAT32 ::= "f32" TOKEN_FLOAT64 ::= "f64" TOKEN_COMPLEX64 ::= "c64" TOKEN_COMPLEX128 ::= "c128" TOKEN_LET ::= "let" TOKEN_STRING ::= "string" TOKEN_BOOL ::= "bool" TOKEN_FUNC ::= "fn" TOKEN_PURE ::= "pure" TOKEN_IN ::= "in" TOKEN_OUT ::= "out" TOKEN_IO ::= "io" TOKEN_DOUBLEDOT ::= ".." TOKEN_ETC ::= "..." TOKEN_IF ::= "if" TOKEN_ELSE ::= "else" TOKEN_WHILE ::= "while" TOKEN_FOR ::= "for" TOKEN_RETURN ::= "return" TOKEN_BREAK ::= "break" TOKEN_CONTINUE ::= "continue" TOKEN_SIZEOF ::= "sizeof" TOKEN_XOR ::= "^" TOKEN_CASE ::= "case" TOKEN_TYPESWITCH ::= "typeswitch" TOKEN_SWITCH ::= "switch" TOKEN_DEFAULT ::= "default" TOKEN_PUBLIC ::= "public" TOKEN_PRIVATE ::= "private" TOKEN_ENUM ::= "enum" TOKEN_CLASS ::= "class" TOKEN_THIS ::= "this" TOKEN_INTERFACE ::= "interface" TOKEN_BY ::= "by" TOKEN_STEP ::= "step" TOKEN_MIN ::= "min" TOKEN_MAX ::= "max" TOKEN_SWAP ::= "swap" TOKEN_ROUND_OPEN ::= "(" TOKEN_ROUND_CLOSE ::= ")" TOKEN_SQUARE_OPEN ::= "[" TOKEN_SQUARE_CLOSE ::= "]" TOKEN_CURLY_OPEN ::= "{" TOKEN_CURLY_CLOSE ::= "}" TOKEN_ANGLE_OPEN_LT ::= "<" TOKEN_ANGLE_CLOSE_GT ::= ">" TOKEN_COMMA ::= "," TOKEN_ASSIGN ::= "=" TOKEN_INC ::= "++" TOKEN_DEC ::= "--" TOKEN_DOT ::= "." TOKEN_PLUS ::= "+" TOKEN_MINUS ::= "-" TOKEN_MPY ::= "" TOKEN_DIVIDE ::= "/" TOKEN_MOD ::= "%" TOKEN_SHR ::= ">>" TOKEN_SHL ::= "<<" TOKEN_NOT ::= "~" TOKEN_AND ::= "&" TOKEN_OR ::= "|" TOKEN_GTE ::= ">=" TOKEN_LTE ::= "<=" TOKEN_DIFFERENT ::= "!=" TOKEN_EQUAL ::= "==" TOKEN_LOGICAL_NOT ::= "!" TOKEN_LOGICAL_AND ::= "&&" TOKEN_LOGICAL_OR ::= "||" TOKEN_COLON ::= ":" TOKEN_SEMICOLON ::= ";" TOKEN_UPD_PLUS ::= "+=" TOKEN_UPD_MINUS ::= "-=" TOKEN_UPD_MPY ::= "=" TOKEN_UPD_DIVIDE ::= "/=" TOKEN_UPD_XOR ::= "^=" TOKEN_UPD_MOD ::= "%=" TOKEN_UPD_SHR ::= ">>=" TOKEN_UPD_SHL ::= "<<=" TOKEN_UPD_AND ::= "&=" TOKEN_UPD_OR ::= "|="
Parser so far on variant of https://github.com/mingodad/CocoR-CPP:
/* ANSI C 89 grammar as specified in http://flash-gordon.me.uk/ansi.c.txt
Processing the C grammar requires LL(1) conflict resolvers, some of which need to check whether an identifier is a type name (see IsTypeName() below). So the grammar assumes that there is a symbol table, from where you can look up an identifier and find out whether it is a type name.
The language in the semantic actions here is C#, but it can easily be translated to any other language. */
$namespace=Sing
ifdef SQUILU
include "Scanner.nut"
typedef SymTab SymTab;
else
include "Scanner.h"
endif
COMPILER Sing
CHARACTERS letter = 'A'..'Z' + 'a'..'z' + '_'. oct = '0'..'7'. digit = '0'..'9'. nzdigit = '1'..'9'. hex = digit + 'a'..'f' + 'A'..'F'. notQuote = ANY - '"' - "\r\n". notApo = ANY - '\'' - "\r\n".
tab = '\t'. cr = '\r'. lf = '\n'. newLine = cr + lf. notNewLine = ANY - newLine . ws = " " + tab + '\u000b' + '\u000c'.
TOKENS TOKEN_NAME = letter {letter | digit}.
floatcon = ( '.' digit {digit} [('e'|'E') ['+'|'-'] digit {digit}] | digit {digit} '.' {digit} [('e'|'E') ['+'|'-'] digit {digit}] | digit {digit} ('e'|'E') ['+'|'-'] digit {digit} ) ['f'|'l'|'F'|'L'].
intcon = ( nzdigit {digit} | '0' {oct} | ("0x"|"0X") hex {hex} ) {'u'|'U'|'l'|'L'}.
TOKEN_LITERAL_STRING = '"' {notQuote} '"'. // no check for valid escape sequences
charcon = '\'' notApo {notApo} '\''. // no check for valid escape sequences
// tokens defined in order to get their names for LL(1) conflict resolvers //{([^,]+),\s*("[^"]+").+ TOKEN_NULL = "null" . TOKEN_TRUE = "true" . TOKEN_FALSE = "false" . TOKEN_VOID = "void" .
TOKEN_MUT = "mut" . TOKEN_REQUIRES = "requires" . TOKEN_NAMESPACE = "namespace" . TOKEN_VAR = "var" . TOKEN_CONST = "const" . TOKEN_TYPE = "type" . TOKEN_MAP = "map" . TOKEN_WEAK = "weak" . TOKEN_INT8 = "i8" . TOKEN_INT16 = "i16" . TOKEN_INT32 = "i32" . TOKEN_INT64 = "i64" . TOKEN_UINT8 = "u8" . TOKEN_UINT16 = "u16" . TOKEN_UINT32 = "u32" . TOKEN_UINT64 = "u64" . TOKEN_FLOAT32 = "f32" . TOKEN_FLOAT64 = "f64" . TOKEN_COMPLEX64 = "c64" . TOKEN_COMPLEX128 = "c128" . TOKEN_LET = "let" . TOKEN_STRING = "string" . TOKEN_BOOL = "bool" .
TOKEN_FUNC = "fn" . TOKEN_PURE = "pure" . TOKEN_IN = "in" . TOKEN_OUT = "out" . TOKEN_IO = "io" . TOKEN_DOUBLEDOT = ".." . TOKEN_ETC = "..." . TOKEN_IF = "if" . TOKEN_ELSE = "else" . TOKEN_WHILE = "while" . TOKEN_FOR = "for" . TOKEN_RETURN = "return" . TOKEN_BREAK = "break" . TOKEN_CONTINUE = "continue" .
TOKEN_SIZEOF = "sizeof" . TOKEN_XOR = "^" . TOKEN_CASE = "case" . TOKEN_TYPESWITCH = "typeswitch" . TOKEN_SWITCH = "switch" . TOKEN_DEFAULT = "default" .
TOKEN_PUBLIC = "public" . TOKEN_PRIVATE = "private" . TOKEN_ENUM = "enum" . TOKEN_CLASS = "class" . TOKEN_THIS = "this" . TOKEN_INTERFACE = "interface" . TOKEN_BY = "by" . TOKEN_STEP = "step" . TOKEN_MIN = "min" . TOKEN_MAX = "max" . TOKEN_SWAP = "swap" .
TOKEN_ROUND_OPEN = "(" . TOKEN_ROUND_CLOSE = ")" . TOKEN_SQUARE_OPEN = "[" . TOKEN_SQUARE_CLOSE = "]" . TOKEN_CURLY_OPEN = "{" . TOKEN_CURLY_CLOSE = "}" . TOKEN_ANGLE_OPEN_LT = "<" . TOKEN_ANGLE_CLOSE_GT = ">" .
TOKEN_COMMA = "," . TOKEN_ASSIGN = "=" . TOKEN_INC = "++" . TOKEN_DEC = "--" . TOKEN_DOT = "." . TOKEN_PLUS = "+" . TOKEN_MINUS = "-" . TOKEN_MPY = "*" . TOKEN_DIVIDE = "/" . //TOKEN_POWER = "**" . TOKEN_MOD = "%" . TOKEN_SHR = ">>" . TOKEN_SHL = "<<" . TOKEN_NOT = "~" . TOKEN_AND = "&" . TOKEN_OR = "|" . TOKEN_GTE = ">=" . TOKEN_LTE = "<=" . TOKEN_DIFFERENT = "!=" . TOKEN_EQUAL = "==" . TOKEN_LOGICAL_NOT = "!" . TOKEN_LOGICAL_AND = "&&" . TOKEN_LOGICAL_OR = "||" . TOKEN_COLON = ":" . TOKEN_SEMICOLON = ";" .
TOKEN_UPD_PLUS = "+=" . TOKEN_UPD_MINUS = "-=" . TOKEN_UPD_MPY = "*=" . TOKEN_UPD_DIVIDE = "/=" . TOKEN_UPD_XOR = "^=" . TOKEN_UPD_MOD = "%=" . TOKEN_UPD_SHR = ">>=" . TOKEN_UPD_SHL = "<<=" . TOKEN_UPD_AND = "&=" . TOKEN_UPD_OR = "|=" .
PRAGMAS //---- preprocessor commands (not handled here) ppDefine = '#' {ws} "define" {notNewLine} newLine. ppUndef = '#' {ws} "undef" {notNewLine} newLine. ppIf = '#' {ws} "if" {notNewLine} newLine. ppElif = '#' {ws} "elif" {notNewLine} newLine. ppElse = '#' {ws} "else" {notNewLine} newLine. ppEndif = '#' {ws} "endif" {notNewLine} newLine. ppInclude = '#' {ws} "include" {notNewLine} newLine. ppLine = '#' {ws} digit {digit} {notNewLine} newLine.
COMMENTS FROM "/" TO "/" COMMENTS FROM "//" TO lf
IGNORE tab + cr + lf
PRODUCTIONS
//---------- Compilation Unit ---------- Sing = [ParseNamespace] {ParseDependency} {ParseDeclaration} EOF .
ParseNamespace = TOKEN_NAMESPACE TOKEN_NAME {TOKEN_DOT TOKEN_NAME} TOKEN_SEMICOLON .
ParseDependency = TOKEN_REQUIRES TOKEN_LITERAL_STRING [TOKEN_COMMA TOKEN_NAME] TOKEN_SEMICOLON .
ParseDeclaration = [TOKEN_PUBLIC] ( ParseType | ParseVar | ParseConst | ParseFunctionDeclaration | ParseEnum | ParseInterface | ParseClass ) .
ParseType = TOKEN_TYPE TOKEN_NAME ParseTypeSpecification TOKEN_SEMICOLON .
ParseVar = TOKEN_VAR TOKEN_NAME [TOKEN_ASSIGN ParseIniter] TOKEN_SEMICOLON .
ParseConst = TOKEN_LET TOKEN_NAME [ParseTypeSpecification] TOKEN_ASSIGN ParseIniter TOKEN_SEMICOLON .
ParseFunctionDeclaration = TOKEN_FUNC TOKEN_NAME [TOKEN_DOT TOKEN_NAME] ParseFunctionType (TOKEN_SEMICOLON | ParseBlock) .
ParseBlock = TOKEN_CURLY_OPEN {ParseStatement} TOKEN_CURLY_CLOSE .
ParseStatement = ParseVar | ParseConst | ParseBlock | ParseWhile | ParseIf | ParseFor | ParseSwitch | ParseTypeSwitch | (TOKEN_BREAK | TOKEN_CONTINUE) TOKEN_SEMICOLON | TOKEN_RETURN [TOKEN_ROUND_OPEN ParseExpression TOKEN_ROUND_CLOSE] TOKEN_SEMICOLON | (TOKEN_INC | TOKEN_DEC) ParsePrefixExpression TOKEN_SEMICOLON | TOKEN_SWAP TOKEN_ROUND_OPEN ParsePrefixExpression TOKEN_COMMA ParsePrefixExpression TOKEN_ROUND_CLOSE TOKEN_SEMICOLON | ParseLeftTermStatement .
ParseWhile = TOKEN_WHILE TOKEN_ROUND_OPEN ParseExpression TOKEN_ROUND_CLOSE ParseBlock .
ParseIf = TOKEN_IF TOKEN_ROUND_OPEN ParseExpression TOKEN_ROUND_CLOSE ParseBlock [TOKEN_ELSE (ParseIf | ParseBlock)] .
ParseFor = TOKEN_FOR TOKEN_ROUND_OPEN TOKEN_NAME {TOKEN_COMMA TOKEN_NAME} TOKEN_IN ParseExpression [TOKEN_COLON ParseExpression [TOKEN_STEP ParseExpression]] TOKEN_ROUND_CLOSE ParseBlock .
ParseSwitch = TOKEN_SWITCH TOKEN_ROUND_OPEN ParseExpression TOKEN_ROUND_CLOSE TOKEN_CURLY_OPEN {ParseSwitchCase} [TOKEN_DEFAULT TOKEN_COLON ParseStatement] TOKEN_CURLY_CLOSE .
ParseSwitchCase = ParseCase {ParseCase} ParseStatement .
ParseCase = TOKEN_CASE ParseExpression TOKEN_COLON .
ParseTypeSwitch = TOKEN_TYPESWITCH TOKEN_ROUND_OPEN TOKEN_NAME TOKEN_ASSIGN ParseExpression TOKEN_ROUND_CLOSE TOKEN_CURLY_OPEN TOKEN_CURLY_CLOSE .
ParseTypeSwitchCase = ParseTypeCase {ParseTypeCase} ParseStatement .
ParseTypeCase = TOKEN_CASE ParseTypeSpecification TOKEN_COLON .
ParseLeftTermStatement = ParsePrefixExpression ( ( TOKEN_ASSIGN | TOKEN_UPD_PLUS | TOKEN_UPD_MINUS | TOKEN_UPD_MPY | TOKEN_UPD_DIVIDE | TOKEN_UPD_XOR | TOKEN_UPD_MOD | TOKEN_UPD_SHR | TOKEN_UPD_SHL | TOKEN_UPD_AND | TOKEN_UPD_OR ) ParseExpression | (TOKEN_INC | TOKEN_DEC)
) TOKEN_SEMICOLON .
ParseEnum = TOKEN_ENUM TOKEN_NAME TOKEN_CURLY_OPEN ParseEnumElement {TOKEN_COMMA ParseEnumElement} TOKEN_CURLY_CLOSE .
ParseEnumElement = TOKEN_NAME [TOKEN_ASSIGN ParseExpression] .
ParseInterface = TOKEN_INTERFACE TOKEN_NAME [TOKEN_COLON ParseNamedType {TOKEN_COMMA ParseNamedType}] TOKEN_CURLY_OPEN {TOKEN_FUNC [TOKEN_MUT] ParseFunctionType TOKEN_SEMICOLON} TOKEN_NAME TOKEN_CURLY_CLOSE .
ParseClass = TOKEN_CLASS TOKEN_NAME [TOKEN_COLON ParseNamedType [TOKEN_BY TOKEN_NAME] {TOKEN_COMMA ParseNamedType [TOKEN_BY TOKEN_NAME]}] .
ParseTypeSpecification = ( TOKEN_INT8 | TOKEN_INT16 | TOKEN_INT32 | TOKEN_INT64 | TOKEN_UINT8 | TOKEN_UINT16 | TOKEN_UINT32 | TOKEN_UINT64 | TOKEN_FLOAT32 | TOKEN_FLOAT64 | TOKEN_COMPLEX64 | TOKEN_COMPLEX128 | TOKEN_STRING | TOKEN_BOOL | TOKEN_VOID ) | ParseNamedType | TOKEN_MAP TOKEN_ROUND_OPEN ParseTypeSpecification TOKEN_ROUND_CLOSE ParseTypeSpecification | ParseIndices | [ TOKEN_CONST | TOKEN_WEAK ] TOKEN_MPY ParseTypeSpecification | ParseFunctionType .
ParseNamedType = TOKEN_NAME .
ParseIndices = ParseOneIndice {ParseOneIndice} .
ParseOneIndice = TOKEN_SQUARE_OPEN [ParseOneIndixeExpr {TOKEN_COMMA ParseOneIndixeExpr} ] TOKEN_SQUARE_CLOSE ParseTypeSpecification .
ParseOneIndixeExpr = ParseExpression | TOKEN_MPY .
ParseFunctionType = [TOKEN_PURE] ParseArgsDef ParseTypeSpecification .
ParseArgsDef = TOKEN_ROUND_OPEN [TOKEN_ETC | ParseSingleArgDef {TOKEN_COMMA ParseSingleArgDef}] TOKEN_ROUND_CLOSE .
ParseSingleArgDef = [ TOKEN_IN | TOKEN_OUT | TOKEN_IO ] TOKEN_NAME ParseTypeSpecification [TOKEN_ASSIGN ParseIniter] .
ParseIniter = [TOKEN_CURLY_OPEN ParseIniter {TOKEN_COMMA ParseIniter} TOKEN_CURLY_CLOSE] ParseExpression .
ParseExpression = ParsePrefixExpression .
ParsePrefixExpression = TOKEN_MINUS | TOKEN_PLUS | TOKEN_AND | TOKEN_NOT | TOKEN_LOGICAL_NOT | TOKEN_MPY | ParsePostfixExpression .
ParsePostfixExpression = ParseRangesOrIndices | TOKEN_DOT | ParseArguments .
ParseRangesOrIndices = TOKEN_SQUARE_OPEN .
ParseArguments = TOKEN_ROUND_OPEN .
END Sing.
— Reply to this email directly, view it on GitHub https://github.com/mdegirolami/sing/issues/3, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEWY54PILHZOQHBK5GNO2LDVDNFO7ANCNFSM5SQUUFPQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>
https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=icon Virus-free. www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=link <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
Using a parser generator to produce an EBNF understood by https://www.bottlecaps.de/rr/ui and following the code flow in https://github.com/mdegirolami/sing/blob/master/compiler/src/Parser.cpp, we can have a nice railroad diagram (https://en.wikipedia.org/wiki/Syntax_diagram) .
Copy and paste the EBNF shown bellow at https://www.bottlecaps.de/rr/ui on the tab "Edit Grammar" then click on the tab "View Diagram".
Parser so far on variant of https://github.com/mingodad/CocoR-CPP: