Skip to content

Grammar railroad diagram #1

@mingodad

Description

@mingodad

Extracting an EBNF understood by https://www.bottlecaps.de/rr/ui to produce a navigable railroad diagram from https://github.com/Hadron67/tscc-compiler/blob/master/src/parser/parser.y , ideally tscc would have an option to output it.

Copy and paste the EBNF shown bellow on https://www.bottlecaps.de/rr/ui in the tab Edit Grammar the click the tab View Diagram to see a navigable railroad diagram.

start ::= options "%%" body "%%" epilogue

options ::= options option
options ::=
option ::= "%lex" states_ "{" lexBody "}"
option ::= associativeDir assocTokens
option ::= "%option" "{" optionBody "}"
option ::= "%header" block
option ::= "%extra_arg" block
option ::= "%type" block
option ::= "%init" block block
option ::= "%output" STRING
option ::= "%token" tokenDefs
option ::= "%token_hook" "(" NAME ")" block
option ::= "%touch" touchTokenList

tokenDefs ::= tokenDefs "<" NAME ">"
tokenDefs ::= "<" NAME ">"
touchTokenList ::= touchTokenList tokenRef
touchTokenList ::= tokenRef
epilogue ::=
epilogue ::= nonEmptyEpilogue
nonEmptyEpilogue ::= nonEmptyEpilogue ANY_CODE
nonEmptyEpilogue ::= ANY_CODE
associativeDir ::= "%left"
associativeDir ::= "%right"
associativeDir ::= "%nonassoc"
assocTokens ::= assocTokens assocToken
assocTokens ::= assocToken
assocToken ::= tokenRef
assocToken ::= NAME
optionBody ::= optionBody NAME "=" STRING
optionBody ::=
states_ ::= "<" states ">"
states_ ::=
states ::= NAME
states ::= states "," NAME
lexBody ::= lexBody lexBodyItem
lexBody ::=
lexBodyItem ::= NAME "=" "<" regexp ">"
lexBodyItem ::= newState "<" regexp ">" lexAction_
lexBodyItem ::= newState "<" NAME ":" regexp ">" lexAction_

newState ::=
lexAction_ ::= ":" lexAction
lexAction_ ::=
lexAction ::= "[" lexActions "]"
lexAction ::= actionBlock

lexActions ::= lexActions "," lexActionItem
lexActions ::= lexActionItem
lexActionItem ::= "+" NAME
lexActionItem ::= "-"
lexActionItem ::= "=>" NAME
lexActionItem ::= "=" STRING
lexActionItem ::= actionBlock
regexp ::= innerRegexp
regexp ::= "%least" innerRegexp
innerRegexp ::= union

union ::= union "|" simpleRE
union ::= simpleRE
simpleRE ::= simpleRE basicRE
simpleRE ::= basicRE
basicRE ::= primitiveRE rePostfix

rePostfix ::= "+"
rePostfix ::= "?"
rePostfix ::= "*"
rePostfix ::=
primitiveRE ::= "(" innerRegexp ")"
primitiveRE ::= "[" inverse_ setRE_ "]"
primitiveRE ::= "<" NAME ">"
primitiveRE ::= "%import" "(" STRING ")"
primitiveRE ::= STRING
inverse_ ::= "^"
inverse_ ::=
setRE_ ::= setRE
setRE_ ::=
setRE ::= setRE "," setREItem
setRE ::= setREItem
setREItem ::= STRING
setREItem ::= STRING "-" STRING
body ::= body bodyItem
body ::= bodyItem
bodyItem ::= compoundRule
compoundRule ::= NAME arrow rules ";"

arrow ::= ":"
arrow ::= "=>"
rules ::= rules "|" rule
rules ::= rule
rule ::= ruleHead ruleBody ruleTrailer

ruleHead ::= "%use" "(" varUseList ")"
ruleHead ::=
varUseList ::= varUseList "," NAME
varUseList ::= NAME
ruleBody ::= ruleItems
ruleBody ::= "%empty"
ruleItems ::= ruleItems ruleItem
ruleItems ::=
itemName ::= NAME "="
itemName ::=
ruleItem ::= NAME
ruleItem ::= NAME "=" NAME
ruleItem ::= itemName tokenRef
ruleItem ::= itemName lexAction

tokenRef ::= "<" NAME ">"
tokenRef ::= STRING
ruleTrailer ::=
ruleTrailer ::= rulePrec
ruleTrailer ::= rulePrec lexAction
rulePrec ::= "%prec" NAME
rulePrec ::= "%prec" tokenRef
block ::= "{" innerBlock "}"

innerBlock ::= innerBlock innerBlockItem
innerBlock ::=
innerBlockItem ::= codeList
innerBlockItem ::= "{" innerBlock "}"

actionBlock ::= always "{" innerActionBlock "}"

always ::= "%always"
always ::=
innerActionBlock ::= innerActionBlock innerActionBlockItem
innerActionBlock ::=
innerActionBlockItem ::= codeList
innerActionBlockItem ::= "$$"
innerActionBlockItem ::= "$token"
innerActionBlockItem ::= "$matched"
innerActionBlockItem ::= EMIT_TOKEN
innerActionBlockItem ::= "{" innerActionBlock "}"

codeList ::= codeList ANY_CODE
codeList ::= ANY_CODE

The above EBNF was extracted adding this code to tscc:

export class Rule{
...
    public toEbnfRR(){
        if(this.lhs.sym.charAt(0) == "@") return "";
        var ret = this.lhs.sym + ' ::=';
        for(var i = 0;i < this.rhs.length;i++){
            var r = this.rhs[i];
            if(r >= 0){
                var tok = this.g.tokens[r];
                // ret += ' <' + this.g.tokens[r].sym + '>';
                ret += ' ' + (tok.alias === null ? tok.sym : `"${tok.alias}"`);
            }
            else {
                var sym = this.g.nts[-r - 1].sym;
                if(sym.charAt(0) != "@") ret += ' ' + sym;
            }
        }
        return ret;
    }
}
...
export class Grammar implements TokenEntry{
...
    toEbnfRR(){
        var ret = '';
        this.forEachRule((lhs, rule) => {
            var s = rule.toEbnfRR();
            ret += s + "\n";
        });
        return ret;
    }
...
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions