vectorgraphics / asymptote

2D & 3D TeX-Aware Vector Graphics Language
https://asymptote.sourceforge.io/
GNU General Public License v3.0
549 stars 90 forks source link

Grammar railroad diagram #458

Closed mingodad closed 4 months ago

mingodad commented 4 months ago

I've just added this project grammar to https://mingodad.github.io/parsertl-playground/playground/ an Yacc/Lex compatible online editor/tester (select Asymptote camp parser from Examples then click Parse to see a parse tree for the content in Input source).

And here is an EBNF to generate a nice navigable railroad diagram, looking at it can give clues on how to simplify/debug/develop further this grammar.

//
// EBNF to be viewd at
//    (IPV6) https://www.bottlecaps.de/rr/ui
//    (IPV4) https://rr.red-dove.com/ui
//
// Copy and paste this at one of the urls shown above in the 'Edit Grammar' tab
// then click the 'View Diagram' tab.
//

file::=
      fileblock

fileblock::=
      /*%empty*/
    | fileblock runnable

bareblock::=
      /*%empty*/
    | bareblock runnable

name::=
      ID
    | name '.' ID
    | '%'

runnable::=
      dec
    | stm
    | modifiers dec
    | modifiers stm

modifiers::=
      MODIFIER
    | PERM
    | modifiers MODIFIER
    | modifiers PERM

dec::=
      vardec
    | fundec
    | typedec
    | ACCESS stridpairlist ';'
    | FROM name UNRAVEL idpairlist ';'
    | FROM name UNRAVEL '*' ';'
    | UNRAVEL name ';'
    | FROM strid ACCESS idpairlist ';'
    | FROM strid ACCESS '*' ';'
    | IMPORT stridpair ';'
    | INCLUDE ID ';'
    | INCLUDE STRING ';'
    | TYPEDEF IMPORT '(' typeparamlist ')' ';'
    | IMPORT TYPEDEF '(' typeparamlist ')' ';'
    | ACCESS strid '(' decdeclist ')' ID ID ';'
    | ACCESS strid '(' decdeclist ')' ';'
    | IMPORT strid '(' decdeclist ')' ';'
    | FROM strid '(' decdeclist ')' ACCESS idpairlist ';'

decdec::=
      ID ASSIGN type
    | type

decdeclist::=
      decdec
    | decdeclist ',' decdec

typeparam::=
      ID

typeparamlist::=
      typeparam
    | typeparamlist ',' typeparam

idpair::=
      ID
    | ID ID ID

idpairlist::=
      idpair
    | idpairlist ',' idpair

strid::=
      ID
    | STRING

stridpair::=
      ID
    | strid ID ID

stridpairlist::=
      stridpair
    | stridpairlist ',' stridpair

vardec::=
      barevardec ';'

barevardec::=
      type decidlist

type::=
      celltype
    | name dims

celltype::=
      name

dims::=
      '[' ']'
    | dims '[' ']'

dimexps::=
      '[' exp ']'
    | dimexps '[' exp ']'

decidlist::=
      decid
    | decidlist ',' decid

decid::=
      decidstart
    | decidstart ASSIGN varinit

decidstart::=
      ID
    | ID dims
    | ID '(' ')'
    | ID '(' formals ')'

varinit::=
      exp
    | arrayinit

block::=
      '{' bareblock '}'

arrayinit::=
      '{' '}'
    | '{' ELLIPSIS varinit '}'
    | '{' basearrayinit '}'
    | '{' basearrayinit ELLIPSIS varinit '}'

basearrayinit::=
      ','
    | varinits
    | varinits ','

varinits::=
      varinit
    | varinits ',' varinit

formals::=
      formal
    | ELLIPSIS formal
    | formals ',' formal
    | formals ELLIPSIS formal

explicitornot::=
      EXPLICIT
    | /*%empty*/

formal::=
      explicitornot type
    | explicitornot type decidstart
    | explicitornot type decidstart ASSIGN varinit
    | explicitornot type ID decidstart
    | explicitornot type ID decidstart ASSIGN varinit

fundec::=
      type ID '(' ')' blockstm
    | type ID '(' formals ')' blockstm

typedec::=
      STRUCT ID block
    | TYPEDEF vardec

slice::=
      ':'
    | exp ':'
    | ':' exp
    | exp ':' exp

value::=
      value '.' ID
    | name '[' exp ']'
    | value '[' exp ']'
    | name '[' slice ']'
    | value '[' slice ']'
    | name '(' ')'
    | name '(' arglist ')'
    | value '(' ')'
    | value '(' arglist ')'
    | '(' exp ')'
    | '(' name ')'
    | THIS

argument::=
      exp
    | ID ASSIGN exp

arglist::=
      argument
    | ELLIPSIS argument
    | arglist ',' argument
    | arglist ELLIPSIS argument

tuple::=
      exp ',' exp
    | tuple ',' exp

exp::=
      name
    | value
    | LIT
    | STRING
    | LIT exp
    | '(' name ')' exp
    | '(' name dims ')' exp
    | '+' exp
    | '-' exp
    | OPERATOR exp
    | exp '+' exp
    | exp '-' exp
    | exp '*' exp
    | exp '/' exp
    | exp '%' exp
    | exp '#' exp
    | exp '^' exp
    | exp LT exp
    | exp LE exp
    | exp GT exp
    | exp GE exp
    | exp EQ exp
    | exp NEQ exp
    | exp CAND exp
    | exp COR exp
    | exp CARETS exp
    | exp AMPERSAND exp
    | exp BAR exp
    | exp OPERATOR exp
    | exp INCR exp
    | NEW celltype
    | NEW celltype dimexps
    | NEW celltype dimexps dims
    | NEW celltype dims
    | NEW celltype dims arrayinit
    | NEW celltype '(' ')' blockstm
    | NEW celltype dims '(' ')' blockstm
    | NEW celltype '(' formals ')' blockstm
    | NEW celltype dims '(' formals ')' blockstm
    | exp '?' exp ':' exp
    | exp ASSIGN exp
    | '(' tuple ')'
    | exp join exp
    | exp dir
    | INCR exp
    | DASHES exp
    | exp INCR
    | exp SELFOP exp
    | QUOTE '{' fileblock '}'

join::=
      DASHES
    | basicjoin
    | dir basicjoin
    | basicjoin dir
    | dir basicjoin dir

dir::=
      '{' CURL exp '}'
    | '{' exp '}'
    | '{' exp ',' exp '}'
    | '{' exp ',' exp ',' exp '}'

basicjoin::=
      DOTS
    | DOTS tension DOTS
    | DOTS controls DOTS
    | COLONS
    | LONGDASH

tension::=
      TENSION exp
    | TENSION exp AND exp
    | TENSION ATLEAST exp
    | TENSION ATLEAST exp AND exp

controls::=
      CONTROLS exp
    | CONTROLS exp AND exp

stm::=
      ';'
    | blockstm
    | stmexp ';'
    | IF '(' exp ')' stm
    | IF '(' exp ')' stm ELSE stm
    | WHILE '(' exp ')' stm
    | DO stm WHILE '(' exp ')' ';'
    | FOR '(' forinit ';' fortest ';' forupdate ')' stm
    | FOR '(' type ID ':' exp ')' stm
    | BREAK ';'
    | CONTINUE ';'
    | RETURN_ ';'
    | RETURN_ exp ';'

stmexp::=
      exp

blockstm::=
      block

forinit::=
      /*%empty*/
    | stmexplist
    | barevardec

fortest::=
      /*%empty*/
    | exp

forupdate::=
      /*%empty*/
    | stmexplist

stmexplist::=
      stmexp
    | stmexplist ',' stmexp

//Tokens

ELLIPSIS ::= "..."
ASSIGN ::= "="
EQ ::= "=="
NEQ ::= "!="
LT ::= "<"
LE ::= "<="
GT ::= ">"
GE ::= ">="
CAND ::= "&&"
COR ::= "||"
OPERATOR ::= "!"
CARETS ::= "^^"
COLONS ::= "::"
INCR ::= "++"
DOTS ::= ".."
DASHES ::= "--"
LONGDASH ::= "---"
AMPERSAND ::= "&"
BAR ::= "|"

SELFOP ::= "+="
SELFOP ::= "-="
SELFOP ::= "*="
SELFOP ::= "/="
SELFOP ::= "#="
SELFOP ::= "%="
SELFOP ::= "^="

AND ::= "and"
CONTROLS ::= "controls"
TENSION ::= "tension"
ATLEAST ::= "atleast"
CURL ::= "curl"
IF ::= "if"
ELSE ::= "else"
WHILE ::= "while"
FOR ::= "for"
DO ::= "do"
RETURN_ ::= "return"
BREAK ::= "break"
CONTINUE ::= "continue"
STRUCT ::= "struct"
TYPEDEF ::= "typedef"
NEW ::= "new"
ACCESS ::= "access"
IMPORT ::= "import"
UNRAVEL ::= "unravel"
FROM ::= "from"
INCLUDE ::= "include"
QUOTE ::= "quote"
MODIFIER ::= "static"
PERM ::= "public"
PERM ::= "private"
PERM ::= "restricted"
THIS ::= "this"
EXPLICIT ::= "explicit"
johncbowman commented 4 months ago

Thank you for your contribution. For the record, I've attached the gzipped railroad diagram. diagram.xhtml.gz

charlesstaats commented 4 months ago

As a general note, posts like this one are better suited for https://sourceforge.net/p/asymptote/discussion/409349. If you post an issue on github, you should be requesting a change to the software (either a bug fix or a feature request), not simply saying, "Here's something useful and/or cool I did related to Asymptote."

We do enjoy reading about contributions like this one. But github issues are designed to be closed and forgotten once there's nothing left to do, which I suspect is not what you want in this case.

Note: If you do have a request or suggestion (e.g., your efforts revealed an issue with / potential improvement to the parser, or you think your work should be incorporated into the official documentation, or....) feel free to clarify and reopen the issue. We can't promise anything, of course — there are many things we'd love to implement if we had the time — but at least we'll understand what you're asking for.