Git Product home page Git Product logo

ebnf2railroad's Introduction

Hi there πŸ‘‹

  • πŸ”­ I’m currently working on a webbased graphical adventure game engine. Github
  • πŸ”­ I’m currently working on Geppetto v2. Github

🏁 Personal projects I'm proud of:

🌲 Geppetto: An electron app to create WebGL Animations, and a player for web. Website, App (search for geppetto), PWA (in development), Npm package
Repo of app, Repo of player

πŸš€ Speedlazer: A webbased 2d shooter game. Github, Play Play Sinterklaas Edition Proud about: GameController support. First WebGL Game with own shaders, own textures, own particle engine.

πŸ“– Koerier van de koning: A dutch webbased text adventure. Github, Play Proud about: Writing the stories and defining the puzzles. I really love the story and puzzles of this one.

🎁 Sinterklaas: A dutch graphical point and click adventure. Github, Play
Proud about: Building the game engine from scratch. Doing all the drawings. Finishing the project on time!

🎁 Tristamon: A dutch turn based game. Github, Play
Proud about: Building the game engine from scratch. Doing all the drawings, animating it with Geppetto, creating the combat engine. Finishing the project on time!

πŸ“Š Ebnf 2 Railroad: A nice tool to produce beautiful documentation from EBNF definitions. Github, Try Online
Proud about: Writing a parser using Jison, creating all kinds of cool AST optimizations, creating an ASCII version of railroad Github

Other work:

ebnf2railroad's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ebnf2railroad's Issues

Add TOC

Potentially with sort options.

Alphabetical, as defined, by hierarchy

How to work have "_"

How to work like that:
class_modifier = "new"
|"public"
|"protected"
|"internal"
|"private"
|"abstract"
|"sealed"
|"static"
|"unsafe"
;
have "_".

How to collapse verbose EBNF into a single diagram?

I have a very verbose EBNF with a lot of redundant non-terminal symbols.

Right now the documentation I get mirrors the ebnf structure, documenting every non-terminal.

I would hesitate to collapse the symbols in the source EBNF, as it will affect the readability of the text. However, the small diagrams are not useful.

Is there a way to collapse all non-terminals to get a single railroad diagram?

Ideally I would like to control the verbosity somehow, probably by explicitly marking non-terminals that I want to remain, and collapsing all others...

I see the structure-optimizer in the code, but it seems not to go this far...

I can provide a minimal example if it would help. Alternatively, I might code a PR, if you guide me in the right direction.

Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

I rewrite Scala Syntax from https://www.scala-lang.org/files/archive/spec/2.12/13-syntax-summary.html, When i run it by ebnf2railroad a.ebnf a.html,it give me the error as follow:

<--- Last few GCs --->

[5896:0000023FA41A0230]    92478 ms: Scavenge 1384.6 (1430.1) -> 1376.9 (1431.1) MB, 3.3 / 0.0 ms  (average mu = 0.194, current mu = 0.162) allocation failure
[5896:0000023FA41A0230]    92496 ms: Scavenge 1384.8 (1431.1) -> 1377.1 (1432.1) MB, 3.6 / 0.0 ms  (average mu = 0.194, current mu = 0.162) allocation failure
[5896:0000023FA41A0230]    92512 ms: Scavenge 1385.0 (1432.1) -> 1377.4 (1434.1) MB, 3.4 / 0.0 ms  (average mu = 0.194, current mu = 0.162) allocation failure


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x01abe869e6e9 <JSObject>
    0: builtin exit frame: concat(this=0x00c4875194b9 <JSArray[35]>,0x02dccdfe4a79 <String[6]: letter>,0x00c4875194b9 <JSArray[35]>)

    1: /* anonymous */ [000000C487519591] [C:\Users\Administrator\AppData\Roaming\npm\node_modules\ebnf2railroad\src\toc.js:~26] [pc=000003686F5F0EA4](this=0x038159a8d5e1 <JSGlobal Object>,child=0x02dccdfe7219 <String[6]: letter>)
    2: arguments adaptor frame: 3...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 00007FF7CE04F04A v8::internal::GCIdleTimeHandler::GCIdleTimeHandler+5114
 2: 00007FF7CE02A0C6 node::MakeCallback+4518
 3: 00007FF7CE02AA30 node_module_register+2032
 4: 00007FF7CE2B20EE v8::internal::FatalProcessOutOfMemory+846
 5: 00007FF7CE2B201F v8::internal::FatalProcessOutOfMemory+639
 6: 00007FF7CE7D2BC4 v8::internal::Heap::MaxHeapGrowingFactor+9556
 7: 00007FF7CE7C9C46 v8::internal::ScavengeJob::operator=+24310
 8: 00007FF7CE7C829C v8::internal::ScavengeJob::operator=+17740
 9: 00007FF7CE7D0F87 v8::internal::Heap::MaxHeapGrowingFactor+2327
10: 00007FF7CE7D1006 v8::internal::Heap::MaxHeapGrowingFactor+2454
11: 00007FF7CE38CBE8 v8::internal::Factory::AllocateRawArray+56
12: 00007FF7CE38D562 v8::internal::Factory::NewFixedArrayWithFiller+66
13: 00007FF7CE4733BB v8::internal::CodeStubAssembler::ConstexprBoolNot+18955
14: 00007FF7CE473EFE v8::internal::CodeStubAssembler::ConstexprBoolNot+21838
15: 00007FF7CE473CEB v8::internal::CodeStubAssembler::ConstexprBoolNot+21307
16: 000003686F35C721

So,i think whether it's better to change loop.

The a.ebnf as follow:

unicode escape = "\", "u", { "u" }, hex digit, hex digit, hex digit, hex digit;
hex digit      = "0" | "1" | "2" | "3" | "4" | "5" | "6"| "7" | "8" | "9" | "A" | "B" | "C" | "D" | "E" | "F" |  "a" | "b" | "c" | "d" | "e" | "f" ;
(*
  Lexical Syntax
  ================================
*)
white space       =  "\u0020" | "\u0009" | "\u000D" | "\u000A" ;
upper            =  "A" | "B" | "C" | "D" | "E" | "F" | "G"
  | "H" | "I" | "J" | "K" | "L" | "M" | "N"
  | "O" | "P" | "Q" | "R" | "S" | "T" | "U"
  | "V" | "W" | "X" | "Y" | "Z" | "$" | "_" ; 
(*
>upper δΉŸεŒ…ε« Unicode category Lu
*)
lower            =  "a" | "b"
  | "c" | "d" | "e" | "f" | "g" | "h" | "i"
  | "j" | "k" | "l" | "m" | "n" | "o" | "p"
  | "q" | "r" | "s" | "t" | "u" | "v" | "w"
  | "x" | "y" | "z" ;
(*
>lower δΉŸεŒ…ε« Unicode category Ll
*)
letter           =  upper | lower;
(*
>letter εŒ…ε« Unicode categories Lo, Lt, Nl ;
*)
paren            =  "(" | ")" | "[" | "]" | "{" | "}" ;
delim            =  "`" | "'" | '"' | "." | ";" | "," ;
opchar           = white space | upper | lower | letter | digit | paren | delim | opchar | "Unicode_Sm" | "Unicode_So";
printable char    =  "all characters in [\u0020, \u007F] inclusive";
char escape seq    = "\", ("b" | "t" | "n" | "f" | "r" | '"' | "'" | "\") ;
op              =  opchar, {opchar} ;
varid            =  lower, idrest ;
plainid          =  upper, idrest |  varid |  op ;
id               =  plainid  |  "`" , { "char no back quote or newline" | unicode escape | char escape seq } ,"`" ;
idrest           =  {letter | digit} ,["_" , op] ;
integer literal   =  (decimal numeral | hex numeral) ,["L" | "l"] ;
decimal numeral   =  "0" | non zero digit ,{digit} ;
hex numeral       =  "0" ,("x" | "X"), hex digit ,{hex digit} ;
digit            =  "0" | non zero digit ;
non zero digit     =   "1" | "2" | "3" | "4" | "5" | "6"| "7" | "8" | "9" ;

floating point literal =  digit ,{digit} ,"." ,digit ,{digit} ,[exponent part], [float type] 
                  |  "." ,digit, {digit}, [exponent part], [float type] 
                  |  digit, {digit} ,exponent part, [float type] 
                 |  digit ,{digit}, [exponent part], float type ;
exponent part     =  ("E" | "e") ,["+" | "-"], digit, {digit} ;
float type        =  "F" | "f" | "D" | "d" ;
boolean literal   =  "true" | "false" ;
character literal =  "'", ("char no quote or newline" | unicode escape | char escape seq) ,"'" ;
string literal    =  '"', {string element} ,'"' 
                 |  '"""' ,multi line chars, '"""' ;
string element    =  "char no double quote or newline"
                 |  unicode escape 
                 |  char escape seq ;
multi line chars   =  {['"'], ['"'], "char no double quote"}, {'"'} ;
symbol literal    =  "'", plainid ;
comment          =  "/*", "any sequence of characters; nested comments are allowed", "*/" 
                 |  "//" ,"any sequence of characters up to end of line" ;
nl               =  "newlinecharacter" ;
semi             =  ";" |  nl, {nl} ;
(*
  Context-free Syntax
  ================================
*)
literal           =  ['-'], integer literal 
                    |  ['-'], floating point literal 
                    |  boolean literal 
                    |  character literal 
                    |  string literal 
                    |  symbol literal 
                    |  "null" ;
qual id            =  id ,{'.', id} ;
ids               =  id ,{',', id} ;
path              =  stable id 
                    |  [id ,'.'] ,'this' ;
stable id          =  id 
                    |  path ,'.', id 
                    |  [id, '.'] ,'super', [class qualifier], '.', id ;
class qualifier    =  '[', id ,']' ;
type              =  function arg types ,"=>", type 
                    |  infix type ,[existential clause] ;
function arg types  = infix type 
                    | "(", [ param type, {"," ,param type } ] ,")" ;
existential clause =  "forSome", "{", existential dcl, {semi ,existential dcl} ,"}" ;
existential dcl    =  "type", type dcl 
                    |  "val" ,val dcl ;
infix type         =  compound type ,{id ,[nl], compound type} ;
compound type      =  annot type ,{"with" ,annot type}, [refinement] 
                    |  refinement ;
annot type         =  simple type, {annotation} ;
simple type        =  simple type, type args 
                    |  simple type, "#", id 
                    |  stable id 
                    |  path ,"." ,"type" 
                    |  "(", types ,")" ;
type args          =  "[", types ,"]" ;
types             =  type, {"," ,type} ;
refinement        =  [nl], "{", refine stat, {semi ,refine stat} ,"}" ;
refine stat        =  dcl  |  "type" ,type def ;
type pat           =  type ;
ascription        =  ":", infix type 
                    |  ":", annotation, {annotation} 
                    |  ":", "_", "*" ;
expr              =  (bindings | ["implicit"], id | "_") ,"=>", expr 
                    |  expr1 ;
expr1             =  "if", "(", expr ,")" ,{nl} ,expr ,[[semi] ,"else", expr] 
                    |  "while", "(" ,expr ,")", {nl}, expr 
                    |  "try" ,("{", block, "}" | expr), ["catch", "{", case clauses ,"}"] ,["finally" ,expr] 
                    |  "do", expr ,[semi] ,"while", "(", expr ,")" 
                    |  "for", ("(", enumerators ,")" | "{", enumerators ,"}") ,{nl} ,["yield"] ,expr 
                    |  "throw", expr 
                    |  "return" ,[expr] 
                    |  [simple expr, "."] ,id ,"=" ,expr 
                    |  simple expr1, argument exprs, "=", expr 
                    |  postfix expr 
                    |  postfix expr ,ascription 
                    |  postfix expr ,"match" ,"{" ,case clauses ,"}" ;
postfix expr       =  infix expr ,[id ,[nl]] ;
infix expr         =  prefix expr 
                    |  infix expr ,id ,[nl] ,infix expr ;
prefix expr        =  ["-" | "+" | "~" | "!"] ,simple expr ;
simple expr        =  "new" ,(class template | template body) 
                    |  block expr 
                    |  simple expr1 ,["_"] ;
simple expr1       =  literal 
                    |  path 
                    |  "_" 
                    |  "(" ,[exprs] ,")" 
                    |  simple expr ,"." ,id 
                    |  simple expr ,type args 
                    |  simple expr1 ,argument exprs 
                    |  "xml expr" ;
exprs             =  expr ,{"," ,expr} ;
argument exprs     =  "(" ,[exprs] ,")" 
                    |  "(" ,[exprs ,","] ,postfix expr ,":" ,"_" ,"*" ,")" 
                    |  [nl] ,block expr ;
block expr         =  "{" ,case clauses ,"}" 
                    |  "{" ,block ,"}" ;
block             =  block stat ,{semi ,block stat}, [result expr] ;
block stat         =  import 
                    |  {annotation} ,["implicit" | "lazy"] ,def 
                    |  {annotation} ,{local modifier} ,tmpl def 
                    |  expr1 ;
result expr        =  expr1 
                    |  (bindings | (["implicit"], id | "_"), ":", compound type) ,"=>", block ;
enumerators       =  generator ,{semi ,generator} ;
generator         =  pattern1 ,"<-", expr ,{[semi] ,guard | semi ,pattern1 ,"=" ,expr} ;
case clauses       =  case clause ,{ case clause } ;
case clause        =  "case" ,pattern ,[guard] ,"=>" ,block ;
guard             =  "if", postfix expr ;
pattern           =  pattern1 ,{ "|", pattern1 } ;
pattern1          =  varid ,":", type pat 
                    |  "_" ,":" ,type pat 
                    |  pattern2 ;
pattern2          =  varid ,["@", pattern3] 
                    |  pattern3 ;
pattern3          =  simple pattern
                    |  simple pattern ,{ id ,[nl] ,simple pattern } ;
simple pattern     =  "_" 
                    |  varid 
                    |  literal 
                    |  stable id 
                    |  stable id ,"(" ,[patterns] ,")" 
                    |  stable id ,"(" ,[patterns ,","], [varid ,"@"] ,"_" ,"*" ,")" 
                    |  "(" ,[patterns] ,")" 
                    |  "xml pattern" ;
patterns          =  pattern ,["," ,patterns] 
                    |  "_" ,"*" ;
type param clause   =  "[", variant type param ,{",", variant type param} ,"]" ;
funtype param clause=  "[" ,type param ,{"," ,type param} ,"]" ;
variant type param  =  {annotation} ,["+" | "-"] ,type param ;
type param         =  (id | "_"), [type param clause] ,[">:", type], ["<:" ,type] ,{"<%" ,type}, {":", type} ;
param clauses      =  {param clause} ,[[nl] ,"(", "implicit", params ,")"] ;
param clause       =  [nl], "(" ,[params] ,")" ;
params            =  param ,{",", param} ;
param             =  {annotation} ,id ,[":", param type] ,["=" ,expr] ;
param type         =  type 
                    |  "=>", type 
                    |  type ,"*" ;
class param clauses =  {class param clause} , [[nl] ,"(" ,"implicit" ,class params ,")"] ;
class param clause  =  [nl] ,"(", [class params] ,")" ;
class params       =  class param ,{"," ,class param} ;
class param        =  {annotation} ,{modifier} , [("val" | "var")] , id ,":" ,param type ,["=" ,expr];
bindings          =  "(" ,binding ,{"," ,binding} ,")" ;
binding           =  (id | "_") ,[":" ,type] ;
modifier          =  local modifier 
                    |  access modifier 
                    |  "override" ;
local modifier     =  "abstract" 
                    |  "final" 
                    |  "sealed" 
                    |  "implicit" 
                    |  "lazy" ;
access modifier    =  ("private" | "protected") ,[access qualifier] ;
access qualifier   =  "[" ,(id | "this") ,"]" ;
annotation        =  "@" ,simple type ,{argument exprs} ;
constrannotation  =  "@" ,simple type ,argument exprs ;
template body      =  [nl] ,"{" ,[self type] ,template stat, {semi ,template stat} ,"}" ;
template stat      =  import 
                    |  {annotation ,[nl]} ,{modifier} ,def 
                    |  {annotation ,[nl]} ,{modifier} ,dcl 
                    |  expr ;
self type          =  id ,[":" ,type] ,"=>" 
                    |  "this" ,":" ,type ,"=>" ;
import            =  "import", import expr ,{"," ,import expr} ;
import expr        =  stable id ,"." ,(id | "_" | import selectors) ;
import selectors   =  "{" ,{import selector ,","} ,(import selector | "_") ,"}" ;
import selector    =  id ,["=>" ,id | "=>" ,"_"] ;
dcl               =  "val" ,val dcl 
                    |  "var" ,var dcl 
                    |  "def" ,fun dcl 
                    |  "type" ,{nl} ,type dcl ;
val dcl            =  ids ,":" ,type ;
var dcl            =  ids ,":" ,type ;
fun dcl            =  fun sig ,[":" ,type] ;
fun sig            =  id ,[funtype param clause] ,param clauses ;
type dcl           =  id ,[type param clause] ,[">:" ,type] ,["<:" ,type] ;
pat var def         =  "val" ,pat def 
                    |  "var" ,var def ;
def               =  pat var def 
                    |  "def" ,fun def
                    |  "type" ,{nl} ,type def 
                    |  tmpl def ;
pat def            =  pattern2 ,{"," ,pattern2} ,[":" ,type] ,"=" ,expr ;
var def            =  pat def 
                    |  ids ,":" ,type ,"=" ,"_" ;
fun def            =  fun sig ,[":" ,type] ,"=" ,expr 
                    |  fun sig ,[nl] ,"{" ,block ,"}" 
                    |  "this" ,param clause ,param clauses ,("=" ,constr expr | [nl] ,constr block) ;
type def           =  id ,[type param clause] ,"=" ,type ;
tmpl def           =  ["case"] ,"class" ,class def 
                    |  ["case"] ,"object" ,object def 
                    |  "trait" ,trait def ;
class def          =  id ,[type param clause] ,{constrannotation}, [access modifier] ,class param clauses ,class template opt ;
trait def          =  id ,[type param clause] ,trait template opt ;
object def         =  id ,class template opt ;
class template opt  =  "extends" ,class template | [["extends"] ,template body] ;
trait template opt  =  "extends" ,trait template | [["extends"] ,template body] ;
class template     =  [early defs], class parents, [template body] ;
trait template     =  [early defs], trait parents ,[template body] ;
class parents      =  constr ,{"with" ,annot type} ;
trait parents      =  annot type ,{"with" ,annot type} ;
constr            =  annot type ,{argument exprs} ;
early defs         = "{" ,[early def ,{semi ,early def}] ,"}" ,"with" ;
early def          =  {annotation ,[nl]} ,{modifier} ,pat var def ;
constr expr        =  self invocation 
                    |  constr block ;
constr block       =  "{" ,self invocation ,{semi ,block stat} ,"}" ;
self invocation    =  "this" ,argument exprs ,{argument exprs} ;
top stat seq        =  top stat, {semi ,top stat} ;
top stat           =  {annotation ,[nl]} ,{modifier} ,tmpl def 
                    |  import 
                    |  packaging 
                    |  package object ;
packaging         =  "package" ,qual id ,[nl] ,"{" ,top stat seq ,"}" ;
package object     =  "package" ,"object" ,object def ;
compilation unit   =  {"package" ,qual id ,semi} ,top stat seq ;

Nested Wrapping is Broken!

Hello! Thanks for the wonderful tool!

I've been using it to work on a new grammar of mine, but I experience some issues when wrapping is turned on! The wrapping is nice and I'd like to use it, but it looks like (when things are wrapped several times / inside of another wrap) it's broken!

Here is my EBNF and a screenshot of the issue:

(*
  The PG Structural Language
  ==========================
*)

Multimer = Monomer , {
  ( "~" (* Glycosidic Bond *)
  | "=" (* Peptide Crosslink*)
  ) , Monomer } ;

Monomer = Glycan , [ "-" , Peptide ] ;

Glycan = Monosaccharide , [ Modifications ] ,
  { Monosaccharide , [ Modifications ] } ;

Peptide = AminoAcid , [ Modifications ] ,
  [ LateralChain ] , { AminoAcid , [ Modifications ] ,
  [ LateralChain ] } ;

LateralChain = "[" , Peptide , "]" ;

Monosaccharide = lowercase ;

AminoAcid = uppercase ;

Modifications = "(" , ( "+" | "-" ) , Moiety ,
  { "," , { space } , ( "+" | "-" ) , Moiety } , ")" ;

Moiety = letter , { letter | digit | "_" } ;

(*
  Basic components
  ----------------
  These are low level components, the small building blocks.
*)

space = " " | "\t" ;

letter = uppercase | lowercase ;

uppercase
  = "A" | "B" | "C" | "D" | "E" | "F" | "G"
  | "H" | "I" | "J" | "K" | "L" | "M" | "N"
  | "O" | "P" | "Q" | "R" | "S" | "T" | "U"
  | "V" | "W" | "X" | "Y" | "Z"
  ;

lowercase
  = "a" | "b" | "c" | "d" | "e" | "f" | "g"
  | "h" | "i" | "j" | "k" | "l" | "m" | "n"
  | "o" | "p" | "q" | "r" | "s" | "t" | "u"
  | "v" | "w" | "x" | "y" | "z"
  ;

digit
  = "0" | "1" | "2" | "3" | "4" | "5" | "6"
  | "7" | "8" | "9"
  ;

image

Note the mess and broken vertical spacing at the bottom there!

Improve parsing errors

$ ebnf2railroad --version
1.9.0

This file yields a cryptic syntax error:

(* test.ebnf *)
Foo = "foo" ;
$ ebnf2railroad test.ebnf
Parse error on line 1: Expected undefined, got null

This file (with lowercase foo) works:

(* test2.ebnf *)
foo = "foo" ;
$ ebnf2railroad test2.ebnf
πŸ“œ Document created at test2.html

If the uppercase identifiers are not allowed, please improve the diagnostics.

Line numbers are off-by-one in parse errors

See example from #28:

(* test.ebnf *)
Foo = "foo" ;
$ ebnf2railroad test.ebnf
Parse error on line 1: Expected undefined, got null

Expected:

Parse error on line 2: Expected undefined, got null

Does not support one-or-more operator

Would be great to support the "one or more" syntax. I see this was requested in #27.

The spec includes syntax for this: see section section 5.8 of ISO/IEC 14977 and this StackOverflow question.

The syntax for one-or-more is a minus sign following a repitition group:

production = { nonterminal }-;

Currently ebnf2railroad throws a syntax error if you put a minus-sign after a repetition group.

Tiny Rendering Error in Complex Overview Diagram

Hello!

This is admittedly a pretty tiny graphical bug, but I figured it's worth reporting! It seems maybe the line is making the tightest turn possible, but can't fit in the space so the end of the curve pokes through the top line?

Tiny Error
(Circled in red)

Here is the EBNF used:

Muropeptide = Monomer , { Connection , Monomer } , [ Connection ] , [ { " " }- ,
  ( Modifications , [ { " " }- , Crosslinks ]
  | Crosslinks , [ { " " }- , Modifications ]
  ) ] ;

Monomer
  = Glycan
  | Peptide
  | Glycan , "-" , Peptide
  ;

Connection
  = "=" (* Crosslink *)
  | "~" (* Glycosidic Bond *)
  | ( "~=" | "=~" ) (* Both *)
  ;

Modifications = "(" ,
  ( Predefined Modification
  | Chemical Offset
  ) , { { " " } , "," , { " " } ,
  ( Predefined Modification
  | Chemical Offset
  ) } , ")" ;

Crosslinks = "(" , Crosslink Descriptors ,
  { { " " } , "," , { " " } , Crosslink Descriptors } , ")" ;

Glycan = { Monosaccharide , [ Modifications ] }- ;

Peptide = { Amino Acid , [ Modifications ] ,
  [ Lateral Chain ] }- ;

Predefined Modification = [ Multiplier ] , letter ,
  { letter | digit | "_" } ;

Chemical Offset = ( "+" | "-" ) , [ Multiplier ] ,
  Chemical Composition ;

Crosslink Descriptors = Crosslink Descriptor ,
  { { " " } , "&" , { " " } , Crosslink Descriptor } ;

Monosaccharide = lowercase ;

Amino Acid = uppercase ;

Lateral Chain = "[" , [ "<" (* C-to-N *) | ">" (* N-to-C *) ] ,
  { Amino Acid , [ Modifications ] }- , "]" ;

Multiplier = Integer , "x" ;

Chemical Composition = { ( Element | Isotope ) ,
  [ Integer ] }- ,
  { Particle Offset } ;

Crosslink Descriptor = position ,
  ( "-" (* Donor-Acceptor *)
  | "=" (* Acceptor=Donor *)
  ) , position ;

Integer = { digit }- ;

Element = uppercase , [ lowercase ] ;

Isotope = "[" , Integer , Element , "]" ;

Particle Offset = ( "+" | "-" ) , [ Integer ] ,
  lowercase ;

letter = uppercase | lowercase ;

uppercase
  = "A" | "B" | "C" | "D" | "E" | "F" | "G"
  | "H" | "I" | "J" | "K" | "L" | "M" | "N"
  | "O" | "P" | "Q" | "R" | "S" | "T" | "U"
  | "V" | "W" | "X" | "Y" | "Z"
  ;

lowercase
  = "a" | "b" | "c" | "d" | "e" | "f" | "g"
  | "h" | "i" | "j" | "k" | "l" | "m" | "n"
  | "o" | "p" | "q" | "r" | "s" | "t" | "u"
  | "v" | "w" | "x" | "y" | "z"
  ;

digit
  = "0" | "1" | "2" | "3" | "4" | "5" | "6"
  | "7" | "8" | "9"
  ;

position = "1" | "2" | "3" | "4" | "5" ;

Let me know if I can provide any more helpful information!

Railroad for '{ }' repetition-symbol is wrong.

Railroad for '{ }' repetition-symbol is wrong.
The railroad diagram should show items repeated 1 or more times.
The railroad diagram currently shows items repeated 0 or more times.

Current railroad, and code.
image

Correct railroad, with hack code.
image

The correct way to produce 0 or more railroad would be:
grammar = [ {rule} ] ;

instead the above produces, extra skip lines:
image

ABNF Support [Feature Request]

Just curious on the what the appetite of supporting ABNF would be? I know this repo has an ebnf focus, but that's why I'm asking.

Depending on your answer I'm willing to contribute resources. Thought I would ask here before going out and doing one from scratch

Supplying --no-target results in error

When using a command such as the following, an error is generated:
ebnf2railroad --write-style --no-target my-grammar.ebnf

TypeError: targetFilename?.endsWith is not a function
    at Object.run (/src/myproject/node_modules/ebnf2railroad/src/cli.js:118:38)
targetFilename?.endsWith is not a function

use --help for usage information

(line number may be off by a few there, as I've inserted some local debugging info)

I believe I see the issue, I'll open a PR momentarily.

Output to SVG file

Connected to me wanting to fix the small graphical bug in #63 , is it possible to add an option for exporting to an SVG file that can be edited in a vector graphics program? When trying to copy-paste the SVG from the HTML in the past, I think I ran into issues with undefined link references?

I don't recall exactly if that was the only issue, but perhaps removing links for the SVG output would fix things and make it easy to post-process these diagrams in an image editing program!

I'm thinking primarily the export of the overview diagram, but perhaps it would be useful to have a way to export all of the sub-component diagrams as well!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.