// This file may contain copyright or proprietary information. // It was based on the following publicly online documents indexed by Google: // http://www.bluespec.com/pdfs_and_docs/BluespecReferenceGuide04052.pdf // http://csg.csail.mit.edu/6.S078/6_S078_2012_www/resources/reference-guide.pdf // However, BSV programs found on the net had some further constructs that I have added my own clauses for. // // Bluespec BSV parser implemented in F# for fsyacc. // David Greaves, University of Cambridge, UK. // %{ open yout open moscow open hprls_hdr open linepoint_hdr type x_lifted_op_t = KB_ab of x_abdiop_t | KB_bop of x_bdiop_t | KB_op of x_diop_t type bsv_ast_t = | KB_dontcare | KB_builtin of string | KB_constantAlias of string | KB_returnStmt of bsv_ast_t * linepoint_t | KB_easc of bsv_ast_t * linepoint_t | KB_eventControl of string * bsv_ast_t * linepoint_t | KB_functionCall of bsv_ast_t * bsv_ast_t list * linepoint_t | KB_intLiteral of string | KB_stringLiteral of string | KB_bitConcat of bsv_ast_t list * linepoint_t | KB_actionValueBlock of string * string option * bsv_ast_t list * string option * linepoint_t | KB_case of bsv_ast_t * (bsv_ast_t list * bsv_ast_t) list * linepoint_t | KB_actionValue | KB_ds_time of bool | KB_typeNat of string | KB_structPattern of (string * bsv_ast_t) list * linepoint_t | KB_subinterfaceDecl of bsv_ast_t list * bsv_ast_t * string * linepoint_t | KB_subinterfaceDef0 of string * string * bsv_ast_t list * string option * linepoint_t | KB_subinterfaceDef1 of bsv_ast_t option * string * bsv_ast_t * linepoint_t | KB_tuplePattern of bsv_ast_t list * linepoint_t | KB_id of string * linepoint_t | KB_patternVar of string | KB_beginEndExpr of string option * bsv_ast_t list * bsv_ast_t * string option | KB_typeIde of string * bsv_ast_t list | KB_typeBit of (int * int) option | KB_typedef of string * bsv_ast_t list | KB_systemFunction of string * bsv_ast_t list | KB_typedefConst of string * bsv_ast_t * linepoint_t | KB_typeFormal of string * string | KB_method_formal of bsv_ast_t * bsv_ast_t | KB_tag of bsv_ast_t * string * linepoint_t | KB_letBinding of string * bsv_ast_t * string * linepoint_t | KB_dot of bsv_ast_t | KB_varDeclDo of bsv_ast_t option * bsv_ast_t * bsv_ast_t * linepoint_t | KB_while of bsv_ast_t * bsv_ast_t * linepoint_t | KB_for of bsv_ast_t * bsv_ast_t * bsv_ast_t * bsv_ast_t * linepoint_t | KB_systemTaskCall of bsv_dtn_t * bsv_ast_t list * linepoint_t | KB_moduleApp of string * bsv_ast_t list * linepoint_t | KB_structSubTagged of bsv_ast_t list * string | KB_import of string * string option * linepoint_t | KB_export of string * bool * linepoint_t | KB_typedefSTUnion of string * bsv_ast_t list * bsv_ast_t * string list * linepoint_t | KB_typedefSynonym of bsv_ast_t * bsv_ast_t * linepoint_t | KB_proviso of string * bsv_ast_t list | KB_attribute of bsv_ast_t list * bsv_ast_t | KB_attribute_spec of bsv_ast_t * bsv_ast_t option | KB_typeAssertion of bsv_ast_t * bsv_ast_t | KB_structExprAssociative of string * (string * bsv_ast_t) list * linepoint_t | KB_structExprPositional of string * bsv_ast_t list * linepoint_t | KB_structMember of bsv_ast_t * string | KB_unionMember of bsv_ast_t option * string | KB_unionSubStruct of bsv_ast_t list * string | KB_structMemberTagged of bsv_ast_t | KB_structMemberSubTagged of bsv_ast_t | KB_monadic of string * bsv_ast_t * linepoint_t | KB_attr_spec of string * bsv_ast_t option | KB_taggedUnion of string * (string * bsv_ast_t) list * bsv_ast_t option * linepoint_t | KB_taggedUnionExpr of string * (string * bsv_ast_t) list * bsv_ast_t option * linepoint_t | KB_diadic of x_lifted_op_t * bsv_ast_t * bsv_ast_t * linepoint_t | KB_interfaceExpr of string * bsv_ast_t list * string option * linepoint_t | KB_query of bsv_ast_t * bsv_ast_t * bsv_ast_t | KB_await of bsv_ast_t * linepoint_t | KB_sublang of string * bsv_ast_t list * linepoint_t | KB_subscripted of bsv_ast_t * bsv_ast_t list * linepoint_t | KB_block of string option * bsv_ast_t list * string option * linepoint_t | KB_regWrite of bsv_ast_t * bsv_ast_t * linepoint_t | KB_moduleInst of bsv_ast_t * string * bsv_ast_t * string * bsv_ast_t list * linepoint_t | KB_if of bsv_ast_t * bsv_ast_t * bsv_ast_t option * linepoint_t | KB_functionDef1 of bsv_ast_t * bsv_ast_t list * string option * linepoint_t | KB_functionDef2 of bsv_ast_t * bsv_ast_t * linepoint_t | KB_typedefEnum of string list * string * string list * linepoint_t | KB_interfaceDecl of bsv_ast_t list * bsv_ast_t * bsv_ast_t list * string option * linepoint_t | KB_rulesExpr of string option * bsv_ast_t * string option | KB_typeclassInstanceDef of string * bsv_ast_t list * bsv_ast_t list * bsv_ast_t list * string option * linepoint_t | KB_bitRange of bsv_ast_t * bsv_ast_t * bsv_ast_t * linepoint_t | KB_functionProto of bsv_ast_t * string * (bsv_ast_t * string) list * bsv_ast_t list * linepoint_t | KB_varDeclAssign of bsv_ast_t option * bsv_ast_t * bsv_ast_t option * linepoint_t | KB_package of string * bsv_ast_t list * bsv_ast_t list * bsv_ast_t list * string option | KB_methodProto of bsv_ast_t list * bsv_ast_t * string * (bsv_ast_t * string) list * bsv_ast_t list * linepoint_t | KB_typeclassDef of string * bsv_ast_t list * bsv_ast_t list * bsv_ast_t list * string option * linepoint_t | KB_rule of bsv_ast_t list * string * bsv_ast_t option * bsv_ast_t list * string option * linepoint_t | KB_methodDef1 of bsv_ast_t option * string * (bsv_ast_t option * string) list * bsv_ast_t option * bsv_ast_t list * string option * linepoint_t | KB_methodDef2 of bsv_ast_t option * string * (bsv_ast_t option * string) list * bsv_ast_t option * bsv_ast_t * linepoint_t | KB_moduleDef of string list * string * (bsv_ast_t * string) list * bsv_ast_t option * (bsv_ast_t * string) list * bsv_ast_t list * bsv_ast_t list * string option * linepoint_t | KB_wildcard and bsv_dtn_t = | K_finish of bsv_ast_t option | K_stop of bsv_ast_t option | DK_s of string let debug (x:string) = () // vprintln 0 x let atoi32 (x:string) = System.Convert.ToInt32(x) let types_dictionary = new System.Collections.Generic.Dictionary() let mktype ty = let (found, ov) = types_dictionary.TryGetValue(ty) let _ = if (not found) then types_dictionary.Add(ty, ty) in ty let glp() = get_linepoint() let parse_error (err_msg:string) = let _ = vprintln 0 ("parse error: " + err_msg) in () let parse_error_rich = let app = List.iter let per (a:Microsoft.FSharp.Text.Parsing.ParseErrorContext<_>) = //let _ = vprintln 0 ("parse error rich: " + a.Message) let _ = if !g_verbose >1 then vprintln 0 (" state=" + sfold (sprintf " %i") a.StateStack) in () in Some per %} %type actionBlock %type actionValueBlock %type attributeInstance_list %type attrName %type attrSpec %type attrSpec_comma_list %type backdoors %type beginEndExpr %type beginEndExprStmt %type beginEndExprStmt_list %type binop5 binop6 binop7 binop8 binop9 binop10 binop11 binop12 binop13 binop14 %type bitConcat %type bitSelect %type colon_id_option %type colon_Id_option %type condExpr %type moduleImpBeginEndStmt %type moduleImpCase %type moduleImpCaseArm %type <(bsv_ast_t list* bsv_ast_t) list> moduleImpCaseArm_list %type moduleImpIf %type moduleImpStmt %type moduleImpStmt_list %type actionBeginEndStmt %type actionCase %type actionCaseArm %type <(bsv_ast_t list * bsv_ast_t) list> actionCaseArm_list %type actionIf %type actionStmt %type actionStmt_list %type actionValueBeginEndStmt %type actionValueCase %type actionValueCaseArm %type <(bsv_ast_t list * bsv_ast_t) list> actionValueCaseArm_list %type actionValueIf %type actionValueStmt %type actionValueStmt_list %type fbodBeginEndStmt %type fbodCase %type fbodCaseArm %type <(bsv_ast_t list * bsv_ast_t) list> fbodCaseArm_list %type fbodIf %type fbodStmt %type fbodStmt_list %type derives_list %type displayTaskName %type exportDecl %type exportItem %type exportItem_comma_list %type expression %type expression_comma_list %type exprPrimary %type functionBody %type functionCall %type functionDef %type functionFormal %type <(bsv_ast_t * string) list> functionFormals_list %type functionProto %type ident %type identifier %type identifier_comma_list %type Identifier_comma_list %type implicitCond %type importDecl %type importItem %type importItem_comma_list %type interfaceDecl %type interfaceExpr %type interfaceStmt %type interfaceStmt_list %type letBinding %type lValue %type lValue_decl %type memberBind %type <(string * bsv_ast_t) list> memberBind_comma_list %type methodDef %type methodFormal %type <(bsv_ast_t option * string) list> methodFormals %type methodProto %type methodProtoFormal %type <(bsv_ast_t * string) list> methodProtoFormals_list %type interfaceMemberDecl_list %type moduleActualArg %type moduleActualArgs %type moduleApp %type <(bsv_ast_t * string) list> moduleArgs %type moduleDef %type moduleInst %type moduleParam %type <(bsv_ast_t * string) list> moduleParams %type <(bsv_ast_t * string) list> moduleParamsList_oom %type moduleStmt %type moduleStmt_list %type operatorExpr5 operatorExpr6 operatorExpr7 operatorExpr8 operatorExpr9 operatorExpr10 operatorExpr11 operatorExpr12 operatorExpr13 operatorExpr14 operatorExpr15 %type overloadedDef %type packageDecl %type packageStmt %type packageStmt_list %type pattern %type pattern_comma_list %type pragma_list %type proviso %type proviso_comma_list %type provisos_list %type regWrite %type returnStmt %type rule %type ruleAssertion_list %type ruleBody %type ruleCond_option %type rulesExpr %type rulesStmt %type structExpr %type structMember %type structMember_list %type structPattern %type structPattern_item %type <(string * bsv_ast_t) list> structPattern_item_comma_list %type subinterfaceDecl %type subinterfaceDef %type subinterfaceStmtList %type subStruct %type subTagged %type sublangExpr %type sublangExp2 %type sublangExpr_list %type systemFunctionCall %type systemTaskCall %type taggedId %type taggedUnionExpr %type tuplePattern %type type %type typeFormals %type typeAssertion %type typeclassDef %type typeclassIde %type typeclassInstanceDef %type type_comma_list %type typeDef %type typeDefType %type typeFormal_list %type typeFormal_list1 %type typeIde %type typeIdeUC %type typeNat %type type_option %type unionMember %type unionMember_list %type unop %type varAssign %type varDeclAssign %type varDeclDo %type varDecl %type varDo %type vflist %token S_IDC S_IDL S_TY SP_stringLiteral %token S_NAT %type SP_intLiteral %token DS_display %token DS_displayb %token DS_displayh %token DS_displayo %token DS_dumpoff %token DS_dumpon %token DS_dumpvars %token DS_finish %token DS_printtimescale %token DS_stime %token DS_stop %token DS_time %token DS_write %token DS_writeb %token DS_writeh %token DS_writeo %token SSS_EOF %token SS_LPAR %token SS_LPARSTAR %token SS_SLASHEQUALS2 %token SS_RPAR %token SS_PLING %token SS_BACKQUOTE %token SS_FWDQUOTE %token SS_COLON %token SS_COLONCOLON %token SS_COMMA %token SS_DOT1 %token SS_DOTDOT %token SS_DOTSTAR %token SS_EQUALS %token SS_HASH %token SS_LBRA %token SS_LBRACE %token SS_LEFTARROW %token SS_QUERY %token SS_RBRA %token SS_RBRACE %token SS_SEMI %token SS_AMPAMPAMP // nonassoc %token SS_LSHIFT %token SS_RSHIFT %token SS_DLTD %token SS_DGTD %token SS_DLED %token SS_DGED %token SS_DEQD %token SS_DNED // Note the diadic operators ought to be declared in order of increasing precedence but fsyacc ignores this? // Left precedence: %token SS_STILE2 %token SS_AMPAMP %token SS_STILE %token SS_AMP %token SS_CARET %token SS_MINUS SS_PLUS %token SS_PERCENT SS_SLASH SS_STAR %token SS_STARRPAR %token S_action %token S_actionvalue %token S_begin %token S_bit %token S_case %token S_clocked_by %token S_default %token S_deriving %token S_else %token S_end %token S_endaction %token S_endactionvalue %token S_endcase %token S_endfunction %token S_endinstance %token S_endinterface %token S_endmethod %token S_endmodule %token S_endpackage %token S_endrule %token S_endrules %token S_endtypeclass %token S_enum %token S_export %token S_function %token S_for %token S_if %token S_import %token S_instance %token S_interface %token S_let %token S_matches %token S_method %token S_module %token S_numeric %token S_package %token S_provisos %token S_reset_by %token S_return %token S_rule %token S_rules %token S_struct %token S_tagged %token S_typeclass %token S_type %token S_typedef %token S_union %token S_void %token S_while %token DS_BUILTIN %token S_noAction %token S_True // Should be defined in standard preamble along with noAction %token S_False // Sequential sub-language: %token S_await %token S_seq %token S_par %token S_endseq %token S_endpar %start packageDecl %% packageDecl: S_package ident SS_SEMI exportDecl importDecl packageStmt_list S_endpackage colon_Id_option SSS_EOF { KB_package($2, $4, $5, $6, $8) } ; // Any capitalisation of identifier: ident: S_TY { $1} | S_IDL { $1} | S_IDC { $1} ; colon_id_option: /* Empty */ { None } | SS_COLON ident { Some $2 } ; colon_Id_option: /* Empty */ { None } | SS_COLON S_IDC { Some $2 } ; exportDecl: /* Empty */ { [] } | S_export exportItem_comma_list SS_SEMI { $2 } ; exportItem_comma_list: exportItem { [ $1 ] } | exportItem SS_COMMA exportItem_comma_list { $1 :: $3 } ; exportItem: ident SS_LPAR SS_DOTDOT SS_RPAR { KB_export($1, true, glp()) } | ident { KB_export($1, false, glp()) } ; importItem_comma_list: importItem { [ $1 ] } | importItem SS_COMMA importItem_comma_list { $1 :: $3 } ; importDecl: /* Empty */ { [] } | S_import importItem_comma_list SS_SEMI { $2 } | S_import importItem_comma_list SS_SEMI importDecl { $2 @ $4 } ; importItem: ident SS_COLONCOLON SS_STAR { KB_import($1, None, glp()) } | ident SS_COLONCOLON ident { KB_import($1, Some $3, glp()) } ; identifier: S_IDL { $1 } ; packageStmt_list: /* Empty */ { [] } | packageStmt packageStmt_list { $1:: $2 } ; packageStmt: attributeInstance_list moduleDef { if $1<>[] then KB_attribute($1, $2) else $2 } | attributeInstance_list interfaceDecl { if $1<>[] then KB_attribute($1, $2) else $2 } | attributeInstance_list functionDef { if $1<>[] then KB_attribute($1, $2) else $2 } | varDecl { $1 } | varAssign SS_SEMI { $1 } | varDeclAssign SS_SEMI { $1 } | typeDef { $1 } | typeclassDef { $1 } | typeclassInstanceDef { $1 } // | externModuleImport { $1 } ; attributeInstance_list: /* Empty */ { [] } | SS_LPARSTAR attrSpec attrSpec_comma_list SS_STARRPAR { $2::$3 } ; attrSpec_comma_list: /* Empty */ { [] } | attrSpec SS_COMMA attrSpec_comma_list { $1::$3 } ; attrSpec: attrName SS_EQUALS expression { KB_attr_spec($1, Some $3) } | attrName { KB_attr_spec($1, None) } ; attrName: S_IDC { $1 } | S_IDL { $1 } ; interfaceDecl: attributeInstance_list S_interface typeDefType SS_SEMI interfaceMemberDecl_list S_endinterface colon_id_option { KB_interfaceDecl($1, $3, $5, $7, glp()) } ; subinterfaceDecl: attributeInstance_list S_interface typeDefType identifier SS_SEMI { KB_subinterfaceDecl($1, $3, $4, glp()) } interfaceMemberDecl_list: /* empty */ { [] } | subinterfaceDecl interfaceMemberDecl_list { $1 :: $2 } | methodProto interfaceMemberDecl_list { $1 :: $2 } ; methodProto: pragma_list S_method type identifier SS_LPAR methodProtoFormals_list SS_RPAR provisos_list SS_SEMI { KB_methodProto($1, $3, $4, $6, $8, glp()) } ; methodProtoFormals_list: /* Empty */ { [] } | methodProtoFormal { [$1] } | methodProtoFormal SS_COMMA methodProtoFormals_list { $1 :: $3 } ; methodProtoFormal: type identifier { ($1, $2) } ; proviso_comma_list: { [ ] } | SS_COMMA proviso_comma_list { $2 } provisos_list: /* empty */ { [] } | S_provisos SS_LPAR proviso proviso_comma_list SS_RPAR { $3::$4 } ; proviso: S_IDC SS_HASH SS_LPAR type_comma_list SS_RPAR { KB_proviso($1, $4) } ; type_comma_list: type { [ $1 ] } | type SS_COMMA type_comma_list { $1 :: $3 } ; varDecl: type lValue_decl SS_SEMI { KB_varDeclAssign(Some $1, $2, None, glp()) } ; expression_comma_list: expression { [ $1 ] } | expression SS_COMMA expression_comma_list { $1 :: $3 } ; letBinding: S_let identifier SS_EQUALS expression { debug("redux: letBinding1 " + $2); KB_letBinding($2, $4, "=", glp()) } | S_let identifier SS_LEFTARROW expression { debug("redux: letBinding2 " + $2); KB_letBinding($2, $4, "<-", glp()) } ; varAssign: lValue SS_EQUALS expression { KB_varDeclAssign(None, $1, Some $3, glp()) } // | lValue SS_LEFTARROW expression { KB_varDeclAssign(None, $1, Some $3, glp()) } ; varDeclAssign: type lValue_decl SS_EQUALS expression { debug("redux: varDeclAssign"); KB_varDeclAssign(Some $1, $2, Some $4, glp()) } ; typeDef: S_typedef S_enum SS_LBRACE Identifier_comma_list SS_RBRACE S_IDC derives_list SS_SEMI { debug("redux: typedefEnum reduced"); KB_typedefEnum($4, mktype $6, $7, glp()) } | S_typedef S_struct SS_LBRACE structMember_list SS_RBRACE typeDefType derives_list SS_SEMI { KB_typedefSTUnion("struct", $4, $6, $7, glp()) } | S_typedef S_union S_tagged SS_LBRACE unionMember_list SS_RBRACE typeDefType derives_list SS_SEMI { KB_typedefSTUnion("tunion", $5, $7, $8, glp()) } | S_typedef SP_intLiteral S_IDC SS_SEMI { KB_typedefConst($3, KB_intLiteral $2, glp()) } | S_typedef SP_stringLiteral S_IDC SS_SEMI { KB_typedefConst($3, KB_stringLiteral $2, glp()) } | S_typedef type typeDefType SS_SEMI { KB_typedefSynonym($3, $2, glp()) } ; identifier_comma_list: identifier { [ $1 ] } | identifier SS_COMMA identifier_comma_list { $1 :: $3 } ; Identifier_comma_list: S_IDC { [ $1 ] } | S_IDC SS_COMMA Identifier_comma_list { $1 :: $3 } ; derives_list: /* Empty */ { [] } | S_deriving SS_LPAR Identifier_comma_list SS_RPAR { debug("redux: derives_list reduced"); $3 } ; structMember_list: /* Empty */ { [] } | DS_BUILTIN { [ KB_builtin("struct") ] } | structMember structMember_list { $1 :: $2 } ; unionMember_list: /* Empty */ { [] } | unionMember unionMember_list { $1 :: $2 } ; structMember: type identifier SS_SEMI { KB_structMember($1, $2) } | subTagged { KB_structMemberSubTagged($1) } ; unionMember: type typeIde SS_SEMI { KB_unionMember(Some $1, $2) } | S_void typeIde SS_SEMI { KB_unionMember(None, $2) } | subStruct { $1 } | subTagged { $1 } ; subStruct: S_struct SS_LBRACE structMember_list SS_RBRACE S_IDC SS_SEMI { KB_unionSubStruct($3, $5) } ; subTagged: S_union S_tagged SS_LBRACE unionMember_list SS_RBRACE S_IDC SS_SEMI { KB_structSubTagged($4, $6) } ; typeclassDef: S_typeclass typeclassIde typeFormals provisos_list SS_SEMI overloadedDef S_endtypeclass colon_id_option { KB_typeclassDef($2, $3, $4, $6, $8, glp()) } ; typeclassIde: S_IDC { $1 } ; overloadedDef: /* Empty */ { [] } | functionProto SS_SEMI overloadedDef { $1::$3 } | varDecl overloadedDef { $1::$2 } ; functionFormal: type identifier { ($1, $2) } | S_type S_numeric identifier { (KB_typeFormal("$numeric", $3), $3) } | S_numeric S_type identifier { (KB_typeFormal("$numeric", $3), $3) } | S_type identifier { (KB_typeFormal("$formal", $2), $2) } | functionProto { ($1, "$HOF") } ; functionFormals_list: /* Empty */ { [] } | functionFormal SS_COMMA functionFormals_list { $1 :: $3 } | functionFormal { [$1] } ; functionProto: S_function type identifier SS_LPAR functionFormals_list SS_RPAR provisos_list { KB_functionProto($2, $3, $5, $7, glp()) } ; functionBody: actionValueBlock { [$1] }// Not correct? | actionBlock { [$1] }// Not correct? | fbodStmt_list { $1 } ; functionDef: functionProto SS_SEMI functionBody S_endfunction colon_id_option { KB_functionDef1($1, $3, $5, glp()) } | functionProto SS_EQUALS expression SS_SEMI { KB_functionDef2($1, $3, glp()) } ; fbodStmt: fbodIf { $1 } | fbodBeginEndStmt { $1 } | fbodCase { $1 } | varDecl { $1 } | varAssign SS_SEMI { $1 } | varDeclAssign SS_SEMI { $1 } | varDo { $1 } | varDeclDo { $1 } | functionDef { $1 } | functionCall SS_SEMI { KB_easc($1, glp()) } | systemTaskCall { KB_easc($1, glp()) } | expression SS_SEMI { KB_easc($1, glp()) } | returnStmt { $1 } | regWrite { $1 } | S_for SS_LPAR varAssign SS_SEMI expression SS_SEMI varAssign SS_RPAR fbodStmt { KB_for($3, $5, $7, $9, glp()) } | S_for SS_LPAR varDeclAssign SS_SEMI expression SS_SEMI varAssign SS_RPAR fbodStmt { KB_for($3, $5, $7, $9, glp()) } | letBinding SS_SEMI { $1 } ; moduleInst: type identifier SS_LPAR SS_RPAR SS_SEMI moduleApp identifier SS_LPAR moduleActualArgs SS_RPAR SS_SEMI { KB_moduleInst($1, $2, $6, $7, $9, glp()) } ; moduleActualArgs: moduleActualArg { [ $1 ] } | moduleActualArg SS_COMMA moduleActualArgs { $1 :: $3 } ; moduleActualArg: expression { $1 } | S_clocked_by expression { KB_eventControl("clocked_by", $2, glp()); } | S_reset_by expression { KB_eventControl("reset_by", $2, glp()); } ; moduleApp: identifier { KB_moduleApp($1, [], glp()) } | identifier SS_HASH SS_LPAR expression_comma_list SS_RPAR { KB_moduleApp($1, $4, glp()) } ; returnStmt: S_return expression SS_SEMI { KB_returnStmt($2, glp()) } ; systemFunctionCall: DS_time { KB_systemFunction ("time", []) } | DS_stime { KB_systemFunction ("stime", []) } ; systemTaskCall: displayTaskName SS_LPAR expression_comma_list SS_RPAR SS_SEMI { KB_systemTaskCall($1, $3, glp()) } | DS_printtimescale SS_SEMI { KB_systemTaskCall(DK_s "printtimescale", [], glp()) } | DS_finish SS_LPAR expression SS_RPAR SS_SEMI { KB_systemTaskCall(DK_s "finish", [$3], glp())} | DS_finish SS_SEMI { KB_systemTaskCall(DK_s "finish", [], glp()) } | DS_stop SS_LPAR expression SS_RPAR SS_SEMI { KB_systemTaskCall(DK_s "stop", [$3], glp())} | DS_stop SS_SEMI { KB_systemTaskCall(DK_s "stop", [], glp()) } | DS_dumpvars SS_SEMI { KB_systemTaskCall(DK_s "dumpvars", [], glp()) } | DS_dumpon SS_SEMI { KB_systemTaskCall(DK_s "dumpon", [], glp()) } | DS_dumpoff SS_SEMI { KB_systemTaskCall(DK_s "dumpoff", [], glp()) } ; displayTaskName: DS_display { DK_s "display" } | DS_displayb { DK_s "displayb" } | DS_displayo { DK_s "displayo" } | DS_displayh { DK_s "displayh" } | DS_write { DK_s "write" } | DS_writeb { DK_s "writeb" } | DS_writeo { DK_s "writeo" } | DS_writeh { DK_s "writeh" } ; // <- Structural/generative assignment. varDeclDo: type lValue_decl SS_LEFTARROW expression SS_SEMI { KB_varDeclDo(Some $1, $2, $4, glp()) } ; varDo: lValue SS_LEFTARROW expression SS_SEMI { KB_varDeclDo(None, $1, $3, glp()) } ; //Enter sublanguage on par or seq keyword. sublangExpr: S_seq sublangExp2 sublangExpr_list S_endseq { KB_sublang("seq", $2::$3, glp()) } | S_par sublangExp2 sublangExpr_list S_endpar { KB_sublang("par", $2::$3, glp()) } ; // This may not be correct or complete: sublangExp2: S_seq sublangExp2 sublangExpr_list S_endseq { KB_sublang("seq", $2::$3, glp()) } | S_par sublangExp2 sublangExpr_list S_endpar { KB_sublang("par", $2::$3, glp()) } | S_while SS_LPAR expression SS_RPAR sublangExp2 { KB_while($3, $5, glp()) } | S_for SS_LPAR varAssign SS_SEMI expression SS_SEMI sublangExp2 SS_RPAR sublangExp2 { KB_for($3, $5, $7, $9, glp()) } | S_for SS_LPAR varDeclAssign SS_SEMI expression SS_SEMI sublangExp2 SS_RPAR sublangExp2 { KB_for($3, $5, $7, $9, glp()) } | actionBlock { $1 } | regWrite { $1 } | S_if SS_LPAR expression SS_RPAR sublangExp2 S_else sublangExp2 { KB_if($3, $5, Some $7, glp()) } | S_if SS_LPAR expression SS_RPAR sublangExp2 { KB_if($3, $5, None, glp()) } | functionCall SS_SEMI { debug "redux sl functionCall"; KB_easc($1, glp()) } | S_await SS_LPAR expression SS_RPAR SS_SEMI { KB_await($3, glp()) } ; sublangExpr_list: /* Empty */ { [ ] } | sublangExp2 sublangExpr_list { $1 :: $2 } ; bitConcat: SS_LBRACE expression_comma_list SS_RBRACE { KB_bitConcat($2, glp()) } ; bitSelect: exprPrimary SS_LBRA expression_comma_list SS_RBRA { KB_subscripted($1, $3, glp()) } | exprPrimary SS_LBRA expression SS_COLON expression SS_RBRA { KB_bitRange($1, $3, $5, glp()) } ; beginEndExpr: S_begin colon_id_option beginEndExprStmt_list expression S_end colon_id_option { KB_beginEndExpr($2, $3, $4, $6) } ; beginEndExprStmt_list: /* Empty */ { [] } | beginEndExprStmt beginEndExprStmt_list { $1 :: $2 } ; beginEndExprStmt: varDecl { $1 } | varAssign SS_SEMI { $1 } | varDeclAssign SS_SEMI { $1 } | functionDef { $1 } // next 3 KB_easc? | systemTaskCall { KB_easc($1, glp()) } | expression SS_SEMI { KB_easc($1, glp()) } // Hmmm want easc on these ? ; // todo forces at least one taggedUnionExpr: S_tagged S_IDC SS_LBRACE memberBind memberBind_comma_list SS_RBRACE { KB_taggedUnionExpr($2, $4::$5, None, glp()) } | S_tagged S_IDC expression { KB_taggedUnionExpr($2, [], Some $3, glp()) } | S_tagged S_IDC { KB_taggedUnionExpr($2, [], None, glp()) } ; memberBind_comma_list: /* Empty */ { [] } | SS_COMMA memberBind memberBind_comma_list { $2 :: $3 } memberBind: identifier SS_COLON expression { debug ("redux: memberBind+" + $1); ($1, $3) } ; actionBlock: S_action colon_id_option actionStmt_list S_endaction colon_id_option { debug "redux actionBlock"; KB_actionValueBlock("action", $2, $3, $5, glp()) } | S_noAction SS_SEMI { debug "redux noAction actionBlock"; KB_actionValueBlock("action", Some "noAction", [], None, glp()) } ; actionStmt: actionIf { $1 } | actionCase { $1 } | actionBeginEndStmt { $1 } // action_For ? // action_While ? | regWrite { $1 } | varDecl { $1 } | varAssign SS_SEMI { $1 } | varDeclAssign SS_SEMI { $1 } // | varDo { $1 } // | varDeclDo { $1 } | letBinding SS_SEMI { $1 } | systemTaskCall { KB_easc($1, glp()) } | expression SS_SEMI { KB_easc($1, glp()) } ; // ASSIGNOP is <= dled regWrite: lValue SS_DLED expression SS_SEMI { debug ("redux regWrite "); KB_regWrite($1, $3, glp()) } | lValue SS_DLED expression SS_SEMI { debug ("redux regWrite [] "); KB_regWrite($1, $3, glp()) } ; //begin generic contexts. contexts are: functionBody action moduleImp actionValue action moduleImpIf: S_if SS_LPAR expression SS_RPAR moduleImpStmt S_else moduleImpStmt { KB_if($3, $5, Some $7, glp()) } | S_if SS_LPAR expression SS_RPAR moduleImpStmt { KB_if($3, $5, None, glp()) } ; moduleImpBeginEndStmt: S_begin colon_id_option moduleImpStmt_list S_end colon_id_option { KB_block($2, $3, $5, glp()) } ; moduleImpStmt_list: /* Empty */ { [] } | moduleImpStmt moduleImpStmt_list { $1:: $2 } ; moduleImpCase: S_case SS_LPAR expression SS_RPAR matches_optional moduleImpCaseArm_list S_endcase { KB_case($3, $6, glp()) } ; moduleImpCaseArm_list: /* Empty */ { [] } | moduleImpCaseArm moduleImpCaseArm_list { $1 :: $2 } ; moduleImpCaseArm: pattern pattern_comma_list SS_COLON moduleImpStmt { ($1::$2, $4) } | S_default SS_COLON moduleImpStmt { ([], $3) } ; // end moduleImp fbodIf: S_if SS_LPAR expression SS_RPAR fbodStmt S_else fbodStmt { KB_if($3, $5, Some $7, glp()) } | S_if SS_LPAR expression SS_RPAR fbodStmt { KB_if($3, $5, None, glp()) } ; fbodBeginEndStmt: S_begin colon_id_option fbodStmt_list S_end colon_id_option { KB_block($2, $3, $5, glp()) } ; fbodStmt_list: /* Empty */ { [] } | fbodStmt fbodStmt_list { $1:: $2 } ; fbodCase: S_case SS_LPAR expression SS_RPAR matches_optional fbodCaseArm_list S_endcase { KB_case($3, $6, glp()) } ; fbodCaseArm_list: /* Empty */ { [] } | fbodCaseArm fbodCaseArm_list { $1 :: $2 } ; fbodCaseArm: pattern pattern_comma_list SS_COLON fbodStmt { ($1::$2, $4) } | S_default SS_COLON fbodStmt { ([], $3) } ; // end fbod actionValueIf: S_if SS_LPAR expression SS_RPAR actionValueStmt S_else actionValueStmt { KB_if($3, $5, Some $7, glp()) } | S_if SS_LPAR expression SS_RPAR actionValueStmt { KB_if($3, $5, None, glp()) } ; actionValueBeginEndStmt: S_begin colon_id_option actionValueStmt_list S_end colon_id_option { KB_block($2, $3, $5, glp()) } ; actionValueStmt_list: /* Empty */ { [] } | actionValueStmt actionValueStmt_list { $1:: $2 } ; actionValueCase: S_case SS_LPAR expression SS_RPAR matches_optional actionValueCaseArm_list S_endcase { KB_case($3, $6, glp()) } ; actionValueCaseArm_list: /* Empty */ { [] } | actionValueCaseArm actionValueCaseArm_list { $1 :: $2 } ; actionValueCaseArm: pattern pattern_comma_list SS_COLON actionValueStmt { ($1::$2, $4) } | S_default SS_COLON actionValueStmt { ([], $3) } ; // end actionValue actionIf: S_if SS_LPAR expression SS_RPAR actionStmt S_else actionStmt { KB_if($3, $5, Some $7, glp()) } | S_if SS_LPAR expression SS_RPAR actionStmt { KB_if($3, $5, None, glp()) } ; actionBeginEndStmt: S_begin colon_id_option actionStmt_list S_end colon_id_option { KB_block($2, $3, $5, glp()) } ; actionStmt_list: /* Empty */ { [] } | actionStmt actionStmt_list { $1:: $2 } ; actionCase: S_case SS_LPAR expression SS_RPAR matches_optional actionCaseArm_list S_endcase { KB_case($3, $6, glp()) } ; matches_optional: /*empty */ { } | S_matches { } ; actionCaseArm_list: /* Empty */ { [] } | actionCaseArm actionCaseArm_list { $1 :: $2 } ; actionCaseArm: pattern pattern_comma_list SS_COLON actionStmt { ($1::$2, $4) } | S_default SS_COLON actionStmt { ([], $3) } ; // end action // 2-d arrays? comma not colon? Array dims optional? lValue: taggedId { $1 } // | taggedId SS_LBRA expression SS_COLON expression SS_RBRA { KB_bitRange($1, $3, $5, glp()) } | taggedId SS_LBRA expression_comma_list SS_RBRA { KB_subscripted($1, $3, glp()) } ; lValue_decl: identifier { KB_id($1, glp()) } // | identifier SS_LBRA expression SS_COLON expression SS_RBRA { KB_bitRange($1, $3, $5, glp()) } | identifier SS_LBRA expression_comma_list SS_RBRA { KB_subscripted(KB_id($1, glp()), $3, glp()) } ; backdoors: /* empty */ { [] } | DS_BUILTIN SP_stringLiteral { [ $2 ] } moduleDef: S_module backdoors identifier moduleParams SS_LPAR type_option SS_RPAR // Single interface module syntax (old) provisos_list SS_SEMI moduleStmt_list S_endmodule colon_id_option { KB_moduleDef($2, $3, $4, $6, [], $8, $10, $12, glp()) } | S_module backdoors identifier moduleParams moduleArgs provisos_list SS_SEMI moduleStmt_list S_endmodule colon_id_option { KB_moduleDef($2, $3, $4, None, $5, $6, $8, $10, glp()) } ; moduleParams: /*Empty */ { [] } | SS_HASH SS_LPAR moduleParam moduleParamsList_oom SS_RPAR { $3::$4 } ; moduleParamsList_oom: /* Empty */ { [] } | SS_COMMA moduleParam moduleParamsList_oom { $2 :: $3 } ; moduleArgs: SS_LPAR moduleParam moduleParamsList_oom SS_RPAR { $2 :: $3 } | SS_LPAR SS_RPAR { [] } moduleParam: type identifier { ($1, $2) } | functionProto { ($1, "$HOF") } ; type_option: /* Empty */ { None } | type { Some $1 } ; moduleStmt_list: /* Empty */ { [] } | moduleStmt moduleStmt_list { $1 :: $2 } ; moduleStmt: moduleInst { $1 } | methodDef { $1 } | rule { $1 } | functionDef { $1 } | moduleImpStmt { $1 } | varDecl { $1 } | subinterfaceDef { $1 } ; subinterfaceDef: S_interface typeIde S_IDL SS_SEMI subinterfaceStmtList S_endinterface colon_id_option { KB_subinterfaceDef0($2, $3, $5, $7, glp()) } // A subinterface member can also be defined using the following syntax. // subinterfaceDef: interface [ type ] identifier = expression ; // The identifier is just the subinterface member name. | S_interface S_IDL SS_EQUALS expression SS_SEMI { KB_subinterfaceDef1(None, $2, $4, glp()) } | S_interface type S_IDL SS_EQUALS expression SS_SEMI { KB_subinterfaceDef1(Some $2, $3, $5, glp()) } ; subinterfaceStmtList: /* empty */ { [] } | methodDef subinterfaceStmtList { $1::$2 } | subinterfaceDef subinterfaceStmtList { $1::$2 } ; moduleImpStmt: moduleImpIf { $1 } | moduleImpCase { $1 } | moduleImpBeginEndStmt { $1 } | S_for SS_LPAR varAssign SS_SEMI expression SS_SEMI varAssign SS_RPAR moduleImpStmt { KB_for($3, $5, $7, $9, glp()) } | S_for SS_LPAR varDeclAssign SS_SEMI expression SS_SEMI varAssign SS_RPAR moduleImpStmt { KB_for($3, $5, $7, $9, glp()) } | varDeclAssign SS_SEMI { $1 } | varDo { $1 } | varDeclDo { $1 } | varAssign SS_SEMI { $1 } | systemTaskCall { KB_easc($1, glp()) } | expression SS_SEMI { KB_easc($1, glp()) } | returnStmt { $1 } ; methodDef: S_method type_option identifier SS_LPAR methodFormals SS_RPAR implicitCond SS_SEMI functionBody S_endmethod colon_id_option { KB_methodDef1($2, $3, $5, $7, $9, $11, glp()) } // A method can also be defined using the following syntax. // methodDef: method [ type ] identifier ( methodFormals ) [ implicitCond ] = expression ; | S_method type_option identifier SS_LPAR methodFormals SS_RPAR implicitCond SS_EQUALS expression { KB_methodDef2($2, $3, $5, $7, $9, glp()) } ; methodFormals: /* None */ { [] } | methodFormal { [$1] } | methodFormal SS_COMMA methodFormals { $1 :: $3 } ; methodFormal: type_option identifier { ($1, $2) } ; implicitCond: /* Empty */ { None } | S_if SS_LPAR expression SS_RPAR { Some $3 } ; typeNat: S_NAT { $1 } ; typeIde: identifier { mktype $1 } | S_IDC { $1 } | S_TY { $1 } ; typeIdeUC: S_IDC { $1 } | S_TY { $1 } ; type: typeIde { KB_typeIde($1, []) } | typeIde SS_HASH SS_LPAR type_comma_list SS_RPAR { KB_typeIde($1, $4) } | typeNat { KB_typeNat $1 } | S_bit { KB_typeBit(None) } | S_bit SS_LBRA typeNat SS_COLON typeNat SS_RBRA { KB_typeBit(Some(atoi32 $3, atoi32 $5)) } ; typeclassInstanceDef: S_instance S_IDC SS_HASH SS_LPAR type_comma_list SS_RPAR provisos_list SS_SEMI vflist S_endinstance colon_id_option { KB_typeclassInstanceDef($2, $5, $7, $9, $11, glp()) } ; vflist: /* Empty */ { [] } | varAssign SS_SEMI vflist { $1 :: $3 } | varDeclAssign SS_SEMI vflist { $1 :: $3 } | functionDef vflist { $1 :: $2 } ; expression: condExpr { $1 } | SS_QUERY { KB_dontcare } | operatorExpr15 { $1 } ; taggedId: identifier { KB_id($1, glp()) } | taggedId SS_DOT1 identifier { KB_tag($1, $3, glp()) } | taggedId SS_DOT1 S_IDC { KB_tag($1, $3, glp()) } ; exprPrimary: taggedId { $1 } | S_IDC { KB_constantAlias $1 } | SP_intLiteral { KB_intLiteral $1 } | SP_stringLiteral { KB_stringLiteral $1 } | SS_LPAR expression SS_RPAR { $2 } | bitConcat { $1 } | bitSelect { $1 } // | beginEndExpr { $1 } | actionBlock { $1 } | actionValueBlock { $1 } | functionCall { $1 } | systemFunctionCall { $1 } | interfaceExpr { $1 } // put in lex | typeAssertion { $1 } | taggedUnionExpr { $1 } | structExpr { $1 } | S_True { KB_systemFunction ("True", []) } //Should be in preample and not builtin. | S_False { KB_systemFunction ("False", []) } | rulesExpr { $1 } | sublangExpr { $1 } // djg added ; functionCall: exprPrimary SS_LPAR moduleActualArgs SS_RPAR { debug "redux fcall n "; KB_functionCall($1, $3, glp()) } | exprPrimary SS_LPAR SS_RPAR { debug "redux fcal 0 "; KB_functionCall($1, [], glp()) } // | S_SizeOf SS_HASH SS_LPAR expression SS_RPAR { debug "redux fcal S_SizeOf"; KB_functionCall(KB_id("SizeOf#", glp()), [$4], glp()) } ; unop: SS_PLUS { "+" } | SS_MINUS { "-" } | SS_PLING { "!" } ; // FSYacc does not support operator precedence? So we have to have all these detailed rules! binop5: SS_STAR { KB_op V_times } | SS_SLASH { KB_op V_divide } | SS_PERCENT { KB_op V_mod } ; binop6: SS_PLUS { KB_op V_plus } | SS_MINUS { KB_op V_minus } ; binop7: SS_LSHIFT { KB_op V_lshift } | SS_RSHIFT { KB_op V_rshift } ; binop8: SS_DLTD { KB_bop V_dltd } | SS_DGTD { KB_bop V_dgtd } | SS_DLED { KB_bop V_dled } | SS_DGED { KB_bop V_dged } ; binop9: SS_DEQD { KB_bop V_deqd } | SS_DNED { KB_bop V_dned } binop10: SS_AMP { KB_op V_bitand } ; binop11: SS_CARET { KB_op V_xor } ; binop12: SS_STILE { KB_op V_bitor } ; binop13: SS_AMPAMP { KB_ab V_band } ; binop14: SS_STILE2 { KB_ab V_bor } ; operatorExpr5: unop exprPrimary { KB_monadic($1, $2, glp()) } | exprPrimary { $1 } operatorExpr6: operatorExpr5 { $1 } | operatorExpr6 binop5 operatorExpr5 { KB_diadic($2, $1, $3, glp()) } ; operatorExpr7: operatorExpr6 { $1 } | operatorExpr7 binop6 operatorExpr6 { KB_diadic($2, $1, $3, glp()) } ; operatorExpr8: operatorExpr7 { $1 } | operatorExpr7 binop7 operatorExpr7 { KB_diadic($2, $1, $3, glp()) } // << >> nonassoc. ; operatorExpr9: operatorExpr8 { $1 } | operatorExpr9 binop8 operatorExpr8 { KB_diadic($2, $1, $3, glp()) } ; operatorExpr10: operatorExpr9 { $1 } | operatorExpr10 binop9 operatorExpr9 { KB_diadic($2, $1, $3, glp()) } ; operatorExpr11: operatorExpr10 { $1 } | operatorExpr11 binop10 operatorExpr10 { KB_diadic($2, $1, $3, glp()) } ; operatorExpr12: operatorExpr11 { $1 } | operatorExpr12 binop11 operatorExpr11 { KB_diadic($2, $1, $3, glp()) } ; operatorExpr13: operatorExpr12 { $1 } | operatorExpr13 binop12 operatorExpr12 { KB_diadic($2, $1, $3, glp()) } ; operatorExpr14: operatorExpr13 { $1 } | operatorExpr14 binop13 operatorExpr13 { KB_diadic($2, $1, $3, glp()) } ; operatorExpr15: operatorExpr14 { $1 } | operatorExpr15 binop14 operatorExpr14 { KB_diadic($2, $1, $3, glp()) } ; condExpr: expression SS_QUERY expression SS_COLON expression { KB_query($1, $3, $5) } ; typeDefType: typeIde { KB_typedef(mktype $1, []) } | typeIde typeFormals { KB_typedef(mktype $1, $2) } // | typeIde SS_HASH SS_LPAR type typeIde SS_COMMA type typeIde SS_RPAR { KB_typedef(mktype $1, [($4,$5);($7,$8)]) } // | typeIde SS_HASH SS_LPAR type type_identifier_comma_list SS_RPAR { KB_typedefType(mktype $1, Some($4, $5)) } ; typeFormal_list: S_numeric S_type S_IDL typeFormal_list1 { KB_typeFormal("$numeric", $3) :: $4 } | S_type S_numeric S_IDL typeFormal_list1 { KB_typeFormal("$numeric", $3) :: $4 } | S_type S_IDL typeFormal_list1 { KB_typeFormal("$formal", $2) :: $3 } // This third case appears in "interface Get#(req_type) request;" // | S_IDL typeFormal_list1 { KB_typeFormal("$bound", $1) :: $2 } // but is ambiguous w.r.t the fourth more general case where a lower-case IDL can now be a type. // This fourth case appears in interface Put#(WordT) in; | type typeFormal_list1 { $1 :: $2 } ; typeFormal_list1: /* empty */ { [] } | SS_COMMA typeFormal_list { $2 } ; typeFormals: /* empty */ { [] } | SS_HASH SS_LPAR typeFormal_list SS_RPAR { $3 } ; pragma_list: attributeInstance_list { $1 } ; actionValueBlock: S_actionvalue colon_id_option actionValueStmt_list S_endactionvalue colon_id_option { KB_actionValueBlock("actionvalue", $2, $3, $5, glp()) } ; actionValueStmt: actionValueIf { $1 } | actionValueCase { $1 } | actionValueBeginEndStmt { $1 } | regWrite { $1 } | varDecl { $1 } | varAssign SS_SEMI { $1 } | varDeclAssign SS_SEMI { $1 } | varDo { $1 } | varDeclDo { $1 } | systemTaskCall { KB_easc($1, glp()) } | expression SS_SEMI { KB_easc($1, glp()) } | returnStmt { $1 } ; interfaceStmt_list: /* Empty */ { [] } | interfaceStmt interfaceStmt_list { $1 :: $2 } interfaceExpr: S_interface typeIde SS_SEMI interfaceStmt_list S_endinterface colon_id_option { KB_interfaceExpr($2, $4, $6, glp()) } ; interfaceStmt: varDecl { $1 } | varDeclAssign SS_SEMI { $1 } | varAssign SS_SEMI{ $1 } | methodDef { $1 } ; typeAssertion: type SS_FWDQUOTE bitConcat { KB_typeAssertion($1, $3) } | type SS_FWDQUOTE SS_LPAR expression SS_RPAR { KB_typeAssertion($1, $4) } ; // todo: forces at least one structExpr: typeIdeUC SS_LBRACE memberBind memberBind_comma_list SS_RBRACE { KB_structExprAssociative($1, $3::$4, glp()) } | typeIdeUC SS_LPAR expression_comma_list SS_RPAR { KB_structExprPositional($1, $3, glp()) } ; pattern: expression { $1 } // Constant // | identifier { KB_patternVar $1 } // Pattern variable (reduce/reduce error) | SS_DOT1 expression { KB_dot $2 } // Constant | SS_DOTSTAR { KB_wildcard } // Wildcard | S_tagged S_IDC SS_DOT1 identifier { KB_taggedUnion($2, [], Some(KB_patternVar $4), glp()) } // Tagged union, no braces. | S_tagged S_IDC structPattern { KB_taggedUnion($2, [], Some $3, glp()) } // Tagged union | S_tagged S_IDC { KB_taggedUnion($2, [], None, glp()) } // Tagged union | tuplePattern { $1 } // Structure ; tuplePattern: SS_LBRACE pattern pattern_comma_list SS_RBRACE { KB_tuplePattern($2 :: $3, glp()) } ; pattern_comma_list: /* Empty */ { [] } | SS_COMMA pattern pattern_comma_list { $2 :: $3 } ; // Ref manual says: // Note that the first and second grammar productions overlap, since an expression can be an identifier. // The first production has priority, i.e., if we encounter a naked identifier, it is interpreted as a pattern variable. structPattern: tuplePattern { $1 } | SS_LBRACE structPattern_item structPattern_item_comma_list SS_RBRACE { KB_structPattern($2::$3, glp()) } ; structPattern_item_comma_list: /* Empty */ { [] } | SS_COMMA structPattern_item structPattern_item_comma_list { $2 :: $3 } ; structPattern_item: identifier SS_COLON pattern { ($1, $3) } ; rule: ruleAssertion_list S_rule identifier ruleCond_option SS_SEMI ruleBody S_endrule colon_id_option { KB_rule($1, $3, $4, $6, $8, glp()) } ; ruleCond_option: /* Empty */ { None } | SS_LPAR expression SS_RPAR { Some $2 } ; ruleBody: actionBlock { [$1] } | actionStmt_list { $1 } ; rulesExpr: S_rules colon_id_option rulesStmt S_endrules colon_id_option { KB_rulesExpr($2, $3, $5) } ; rulesStmt: varDecl { $1 } | varAssign SS_SEMI { $1 } | varDeclAssign SS_SEMI { $1 } | rule { $1 } ; ruleAssertion_list: attributeInstance_list { $1 } ; SP_intLiteral: S_NAT { $1 } // for now %% // eof