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

📄 preccx.1

📁 編譯器的辭法分析器工具
💻 1
📖 第 1 页 / 共 3 页
字号:
The following macros can be set if required:.IP # define READBUFFERSIZE length.PP(default 2048) This defines the lookahead token buffer length.  No morethan <length> tokens can appear between cut marks (`!')  in the script,as without cut indicators, preccx cannot know if the parser might laterbacktrack or not, and will not embed buffer reset instructions (in v2.41and later versions, \fIpreccx\fP will attempt to increase the buffer inREADBUFFERSIZE increments when necessary, so it is not a hard limit)..IP # define MAXPROGRAMSIZE length.PP(default 4096) This defines the maximum length of the internal programbuilt by parsers in order to execute attached actions..IP # define STACKSIZE length.PP(default 0) This defines the size of a runtime stack formerly used tomanipulate  attached attributes in versions prior to 2.41 and it is nowobsolete. The usage was approximately proportional  to  nesting  depthin productions.   The stack can be re-enabled by setting the STACKSIZEto some  positive amount. The V(n) macro can then be used to access it..PPIt can be safely left as 0 in code generated by preccx  2.41 and above..IP # define CONTEXTSTACKSIZE length.PP(default 1024) This defines the number of breakpoints that can be heldfor backtracking.  Usage is proportional to the number of sequents inproductions between cuts..IP# define C_STACKSIZE length.PP(default 0x7FFF or 32K) This is the C call stack..PPNow for the horrors of synthetic attributes. To get a parser generatedby \fIpreccx\fP to do anything significant, you need either to get it tosynthesise a data structure, or get it to generate outputs.  Whichever,you usually need to scatter \fIactions\fP and \fIattributes\fP throughthe script.  There are two styles of script to get to know:(a) old \fIyacc\fP(1)-style scripts, in which attributes are referred to bynumber,  and (b) new style scripts,  in which synthesized attributes are referred to by name..PPActions are pieces of C code (terminated by a semi-colon) and placedbetween a pair of bracket-colons (`{:\0...\0:}') in the grammar definitionscript. For  example, this action uses old-style \fIyacc\fP(1) numericalreferences  to  build a numerical value which it stashes in a C globalvariable:.IP @ addexpr = expr <'+'> expr {: total=$1+$3; :}.PPIn the new style of named reference, this would be  rendered as follows:.IP @ addexpr = expr\\x <'+'> expr\\y {: total=$x+$y; :}.IPIf the computed value is to be attached as an  attribute for the parse,this can be rendered as follows:.IP.@ addexpr = expr\\x <'+'> expr\\y {@ $x+$y @}.PPA newly attached attribute can then be used as an  inheritedparameter in the rest of the parse: .IP @ sum(subtotal) = addexpr\\x <'+'> sum(subtotal+$x) @ \0\0\0\0\0\0\0\0\0\0\0\0\0\0 | \0....PPIn contrast, the value of total generated in the action is notavailable to the parse because actions execute later than the parsetime.  The value is available to later actions, however.  And it  is available  in  the parse once the next cut mark '!' in the script hasbeen passed. .PPIn the action, `$1' is the value attached to the leftmost term, and `$3'is that attached to the rightmost term.  The `$1' may be replaced by theexplicit `*(VALUE*)p_1' within C macros (their contents are not directlyaccessible to preccx and this is what `$1' expands to) in version 2.41and above.  In earlier versions than 2.41, `V(1)' is the appropriatereplacement to use..PP`Values' attached to each term of a \fIpreccx\fP expression are an appropriateway to think of what is going on.  Note that the full \fIyacc\fP(1) style ofscript,  with  attribute   assignments mixed into  the action code viathe `$$' pseudo-variable, is only supported until v2.40 and no later.Moreover, the \fIyacc\fP-style numerical referencing via `$1',  `$2' and soon,  from  v2.41 on requires the `-old' command line switch to preccx. In previous versions of \fIpreccx\fP, it was supported withoutrestriction..PPEarlier versions of preccx than version 2.41 used a runtime interpreter(like yacc(1)) and a dynamic stack to implement the synthesizedattributes.  Version 2.41 and above compiles the  attributes instead.The  difference  makes  for some slight incompatibilities with yacc(1):the $0 reference  now makes no sense, for example.  It used to refer tothe attribute attached to the term just seen  to  the  left  and wasavailable  below  on  the  dynamic stack.  But in a compiled model, itis simply out of scope. .SH A BIT OF HISTORYIn version 1.5 to 2.40, \fIpreccx\fP generated code to  shift  the frame  ofreference  in a runtime attribute stack automatically.  This was setby `call_mode=0' (the default)  in  the BEGIN  macro.   In earlierversions, or if `call_mode=1' was set, frame shifts had to be codedexplicitly in the  script: this  would  be accomplished by including aVV(n) call early in the action attached to each clause.  For example, athree term  clause  would  need  a VV(3) call.  After the call (incall_mode=1 mode) the $n values would be  correctly  aligned with thegrammar expressions, and without it, they would not be.  The value to beassociated with  the  whole  expression was  written  into  $1.  Writing VV(3)=$2 was shorthand for VV(3);$1=$2.  After version 1.5 andwith `call_mode=0'  set, the  explicit VV(3) was not required and theattribute build  could be coded as $1=$2 alone.  Or, for  compatabilitywith  \fIyacc\fP(1), as $$=$2..PPThis was all exactly equivalent to the treatment in the Unix \fIyacc\fP(1)utility, and it allowed you to incorporate the same incomprehensibletricks of pulling values off the stack when they were notionally`further to the left' than the scope of the current expression, using $0or even lower references..PPTo recap, in versions 1.50 to 2.40 the user had to choose a `call mode'which controlled the way the stack of attributes is handled at run time.Using the default call_mode=0  mode, stack  frame  shifts were automaticand it was not necessary to set VV(n) (shift value stack by n) commandsin  actions. If call_mode=1, then stack shifts were left to the user,and VV(n) instructions had to be added  explicitly  to  actions. Fromversion 2.41 up  `call mode' is  entirely  obsolete  so  you can forgetit!.PPIn earlier versions  than  1.50,  the  only call mode was call_mode=1.The call mode in later versions was set by: .IPcall_mode = 0 (automatic); or 1 (user-directed);.PPin the BEGIN macro,  to  be  #defined  before  the  #include <cc.h> or<ccx.h>  in the script.  In version 2.41 none of this is necessary asthe attributes are  handled  in  the  C runtime call stack,  which islooked  after by C.  You can #define  STACKSIZE  0 (to remove the stackentirely, to save space), all this also before the  #include <cc.h> or<ccx.h>  directive..PPHistory off..SH ATTRIBUTESIn version 2.41 and above, the job of building synthetic attributes hasbeen hived off into the parser proper.  Synthetic attributes are anynon-side-effecting expression, possibly involving the dollarvariables which denote the values of attributes of other terms in aclause. They are written within {@ ... @} symbols. The last attribute in aclause becomes the attribute of a clause. For example:.IP@ tree = <'('> tree\\x <')'> tree\\y {@ mknode($x,$y) @}.IP@ \0\0\0\0 | ....PPis sufficient to build a simple parse tree for bracketed input. Notehowever that the attribute should be non-side-effecting. It may becalled several times in a parse. Since compound structures have to bebuilt via side-effects in C, each call to mknode will have to check itsarguments to see whether it has been called before, and to return thepreviously built structure if it has. It will have to do its ownmemoizing. On the other hand, rebuilding the structure several timesbecomes an allowable strategy when garbage collection takes place oftenenough to reclaim wasted structures. Either technique removes visibleside-effects. .SH ACTIONSReal side-effects that the parse is intended to invoke are coded in allversions of \fIpreccx\fP as actions between {:...:} pairs, analogouslyto \fIyacc\fP(1). Side-effecting actions need a little explanation.Because \fIpreccx\fP is an infinite look-ahead parser, it cannotexecute actions at the same time as it reads input. It might have tolater backtrack across its parse, and, whilst it might deconstruct datastructures built up in the parse, it is certainly impossible, forexample, to undo any writes to \fIstdout\fP which might have occurred..PPSo \fIpreccx\fP builds a program as it parses. When the parse finishescorrectly, the program is executed by an internal engine, but if the parseis unsuccessful or has to be backtracked, the program is `unbuilt' beforeits actions are executed. This program is a linear sequence of C code actionswhich have been specified in the \fIpreccx\fP definition file. Thus thespecification:.IP @abc=a\0b\0c\0{:printf("D");:}.IP @a=<'a'>\0{:printf("A");:}.IP @b=<'b'>\0{:printf("B");:}.IP @c=<'c'>\0{:printf("C");:}.PPwill, upon receiving input "abc", generate the program.IP printf("A");printf("B");printf("C");printf("D");.PPto be executed later.Thus actions attached to a sequence expression may be thought of as occurringimmediately after the actions attached to sub-expressions, and so ondown. That explanation should enable you to generate side-effects inthe correct sequence..PPAs remarked above, in version 1.50 to 2.40 of \fIpreccx\fP, attributes werebuilt in the side-effecting actions, in yacc(1) style. In version 2.41 andabove, attributes are attached using the new {@foo@} notation. Thisis certainly mechanically more robust, and it ought to be conceptuallycleaner too. Attributes need  the {@ @} signs and should not haveside-effects.   Actions need {: :} signs and should contain onlyside-effects, and cannot make attributes..PP.SH USAGE.I Preccxgrammar description files conventionally have the .\fIy\fP suffix, andshould follow the following format:.IP# define TOKEN ... (default = char).IP# define VALUE ... (default = char*).IP# define BEGIN ... (default nothing).IP# define END\0\0 ... (default nothing).IP# define ON_ERROR(x) ... (defaults to standard).IP# include "cc.h"  (or ccx.h).IP @ first\0definition : attached action; :.IP @ ....IP @ ....IPMAIN(name of entry parser).PPThe cc.h header file may be used instead of ccx.h in scripts whichconsist only of unparameterized definitions and terms..SH EXAMPLEThe following script defines a simple +/- calculator in the version2.41 language, using parameters. For scripts that work with earlierversions of the language, see earlier versions of the manual.  Somenotes on differences appear afterward..IP# define TOKEN char.IP# define VALUE int.IP# define BEGIN printf("\\nready> ");.IP#\0include\0"ccx.h".IP#\0include\0<ctype.h>.IP @\0digit\0=\0(isdigit)\\x\0\0\0\0{@ $x-'0' @}.IP @\0posint(t)=\0digit\\x\0posint(10*t+$x).IP @\0\0\0\0\0\0\0|\0digit\\x\0\0\0\0\0\0\0\0\0\0\0\0{@ 10*t+$x @}.IP @\0posint0=\0posint(0).IP @\0anyint=\0<'-'>\0posint0\\x\0\0\0\0{@ -$x @}.IP @\0\0\0\0\0\0\0|\0posint(0).IP @\0atom\0\0=\0<'('>\0expr\\x\0<')'>\0{@ $x @}.IP @\0\0\0\0\0\0\0|\0int.IP @\0expr\0\0=\0atom\\x\0sign_sum\\y\0\0{@ $x+$y @}.IP @\0\0\0\0\0\0\0|\0atom.IP @\0sign_sum=\0<'-'>\0atom\\x\0sign_sum\\y.IP @\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0{@ -$x+$y @}.IP @\0\0\0\0\0\0\0\0\0|\0<'-'>\0atom\\x\0\0\0\0\0{@ -$x @}.IP @\0\0\0\0\0\0\0\0\0|\0<'+'>\0atom\\x\0sign_sum\\y.IP @\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0{@ $x+$y @}.IP @\0\0\0\0\0\0\0\0\0|\0<'+'>\0atom\\x\0\0\0\0\0{@ $x @}.IP @\0top\0\0\0\0\0=\0expr\\x\0\0\0\0\0\0\0\0\0\0\0{: printf("=%d\\n",$x); :}.IPMAIN(expr).PPThis script must be passed through \fIpreccx\fP:.IPpreccx\0<\0calculator.y\0>\0calculator.c.PPand then compiled, using the \fIpreccx\fP kernel library in libcc.a:.IPgcc\0\-Wall\0\-ansi\0\-o\0calculator\0calculator.c\0\-L\0...\0\-lcc.PPThe three dots stand for the directory in which the preccx library file

⌨️ 快捷键说明

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