llvm / circt

Circuit IR Compilers and Tools
https://circt.org
Other
1.69k stars 302 forks source link

FirParser grammar railroad diagram #1374

Open mingodad opened 3 years ago

mingodad commented 3 years ago

I've got the grammar comments in lib/Dialect/FIRRTL/Import/FIRParser.cpp and did some manuall fixes to be able to sse it at https://www.bottlecaps.de/rr/ui .

Copy and paste the EBNF bellow on https://www.bottlecaps.de/rr/ui tab Edit Grammar then switch to the tab View Diagram.

intLit    ::= UnsignedInt | SignedInt | HexLit | OctalLit | BinaryLit
HexLit    ::= '"' 'h' ( '+' | '-' )? ( HexDigit )+ '"'
OctalLit  ::= '"' 'o' ( '+' | '-' )? ( OctalDigit )+ '"'
BinaryLit ::= '"' 'b' ( '+' | '-' )? ( BinaryDigit )+ '"'

optional-width ::= ('<' intLit '>')?

id  ::= Id | keywordAsId

fieldId ::= Id | RelaxedId | UnsignedInt | keywordAsId

type ::= 'Clock'
    | 'Reset'
    | 'AsyncReset'
    | 'UInt' optional-width
    | 'SInt' optional-width
    | 'Analog' optional-width
    | '{' field* '}'
    | type '[' intLit ']'

field::= 'flip'? fieldId ':' type

ruw ::= 'old' | 'new' | 'undefined'

exp ::= id    // Ref
    | prim
    | integer-literal-exp
    | exp '.' fieldId
    | exp '[' intLit ']'
    | exp '.' DoubleLit // TODO Workaround for #470
    | exp '[' exp ']'
    | exp '.' fieldId
    | exp '[' intLit ']' | exp '[' exp ']'

prim ::= primop exp* intLit*  ')'

integer-literal-exp ::= 'UInt' optional-width '(' intLit ')'
    | 'SInt' optional-width '(' intLit ')'

simple_stmt_block ::= simple_stmt*

simple_stmt ::= stmt

stmt ::= attach
    | memport
    | printf
    | skip
    | stop
    | when
    | leading-exp-stmt
    | instance
    | cmem | smem | mem
    | node | wire
    | register

attach ::= 'attach' '(' exp+ ')' info?
stmt ::= mdir 'mport' id '=' id '[' exp ']' exp info?
mdir ::= 'infer' | 'read' | 'write' | 'rdwr'
printf ::= 'printf(' exp exp StringLit exp* ')' info?
skip ::= 'skip' info?
stop ::= 'stop(' exp exp intLit ')' info?
assert ::= 'assert(' exp exp exp StringLit ')' info?
assume ::= 'assume(' exp exp exp StringLit ')' info?
cover ::= 'cover(' exp exp exp StringLit ')' info?
when  ::= 'when' exp ':' info? suite? ('else' ( when | ':' info? suite?))? suite ::= simple_stmt | INDENT simple_stmt+ DEDENT
leading-exp-stmt ::= exp '<=' exp info?
    | exp '<-' exp info?
    | exp 'is' 'invalid' info?
instance ::= 'inst' id 'of' id info?
cmem ::= 'cmem' id ':' type info?
smem ::= 'smem' id ':' type ruw? info?
mem ::= 'mem' id ':' info? INDENT memField* DEDENT
memField ::= 'data-type' '=>' type NEWLINE
    | 'depth' '=>' intLit NEWLINE
    | 'read-latency' '=>' intLit NEWLINE
    | 'write-latency' '=>' intLit NEWLINE
    | 'read-under-write' '=>' ruw NEWLINE
    | 'reader' '=>' id+ NEWLINE
    | 'writer' '=>' id+ NEWLINE
    | 'readwriter' '=>' id+ NEWLINE

node ::= 'node' id '=' exp info?
wire ::= 'wire' id ':' type info?
register    ::= 'reg' id ':' type exp ('with' ':' reset_block)? info?

reset_block ::= INDENT simple_reset info? NEWLINE DEDENT
    | '(' simple_reset ')'
simple_reset ::= simple_reset0
    | '(' simple_reset0 ')'
simple_reset0::=  "reset" "=>" '(' exp exp ')'
pohwist ::= port*
port     ::= dir id ':' type info? NEWLINE
dir      ::= 'input' | 'output'
module ::= 'module' id ':' info? INDENT pohwist simple_stmt_block DEDENT
    | 'extmodule' id ':' info? INDENT pohwist defname? parameter* DEDENT
defname   ::= 'defname' '=' id NEWLINE
parameter ::= 'parameter' id '=' intLit NEWLINE
    | 'parameter' id '=' StringLit NEWLINE
    | 'parameter' id '=' floatingpoint NEWLINE
    | 'parameter' id '=' RawString NEWLINE
file ::= circuit
circuit ::= 'circuit' id ':' info? INDENT module* DEDENT EOF
fabianschuiki commented 3 years ago

Pretty neat :smiley: