📄 readme
字号:
takes over. The problem with this is that error recoveryis started in the same state context that exists on thelast surveyed branch of the conflict tree. Sometimes thislast branch may be of zero length and it results inrecovering to exactly the same state as existed beforeentering the conflict. BtYacc cycles then.We solved this problem by memorizing the longest path inthe conflict tree while browsing it. If we ever get intoerror recovery, we restore state that existed on thelongest path. Effectively we say: if we have an error,let us move forward as far as we possibly could while wewere browsing the conflict tree.** Introduce YYVALID_NESTED operation in addition tosimply YYVALID. When we have a nested conflict (conflictwhile processing in trial mode for another conflict), wewant to relate YYVALID to a particular level of conflictbeing in trial.Since we mostly anticipate only 2-level nested conflictsYYVALID_NESTED tells the parser to satisfy only theinternal conflict. Therefore, in 1-level conflictsituation YYVALID_NESTED acts like a regular YYVALID, butin 2-level conflict it is a no-op and the other YYVALIDfor outer conflict will be searched for.** Improved handling of situation where /tmp directory ismissing. Original btyacc just died quietly when /tmpdirectory was missing. We added code that states theproblem explicitly. While on UNIX /tmp directory is alwayspresent, it may be missing on WIN32 systems, thereforediagnosing this situation is important. Version 1.0 changes: BackTracking ================================= by Chris DoddBTYACC is a modified version of yacc that supportsautomatic backtracking and semantic disambiguation toparse ambiguous grammars, as well as syntactic sugar forinherited attributes (which tend to introduce conflicts).Whenever a btyacc generated parser runs into ashift-reduce or reduce-reduce error in the parse table, itremembers the current parse point (yacc stack and inputstream state), and goes into trial parse mode. It thencontinues parsing, ignoring most rule actions. If it runsinto an error (either through the parse table or throughan action calling YYERROR), it backtracks to the mostrecent conflict point and tries a different alternative.If it finds a successful parse (reaches the end of theinput or an action calls YYVALID), it backtracks to thepoint where it first entered trial parse mode, andcontinues with a full parse (executing all actions),following the path of the successful trial.Actions in btyacc come in two flavors -- {}-actions, whichare only executed when not in trial mode, and []-actionswhich are executed regardless of mode. There are alsoinherited attributes, which look like arguments (they areenclosed in "()") and act like []-actions.What this buys you:* No more lexer feedback hack. In yacc grammars for C, astandard hack, know as the "lexer feedback hack" is usedto find typedef names. The lexer uses semanticinformation to decide if any given identifier is atypedef-name or not and returns a special token. Withbtyacc, you no longer need to do this; the lexer shouldjust always return an identifier. The btyacc grammar thenneeds a rule of the form:typename: ID [ if (!IsTypeName(LookupId($1))) YYERROR; ]While the hack works adequately well for parsing C, itbecomes a nightmare when you try to parse something likeC++, where treating an ID as a typedef becomes heavilydependent on context.* Easy disambiguation via simple ordering. Btyacc runsits trials via the rule "try shifting first, then tryreducing by the order that the conflicting rules appear inthe input file". This means you can deal with semantic adisambiguation rule like: [1] If it looks like a declaration it is, otherwise [2] If it looks like an expression it is, otherwise [3] it is a syntax error [Ellis&Stroustrup, Annotated C++ Reference Manual, p93]To deal with this, you need only put all the rules fordeclarations before the rules for expressions in thegrammar file.* No extra cost if you do not use it. Backtracking isonly triggered when the parse hits a shift/reduce orreduce/reduce conflict in the table. If you have noconflicts in your grammar, there is no extra cost, otherthan some extra code which will never be invoked.* C++ and ANSI C compatible parsers. The parsers producedby btyacc can be compiled with C++ correctly. If you"#define" YYSTYPE to be some C++ type with constructor anddestructor, everything will work fine. My favorite is"#define YYSTYPE SmartPointer", where SmartPointer is asmart pointer type that does garbage collection on thepointed to objects.BTYACC was originally written to make it easy to write aC++ parser (my goal was to be able to use the grammar outof the back of the ARM with as few modifications aspossible). Anyone who has ever looked at Jim Roskindpublic domain C++ yacc grammar, or the yacc-based grammarused in g++ knows how difficult this is. BTYACC is veryuseful for parsing any ambiguous grammar, particularlyones that come from trying to merge two (or more) completegrammars.Limitations of the backtracking: Currently, the generatedparser does NO pruning of alternate parsing paths. Toavoid an exponential explosion of possible paths (andparsing time), you need to manually tell the parser whenit can throw away saved paths using YYVALID. In practice,this turns out to be fairly easy to do. A C++ parser (forexample) can just put a [YYVALID;] after every completedeclaration and statement rule, corresponding to pruningthe backtracking state after seeing a ';' or '}' -- therewill never be a situation in which it is useful tobacktrack past either of these.Inherited attributes in btyacc:Inherited attributes look a lot like function arguments tonon-terminals, which is what they end up being in arecursive descent parser, but NOT how they are implementedin btyacc. Basically they are just syntactic sugar forembedded semantic actions and $0, $-1, ... in normal yacc.btyacc gives you two big advantages besides just thesyntax: 1. it does type checking on the inherited attributes, so you do not have to specify $<type>0 and makes sure you give the correct number of arguments (inherited attributes) to every use of a non-terminal. 2. It "collapses" identical actions from that are produced from inherited attributes. This eliminates many potential reduce-reduce conflicts arising from the inherited attributes.You use inherited attributes by declaring the types of theattributes in the preamble with a type declaration anddeclaring names of the attributes on the lhs of the yaccrule. You can of course have more than one rule with thesame lhs, and you can even give them different names ineach, but the type and number must be the same.Here is a small example: /* lhs takes 2 inherited attributes */%type <t1> lhs(<t1>, <t2>) stuff(<t1>, <t2>)%%lhs($i1, $i2) : { $$ = $i1 } | lhs($i1, $i2) stuff($1,$i2) { $$ = $2; }This is roughly equivalent to the following yacc code:lhs : { $$ = $<t1>-1; } | lhs [ $<t1>$ = $-1; ] [ $<t2>$ = $<t2>0; ] stuff { $$ = $4; } ;See the file "test/t2.y" for a longer and more completeexample. At the current time, the start symbol cannothave any arguments.Variant parsers:Btyacc supports the -S flag to use a different parserskeleton, changing the way that the parser is called andused. The skeleton "push.skel" is included to produce a"passive" parser that you feed tokens to (rather thanhaving the parser call a separate yylex routine). Withpush.skel, yyparse is defined as follows:int yyparse(int token, YYSTYPE yylval)You should call yyparse repeatedly with successive tokensof input. It returns 0 if more input is needed, 1 for asuccessful parse, and -1 for an unrecoverable parse error. Miscellaneous Features in ver. 1.0 ---------------------------------- by Chris Dodd The -r option has been implemented. The -r option tellsYacc to put the read-only tables in y.tab.c and the code andvariables in y.code.c. Keith Bostic asked for this option sothat :yyfix could be eliminated. The -l and -t options have been implemented. The -loption tells Yacc not to include #line directives in the codeit produces. The -t option causes debugging code to beincluded in the compiled parser. The code for error recovery has been changed toimplement the same algorithm as AT&T Yacc. There will stillbe differences in the way error recovery works because AT&TYacc uses more default reductions than Berkeley Yacc. The environment variable TMPDIR determines the directorywhere temporary files will be created. If TMPDIR is defined,temporary files will be created in the directory whosepathname is the value of TMPDIR. By default, temporary filesare created in /tmp. The keywords are now case-insensitive. For example,%nonassoc, %NONASSOC, %NonAssoc, and %nOnAsSoC are all equivalent. Commas and semicolons that are not part of C code aretreated as commentary. Line-end comments, as in BCPL, are permitted. Line-endcomments begin with // and end at the next end-of-line.Line-end comments are permitted in C code; they are convertedto C comments on output. The form of y.output files has been changed to look morelike those produced by AT&T Yacc. A new kind of declaration has been added. The form of the declaration is %ident stringwhere string is a sequence of characters beginning with adouble quote and ending with either a double quote or thenext end-of-line, whichever comes first. The declarationwill cause a #ident directive to be written near the start of the output file. If a parser has been compiled with debugging code, thatcode can be enabled by setting an environment variable. If the environment variable YYDEBUG is set to 0, debuggingoutput is suppressed. If it is set to 1, debugging output is written to standard output. Building BtYacc --------------- by Chris Dodd and Vadim MaslovWe used GCC and GNU make to compile BtYacc both on UNIX andWIN32 paltforms. You are welcome to try differentcombinations of makes and compilers. Most likely it willwork, but it may require Makefile changes.There is no config script.Just type "make" and it should compile.AWK. If you want to change file btyaccpa.ske (backtracking parser skeleton), you will need awk to compile it into skeleton.c file. We used GNU AWK (gawk) version 3.0.It is known that using older versions of gawkmay create problems in compilation, because older awks have problems with backslashes at the end of a line.For MSDOS, there a "makefile.dos" that should do the trick.Note: makefile.dos was not tested for a long time.The result of compilation should be a single executable called"btyacc" which you can install anywhere you like; it does not require any other files in the distribution to run. Legal Stuff ----------- by Chris Dodd and Vadim MaslovIn English: BtYacc is freeware. BtYacc is distributed with no warranty whatsoever. The author and any other contributors take no responsibility for any and all consequences of its use.In Legalese: LIMITATION OF LIABILITY. NEITHER SIBER SYSTEMSNOR ANY OF ITS LICENSORS NOR ANY BTYACC CONTRIBUTOR SHALL BELIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIALDAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE, DATA ORDATA USE, CAUSED BY BTYACC AND INCURRED BY CUSTOMER OR ANYTHIRD PARTY, WHETHER IN AN ACTION IN CONTRACT OR TORT, EVENIF SIBER SYSTEMS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCHDAMAGES.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -