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

📄 ss2

📁 UNIX v6源代码 这几乎是最经典的unix版本 unix操作系统设计和莱昂氏unix源代码分析都是用的该版
💻
字号:
.SHSection 2: Actions.PPTo each grammar rule, the user may associate an action to be performed each timethe rule is recognized in the input process.This action may return a value, and may obtain the values returned by previousactions in the grammar rule.In addition, the lexical analyzer can return valuesfor tokens, if desired..PPWhen invoking Yacc, the user specifies a programming language; currently, Ratfor and C are supported.An action is an arbitrary statement in this language, and as such can doinput and output, call subprograms, and alterexternal vectors and variables (recall that a ``statement'' in both C and Ratfor can be compoundand do many distinct tasks).An action is specified by an equal sign ``=''at the end of a grammar rule, followed byone or more statements, enclosed in curly braces ``{'' and ``}''.For example,.DSA: \'(\' B \')\' = { hello( 1, "abc" );  }.DEand.DSXXX: YYY ZZZ =	{		printf("a message\en");		flag = 25;	}.DEare grammar rules with actions in C.A grammar rule with an action need not end with a semicolon; in fact, it is an error to have a semicolonbefore the equal sign..PPTo facilitate easy communication between the actions and the parser, the action statements are alteredslightly.The symbol ``dollar sign'' ``$'' is used as a signal to Yacc in this context..PPTo return a value, the action normally sets thepseudo-variable ``$$'' to some integer value.For example, an action which does nothing but return the value 1 is.DS= { $$ = 1; }.DE.PPTo obtain the values returned by previous actions and the lexical analyzer, theaction may use the (integer) pseudo-variables $1, $2, . . .,which refer to the values returned by thecomponents of the right side of a rule, reading from left to right.Thus, if the rule is.DSA: B C D ;.DEfor example, then $2 has the value returned by C, and $3 the value returned by D..PPAs a more concrete example, we might have the rule.DSexpression: \'(\' expression \')\' ;.DEWe wish the value returned by this rule to be the value of the expression in parentheses.Then we write.DSexpression: \'(\' expression \')\'    = { $$ = $2 ; }.DE.PPAs a default, the value of a rule is the value of the first element in it ($1).This is true even if there is no explicit action given for the rule.Thus, grammar rules of the form.DSA: B ;.DEfrequently need not have an explict action..PPNotice that, although the values of actions are integers, these integers may in factcontain pointers (in C) or indices into an array (in Ratfor); in this way,actions can return and reference more complex data structures..PPSometimes, we wish to get control before a rule is fully parsed, as well as at theend of the rule.There is no explicit mechanism in Yacc to allow this; the same effect can be obtained, however,by introducing a new symbol which matches the empty string, and inserting an action for this symbol.For example, we might have a rule describing an ``if'' statement:.DSstatement: IF \'(\' expr \')\' THEN statement.DESuppose that we wish to get control after seeing the right parenthesisin order to output some code.We might accomplish this by the rules:.DSstatement:  IF \'(\' expr \')\' actn THEN statement 	= { call action1 }actn:   /* matches the empty string */	= { call action2 }.DE.PPThus, the new nonterminal symbol actn matches no input, but serves only to call action2 after theright parenthesis is seen..PPFrequently, it is more natural in such cases to break the rule intoparts where the action is needed.Thus, the above example might also have been written.DSstatement:  ifpart THEN statement	= { call action1 }ifpart:      IF \'(\' expr \')\'	= { call action2 }.DE.PPIn many applications, output is not done directly by the actions;rather, a data structure, such as a parse tree, is constructed in memory,and transformations are applied to it before output is generated.Parse trees are particularly easy toconstruct, given routines which build and maintain the treestructure desired.For example, suppose we have a C function``node'', written so that the call.DSnode( L, n1, n2 ).DEcreates a node with label L, and descendants n1 and n2, and returns a pointerto the newly created node.Then we can cause a parse tree to be built by supplying actions such as:.DSexpr: expr \'+\' expr 	= { $$ = node( \'+\', $1, $3 ); }.DEin our specification..PPThe user may define other variables to be used by the actions.Declarations and definitions can appear in two places in theYacc specification: in the declarations section, and at the head of the rules sections, before thefirst grammar rule.In each case, the declarations and definitions are enclosed in the marks ``%{'' and ``%}''.Declarations and definitions placed in the declarations section have global scope, and are thus known to the action statements and the lexical analyzer.Declarations and definitions placed at the head of the rules section have scope local tothe action statements.Thus, in the above example, we might have included.DS%{ int variable 0; %}.DEin the declarations section, or, perhaps,.DS%{ static int variable; %}.DEat the head of the rules section.If we were writing Ratfor actions, we might want to include someCOMMON statements at the beginning of the rules section, to allow foreasy communication between the actions and other routines.For both C and Ratfor, Yacc has used only external names beginning in ``yy'';the user should avoid such names.

⌨️ 快捷键说明

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