Lyra EBNF Grammar

From Lyra

Jump to: navigation, search
(* The EBNF file conforms to the ISO/IEC 14977 : 1966(E) standard. 
   http://www.cl.cam.ac.uk/~mgk25/iso-14977.pdf *)

(* Below lists the EBNF brackets used in this file. 
   '  ' first quote 
   "  " second quote 
   (  ) group
   [  ] option
   {  } repeat, 0 or more

   In addition, - means exception, and { X } - means one or more
   repetitions of X (repetition except empty) . *)


(* -------------------- Fundamentals -------------------- *)

(* alphabetical characters *)
Letter       = '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' |
               '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' ;

(* Digits *)
Digit        = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ;
BinDigit     = '0' | '1' ;
OctDigit     = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '0' ;
HexDigit     = Digit | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' |
                       'A' | 'B' | 'C' | 'D' | 'E' | 'F' ;
NonZeroDigit = Digit - '0' ;


(* ASCII displayable *)
AllCharacter = Digit | Letter |
               ' ' | '!' | '"' | '#' | '$' | '%' | '&' | "'" |
               '(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' |
               ':' | ';' | '<' | '=' | '>' | '?' | '@' | '[' |
               '\' | ']' | '^' | '_' | '`' | '{' | '|' | '}' | '~' ;

(* String *)
String       = '"' { AllCharacter - '"'} '"' ;

(* Identifier, same as in C *)
Identifier   = ( Letter | '_' ) { ( Letter | Digit | '_' ) } ;

(* Decimal, Hexadecimal and Binary Integers *)
Integer      = NaturalNum [ Suffix ] | 
               '0' { OctDigit } [ Suffix ] |
               '0' ( 'x' | 'X' ) { HexDigit } - [ Suffix ] |
               '0' ( 'b' | 'B' ) { BinDigit } - [ Suffix ] |
               NaturalNum "'" ( 'd' | 'D' ) { Digit } - |
               NaturalNum "'" ( 'x' | 'X' ) { HexDigit } - |
               NaturalNum "'" ( 'o' | 'O' ) { OctDigit } - |
               NaturalNum "'" ( 'b' | 'B' ) { BinDigit } -
               ;

NaturalNum   = NonZeroDigit { Digit } ;

Suffix       = ( 'u' | 'U' ) [ ( 'l' | 'L' ) ] | 
               ( 'l' | 'L' ) [ ( 'u' | 'U' ) ] ;


(* --------------------   Program    -------------------- *)
Program      = { ( FuncDef | FuncDecl | ModuleDef | IncludeDef |
                    TypeDef | ConstDef ) } ;

(* --------------------  Constant  ---------------------- *)

ConstDef     = 'const' TypeRef Identifier { '[' Integer ']' }
                '=' ComplexExp ';' ;

(* --------------------  Functions   -------------------- *)
FuncDef      = [TemplFormal] 'function' TypeRef Identifier '(' ArgList ')'
               [ 'pure' ] '{'
                  { Statement }
               '}' ;

ArgList      = Arg { ',' Arg } | '...' ;
Arg          = TypeRef Identifier { '[' Integer ']' } ;

FuncDecl     = [TemplFormal] 'function' TypeRef Identifier '(' ArgList ')'
               [ 'pure' ] ';' ;

TemplFormal  = 'template' '<' TemplFmlArg { ',' TemplFmlArg } '>' ;

TemplFmlArg  = 'type' Identifier [ '=' TypeRef ] |
               TypeRef Identifier [ '=' SimpleExp ] ;

TemplActual  = '#' '<' TemplActArg { ',' TemplActArg } '>' ;

TemplActArg  = 'type' [ Identifier '=' ] TypeRef |
               [ Identifier '=' ] SimpleExp ;

(* --------------------    Include   -------------------- *)
IncludeDef   = 'include' String ';' ;

(* -------------------- Module Class -------------------- *)
ModuleDef    = [TemplFormal] 'module' Identifier [ '(' PortList ')' ] '{'
                 (* Ok to have stray ;s *)
                 { (ModuleElement | ';' ) }
               '}' ;


PortList     = Port { ',' Port } ;
Port         = PortType Identifier ;

(* Port type is optional *)
PortType     = ('in' | 'out' |
                'bin' | 'bout' |
                'rin' | 'rout' |
                'sin' | 'sout' ) [ '<' TypeRef '>' ] |
               ('io' | 'bio' | 'rio' | 
                'oi' | 'boi' | 'roi' )
                  [ '<' TypeRef ',' TypeRef  '>' ] ;

ModuleElement
             = RdvDecl | ModuleInstance | RegDecl | InitDecl | DpDef | FsmDef ;

ModuleInstance
             = Identifier [ TemplActual] Identifier [ '(' ( 
                    (* Named assoication *)
                    '.' Identifier '('Identifier')'
                    {',' '.' Identifier '('Identifier')'} |
                    (* prositional association *)
                    Identifier {',' Identifier} 
                ) ')' ] ';' ;

RdvDecl      = ('rendv' | 'barrier') 
                   Identifier [ '(' Integer ')' ]
                     { ',' Identifier [ '(' Integer ')' ] } ';' |
                'signal'
                   Identifier { ',' Identifier } ';' ;

RegDecl      = 'reg' TypeRef Identifier { '[' Integer ']' } 
                 { ',' Identifier { '[' Integer ']' } } ';' ;


(* Initial statements initialize registers. *)
InitDecl     = 'init' Statement ;

(* -------------------- DataPath definition -------------------- *)
DpDef        = 'dp' [Identifier] [ '(' PortList ')' ] '{'
                 { ValDecl }
                 { Statement } -
               '}' ;

(* -------------------- Fsm definition -------------------- *)

FsmDef       = 'fsm' [ Identifier ] [ '(' PortList ')' ] '{'
                 (* first state is the initial state *)
                 { ValDecl }
                 { StateDeclList } -
               '}' ;

ValDecl      = 'val' TypeRef Identifier { '[' Integer ']' } 
                 { ',' Identifier { '[' Integer ']' } } ';' ;

ComplexExpList
             = ComplexExp {',' ComplexExp} ;

StateDecl    = ( 'state' | 'init' ) StateRegExp ':' Statement ;

StateRegExp  = Identifier |
               (Letter | '_' | '*' '?' ) (* not implemented yet *)
               { (Letter | Digit | '_' | '*' | '?' ) } ; (* not yet *)

StmtOption   =  ';' |
                Statement ;

GotoStmt     = 'goto' Identifier ';'; 

WhenStmt     = 'when' '(' [ ComplexExpList ] ')' Statement ;

SwitchStmt   = 'switch' '(' ComplexExp ')' '{'
                    {'case' Interger ':' Statement } -
                    ['default' ':' Statement ]
                '}' ;

ValDecl      = 'val' TypeRef Identifier [ '[' Integer ']' ] 
                 { ',' Identifier [ '[' Integer ']' ] } ';' ;

ValStmt      = ValDecl ;

GroupStmt    = '{' { Statement } '}' ;

(* -------------------- Types -------------------- *)

(* Typedef *)
TypeDef      = 'typedef' TypeRef Identifier ';' ;

(* Integer Type Name *)
IntTypeName  = ('int' | 'uint') '<' SimpleExp '>' [ '{' IntFieldList '}' ] ;

IntTypeFieldList
             = IntTypeField { ',' IntTypeField } [','] ;

(* A field in an integer, name : type = {bits} ; *)
IntTypeField = Identifier ':' [ TypeRef '=' ] BitExtract ;

(* Tuple Type *)
TupleTypeName 
             = '(' TypeRef { ',' TypeRef } ')' ;

(* Array Type *)
ArrayTypeName
             = TypeRef '[' [ ComplexExp ] ']' ;

(* Type Reference *)
TypeRef      = IntTypeName | TupleTypeName | ArrayTypeName |
                'bool' | 'string' | 'void' |
                Identifier ;

(* Extract a bit or a range (left>=right), 0 is the LSB *)
BitExtract   = '{' ComplexExp '}' |
               '{' ComplexExp ':' ComplexExp '}' ;

(* Constant values *)
Constants    = Integer | 'true' | 'false' | String ;

(* EBNF cannot specify precedence directly but to make things readable
   I added precedence regardless  *)
ComplexExp  =  SimpleExp |
               (* -------- precedence level 1 begin ------ *)
               (* reference to an element in an array *)
               Identifier '[' ComplexExp ']' |
               (* function calling, or port access 
               Identifier '.' 'read'  '(' ')' |
               Identifier '.' 'write' TupleExp *)
               Identifier [ TemplActual ] TupleExp | 
               Identifier '.read' '(' ')' | 
               Identifier '.write' TupleExp | 
               (* bit extraction *)
               ComplexExp BitExtract |
               (* field reference or rendv begin/end/read/write *)
               ComplexExp '.' Identifier |
               (* tuple element reference *)
               ComplexExp '.' '$' Integer |
               (* -------- precedence level 2 begin ------ *)
               (* cast in SimpleExp is here too *)
               (* unary operators, 1's complement and negation *)
               '~' ComplexExp |
               '-' ComplexExp |
               '!' ComplexExp |
               (* -------- precedence level 3 begin ------ *)
               ComplexExp '::' ComplexExp |
               (* -------- precedence level 4 begin ------ *)
               ComplexExp '*'  ComplexExp |
               ComplexExp '/'  ComplexExp |
               ComplexExp '%'  ComplexExp |
               (* -------- precedence level 5 begin ------ *)
               ComplexExp '+'  ComplexExp |
               ComplexExp '-'  ComplexExp |
               (* -------- precedence level 6 begin ------ *)
               ComplexExp '>>' ComplexExp |
               ComplexExp '<<' ComplexExp |
               (* -------- precedence level 7 begin ------ *)
               ComplexExp '>=' ComplexExp |
               ComplexExp '<=' ComplexExp |
               ComplexExp '>'  ComplexExp |
               ComplexExp '<'  ComplexExp |
               (* -------- precedence level 8 begin ------ *)
               ComplexExp '==' ComplexExp |
               ComplexExp '!=' ComplexExp |
               (* -------- precedence level 9 begin ------ *)
               ComplexExp '&'  ComplexExp |
               (* -------- precedence level 10 begin------ *)
               ComplexExp '^'  ComplexExp |
               (* -------- precedence level 11 begin------ *)
               ComplexExp '|'  ComplexExp |
               (* -------- precedence level 12 begin------ *)
               ComplexExp '&&' ComplexExp |
               (* -------- precedence level 13 begin------ *)
               ComplexExp '||' ComplexExp |
               (* -------- precedence level 14 begin------ *)
               ComplexExp '?'  ComplexExp ':' ComplexExp ;

(* simple exps are used within < >'s, i.e. in template parameters and
   integer type width specification  *)
SimpleExp    = (* immediate constant *)
               Constants | 
               (* reference to a scalar register or alias *)
               Identifier  |       
               (* tuple *)
               TupleExp |
               (* array forming *)
               BraceExp |
               (* size of a variable *)
               'sizeof' '(' ComplexExp ')' |
               (* type cast *)
               '<' TypeRef '>' ComplexExp ;

(* tuple or paranthesis *)
TupleExp     = '(' [ ComplexExp { ',' ComplexExp } ] ')' ;

BraceExp     = '{' [ ComplexExp { ',' ComplexExp } ] '}' ;

(* -------------------- Statement -------------------- *)

Statement = ComplexExp ';' |
            (* assignment *) 
            ComplexExp '=' ComplexExp ';' |
            'return' [ ComplexExp ] ';' |
            GotoStmt ';' |
            WhenStmt  |
            SwitchStmt |
            ValStmt |
            GroupStmt ;