⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 preccx.y

📁 編譯器的辭法分析器工具
💻 Y
📖 第 1 页 / 共 2 页
字号:
@ line = declaration@      | notanat passthrough@      |  :VV(0)="";printf("\n");:@ notanat = NOTANAT : VV(1)=putchar(T(1)); :/* this is a deliberate pop of the value 'behind'  if we get none */@ passthrough = {anychar : VV(2)=V(1); :}*@                :getname(&V(1));printf("%s\n",V(1)); RESET;:@ anychar = ANYTHING : VV(1)=putchar(T(1)); :                /* ----  parser expressions -------- */@ expression = alternates@            | empty/* a <'|'> separated series, at least one <'|'>  - note the overpull    I prefer the order which results from recursion */@ alternates = sequence@              [ WHITESPACE OR WHITESPACE alternates@                :char *n;@                 VV(5)=(GETNEWNAME(&n,plainenv,NULL),P_ALT(n,V(1),V(5)));:@              ]/* appending is much more efficient than prepending because I don't waste  C-stack space with MARK before a parse *//* this is a command separated sequence of sequents which are not commands*/@ sequence = manysequents @            { @              SOMESPACE command@              SOMESPACE manysequents@                 :char *n;@                  VV(3)=(GETNEWNAME(&n,plainenv,NULL),P_AND(n,V(1),V(3)));:@            }*@            [ WHITESPACE command ] /* here we attach to the manysequents which this follows */@ command = COLON c_code COLONorEOL@           : char *n,*m;@             VV(5)=(GETNEWNAME(&n,plainenv,NULL),GETNEWNAME(&m,plainenv,NULL),P_ATT(m,V(1),n,V(4))); :/* commands can't be treated as ordinary atoms at the moment, because they * are required to end a sequence of 'and's and force a stack shift */@ c_code = cstuffs : VV(1)=V(1); getname(&V(1)); :/* the stuff inside a command is a sequence of C constants or C tokens */@ cstuffs= cstuff {cstuff : VV(2) = V(1); :}*@        |  : VV(0) =""; :/* all the component tokens are accumulating in the cbuff */@ cstuff = STRING@        | CHARCONST@        | DOLLARID@        | COMMENT@        | NOTACOLON : VV(1) = putchar(T(1)); :/* manysequents is a 0 or more long list of nonempty non-commands *//* start a new count *//* do the pulling in moresequents, if it happens */@ manysequents = firstsequent [ moresequents ] : popcount();:/* need "empty newvar empty" and "sequent newvar empty" to make the   above complete, but it's too much bother right now */@ firstsequent = { sequent@                | empty@                }            :pushcount();:        /* overpull again in the option            again, I prefer to use recursion for better output order *//* without a parameterized spec, I can't prevent repetitions */@ newvar = BACKSLASH IDENTIFIER@     :VV(2)=V(2);getname(&V(2));ADDVAR(V(2));:/* moresequents is a 1 or more long list of sequents, or an attr decl * followed by a 1 or more long list. It is not empty. It is not * (presently) a newvar on its own, though it might eventually be */@ moresequents = newvar SOMESPACE sequent [ moresequents ]@        : char *n; VV(4)=V(1);popenv();@          GETNEWNAME(&n,plainenv,NULL);V(1)=P_STAR(n,V(1),V(4),V(2));:@              | dummyvar SOMESPACE sequent [ moresequents ]@        : char *n; VV(4)=V(1);@          if (precc_data.oldattributes){popenv();@          GETNEWNAME(&n,plainenv,NULL);V(1)=P_STAR(n,V(1),V(4),V(2));}@          else{@          GETNEWNAME(&n,plainenv,NULL);V(1)=P_AND(n,V(1),V(4));}:/* in the above, have to be careful to avoid allowing a trailing "empty"   because that wrecks the returned value from an @foo@ */@ dummyvar =  :/*empty*/ VV(0)=V(1);@             if(precc_data.oldattributes){@             getname(&V(1));@             GETANAME(&V(1),"p_","",count++);@             V(1)=GNAME(V(1));putname(V(1));@             getname(&V(1));@             ADDVAR(V(1)); }        /* Don't overpull now because ... */@ sequent = seqoperand [ postfix ]         /* in each of these cases the postfix must behave as though the        seqoperand were before it and overpull its arguments and write into        the stack position to the left of itself */@ postfix = starop@         | plusop @         | hideop@ bracket = OPENBRACE WHITESPACE@           expression@           WHITESPACE CLOSEBRACE@    : VV(5) = V(3); :@ option =  OPENBRACKET WHITESPACE@           expression@           WHITESPACE CLOSEBRACKET@   : char *n;VV(5)=(GETNEWNAME(&n,plainenv,NULL),P_OPT(n,V(3))); :@ empty =  : VV(0)= "p_nothing0"; :@ result=  AT WHITESPACE expr WHITESPACE AT@                 :char *n; VV(5)=(getname(&V(3)),@                  GETNEWNAME(&n,plainenv,NULL),P_ATA(n,V(3))); :                /* here is one overpull */int starflag=0;char *starqual;@ starop = STAR [ expr :starflag=1;VV(2)=(getname(&V(2)),V(2));:]@          : char *n;if(starflag){@                  VV(2)=(GETNEWNAME(&n,plainenv,NULL),P_ITR(n,V(1),V(3))); @                  }  else {@                  VV(2)=(GETNEWNAME(&n,plainenv,NULL),P_INF(n,V(1)));@                  }  starflag=0; :@ anymatch = QUESTION : VV(1)="p_anything0"; :/* recall that exprnames get saved in the cbuff */@ seqoperand = bracket@            | option@            | literal@            | antiliteral@            | range  @            | test@            | phantom@            | result@            | untilmatch@            | anymatch | beginmatch | eofmatch@            | dollarplingmatch | finishmatch@            | plingexpr@            | plingmatch | exprname@ plingexpr  = PLING bracket @     : char *n;   VV(2)=(GETNEWNAME(&n,plainenv,NULL),P_ERR(n,V(2))); :@ phantom = CLOSEBRACKET WHITESPACE@              expression@           WHITESPACE OPENBRACKET@           :char *n;VV(5)=(GETNEWNAME(&n,plainenv,NULL),P_PHA(n,V(3))); :/* a literal is anything inside angle brackets. * an antiliteral is anything inside anti angle brackets. * anglebrackets inside may be escaped to protect them */@ lstuff = STRING @        | CHARCONST@        | COMMENT@        | NOTARIGHTANGLEBRACKET : VV(1) = putchar(T(1)); :@ alstuff = STRING  @         | CHARCONST@         | COMMENT@         | NOTALEFTANGLEBRACKET : VV(1) = putchar(T(1)); :@ lstuffs  = lstuff {lstuff : VV(2) = V(1); :}*@          |  : VV(0)=""; :/* close the accumulator for lstuffs */@ lits     = lstuffs :VV(1)=V(1);getname(&V(1));:@ alstuffs = alstuff {alstuff : VV(2) = V(1); :}*@          |  : VV(0)=""; :/* close the accumulator for alstuffs */@ alits    = alstuffs :VV(1)=V(1);getname(&V(1));:@ LITERAL  = LEFTANGLEBRACKET@             lits@            RIGHTANGLEBRACKET@            : VV(3) = V(2); :@ ANTILITERAL = RIGHTANGLEBRACKET@               alits@               LEFTANGLEBRACKET @               : VV(3) = V(2) ; : @ literal = LITERAL @  :char *n;VV(1)=(GETNEWNAME(&n,plainenv,NULL),P_LIT(n,V(1))); :@ antiliteral = ANTILITERAL@  :char *n;VV(1)=(GETNEWNAME(&n,plainenv,NULL),P_ALI(n,V(1))); :@ range = OPENPAREN expr CLOSEPAREN@  :char *n;VV(3)=(getname(&V(2)),GETNEWNAME(&n,plainenv,NULL),P_RAN(n,V(2)));:@ test =  CLOSEPAREN expr OPENPAREN@  :char *n;VV(3)=(getname(&V(2)),GETNEWNAME(&n,plainenv,NULL),P_TST(n,V(2)));:@ beginmatch  = CARET : VV(1)="p_first0"; :@ finishmatch = DOLLAR : VV(1)="p_last0"; :@ plingmatch  = PLING : VV(1)="p_uniq0"; :@ dollarplingmatch = DOLLAR PLING : VV(2)="p_lastuniq0"; :@ eofmatch = DOLLAR DOLLAR : VV(2)="p_eof0"; :                /* another overpull */@ plusop = PLUS@              : char *n;VV(2)=(GETNEWNAME(&n,plainenv,NULL),P_SOM(n,V(1))); :@ hideop = SLASH OPENPAREN expr CLOSEPAREN@  :char *n;@   VV(5)=(getname(&V(4)),GETNEWNAME(&n,plainenv,NULL),P_HID(n,V(1),V(4)));:@ untilmatch = ELLIPSIS WHITESPACE seqoperand@   : char *n;VV(3)=(GETNEWNAME(&n,plainenv,NULL),P_UNT(n,V(3))); :                /* ------- finis -------- */MAIN(line)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -