Basic Syntax Diagrams

From The Document Foundation Wiki
Jump to: navigation, search


Preamble

Definition and purpose of Syntax diagrams can be found in wikipedia. Diagrams are produced either using Backus–Naur form (BNF) - or any grammar derived from BNF - either resorting to specific program libraries.
Diagrams generation is only illustrated using either Railroad Diagram Generator from Gunther Rademacher, either Railroad Diagrams by Tab Atkins.
This page assumes you know how to read syntax diagrams.

Mockup, Cheatsheet

Demonstration diagrams for LibreOffice Basic language can be found in this page.

A Basic Syntax cheatsheet (WiP) can be found in this page.

Railroad Diagrams

  • Railroad Diagram Generator supports the BNF grammar, .xhtml or .png file generation as well as diagram prototyping.
  • Railroad Diagrams allows diagram prototyping, default options in statements, .svg file generation. Inline .svg diagram generation is possible with its JavaScript library.

Using Tab Atkins' Diagrams

LibreOffice Basic syntax diagrams use Railroad Diagrams. They are generated out of its Python library. Original styling has been tweaked by Ilmari Lauhakangas.

Conventions used are:

  • Basic keywords use propercasing e.g. Call, DimArray, MsgBox, Property, ..
  • Variables are denoted with lowercase e.g. expression, param, value, ..
  • Non-terminal items are denoted with lowercase and rectangles.
  • Diagram fragments are denoted with different extremities.
  • Previous notation in help files remains and is modified when appropriate.

Prototyping with JavaScript library

Diagrams are prototyped locally using generator-no-module.html or online from here.
LibreOffice Basic LET statement JavaScript/Python example diagram:

  Diagram(
    Optional(
      Choice(0,'Let','Set')
    ),
    NonTerminal('variable'),
    Terminal('='),
    Choice(0,
      NonTerminal('expression'),
      Sequence(Optional('New'),NonTerminal('object'))
    )
  )

…

Generating SVG with Python library

Scalable Vector Graphics files can be generated directly from LibreOffice, by copying the prototyped diagram code into Python example file below. Please make sure to drop railroad.py module in LibreOffice <program> folder beforehand.
With Python:

# -*- coding: utf-8 -*-
from railroad import *
import railroad
railroad.VS = 20
railroad.AR = 15
railroad.DEFAULT_STYLE = '''\
    svg.railroad-diagram {
        background-color:transparent;
    }
    svg.railroad-diagram path {
        stroke-width:1;
        stroke:black;
        fill:rgba(0,0,0,0);
    }
    svg.railroad-diagram text {
        font:bold 14px monospace;
        font-family: Verdana, sans-serif;
        text-anchor:middle;
    }
    svg.railroad-diagram text.label{
        text-anchor:start;
    }
    svg.railroad-diagram text.comment{
        font:italic 12px monospace;
    }
    svg.railroad-diagram rect{
        stroke-width:1;
        stroke:black;
        fill:transparent;
    }
'''

HOME_DIR = 'C:\\Users\\<user>\\Documents\\'

def a_fragment():  # ComplexDiagram example
  with open(HOME_DIR + 'argument_fragment.svg', 'w+') as svg:
    Diagram(  # type='complex',
      Sequence(
        Choice(0,
          Sequence(
            Optional('Optional'),
            Choice(0,'ByRef','ByVal')),
          'ParamArray'), 
        NonTerminal('argument'),
        Choice(0,
          Sequence(
            Choice(0, Sequence('As', NonTerminal('typename')), NonTerminal('char')),
            Optional(Sequence('=', NonTerminal('expression')))
          ),
          Sequence('()', Optional('As Variant'))
        )
      ), type='complex'
    ).writeSvg(svg.write)

def a_statement():  # Diagram() example
  with open(HOME_DIR + 'Call_statement.svg', 'w+') as svg:
    Diagram(
      Sequence(
        Optional("Call"),
        NonTerminal('name'),
        Choice(0,
          Sequence('(',
            OneOrMore(
              Sequence(Optional(Sequence(NonTerminal('param'),':='),'skip'),NonTerminal('value')),
              ','
              ),
            ')'
            ),
          OneOrMore(
            Sequence(Optional(Sequence(NonTerminal('param'),':='),'skip'),NonTerminal('value')),
            ','
            )
        )
      )
    ).writeSvg(svg.write)

g_exportedScripts = (a_statement, a_fragment)

…

Using Gunther Rademacher's Diagrams

Sample diagrams produced out of Railroad Diagram Generator are stored in Documentation team Nextcloud instance.

LibreOffice Basic CALL statement BNF example:

CALL ::= "Call"? foo
          ("("(parm ":=")? value ("," (parm ":=")? value)*")"
          | (parm ":=")? value ("," (parm ":=")? value)*)

…

Python.org documentation uses intensively BNF notation without exhibiting diagrams.

Python import statement BNF example:

import_stmt     ::=  "import" module ["as" name] ( "," module ["as" name] )*
                     | "from" relative_module "import" identifier ["as" name]
                     ( "," identifier ["as" name] )*
                     | "from" relative_module "import" "(" identifier ["as" name]
                     ( "," identifier ["as" name] )* [","] ")"
                     | "from" module "import" "*"
module          ::=  (identifier ".")* identifier
relative_module ::=  "."* module | "."+
name            ::=  identifier