ncihnegn / miranda

Miranda is a pure, non-strict, polymorphic, higher order functional programming language designed by David Turner in 1983-6. https://codesync.global/media/open-sourcing-miranda-david-turner-code-mesh-v-2020-codemeshv2020/
http://miranda.org.uk
Other
54 stars 8 forks source link

Grammar railroad diagram #2

Open mingodad opened 1 month ago

mingodad commented 1 month ago

Using a modified byacc (https://github.com/mingodad/lalr-parser-test/tree/main/byacc) that can export an EBNF understood by (IPV4) https://rr.red-dove.com/ui or (IPV6) https://www.bottlecaps.de/rr/ui that generates a nice navigable railroad diagram for the grammar in https://github.com/ncihnegn/miranda/blob/master/rules.y (see the instruction bellow at the top).

//
// 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 url shown above in the 'Edit Grammar' tab
// then click the 'View Diagram' tab.
//
entity ::=
     /*error
    |*/ script
    | VALUE exp
    | EVAL exp
    | EVAL exp COLONCOLON
    | EVAL exp TO

script ::=
     /*empty*/
    | defs

exp ::=
     op
    | e1

op ::=
     '~'
    | '#'
    | diop

diop ::=
     '-'
    | diop1

diop1 ::=
     '+'
    | PLUSPLUS
    | ':'
    | MINUSMINUS
    | VEL
    | '&'
    | relop
    | '*'
    | '/'
    | DIV
    | REM
    | '^'
    | '.'
    | '!'
    | INFIXNAME
    | INFIXCNAME

relop ::=
     '>'
    | GE
    | eqop
    | NE
    | LE
    | '<'

eqop ::=
     EQEQ
    | '='

rhs ::=
     cases WHERE ldefs
    | exp WHERE ldefs
    | exp
    | cases

cases ::=
     exp ',' if exp
    | exp ',' OTHERWISE
    | cases reindent ELSEQ alt

alt ::=
     here exp
    | here exp ',' if exp
    | here exp ',' OTHERWISE

if ::=
     /*empty*/
    | IF

indent ::=
     /*empty*/

outdent ::=
     separator

separator ::=
     OFFSIDE
    | ';'

reindent ::=
     /*empty*/

liste ::=
     exp
    | liste ',' exp

e1 ::=
     '~' e1
    | e1 PLUSPLUS e1
    | e1 ':' e1
    | e1 MINUSMINUS e1
    | e1 VEL e1
    | e1 '&' e1
    | reln
    | e2

es1 ::=
     '~' e1
    | e1 PLUSPLUS e1
    | e1 PLUSPLUS
    | e1 ':' e1
    | e1 ':'
    | e1 MINUSMINUS e1
    | e1 MINUSMINUS
    | e1 VEL e1
    | e1 VEL
    | e1 '&' e1
    | e1 '&'
    | relsn
    | es2

e2 ::=
     '-' e2
    | '#' e2
    | e2 '+' e2
    | e2 '-' e2
    | e2 '*' e2
    | e2 '/' e2
    | e2 DIV e2
    | e2 REM e2
    | e2 '^' e2
    | e2 '.' e2
    | e2 '!' e2
    | e3

es2 ::=
     '-' e2
    | '#' e2
    | e2 '+' e2
    | e2 '+'
    | e2 '-' e2
    | e2 '-'
    | e2 '*' e2
    | e2 '*'
    | e2 '/' e2
    | e2 '/'
    | e2 DIV e2
    | e2 DIV
    | e2 REM e2
    | e2 REM
    | e2 '^' e2
    | e2 '^'
    | e2 '.' e2
    | e2 '.'
    | e2 '!' e2
    | e2 '!'
    | es3

e3 ::=
     comb INFIXNAME e3
    | comb INFIXCNAME e3
    | comb

es3 ::=
     comb INFIXNAME e3
    | comb INFIXNAME
    | comb INFIXCNAME e3
    | comb INFIXCNAME
    | comb

comb ::=
     comb arg
    | arg

reln ::=
     e2 relop e2
    | reln relop e2

relsn ::=
     e2 relop e2
    | e2 relop
    | reln relop e2

arg ::=
     LEX lexrules ENDIR
    | NAME
    | CNAME
    | CONST
    | READVALSY
    | SHOWSYM
    | DOLLAR2
    | '[' ']'
    | '[' exp ']'
    | '[' exp ',' exp ']'
    | '[' exp ',' exp ',' liste ']'
    | '[' exp DOTDOT exp ']'
    | '[' exp DOTDOT ']'
    | '[' exp ',' exp DOTDOT exp ']'
    | '[' exp ',' exp DOTDOT ']'
    | '[' exp '|' qualifiers ']'
    | '[' exp DIAG qualifiers ']'
    | '(' op ')'
    | '(' es1 ')'
    | '(' diop1 e1 ')'
    | '(' ')'
    | '(' exp ',' liste ')'

lexrules ::=
     lexrules lstart here re indent ARROW exp lpostfix outdent
    | lexdefs

lstart ::=
     /*empty*/
    | '<' cnames '>'

cnames ::=
     CNAME
    | cnames CNAME

lpostfix ::=
     /*empty*/
    | LBEGIN CNAME
    | LBEGIN CONST

lexdefs ::=
     lexdefs LEXDEF indent '=' re outdent
    | /*empty*/

re ::=
     re1 '|' re
    | re1

re1 ::=
     lterm '/' lterm
    | lterm '/'
    | lterm

lterm ::=
     lfac lterm
    | lfac

lfac ::=
     lunit '*'
    | lunit '+'
    | lunit '?'
    | lunit

lunit ::=
     '(' re ')'
    | CONST
    | CHARCLASS
    | ANTICHARCLASS
    | '.'
    | name

name ::=
     NAME
    | CNAME

qualifiers ::=
     exp
    | generator
    | qualifiers ';' generator
    | qualifiers ';' exp

generator ::=
     e1 ',' generator
    | generator1

generator1 ::=
     e1 LEFTARROW exp
    | e1 LEFTARROW exp ',' exp DOTDOT

defs ::=
     def
    | defs def

def ::=
     v act2 indent '=' here rhs outdent
    | spec
    | ABSTYPE here typeforms indent WITH lspecs outdent
    | typeform indent act1 here EQEQ type act2 outdent
    | typeform indent act1 here COLON2EQ construction act2 outdent
    | indent setexp EXPORT parts outdent
    | FREE here '{' specs '}'
    | INCLUDE bindings modifiers outdent

def ::=
     here BNF names outdent productions ENDIR

setexp ::=
     here

bindings ::=
     /*empty*/
    | '{' bindingseq '}'

bindingseq ::=
     bindingseq binding
    | binding

binding ::=
     NAME indent '=' exp outdent
    | typeform indent act1 EQEQ type act2 outdent

modifiers ::=
     /*empty*/
    | negmods

negmods ::=
     negmods negmod
    | negmod

negmod ::=
     NAME '/' NAME
    | CNAME '/' CNAME
    | '-' NAME

here ::=
     /*empty*/

act1 ::=
     /*empty*/

act2 ::=
     /*empty*/

ldefs ::=
     ldef
    | ldefs ldef

ldef ::=
     spec
    | typeform here EQEQ
    | typeform here COLON2EQ
    | v act2 indent '=' here rhs outdent

vlist ::=
     v
    | vlist ',' v

v ::=
     v1
    | v1 ':' v

v1 ::=
     v1 '+' CONST
    | '-' CONST
    | v2 INFIXNAME v1
    | v2 INFIXCNAME v1
    | v2

v2 ::=
     v3
    | v2 v3

v3 ::=
     NAME
    | CNAME
    | CONST
    | '[' ']'
    | '[' vlist ']'
    | '(' ')'
    | '(' v ')'
    | '(' v ',' vlist ')'

type ::=
     type1
    | type ARROW type

type1 ::=
     type2 INFIXNAME type1
    | type2

type2 ::=
     tap
    | argtype

tap ::=
     NAME argtype
    | tap argtype

argtype ::=
     NAME
    | typevar
    | '(' typelist ')'
    | '[' type ']'
    | '[' type ',' typel ']'

typelist ::=
     /*empty*/
    | type
    | type ',' typel

typel ::=
     type
    | typel ',' type

parts ::=
     parts NAME
    | parts '-' NAME
    | parts PATHNAME
    | parts '+'
    | NAME
    | '-' NAME
    | PATHNAME
    | '+'

specs ::=
     specs spec
    | spec

spec ::=
     typeforms indent here COLONCOLON ttype outdent

lspecs ::=
     lspecs lspec
    | lspec

lspec ::=
     namelist indent here COLONCOLON type outdent

namelist ::=
     NAME ',' namelist
    | NAME

typeforms ::=
     typeforms ',' typeform act2
    | typeform act2

typeform ::=
     CNAME typevars
    | NAME typevars
    | typevar INFIXNAME typevar
    | typevar INFIXCNAME typevar

ttype ::=
     type
    | TYPE

typevar ::=
     '*'
    | TYPEVAR

typevars ::=
     /*empty*/
    | typevar typevars

construction ::=
     constructs

constructs ::=
     construct
    | constructs '|' construct

construct ::=
     field here INFIXCNAME field
    | construct1

construct1 ::=
     '(' construct ')'
    | construct1 field1
    | here CNAME

field ::=
     type
    | argtype '!'

field1 ::=
     argtype '!'
    | argtype

names ::=
     /*empty*/
    | names NAME

productions ::=
     lspec
    | production
    | productions lspec
    | productions production

production ::=
     NAME params ':' indent grhs outdent

params ::=
     /*empty*/

params ::=
     '(' names ')'

grhs ::=
     here phrase

phrase ::=
     error_term
    | phrase1
    | phrase1 '|' error_term

phrase1 ::=
     term
    | phrase1 '|' here term

term ::=
     count_factors

term ::=
     count_factors indent '=' here rhs outdent

error_term ::=
     ERRORSY

error_term ::=
     ERRORSY indent '=' here rhs outdent

count_factors ::=
     EMPTYSY
    | EMPTYSY factors

count_factors ::=
     factors

factors ::=
     factor
    | factors factor

factor ::=
     unit
    | '{' unit '}'
    | '{' unit
    | unit '}'

unit ::=
     symbol
    | symbol '*'
    | symbol '+'
    | symbol '?'

symbol ::=
     NAME
    | ENDSY
    | CONST
    | '^'

symbol ::=
     '[' exp ']'
    | '-'

//Tokens

ABSTYPE ::= "abstype"
//ANTICHARCLASS ::= ANTICHARCLASS
ARROW ::= "->"
BNF ::= "%bnf"
//CHARCLASS ::= CHARCLASS
//CNAME ::= CNAME
COLON2EQ ::= "::="
COLONCOLON ::= "::"
DIAG ::= "//"
DIV ::= "div"
DOLLAR2 ::= "$$"
DOTDOT ::= ".."
ELSEQ ::= ";="
EMPTYSY ::= "empty"
ENDIR ::= "%%"
ENDSY ::= "end"
EQEQ ::= "=="
ERRORSY ::= "error"
//EVAL ::= EVAL
EXPORT ::= "%export"
FREE ::= "%free"
GE ::= ">="
IF ::= "if"
INCLUDE ::= "%include"
LBEGIN ::= "%%begin"
LE ::= "<="
LEFTARROW ::= "<-"
LEX ::= "%lex"
//LEXDEF ::= LEXDEF
MINUSMINUS ::= "--"
NE ::= "~="
//OFFSIDE ::= OFFSIDE
OTHERWISE ::= "otherwise"
//PATHNAME ::= PATHNAME
PLUSPLUS ::= "++"
READVALSY ::= "readvals"
REM ::= "mod"
SHOWSYM ::= "show"
TO ::= "&>"
TYPE ::= "type"
//TYPEVAR ::= TYPEVAR
//VALUE ::= VALUE
VEL ::= "\\/"
WHERE ::= "where"
WITH ::= "with"
mingodad commented 1 month ago

Also to be able to build miranda on Ubntu 18.04 I needed to change a bit the sed filters applied to .host see diff bellow:

----------------------------------- Makefile -----------------------------------
index 5f7ec73..b36859d 100644
@@ -20,7 +20,7 @@ mira: big.o cmbnms.o data.o lex.o reduce.o steer.o trans.o types.o y.tab.o \
                version.c miralib/.version Makefile .host
    $(CC) $(CFLAGS) -DVERS=`cat miralib/.version` \
         -DVDATE="\"`git show -s --format=%cd --date=format:'%d %b %Y'`\"" \
-       -DHOST="`cat .host`" version.c cmbnms.o y.tab.o data.o lex.o \
+       -DHOST="\"`cat .host`\"" version.c cmbnms.o y.tab.o data.o lex.o \
        big.o reduce.o steer.o trans.o types.o -lm -o mira
    strip mira$(EX)
 .host:
@@ -28,7 +28,7 @@ mira: big.o cmbnms.o data.o lex.o reduce.o steer.o trans.o types.o y.tab.o \
    @echo $(CC) $(CFLAGS) >> .host
    $(CC) -v 2>> .host
    sed -i 's/.*/&\\\\n/' .host
-   sed -i 's/\\n /\\n/g' .host
+   sed -i -z 's/\n//g' .host
 y.tab.c y.tab.h: rules.y
    $(YACC) -d rules.y
 big.o cmbns.o data.o lex.o reduce.o steer.o trans.o types.o y.tab.o: \