📄 gram.y
字号:
| START domain keyData { SHOWPARSE("=== key -> START domain keyData\n"); DiskKey key = $2; key.SetType(KT_Start); key.keyFlags = 0; key.keyData = $3; $$ = key; } | slot { SHOWPARSE("=== key -> slot\n"); $$ = image.GetNodeSlot($1, $<slot>1); } ;domain: NAME { SHOWPARSE("=== domain -> NAME\n"); DiskKey key; if (image.GetDirEnt($1, key) == false) { Diag::printf("%s:%d: unknown object \"%s\"\n", current_file.str(), current_line, $1.str()); num_errors++; YYERROR; } if (key.IsType(KT_Process) == false && key.IsType(KT_Start) == false && key.IsType(KT_Resume) == false) { Diag::printf("%s:%d: must be domain name\n", current_file.str(), current_line); num_errors++; YYERROR; } $<is>$ = $1; $$ = key; } ;node: NAME { SHOWPARSE("=== node -> NAME\n"); DiskKey key; if (image.GetDirEnt($1, key) == false) { Diag::printf("%s:%d: unknown object \"%s\"\n", current_file.str(), current_line, $1.str()); num_errors++; YYERROR; } if (key.IsNodeKeyType() == false) { Diag::printf("%s:%d: must be node key type\n", current_file.str(), current_line); num_errors++; YYERROR; } $$ = key; } | slot { SHOWPARSE("=== node -> slot\n"); DiskKey key = image.GetNodeSlot($1, $<slot>1); if (key.IsNodeKeyType() == false) { Diag::printf("%s:%d: must be node key type\n", current_file.str(), current_line); num_errors++; YYERROR; } $$ = key; } ;segmode: NAME { SHOWPARSE("=== segmode -> NAME\n"); DiskKey key; if (image.GetDirEnt($1, key) == false) { Diag::printf("%s:%d: unknown object \"%s\"\n", current_file.str(), current_line, $1.str()); num_errors++; YYERROR; } if ( key.IsSegKeyType() ) { $$ = key; } else { Diag::printf("%s:%d: must be segmode key\n", current_file.str(), current_line); num_errors++; YYERROR; } } ;/*domainkey: key { SHOWPARSE("=== domainkey -> key\n"); if ($1.IsType(KT_Process) == false) { Diag::printf("%s:%d: must be domain key\n", current_file.str(), current_line); num_errors++; YYERROR; } $$ = $1; } ; */startkey: key { SHOWPARSE("=== startkey -> key\n"); if ($1.IsType(KT_Start) == false) { Diag::printf("%s:%d: \"%s\" must be start key\n", current_file.str(), current_line); num_errors++; YYERROR; } $$ = $1; } ;segkey: key { SHOWPARSE("=== segkey -> key\n"); if ($1.IsSegModeType() == false && $1.IsVoidKey() == false && $1.IsType(KT_TimePage) == false) { Diag::printf("%s:%d: must be segment or " "segtree key\n", current_file.str(), current_line); num_errors++; YYERROR; } $$ = $1; } ;schedkey: key { SHOWPARSE("=== schedkey -> key\n"); if ($1.IsType(KT_Sched) == false) { Diag::printf("%s:%d: must be schedule key\n", current_file.str(), current_line); num_errors++; YYERROR; } $$ = $1; } ;numberkey: key { SHOWPARSE("=== numberkey -> key\n"); if ($1.IsType(KT_Number) == false) { Diag::printf("%s:%d: must be number key\n", current_file.str(), current_line); num_errors++; YYERROR; } $$ = $1; } ;arch_reg: NAME { SHOWPARSE("=== arch_reg -> NAME\n"); /* See if it's really an architecture name: */ RegDescrip *rd = RegDescrip::Lookup(CurArch, $1); if (rd == 0) { Diag::printf("%s:%d: \"%s\" is not a valid " "register name\n", current_file.str(), current_line, $1.str()); num_errors++; YYERROR; } $$ = rd; } ;segtype: SEGMENT { SHOWPARSE("=== segtype -> SEGMENT\n"); $$ = 1; } | SEGTREE { SHOWPARSE("=== segtype -> SEGTREE\n"); $$ = 0; } ;qualifier: RO { SHOWPARSE("=== qualifier -> RO\n"); $$ = ATTRIB_RO; } | RO NC { SHOWPARSE("=== qualifier -> RO NC\n"); $$ = ATTRIB_RO | ATTRIB_NC; } | RO NC WEAK { SHOWPARSE("=== qualifier -> RO NC\n"); $$ = ATTRIB_RO | ATTRIB_NC | ATTRIB_WEAK; } | RO WEAK { SHOWPARSE("=== qualifier -> RO NC\n"); $$ = ATTRIB_RO | ATTRIB_WEAK; } | RO WEAK NC { SHOWPARSE("=== qualifier -> RO NC\n"); $$ = ATTRIB_RO | ATTRIB_NC | ATTRIB_WEAK; } | NC { SHOWPARSE("=== qualifier -> NC\n"); $$ = ATTRIB_NC; } | NC RO { SHOWPARSE("=== qualifier -> NC RO\n"); $$ = ATTRIB_RO | ATTRIB_NC; } | NC RO WEAK { SHOWPARSE("=== qualifier -> NC RO\n"); $$ = ATTRIB_RO | ATTRIB_NC | ATTRIB_WEAK; } | NC WEAK { SHOWPARSE("=== qualifier -> NC RO\n"); $$ = ATTRIB_RO | ATTRIB_NC; } | NC WEAK RO { SHOWPARSE("=== qualifier -> NC RO\n"); $$ = ATTRIB_RO | ATTRIB_NC | ATTRIB_WEAK; } | WEAK { SHOWPARSE("=== qualifier -> NC\n"); $$ = ATTRIB_WEAK; } | WEAK NC { SHOWPARSE("=== qualifier -> NC\n"); $$ = ATTRIB_WEAK | ATTRIB_NC; } | WEAK NC RO { SHOWPARSE("=== qualifier -> NC\n"); $$ = ATTRIB_WEAK | ATTRIB_NC | ATTRIB_RO; } | WEAK RO { SHOWPARSE("=== qualifier -> NC\n"); $$ = ATTRIB_WEAK | ATTRIB_RO; } | WEAK RO NC { SHOWPARSE("=== qualifier -> NC\n"); $$ = ATTRIB_WEAK | ATTRIB_NC | ATTRIB_RO; } | SENSE { SHOWPARSE("=== qualifier -> SENSE\n"); $$ = ATTRIB_WEAK | ATTRIB_NC | ATTRIB_RO; } | /* nothing */ { SHOWPARSE("=== qualifier -> <nothing>\n"); $$ = 0; } ;/* OID can only be hex to simplify conversion */oid: HEX { SHOWPARSE("=== oid -> HEX\n"); int len = strlen($1.str()); if (len > 18) { Diag::printf("%s:%d: oid value too large\n", current_file.str(), current_line); num_errors++; YYERROR; } char digits[19]; strcpy(digits, $1.str()); uint32_t lo; uint32_t hi = 0; if ( len > 10 ) { /* has significant upper digits... */ lo = strtoul(digits + (len - 8), 0, 16); digits[len - 8] = 0; hi = strtoul(digits, 0, 16); } else { /* has significant upper digits... */ lo = strtoul(digits, 0, 16); } uint64_t oid = hi; oid <<= 32; oid |= (uint64_t) lo; $$ = oid; } ;blss: KW_BLSS arith_expr { SHOWPARSE("=== blss -> arith_expr\n"); Diag::printf("%s:%d: Obsolete syntax 'blss <number>', use" " 'lss <number>' where <number> is now\n" " the **unbiased** lss value.\n", current_file.str(), current_line); if ($2 > MAX_BLSS) { Diag::printf("%s:%d: blss value too large\n", current_file.str(), current_line); num_errors++; YYERROR; } $$ = $2; } | KW_LSS arith_expr { SHOWPARSE("=== lss -> arith_expr\n"); if ($2 > (MAX_BLSS - EROS_PAGE_BLSS)) { Diag::printf("%s:%d: lss value too large\n", current_file.str(), current_line); num_errors++; YYERROR; }#ifdef USE_SMALLER_BLSS $$ = $2;#else $$ = $2 + EROS_PAGE_BLSS;#endif } ;priority: arith_expr { SHOWPARSE("=== priority -> arith_expr\n"); if ($1 > Prio::High) { Diag::printf("%s:%d: priority value too large\n", current_file.str(), current_line); num_errors++; YYERROR; } } ;slot: NAME '[' slotno ']' { SHOWPARSE("=== slot -> NAME [ slotno ]\n"); DiskKey key; if (image.GetDirEnt($1, key) == false) { Diag::printf("%s:%d: unknown object \"%s\"\n", current_file.str(), current_line, $1.str()); num_errors++; YYERROR; } $$ = key; $<slot>$ = $3; uint32_t restriction = 0; if (key.IsNodeKeyType() == false) { Diag::printf("%s:%d: must be node key type\n", current_file.str(), current_line); num_errors++; YYERROR; } if (key.IsType(KT_Process) || key.IsType(KT_Start) || key.IsType(KT_Resume)) { restriction |= DomRootRestriction[$3]; }#ifdef KT_Wrapper else if ( key.IsType(KT_Wrapper) ) { restriction |= CalcWrapperRestriction(key, $3); }#else else if ( key.IsType(KT_Segment) && key.IsRedSegmentKey() ) { restriction |= CalcRedSegRestriction(key, $3); }#endif $<restriction>$ = restriction; SHOWPARSE1("=== +++ restriction = 0x%x\n", restriction); } | slot '[' slotno ']' { uint32_t restriction = 0; if ($<restriction>1 & (RESTRICT_VOID|RESTRICT_NUMBER|RESTRICT_SCHED)) { Diag::printf("%s:%d: cannot indirect through number/void key\n", current_file.str(), current_line); num_errors++; YYERROR; } if ($<restriction>1 & RESTRICT_GENREGS) restriction |= RESTRICT_NUMBER; if (($<restriction>1 & RESTRICT_KEYREGS) && $3 == 0) restriction |= RESTRICT_VOID; DiskKey key = image.GetNodeSlot($1, $<slot>1); $<slot>$ = $3; $$ = key; if ( !key.IsSegKeyType() ) { Diag::printf("%s:%d: LHS of '[slot]' must be segmode key\n" " You may need to say \"new [small] process with constituents\"\n" " ^^^^^^^^^^^^^^^^^\n", current_file.str(), current_line); num_errors++; YYERROR; } if (key.IsType(KT_Process) || key.IsType(KT_Start) || key.IsType(KT_Resume)) { restriction |= DomRootRestriction[$3]; }#ifdef KT_Wrapper else if ( key.IsType(KT_Wrapper) ) { restriction |= CalcWrapperRestriction($1, $3); }#else else if ( key.IsType(KT_Segment) && key.IsRedSegmentKey() ) { restriction |= CalcRedSegRestriction($1, $3); }#endif $<restriction>$ = restriction; SHOWPARSE1("=== +++ restriction = 0x%x\n", restriction); }slotno: arith_expr { SHOWPARSE("=== slotno -> arith_expr\n"); if ($1 > EROS_NODE_SIZE) { Diag::printf("%s:%d: slot index too large\n", current_file.str(), current_line); num_errors++; YYERROR; } } ;offset: arith_expr { SHOWPARSE("=== offset -> arith_expr\n"); /* This is WRONG -- the offset should be a 64 bit quantity */ $$ = $1; } ;keyData: arith_expr { SHOWPARSE("=== keyData -> arith_expr\n"); if ($1 > 0xffffu) { Diag::printf("%s:%d: key data value too large\n", current_file.str(), current_line); num_errors++; YYERROR; } } ;arith_expr: bit_expr { /* FIX: Not sure that the operator precedence is correct * here. Where should bit ops be in the operator precedence scale? */ SHOWPARSE("=== arith_expr -> bit_expr\n"); $$ = $1; } ;bit_expr: add_expr '|' add_expr { SHOWPARSE("=== bit_expr -> add_expr '|' add_expr\n"); $$ = $1 | $3; } | add_expr '^' add_expr { SHOWPARSE("=== bit_expr -> add_expr '^' add_expr\n"); $$ = $1 ^ $3; } | add_expr '&' add_expr { SHOWPARSE("=== bit_expr -> add_expr '&' add_expr\n"); $$ = $1 & $3; } | add_expr { SHOWPARSE("=== bit_expr -> add_expr\n"); $$ = $1; } ;add_expr: mul_expr '+' mul_expr { SHOWPARSE("=== add_expr -> mul_expr '+' mul_expr\n"); $$ = $1 + $3; } | mul_expr '-' mul_expr { SHOWPARSE("=== add_expr -> mul_expr '-' mul_expr\n"); $$ = $1 - $3; } | mul_expr { SHOWPARSE("=== add_expr -> mul_expr\n"); $$ = $1; } ;mul_expr: number { SHOWPARSE("=== add_expr -> number\n"); $$ = $1; } | mul_expr '*' number { SHOWPARSE("=== mul_expr -> mul_expr '*' number\n"); $$ = $1 * $3; } | mul_expr '%' number { SHOWPARSE("=== mul_expr -> mul_expr '%' number\n"); $$ = $1 * $3; } | mul_expr '/' number { SHOWPARSE("=== mul_expr -> mul_expr '/' number\n"); $$ = $1 / $3; } ;number: numeric_constant { SHOWPARSE("=== number -> numeric_constant\n"); $$ = $1; } | '(' arith_expr ')' { SHOWPARSE("=== number -> '(' arith_expr ')'\n"); $$ = $2; } | '-' number { SHOWPARSE("=== number -> '-' number\n"); $$ = - $2; } | '~' number { SHOWPARSE("=== number -> '~' number\n"); $$ = ~ $2; } ;numeric_constant: HEX { SHOWPARSE("=== number -> HEX\n"); unsigned long value = strtoul($1.str(), 0, 0); $$ = value; } | DEC { SHOWPARSE("=== number -> DEC\n"); unsigned long value = strtoul($1.str(), 0, 0); $$ = value; } | OCT { SHOWPARSE("=== number -> OCT\n"); unsigned long value = strtoul($1.str(), 0, 0); $$ = value; } | BIN { SHOWPARSE("=== number -> BIN\n"); unsigned long value = strtoul($1.str()+2, 0, 2); $$ = value; } ;string_lit: STRINGLIT { SHOWPARSE("=== string_lit -> STRINGLIT\n"); $$ = $1; } | string_lit STRINGLIT { SHOWPARSE("=== string_lit => string_lit STRINGLIT\n"); $$ = $1 + $2; } ;%%intmain(int argc, char *argv[]){ int c; extern int optind;#if 0 extern char *optarg;#endif extern int yy_flex_debug; yy_flex_debug = 0; /* until proven otherwise */ int opterr = 0; const char *output; InternedString architecture; bool verbose = false; bool use_std_inc_path = true; bool use_std_def_list = true; StrBuf cpp_cmd; StrBuf cpp_cmd_args; cpp_cmd << "/lib/cpp "; /* Set up standard EROS include search path: */ StrBuf stdinc; stdinc << "-I" << App::BuildPath("/eros/include") << ' '; StrBuf stddef; stddef << ' '; while ((c = getopt(argc, argv, "a:o:dvn:I:A:D:")) != -1) { const char cc = c; switch(c) { case 'v': verbose = true; break; case 'o':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -