Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grammar railroad diagram #61

Open
mingodad opened this issue Jul 19, 2022 · 3 comments
Open

Grammar railroad diagram #61

mingodad opened this issue Jul 19, 2022 · 3 comments
Assignees

Comments

@mingodad
Copy link

Looking through the code I think that adding an option to export the grammar to a format that can be recognized by https://www.bottlecaps.de/rr/ui to generate a navigable railroad diagram (https://en.wikipedia.org/wiki/Syntax_diagram) would make it easier to develop/debug/document jessica.

For example I manually created a grammar compatible with chpeg / cpp-peglib that can parse pegquasi grammars on their playgrounds (https://chrishixon.github.io/chpeg/playground/ , https://yhirose.github.io/cpp-peglib/) :

# Hierarchical syntax

Grammar      <- _Spacing Definition+ _EndOfFile

Definition   <- Identifier LEFTARROW Expression SEMI #&${ACCEPT}

Expression   <- Sequence ( _SLASH Sequence )*

Sequence     <- Prefix* HOLE?

Prefix       <- AND HOLE
              / AND Suffix
              / NOT Suffix
              /     Suffix

Suffix       <- Primary (STARSTAR / PLUSPLUS) Primary
              / Primary (QUESTION
                        / STAR
                        / PLUS)
              / Primary

Primary      <- Super
              / Identifier !LEFTARROW
              / OPEN Expression CLOSE
              / Literal
              / Class
              / DOT
              / BEGIN
              / END


Super        <- 'super.' Identifier

# Lexical syntax

Identifier   <- < IdentStart IdentCont* > _Spacing
IdentStart   <- [a-zA-Z_]
IdentCont    <- IdentStart / [0-9]
Literal      <- ['] < (!['] Char )* > ['] _Spacing
              / ["] < (!["] Char )* > ["] _Spacing
Class        <- '[' < (!']' Range)* > ']' _Spacing
Range        <- Char '-' Char / Char
Char         <- '\\' [abefnrtv'"\[\]\\`$]
              / '\\x' [0-9a-fA-F][0-9a-fA-F]
              / '\\' '-'
              / !'\\' .
LEFTARROW    <- '<-' _Spacing
_SLASH        <- '/' _Spacing              #${_ => SKIP};
SEMI         <- ';' _Spacing
AND          <- '&' _Spacing
NOT          <- '~' _Spacing
QUESTION     <- '?' _Spacing
STAR         <- '*' _Spacing
PLUS         <- '+' _Spacing
OPEN         <- '(' _Spacing
CLOSE        <- ')' _Spacing
DOT          <- '.' _Spacing
#_Spacing {I}     <- (Space / Comment)*        # this line is for chpeg
~_Spacing {I}     <- (Space / Comment)*        # this line is for cpp-peglib
Comment      <- '#' (!EndOfLine .)* EndOfLine
Space        <- ' ' / '\t' / EndOfLine
EndOfLine    <- '\r\n' / '\n' / '\r'
_EndOfFile    <- !.

HOLE_LITERAL <- Literal / [`] < (![`] Char )* > [`] _Spacing
HOLE         <- "${" (!'}' ( HOLE_LITERAL / .))* "}" _Spacing
BEGIN        <- '<' _Spacing
END          <- '>' _Spacing
PLUSPLUS     <- '++' _Spacing
STARSTAR     <- '**' _Spacing

And with a variant of that I could do a basic conversion of jessica to a peg format that can be used at https://www.bottlecaps.de/convert/ to be converted and generate a navigable railroad diagram.

Copy and paste the grammar shown bellow on https://www.bottlecaps.de/convert/ on the Input grammar: textarea and then click the Convert button then click the View Diagram button (that will appear after the conversion) to view the navigable railroad diagram.

 start  <-
	 _WS  moduleBody  _EOF 

 LATER  <-
	 "~."  ! [0-9] _WS 

 RESERVED_WORD  <-
	 "super."  RESERVED_WORD 
	/  (  "insulate"  _WSN  ) 

 primaryExpr  <-
	 "super."  primaryExpr 
	/  functionExpr 

 propDef  <-
	 methodDef 
	/  "super."  propDef 

 purePropDef  <-
	 methodDef 
	/  "super."  purePropDef 

 prePre  <-
	 (  PLUSPLUS  /  MINUSMINUS  ) 
	/  "super."  prePre 

 memberPostOp  <-
	 "super."  memberPostOp 
	/  LEFT_BRACKET  assignExpr  RIGHT_BRACKET 
	/  LATER  LEFT_BRACKET  assignExpr  RIGHT_BRACKET 
	/  LATER  IDENT_NAME 

 callPostOp  <-
	 "super."  callPostOp 
	/  LATER  args 

 postOp  <-
	 (  PLUSPLUS  /  MINUSMINUS  )  _WS 

 assignExpr  <-
	 arrowFunc 
	/  functionExpr 
	/  lValue  postOp 
	/  lValue  (  EQUALS  /  assignOp  )  assignExpr 
	/  "super."  assignExpr 
	/  primaryExpr 

 pureExpr  <-
	 arrowFunc 
	/  "super."  pureExpr 

 lValue  <-
	 primaryExpr  LEFT_BRACKET  indexExpr  RIGHT_BRACKET 
	/  primaryExpr  LATER  LEFT_BRACKET  indexExpr  RIGHT_BRACKET 
	/  primaryExpr  DOT  IDENT_NAME 
	/  primaryExpr  LATER  IDENT_NAME 
	/  useVar 

 assignOp  <-
	 (  "*="  /  "/="  /  "%="  /  "+="  /  "-="  /  "<<="  /  ">>="  /  ">>>="  /  "&="  /  "^="  /  "|="  /  "**="  )  _WS 

 statement  <-
	 block 
	/  IF  LEFT_PAREN  expr  RIGHT_PAREN  arm  ELSE  elseArm 
	/  IF  LEFT_PAREN  expr  RIGHT_PAREN  arm 
	/  breakableStatement 
	/  terminator 
	/  IDENT  COLON  statement 
	/  TRY  block  catcher  finalizer 
	/  TRY  block  catcher 
	/  TRY  block  finalizer 
	/  DEBUGGER  SEMI 
	/  exprStatement 

 arm  <-
	 block 

 elseArm  <-
	 arm 
	/  IF  LEFT_PAREN  expr  RIGHT_PAREN  arm  ELSE  elseArm 
	/  IF  LEFT_PAREN  expr  RIGHT_PAREN  arm 

 breakableStatement  <-
	 FOR  LEFT_PAREN  declOp  forOfBinding  OF  expr  RIGHT_PAREN  arm 
	/  FOR  LEFT_PAREN  declaration  expr  SEMI  expr  RIGHT_PAREN  arm 
	/  WHILE  LEFT_PAREN  expr  RIGHT_PAREN  arm 
	/  SWITCH  LEFT_PAREN  expr  RIGHT_PAREN  LEFT_BRACE  clause  RIGHT_BRACE 

 terminator  <-
	 "continue"  _NO_NEWLINE  IDENT  SEMI 
	/  "continue"  _WS  SEMI 
	/  "break"  _NO_NEWLINE  IDENT  SEMI 
	/  "break"  _WS  SEMI 
	/  "return"  _NO_NEWLINE  expr  SEMI 
	/  "return"  _WS  SEMI 
	/  "throw"  _NO_NEWLINE  expr  SEMI 

 block  <-
	 LEFT_BRACE  body  RIGHT_BRACE 

 body  <-
	 statementItem 

 statementItem  <-
	 declaration 
	/  statement 

 declaration  <-
	 declOp  binding  (  _COMMA  binding  )  *  SEMI 
	/  functionDecl 

 declOp  <-
	 (  "const"  /  "let"  )  _WSN 

 forOfBinding  <-
	 bindingPattern 
	/  defVar 

 binding  <-
	 bindingPattern  EQUALS  assignExpr 
	/  defVar  EQUALS  assignExpr 
	/  defVar 

 bindingPattern  <-
	 LEFT_BRACKET  elementParam  (  _COMMA  elementParam  )  *  RIGHT_BRACKET 
	/  LEFT_BRACE  propParam  (  _COMMA  propParam  )  *  RIGHT_BRACE 

 pattern  <-
	 bindingPattern 
	/  defVar 
	/  undefined 
	/  dataLiteral 
	/  HOLE 

 elementParam  <-
	 param 

 param  <-
	 ELLIPSIS  pattern 
	/  defVar  EQUALS  assignExpr 
	/  pattern 

 propParam  <-
	 ELLIPSIS  pattern 
	/  propName  COLON  pattern 
	/  defVar  EQUALS  assignExpr 
	/  defVar 

 exprStatement  <-
	 !  cantStartExprStatement  expr  SEMI 

 cantStartExprStatement  <-
	 (  "{"  /  "function"  /  "async"  _NO_NEWLINE  "function"  /  "class"  /  "let"  /  "["  )  _WSN 

 terminatedBody  <-
	 (  (  !  terminator  statementItem  )  terminator  ) 

 clause  <-
	 caseLabel  LEFT_BRACE  terminatedBody  RIGHT_BRACE 

 caseLabel  <-
	 CASE  expr  COLON 
	/  DEFAULT  _WS  COLON 

 catcher  <-
	 CATCH  LEFT_PAREN  pattern  RIGHT_PAREN  block 

 finalizer  <-
	 FINALLY  block 

 functionDecl  <-
	 FUNCTION  defVar  LEFT_PAREN  param  (  _COMMA  param  )  *  RIGHT_PAREN  block 

 functionExpr  <-
	 FUNCTION  defVar  LEFT_PAREN  param  (  _COMMA  param  )  *  RIGHT_PAREN  block 

 arrowFunc  <-
	 arrowParams  _NO_NEWLINE  ARROW  block 
	/  arrowParams  _NO_NEWLINE  ARROW  assignExpr 

 arrowParams  <-
	 IDENT 
	/  LEFT_PAREN  param  (  _COMMA  param  )  *  RIGHT_PAREN 

 methodDef  <-
	 method 
	/  GET  propName  LEFT_PAREN  RIGHT_PAREN  block 
	/  SET  propName  LEFT_PAREN  param  RIGHT_PAREN  block 

 method  <-
	 propName  LEFT_PAREN  param  (  _COMMA  param  )  *  RIGHT_PAREN  block 

 moduleBody  <-
	 moduleItem 

 moduleItem  <-
	 SEMI 
	/  importDecl 
	/  exportDecl 
	/  moduleDeclaration 

 useImport  <-
	 IDENT 

 defImport  <-
	 IDENT 

 moduleDeclaration  <-
	 "const"  _WSN  moduleBinding  (  _COMMA  moduleBinding  )  *  SEMI 

 hardenedExpr  <-
	 dataLiteral 
	/  undefined 
	/  "harden"  _WS  LEFT_PAREN  (  pureExpr  /  useImport  )  RIGHT_PAREN 
	/  useVar 

 moduleBinding  <-
	 bindingPattern  EQUALS  hardenedExpr 
	/  defVar  EQUALS  hardenedExpr 
	/  defVar 

 importClause  <-
	 STAR  AS  defImport 
	/  namedImports 
	/  defImport  _COMMA  STAR  AS  defImport 
	/  defImport  _COMMA  namedImports 
	/  defImport 

 safeImportClause  <-
	 safeNamedImports 

 importSpecifier  <-
	 IDENT_NAME  AS  defImport 
	/  defImport 

 safeImportSpecifier  <-
	 IDENT_NAME  AS  defVar 
	/  defVar 

 namedImports  <-
	 LEFT_BRACE  importSpecifier  (  _COMMA  importSpecifier  )  *  _COMMA  RIGHT_BRACE 

 safeNamedImports  <-
	 LEFT_BRACE  safeImportSpecifier  (  _COMMA  safeImportSpecifier  )  *  _COMMA  RIGHT_BRACE 

 safeModule  <-
	 STRING 

 importDecl  <-
	 IMPORT  importClause  FROM  STRING  SEMI 
	/  IMPORT  safeImportClause  FROM  safeModule  SEMI 

 exportDecl  <-
	 EXPORT  DEFAULT  exportableExpr  SEMI 
	/  EXPORT  moduleDeclaration 

 exportableExpr  <-
	 hardenedExpr 

 ARROW  <-
	 "=>"  _WS 

 AS  <-
	 "as"  _WSN 

 DEBUGGER  <-
	 "debugger"  _WSN 

 PLUSPLUS  <-
	 "++"  _WSN 

 MINUSMINUS  <-
	 "--"  _WSN 

 CASE  <-
	 "case"  _WSN 

 IF  <-
	 "if"  _WSN 

 ELSE  <-
	 "else"  _WSN 

 FOR  <-
	 "for"  _WSN 

 OF  <-
	 "of"  _WSN 

 WHILE  <-
	 "while"  _WSN 

 BREAK  <-
	 "break"  _WSN 

 CONTINUE  <-
	 "continue"  _WSN 

 SWITCH  <-
	 "switch"  _WSN 

 TRY  <-
	 "try"  _WSN 

 CATCH  <-
	 "catch"  _WSN 

 FINALLY  <-
	 "finally"  _WSN 

 GET  <-
	 "get"  _WSN 

 SET  <-
	 "set"  _WSN 

 IMPORT  <-
	 "import"  _WSN 

 EXPORT  <-
	 "export"  _WSN 

 FROM  <-
	 "from"  _WSN 

 FUNCTION  <-
	 "function"  _WSN 

 DEFAULT  <-
	 "default"  _WSN 

 EQUALS  <-
	 "="  _WS 

 SEMI  <-
	 ";"  _WS 

 STAR  <-
	 "*"  _WS 
@erights erights self-assigned this Jul 21, 2022
@erights
Copy link

erights commented Jul 21, 2022

@mingodad wow, this looks like great work! What do you think we should add to this repository? Would you be interesting in submitting a PR? I would happily review, thanks!

@mingodad
Copy link
Author

Why not add the capability to export the grammar like I did manually directly in the pegquasi itself ?

@erights
Copy link

erights commented Aug 6, 2022

Hi @michaelfig I added you to the assignees along with me. Looks like fun! Let's discuss sometime. No rush.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants