📄 gram.y
字号:
%{/* * Copyright (C) 1998, 1999, 2001, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <sys/fcntl.h>#include <sys/stat.h>#include <getopt.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <ctype.h>#include <eros/target.h>#include <erosimg/App.hxx>#include <erosimg/ErosImage.hxx>#include <erosimg/ExecImage.hxx>#include <erosimg/PtrMap.hxx>#include <erosimg/Parse.hxx>#include <erosimg/StrBuf.hxx>#include <eros/Key.h>#include <eros/ProcessState.h>#include <disk/DiskKey.hxx>#include <disk/DiskLSS.hxx>#include <eros/StdKeyType.h>#include "../../../lib/domain/include/domain/Runtime.h"/* Made this a structure to avoid construction problems */#include "ParseType.h"bool showparse = false;#define SHOWPARSE(s) if (showparse) Diag::printf(s)#define SHOWPARSE1(s,x) if (showparse) Diag::printf(s,x) extern void PrintDiskKey(const DiskKey&);class App App("mkimage");InternedString NoArch("Unknown Architecture");InternedString CurArch = NoArch;InternedString current_file("<stdin>");int current_line = 1;extern FILE *yyin;int num_errors = 0; /* hold the number of syntax errors encountered. */void ShowImageDirectory(const ErosImage& image);void ShowImageThreadDirectory(const ErosImage& image);boolAddProgramSegment(ErosImage& image, InternedString fileName, DiskKey &key);boolGetProgramSymbolValue(InternedString fileName, InternedString symName, uint32_t& value);boolAddRawSegment(ErosImage& image, InternedString fileName, DiskKey &key);boolAddZeroSegment(ErosImage& image, DiskKey &key, uint32_t nPages);boolAddEmptySegment(ErosImage& image, DiskKey &key, uint32_t nPages);boolGetMiscKeyType(InternedString s, uint32_t& ty);/* returns false on error */bool QualifyKey(uint32_t, DiskKey in, DiskKey& out);DiskKey NumberFromString(InternedString&);#define ATTRIB_RO 0x1#define ATTRIB_NC 0x2#define ATTRIB_WEAK 0x4#define YYSTYPE ParseTypeextern void yyerror(const char *);extern int yylex();extern int yylex (YYSTYPE *lvalp);ErosImage image;uint32_t DomRootRestriction[EROS_NODE_SIZE] = { RESTRICT_SCHED, /* dr00: schedule slot */ RESTRICT_START, /* dr01: keeper slot */ RESTRICT_SEGMODE, /* dr02: address space */ RESTRICT_KEYREGS, /* dr03: key regs (future: capability space) */ RESTRICT_IOSPACE, /* dr04: reserved -- i/o space */ RESTRICT_SEGMODE, /* dr05: reserved -- symbol space */ RESTRICT_START, /* dr06: brand */ RESTRICT_NUMBER, /* dr07: trap_code */ RESTRICT_NUMBER, /* dr08: pc, sp register */ 0, /* dr09: architecture defined */ 0, /* dr10: architecture defined */ 0, /* dr11: architecture defined */ 0, /* dr12: architecture defined */ 0, /* dr13: architecture defined */ 0, /* dr14: architecture defined */ 0, /* dr15: architecture defined */ 0, /* dr16: architecture defined */ 0, /* dr17: architecture defined */ 0, /* dr18: architecture defined */ 0, /* dr19: architecture defined */ 0, /* dr20: architecture defined */ 0, /* dr21: architecture defined */ 0, /* dr22: architecture defined */ 0, /* dr23: architecture defined */ 0, /* dr24: architecture defined */ 0, /* dr25: architecture defined */ 0, /* dr26: architecture defined */ 0, /* dr27: architecture defined */ 0, /* dr28: architecture defined */ 0, /* dr29: architecture defined */ 0, /* dr30: architecture defined */ 0, /* dr31: architecture defined */};#ifdef KT_Wrapperuint32_t CalcWrapperRestriction(DiskKey segKey, uint32_t slot);#elseuint32_t CalcRedSegRestriction(DiskKey segKey, uint32_t slot);#endifbool CheckRestriction(uint32_t restriction, DiskKey key);%}/* Following will not work until I hand-rewrite the lexer *//* %pure_parser */%token <NONE> RO NC WEAK SENSE NODE PAGE NEW HIDE PROGRAM SMALL%token PROCESS DOMAIN/* %token <NONE> IMPORT */%token <NONE> SEGMENT SEGTREE NULLKEY ZERO WITH PAGES RED EMPTY%token <NONE> KW_BLSS KW_LSS CONSTITUENTS%token <NONE> WRAPPER%token <NONE> ARCH PRINT SPACE REG KEEPER START BACKGROUND IOSPACE SYMTAB%token PRIORITY SCHEDULE%token <NONE> BRAND GENREG SLOT ROOT OREQ KEY SUBSEG AT CLONE COPY%token <NONE> PC SP ALL SLOTS KEYS STRING LIMIT RUN IPL AS%token <NONE> RANGE NUMBER SCHED MISC VOLSIZE DIRECTORY PRIME%token <NONE> PHYSMEM%token <NONE> SYMBOL CAPABILITY%token <NONE> VOIDKEY%token <is> NAME STRINGLIT HEX OCT BIN DEC WORD%token <is> MISC_KEYNAME%type <key> key segkey domain startkey%type <key> qualified_key node%type <key> schedkey numberkey/* Following are bare key names of appropriate type -- need to be distinguished to avoid shift/reduce errors: */%type <key> segmode slot%type <w> qualifier segtype blss keyData slotno%type <w> number numeric_constant arith_expr add_expr mul_expr bit_expr%type <w> offset priority%type <oid> oid%type <rd> arch_reg%type <is> string_lit%%start: /* empty */ | start stmt ;stmt: stmt ';' { if (App.IsInteractive()) ShowImageDirectory(image); SHOWPARSE("=== line -> stmt \\n\n"); } | error ';' { yyerrok; } ;stmt: /* IMPORT STRING { SHOWPARSE("=== stmt -> IMPORT STRING\n"); ErosImage importImage; importImage.ReadFromFile($2.str()); image.Import(importImage); } | */ HIDE NAME { SHOWPARSE("=== stmt -> HIDE NAME\n"); if (image.DelDirEnt($2) == false) { Diag::printf("%s:%d: \"%s\" is not in the image directory\n", current_file.str(), current_line, $2.str()); num_errors++; YYERROR; } } | NAME '=' qualified_key { /* no restrictions */ SHOWPARSE("=== stmt -> NAME = qualified_key\n"); image.AssignDirEnt($1, $3); } | slot '=' qualified_key { SHOWPARSE("=== stmt -> slot = key\n"); if ( !CheckRestriction($<restriction>1, $3) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } image.SetNodeSlot($1, $<slot>1, $3); } | PRINT string_lit { /* Really print quoted string... */ SHOWPARSE("=== stmt -> PRINT STRING\n"); Diag::printf("%s\n", $2.str()); } | PRINT DIRECTORY { SHOWPARSE("=== stmt -> PRINT DIRECTORY\n"); ShowImageDirectory(image); } | PRINT key { SHOWPARSE("=== stmt -> PRINT key\n"); PrintDiskKey($2); Diag::printf("\n"); } | PRINT SEGMENT segkey { SHOWPARSE("=== stmt -> PRINT SEGMENT segkey\n"); image.PrintSegment($3); } | PRINT PAGE key { SHOWPARSE("=== stmt -> PRINT PAGE key\n"); if ($3.IsType(KT_Page) == false) { Diag::printf("%s:%d: must be page key\n", current_file.str(), current_line); num_errors++; YYERROR; } image.PrintPage($3); } | PRINT NODE key { SHOWPARSE("=== stmt -> PRINT NODE key\n"); if ($3.IsNodeKeyType() == false) { Diag::printf("%s:%d: must be node key\n", current_file.str(), current_line); num_errors++; YYERROR; } image.PrintNode($3); } | PRINT DOMAIN key { SHOWPARSE("=== stmt -> PRINT DOMAIN key\n"); Diag::warning("%s:%d: Obsolete syntax 'print domain', use 'print process'\n", current_file.str(), current_line); if ($3.IsNodeKeyType() == false) { Diag::printf("%s:%d: must be node key\n", current_file.str(), current_line); num_errors++; YYERROR; } image.PrintDomain($3); } | PRINT PROCESS key { SHOWPARSE("=== stmt -> PRINT PROCESS key\n"); if ($3.IsNodeKeyType() == false) { Diag::printf("%s:%d: must be node key\n", current_file.str(), current_line); num_errors++; YYERROR; } image.PrintDomain($3); } | ARCH NAME { SHOWPARSE("=== stmt -> ARCH NAME\n"); ExecArch::Architecture arch = ExecArch::FromString($2); if (arch == ExecArch::arch_unknown) { Diag::printf("%s:%d: unknown architecture \"%s\".\n", current_file.str(), current_line, $2.str()); num_errors++; YYERROR; } CurArch = $2; } | node SPACE '=' segkey { SHOWPARSE("=== stmt -> domain SPACE = segkey\n"); if ( !CheckRestriction(DomRootRestriction[ProcAddrSpace], $4) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } image.SetNodeSlot($1, ProcAddrSpace, $4); } | node SYMTAB '=' key { SHOWPARSE("=== stmt -> domain SYMTAB = key\n"); if ( !CheckRestriction(DomRootRestriction[ProcSymSpace], $4) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } image.SetNodeSlot($1, ProcSymSpace, $4); } | node IOSPACE '=' key { SHOWPARSE("=== stmt -> domain IOSPACE = segkey\n"); if ( !CheckRestriction(DomRootRestriction[ProcIoSpace], $4) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } image.SetNodeSlot($1, ProcIoSpace, $4); } | node PC '=' arith_expr { SHOWPARSE("=== stmt -> domain PC = arith_expr\n"); DiskKey key = image.GetNodeSlot($1, ProcPCandSP); if (key.IsType(KT_Number) == false) { Diag::printf("%s:%d: Slot did not hold number key\n", current_file.str(), current_line); num_errors++; YYERROR; } key.nk.value[0] = $4; image.SetNodeSlot($1, ProcPCandSP, key); } | node SP '=' arith_expr { SHOWPARSE("=== stmt -> domain SP = arith_expr\n"); DiskKey key = image.GetNodeSlot($1, ProcPCandSP); if (key.IsType(KT_Number) == false) { Diag::printf("%s:%d: Slot did not hold number key\n", current_file.str(), current_line); num_errors++; YYERROR; } key.nk.value[1] = $4; image.SetNodeSlot($1, ProcPCandSP, key); } | node PC '=' numberkey { SHOWPARSE("=== stmt -> domain PC = numberkey\n"); if ( !CheckRestriction(DomRootRestriction[ProcPCandSP], $4) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } DiskKey k = image.GetNodeSlot($1, ProcPCandSP); k.nk.value[0] = $4.nk.value[0]; image.SetNodeSlot($1, ProcPCandSP, k); } | node PRIORITY '=' schedkey { SHOWPARSE("=== stmt -> process PRIORITY = schedkey\n"); Diag::warning("%s:%d: Obsolete syntax '<proc> priority', use '<proc> schedule'\n", current_file.str(), current_line); if ( !CheckRestriction(DomRootRestriction[ProcSched], $4) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } image.SetNodeSlot($1, ProcSched, $4); } | node SCHEDULE '=' schedkey { SHOWPARSE("=== stmt -> process SCHEDULE = schedkey\n"); if ( !CheckRestriction(DomRootRestriction[ProcSched], $4) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } image.SetNodeSlot($1, ProcSched, $4); } | node BRAND '=' startkey { SHOWPARSE("=== stmt -> domain BRAND = startkey\n"); if ( !CheckRestriction(DomRootRestriction[ProcBrand], $4) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } image.SetNodeSlot($1, ProcBrand, $4); } | node DOMAIN KEEPER '=' startkey { SHOWPARSE("=== stmt -> process DOMAIN KEEPER = startkey\n"); Diag::warning("%s:%d: Obsolete syntax 'DOMAIN KEEPER', use 'new process'\n", current_file.str(), current_line); if ( !CheckRestriction(DomRootRestriction[ProcKeeper], $5) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } image.SetNodeSlot($1, ProcKeeper, $5); } | node PROCESS KEEPER '=' startkey { SHOWPARSE("=== stmt -> process PROCESS KEEPER = startkey\n"); if ( !CheckRestriction(DomRootRestriction[ProcKeeper], $5) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } image.SetNodeSlot($1, ProcKeeper, $5); } | node SEGMENT KEEPER '=' startkey { SHOWPARSE("=== stmt -> domain BRAND = startkey\n"); if ( !CheckRestriction(RESTRICT_START, $5) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; }#ifdef KT_Wrapper image.SetNodeSlot($1, WrapperKeeper, $5); DiskKey key = image.GetNodeSlot($1, WrapperFormat); key.nk.value[0] |= WRAPPER_KEEPER; image.SetNodeSlot($1, WrapperFormat, key);#else image.SetNodeSlot($1, RedSegKeeper, $5); DiskKey key = image.GetNodeSlot($1, RedSegFormat); REDSEG_SET_KPR_SLOT(key.nk, RedSegKeeper); image.SetNodeSlot($1, RedSegFormat, key);#endif } | node BACKGROUND SEGMENT '=' segkey { SHOWPARSE("=== stmt -> node BACKGROUND SEGMENT = segkey\n"); if ( !CheckRestriction(RESTRICT_SEGMODE, $5) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; }#ifdef KT_Wrapper image.SetNodeSlot($1, WrapperBackground, $5); DiskKey key = image.GetNodeSlot($1, WrapperFormat); key.nk.value[0] |= WRAPPER_BACKGROUND; image.SetNodeSlot($1, WrapperFormat, key);#else image.SetNodeSlot($1, RedSegBackground, $5); DiskKey key = image.GetNodeSlot($1, RedSegFormat); REDSEG_SET_BG_SLOT(key.nk, RedSegBackground); image.SetNodeSlot($1, RedSegFormat, key);#endif } | slot OREQ numberkey { SHOWPARSE("=== stmt -> slot |= numberkey\n"); DiskKey key = image.GetNodeSlot($1, $<slot>1); if ( !CheckRestriction($<restriction>1, $3) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } if (key.IsType(KT_Number) == false) { Diag::printf("%s:%d: Operator '|=' requires a number key\n", current_file.str(), current_line); num_errors++; YYERROR; } key.nk.value[2] |= $3.nk.value[2]; key.nk.value[1] |= $3.nk.value[1]; key.nk.value[0] |= $3.nk.value[0]; image.SetNodeSlot($1, $<slot>1, $3); } | node KEY REG slotno '=' qualified_key { SHOWPARSE("=== stmt -> domain KEY REG keyreg_slotno = qualified_key\n"); if ( !CheckRestriction($4 ? 0 : RESTRICT_VOID, $6) ) { Diag::printf("%s:%d: key does not meet slot restriction\n", current_file.str(), current_line); num_errors++; YYERROR; } DiskKey genKeys = image.GetNodeSlot($1, ProcGenKeys); image.SetNodeSlot(genKeys, $4, $6); } | node SLOTS '=' COPY node { SHOWPARSE("=== stmt -> node SLOTS = COPY node\n"); DiskKey toKey = $1; DiskKey fromKey = $5; for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) { DiskKey tmp = image.GetNodeSlot(fromKey, i); image.SetNodeSlot(toKey, i, tmp); } } | segmode offset '=' WORD arith_expr { SHOWPARSE("=== stmt -> segment offset = WORD arith_expr\n"); DiskKey pageKey; if (image.GetPageInSegment($1, $2, pageKey) == false) { pageKey = image.AddZeroDataPage(); image.AddPageToSegment($1, $2, pageKey); } uint32_t pageOffset = $2 & EROS_PAGE_MASK; image.SetPageWord(pageKey, pageOffset, $5); }/* | segmode SLOT slot '=' key { SHOWPARSE("=== stmt -> node SLOT slot = key\n"); image.SetNodeSlot($1, $3, $5); } */ | segmode ALL SLOTS '=' key { SHOWPARSE("=== stmt -> node ALL SLOTS = key\n"); for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) image.SetNodeSlot($1, i, $5); } | RUN domain { SHOWPARSE("=== stmt -> RUN domain\n"); if (!image.AddStartup($<is>2, $2)) { PrintDiskKey($2); Diag::printf("%s:%d: run stmt could not be applied\n", current_file.str(), current_line); num_errors++; YYERROR; } } | IPL domain { SHOWPARSE("=== stmt -> IPL domain\n"); /* Set the domain to the "running" state (runState == 1) */ DiskKey key; if (image.GetDirEnt(":ipl:", key)) { Diag::printf("%s:%d: redundant ipl statement ignored\n", current_file.str(), current_line); num_errors++; YYERROR; } else { key = $2; key.SetType(KT_Process); image.AddDirEnt(":ipl:", key); image.SetProcessState(key, RS_Running);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -