mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:03:02 +01:00
Added btyacc sources.
This commit is contained in:
parent
7e064ef34e
commit
8332c5ed52
100
extern/btyacc/Makefile
vendored
Normal file
100
extern/btyacc/Makefile
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
#
|
||||
# Makefile for BtYacc.
|
||||
#
|
||||
|
||||
VERSION = 3-0
|
||||
|
||||
DEST = .
|
||||
|
||||
HDRS = defs.h mstring.h
|
||||
|
||||
CFLAGS = -g -Wall -Wstrict-prototypes -Wmissing-prototypes
|
||||
|
||||
#LDFLAGS = -static
|
||||
|
||||
LIBS =
|
||||
|
||||
CC = gcc
|
||||
LINKER = gcc
|
||||
# LINKER = cl
|
||||
# CC = cl
|
||||
|
||||
MAKEFILE = Makefile
|
||||
|
||||
OBJS = closure.o error.o lalr.o lr0.o main.o mkpar.o output.o \
|
||||
mstring.o reader.o readskel.o skeleton.o symtab.o verbose.o warshall.o
|
||||
|
||||
PRINT = pr -f -l88
|
||||
|
||||
PROGRAM = btyacc
|
||||
|
||||
SRCS = closure.c error.c lalr.c lr0.c main.c mkpar.c output.c \
|
||||
mstring.c reader.c readskel.c skeleton.c symtab.c verbose.c warshall.c
|
||||
|
||||
OTHERS = README README.BYACC \
|
||||
Makefile btyaccpa.ske push.skel empty.y skel2c manpage makefile.dos \
|
||||
skeleton.c
|
||||
|
||||
all: $(PROGRAM)
|
||||
|
||||
$(PROGRAM): $(OBJS) $(LIBS)
|
||||
$(LINKER) $(LDFLAGS) -o $(PROGRAM) $(OBJS) $(LIBS)
|
||||
|
||||
clean:; rm -f $(OBJS)
|
||||
|
||||
clobber:; rm -f $(OBJS) $(PROGRAM)
|
||||
|
||||
distclean:; rm -f $(OBJS) $(PROGRAM) skeleton.c *.zip *.gz
|
||||
|
||||
depend:; mkmf -f $(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST)
|
||||
|
||||
index:; ctags -wx $(HDRS) $(SRCS)
|
||||
|
||||
install: $(PROGRAM)
|
||||
cp $(PROGRAM).exe /bin
|
||||
|
||||
oldinstall: $(PROGRAM)
|
||||
@echo Installing $(PROGRAM) in $(DEST)
|
||||
install -s $(PROGRAM) $(DEST)
|
||||
|
||||
listing:; $(PRINT) Makefile $(HDRS) $(SRCS) | lpr
|
||||
|
||||
lint:; lint $(SRCS)
|
||||
|
||||
program: $(PROGRAM)
|
||||
|
||||
tags: $(HDRS) $(SRCS)
|
||||
ctags $(HDRS) $(SRCS)
|
||||
|
||||
dist: tar zip
|
||||
|
||||
tar:
|
||||
rm -f btyacc.tar btyacc.tar.gz
|
||||
tar cvf btyacc.tar $(OTHERS) $(SRCS) $(HDRS) test/*.y
|
||||
gzip -9 btyacc.tar
|
||||
mv btyacc.tar.gz btyacc-$(VERSION).tar.gz
|
||||
|
||||
zip:
|
||||
zip btyacc.zip $(OTHERS) $(SRCS) $(HDRS) test/*.y
|
||||
mv btyacc.zip btyacc-$(VERSION).zip
|
||||
|
||||
skeleton.c: btyaccpa.ske skel2c
|
||||
awk -f skel2c btyaccpa.ske >skeleton.c
|
||||
|
||||
etags TAGS:
|
||||
etags *.c *.h
|
||||
|
||||
###
|
||||
closure.o: defs.h
|
||||
error.o: defs.h
|
||||
lalr.o: defs.h
|
||||
lr0.o: defs.h
|
||||
main.o: defs.h
|
||||
mkpar.o: defs.h
|
||||
mstring.o: mstring.h
|
||||
output.o: defs.h
|
||||
reader.o: defs.h mstring.h
|
||||
skeleton.o: defs.h
|
||||
symtab.o: defs.h
|
||||
verbose.o: defs.h
|
||||
warshall.o: defs.h
|
592
extern/btyacc/README
vendored
Normal file
592
extern/btyacc/README
vendored
Normal file
@ -0,0 +1,592 @@
|
||||
BTYACC -- backtracking yacc
|
||||
===========================
|
||||
|
||||
BTYACC was created by Chris Dodd using ideas from many
|
||||
places and lots of code from the Berkeley Yacc
|
||||
distribution, which is a public domain yacc clone put
|
||||
together by the good folks at Berkeley. This code is
|
||||
distributed with NO WARRANTEE and is public domain.
|
||||
It is certain to contain bugs, which you should
|
||||
report to: chrisd@collins.com.
|
||||
|
||||
Vadim Maslov of Siber Systems <vadik@siber.com>
|
||||
considerably modified BTYACC to make it suitable
|
||||
for production environment.
|
||||
|
||||
Several people have suggested bug fixes that
|
||||
were incorporated into BtYacc.
|
||||
|
||||
See the README.BYACC files for more about
|
||||
Berkeley Yacc and other sources of info.
|
||||
|
||||
http://www.siber.com/btyacc/ is the current home of BtYacc.
|
||||
It is provided courtesy of Siber Systems http://www.siber.com/.
|
||||
|
||||
|
||||
Version 3.0 changes
|
||||
-------------------
|
||||
by Vadim Maslov
|
||||
|
||||
Changes mostly occurred in btyaccpa.ske file that
|
||||
contains the parsing shift/reduce/backtrack algorithm.
|
||||
|
||||
Version 3.0 innovations focus on:
|
||||
- text position computation and propagation,
|
||||
- industrial-strength error processing and recovery.
|
||||
|
||||
|
||||
** Added mechanism for computing and propagating
|
||||
text position of tokens and non-terminals.
|
||||
|
||||
Compilers often need to build AST trees such that every node
|
||||
in a tree can relate to the parsed program source it came from.
|
||||
The following applications are very likely to need this:
|
||||
- debuggers that show actual source of the debugged program,
|
||||
- source-to-source translators that want
|
||||
unchanged parts of the tree to generate the unchanged code.
|
||||
|
||||
The new YYPOSN mechanism added in this version of BtYacc
|
||||
helps you in automating the text position computation
|
||||
and in assigning the computed text positions to the AST.
|
||||
This mechanism is successfully used in commercial
|
||||
parsers and source-to-source translators.
|
||||
|
||||
In standard Yaccs every token and every non-terminal
|
||||
has an YYSTYPE semantic value attached to it.
|
||||
In this new version every token and every non-terminal
|
||||
also has an YYPOSN text position attached to it.
|
||||
YYPOSN is a user-defined type that can be anything and
|
||||
that has a meaning of text position attached to
|
||||
token or non-terminal.
|
||||
|
||||
In addition to semantic value stack BtYacc now maintains
|
||||
text position stack. Behavior of the text position stack
|
||||
is similar to the behavior of the semantic value stack.
|
||||
|
||||
If using text position mechanism,
|
||||
you need to define the following:
|
||||
|
||||
YYPOSN Preprocessor variable that contains C/C++ type of
|
||||
the text position attached to
|
||||
every token and non-terminal.
|
||||
|
||||
yyposn Global variable of type YYPOSN.
|
||||
The lexer must assign text position of
|
||||
the returned token to yyposn, just like it assigns
|
||||
semantic value of the returned token to yylval.
|
||||
|
||||
YYREDUCEPOSNFUNC
|
||||
Preprocessor variable that points to unction that
|
||||
is called after the grammar rule reduction
|
||||
to reduce text positions located on the stack.
|
||||
|
||||
This function is called by BtYacc to reduce text
|
||||
positions. The function is called immediately after
|
||||
the regular rule reduction occurs.
|
||||
|
||||
The function has the following prototype:
|
||||
void ReducePosn(YYPOSN &ret,
|
||||
YYPOSN *terms,
|
||||
YYSTYPE *term_vals,
|
||||
int term_no,
|
||||
int stk_pos,
|
||||
int yychar,
|
||||
YYPOSN &yyposn,
|
||||
UserType extra);
|
||||
|
||||
The function arguments are:
|
||||
- ret
|
||||
Reference to the text position returned by
|
||||
the rule. The function must write the computed
|
||||
text position returned by the rule to ret.
|
||||
This is analogue of the $$ semantic value.
|
||||
|
||||
- term_posns
|
||||
Array of the right-hand side rule components
|
||||
YYPOSN text positions. These are analogues of
|
||||
$1, $2, ..., $N in the text position world.
|
||||
|
||||
- term_vals
|
||||
Array of the right-hand side (RHS) rule components
|
||||
YYSTYPE values. These are the $1,...,$N themselves.
|
||||
|
||||
- term_no
|
||||
Number of the components in RHS of the reduced rule.
|
||||
Equal to size of arrays term_posns and term_vals.
|
||||
Also equal to N in $1,...,$N in the reduced rule.
|
||||
|
||||
- stk_pos
|
||||
YYSTYPE/YYPOSN stack position before the reduction.
|
||||
|
||||
- yychar
|
||||
Lookahead token that immediately follows
|
||||
the reduced RHS components.
|
||||
|
||||
- yyposn
|
||||
YYPOSN of the token that immediately follows
|
||||
the reduced RHS components.
|
||||
|
||||
- extra
|
||||
User-defined extra argument passed to ReducePosn.
|
||||
|
||||
Typically this function extracts text positions from
|
||||
the right-hand side rule components and either
|
||||
assigns them to the returned $$ structure/tree or
|
||||
if no $$ value is returned, puts them into
|
||||
the ret text position from where
|
||||
it will be picked up by the later reduced rules.
|
||||
|
||||
YYREDUCEPOSNFUNCARG
|
||||
Extra user-defined argument passed to
|
||||
the ReducePosn function. This argument can use
|
||||
any variables defined in btyaccpa.ske.
|
||||
|
||||
|
||||
** Added code to btyaccpa.ske that automatically cleans up
|
||||
semantic semantic values and text positions of tokens
|
||||
and non-terminals that are discarded and deleted as
|
||||
a result of error processing.
|
||||
|
||||
In the previous versions the discarded token and non-terminal
|
||||
semantic values were not cleaned that caused quite severe
|
||||
leaks. The only way to fix it was to add garbage collection
|
||||
to YYSTYPE class.
|
||||
|
||||
Now BtYacc skeleton calls delete functions for semantic
|
||||
values and positions of the discarded tokens and
|
||||
non-terminals.
|
||||
|
||||
You need to define the following functions that BtYacc
|
||||
calls when it needs to delete semantic value or text position.
|
||||
|
||||
YYDELETEVAL
|
||||
User-defined function that is called by BtYacc
|
||||
to delete semantic value of the token or non-terminal.
|
||||
|
||||
The user-defined function must have the prototype:
|
||||
void DeleteYYval(YYSTYPE v, int type);
|
||||
v is semantic value to delete,
|
||||
type is one of the following:
|
||||
0 discarding token
|
||||
1 discarding state
|
||||
2 cleaning up stack when aborting
|
||||
|
||||
YYDELETEPOSN
|
||||
User-defined function that is called by BtYacc
|
||||
to delete text position of the token or non-terminal.
|
||||
|
||||
The user-defined function must have the prototype:
|
||||
void DeleteYYposn(YYPOSN p, int type);
|
||||
v is semantic value to delete,
|
||||
type is one of the following:
|
||||
0 discarding token
|
||||
1 discarding state
|
||||
2 cleaning up stack when aborting
|
||||
|
||||
|
||||
** User can define "detailed" syntax error processing
|
||||
function that reports an *exact* position of
|
||||
the token that caused the error.
|
||||
|
||||
If you define preprocessor variable YYERROR_DETAILED in
|
||||
your grammar then you need define the following
|
||||
error processing function:
|
||||
|
||||
void yyerror_detailed(char *text,
|
||||
int errt,
|
||||
YYSTYPE &errt_value,
|
||||
YYPOSN &errt_posn);
|
||||
|
||||
It receives the following arguments:
|
||||
text Error message.
|
||||
errt Code of the token that caused the error.
|
||||
errt_value Value of the token that caused the error.
|
||||
errt_posn Text position of token that caused error.
|
||||
|
||||
|
||||
** Dropped compatibility with C.
|
||||
|
||||
Compatibility with C became increasingly difficult
|
||||
to maintain as new features were added to btyaccpa.ske.
|
||||
So we dropped it. If anybody wants to make the new version
|
||||
compatible with C, we would gladly accept the changes.
|
||||
|
||||
Meanwhile we expect that you use C++ to write grammar
|
||||
actions and everything else in grammar files.
|
||||
Since C is (in a sense) subset of C++, your C-based
|
||||
grammar may work if you use C++ compiler to compile it.
|
||||
|
||||
Version 3.0 bugs fixed
|
||||
----------------------
|
||||
|
||||
Matthias Meixner <meixner@mes.th-darmstadt.de> fixed a bug:
|
||||
BtYacc does not correctly handle typenames, if one typename
|
||||
is a prefix of another one and if this type is used after
|
||||
the longer one. In this case BTYacc produces invalid code.
|
||||
|
||||
|
||||
Version 2.1 changes
|
||||
-------------------
|
||||
by Vadim Maslov
|
||||
|
||||
** Added preprocessor statements to BtYacc that are similar
|
||||
in function and behavior to C/C++ preprocessor statements.
|
||||
|
||||
These statements are used to:
|
||||
|
||||
- Introduce modularity into a grammar by breaking it
|
||||
into several *.y files and assembling different
|
||||
grammars from the *.y modules using %include and %ifdef.
|
||||
|
||||
- Have several versions of the same grammar
|
||||
by using %ifdef and $endif.
|
||||
|
||||
- To include automatically generated grammar fragment.
|
||||
For instance, we use %include to include
|
||||
automatically generated list of tokens.
|
||||
|
||||
Preprocessor statements are:
|
||||
|
||||
%define <var-name>
|
||||
Define preprocessor variable named <var-name>.
|
||||
|
||||
%ifdef <var-name>
|
||||
If preprocessor variable named <var-name>
|
||||
is defined by %define, then process the text from
|
||||
this %ifdef to the closing %endif.
|
||||
|
||||
%endif
|
||||
Closing bracket for %ifdef preprocessor statement.
|
||||
Only one nesting level of %ifdef-%endif is allowed.
|
||||
|
||||
%include <file-name>
|
||||
Process contents of the file named <file-name>.
|
||||
If <file-name> is a relative name, it is looked up
|
||||
in a directory in which btyacc was started.
|
||||
Only one nesting level of %include is allowed.
|
||||
|
||||
|
||||
Version 2.0 changes
|
||||
-------------------
|
||||
by Vadim Maslov
|
||||
|
||||
|
||||
** Changed 16-bit short numbers to 32-bit int numbers in
|
||||
grammar tables, so that huge grammar tables (tables that
|
||||
are larger than 32768 elements) resulting from huge
|
||||
grammars (Cobol grammar, for instance) can work correctly.
|
||||
You need to have 32-bit integer to index table bigger than
|
||||
32768 elements, 16-bit integer is not enough.
|
||||
|
||||
The original BtYacc just generated non-working tables
|
||||
larger than 32768 elements without even notifying about
|
||||
the table overflow.
|
||||
|
||||
|
||||
** Make error recovery work correctly when error happens
|
||||
while processing nested conflicts. Original BtYacc could
|
||||
infinitely cycle in certain situations that involved error
|
||||
recovery while in nested conflict.
|
||||
|
||||
More detailed explanation: when we have nested conflicts
|
||||
(conflict that happens while trial-processing another
|
||||
conflict), it leads btyacc into NP-complete searching of
|
||||
conflict tree. The ultimate goal is YYVALID operator that
|
||||
selects a particular branch of that tree as a valid one.
|
||||
|
||||
If no YYVALID is found on the tree, then error recovery
|
||||
takes over. The problem with this is that error recovery
|
||||
is started in the same state context that exists on the
|
||||
last surveyed branch of the conflict tree. Sometimes this
|
||||
last branch may be of zero length and it results in
|
||||
recovering to exactly the same state as existed before
|
||||
entering the conflict. BtYacc cycles then.
|
||||
|
||||
We solved this problem by memorizing the longest path in
|
||||
the conflict tree while browsing it. If we ever get into
|
||||
error recovery, we restore state that existed on the
|
||||
longest path. Effectively we say: if we have an error,
|
||||
let us move forward as far as we possibly could while we
|
||||
were browsing the conflict tree.
|
||||
|
||||
|
||||
** Introduce YYVALID_NESTED operation in addition to
|
||||
simply YYVALID. When we have a nested conflict (conflict
|
||||
while processing in trial mode for another conflict), we
|
||||
want to relate YYVALID to a particular level of conflict
|
||||
being in trial.
|
||||
|
||||
Since we mostly anticipate only 2-level nested conflicts
|
||||
YYVALID_NESTED tells the parser to satisfy only the
|
||||
internal conflict. Therefore, in 1-level conflict
|
||||
situation YYVALID_NESTED acts like a regular YYVALID, but
|
||||
in 2-level conflict it is a no-op and the other YYVALID
|
||||
for outer conflict will be searched for.
|
||||
|
||||
|
||||
** Improved handling of situation where /tmp directory is
|
||||
missing. Original btyacc just died quietly when /tmp
|
||||
directory was missing. We added code that states the
|
||||
problem explicitly. While on UNIX /tmp directory is always
|
||||
present, it may be missing on WIN32 systems, therefore
|
||||
diagnosing this situation is important.
|
||||
|
||||
|
||||
Version 1.0 changes: BackTracking
|
||||
=================================
|
||||
by Chris Dodd
|
||||
|
||||
BTYACC is a modified version of yacc that supports
|
||||
automatic backtracking and semantic disambiguation to
|
||||
parse ambiguous grammars, as well as syntactic sugar for
|
||||
inherited attributes (which tend to introduce conflicts).
|
||||
Whenever a btyacc generated parser runs into a
|
||||
shift-reduce or reduce-reduce error in the parse table, it
|
||||
remembers the current parse point (yacc stack and input
|
||||
stream state), and goes into trial parse mode. It then
|
||||
continues parsing, ignoring most rule actions. If it runs
|
||||
into an error (either through the parse table or through
|
||||
an action calling YYERROR), it backtracks to the most
|
||||
recent conflict point and tries a different alternative.
|
||||
If it finds a successful parse (reaches the end of the
|
||||
input or an action calls YYVALID), it backtracks to the
|
||||
point where it first entered trial parse mode, and
|
||||
continues with a full parse (executing all actions),
|
||||
following the path of the successful trial.
|
||||
|
||||
Actions in btyacc come in two flavors -- {}-actions, which
|
||||
are only executed when not in trial mode, and []-actions
|
||||
which are executed regardless of mode. There are also
|
||||
inherited attributes, which look like arguments (they are
|
||||
enclosed in "()") and act like []-actions.
|
||||
|
||||
What this buys you:
|
||||
|
||||
* No more lexer feedback hack. In yacc grammars for C, a
|
||||
standard hack, know as the "lexer feedback hack" is used
|
||||
to find typedef names. The lexer uses semantic
|
||||
information to decide if any given identifier is a
|
||||
typedef-name or not and returns a special token. With
|
||||
btyacc, you no longer need to do this; the lexer should
|
||||
just always return an identifier. The btyacc grammar then
|
||||
needs a rule of the form:
|
||||
|
||||
typename: ID [ if (!IsTypeName(LookupId($1))) YYERROR; ]
|
||||
|
||||
While the hack works adequately well for parsing C, it
|
||||
becomes a nightmare when you try to parse something like
|
||||
C++, where treating an ID as a typedef becomes heavily
|
||||
dependent on context.
|
||||
|
||||
* Easy disambiguation via simple ordering. Btyacc runs
|
||||
its trials via the rule "try shifting first, then try
|
||||
reducing by the order that the conflicting rules appear in
|
||||
the input file". This means you can deal with semantic a
|
||||
disambiguation 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 for
|
||||
declarations before the rules for expressions in the
|
||||
grammar file.
|
||||
|
||||
* No extra cost if you do not use it. Backtracking is
|
||||
only triggered when the parse hits a shift/reduce or
|
||||
reduce/reduce conflict in the table. If you have no
|
||||
conflicts in your grammar, there is no extra cost, other
|
||||
than some extra code which will never be invoked.
|
||||
|
||||
* C++ and ANSI C compatible parsers. The parsers produced
|
||||
by btyacc can be compiled with C++ correctly. If you
|
||||
"#define" YYSTYPE to be some C++ type with constructor and
|
||||
destructor, everything will work fine. My favorite is
|
||||
"#define YYSTYPE SmartPointer", where SmartPointer is a
|
||||
smart pointer type that does garbage collection on the
|
||||
pointed to objects.
|
||||
|
||||
BTYACC was originally written to make it easy to write a
|
||||
C++ parser (my goal was to be able to use the grammar out
|
||||
of the back of the ARM with as few modifications as
|
||||
possible). Anyone who has ever looked at Jim Roskind
|
||||
public domain C++ yacc grammar, or the yacc-based grammar
|
||||
used in g++ knows how difficult this is. BTYACC is very
|
||||
useful for parsing any ambiguous grammar, particularly
|
||||
ones that come from trying to merge two (or more) complete
|
||||
grammars.
|
||||
|
||||
Limitations of the backtracking: Currently, the generated
|
||||
parser does NO pruning of alternate parsing paths. To
|
||||
avoid an exponential explosion of possible paths (and
|
||||
parsing time), you need to manually tell the parser when
|
||||
it can throw away saved paths using YYVALID. In practice,
|
||||
this turns out to be fairly easy to do. A C++ parser (for
|
||||
example) can just put a [YYVALID;] after every complete
|
||||
declaration and statement rule, corresponding to pruning
|
||||
the backtracking state after seeing a ';' or '}' -- there
|
||||
will never be a situation in which it is useful to
|
||||
backtrack past either of these.
|
||||
|
||||
Inherited attributes in btyacc:
|
||||
|
||||
Inherited attributes look a lot like function arguments to
|
||||
non-terminals, which is what they end up being in a
|
||||
recursive descent parser, but NOT how they are implemented
|
||||
in btyacc. Basically they are just syntactic sugar for
|
||||
embedded semantic actions and $0, $-1, ... in normal yacc.
|
||||
btyacc gives you two big advantages besides just the
|
||||
syntax:
|
||||
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 the
|
||||
attributes in the preamble with a type declaration and
|
||||
declaring names of the attributes on the lhs of the yacc
|
||||
rule. You can of course have more than one rule with the
|
||||
same lhs, and you can even give them different names in
|
||||
each, 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 complete
|
||||
example. At the current time, the start symbol cannot
|
||||
have any arguments.
|
||||
|
||||
Variant parsers:
|
||||
|
||||
Btyacc supports the -S flag to use a different parser
|
||||
skeleton, changing the way that the parser is called and
|
||||
used. The skeleton "push.skel" is included to produce a
|
||||
"passive" parser that you feed tokens to (rather than
|
||||
having the parser call a separate yylex routine). With
|
||||
push.skel, yyparse is defined as follows:
|
||||
|
||||
int yyparse(int token, YYSTYPE yylval)
|
||||
|
||||
You should call yyparse repeatedly with successive tokens
|
||||
of input. It returns 0 if more input is needed, 1 for a
|
||||
successful 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 tells
|
||||
Yacc to put the read-only tables in y.tab.c and the code and
|
||||
variables in y.code.c. Keith Bostic asked for this option so
|
||||
that :yyfix could be eliminated.
|
||||
|
||||
The -l and -t options have been implemented. The -l
|
||||
option tells Yacc not to include #line directives in the code
|
||||
it produces. The -t option causes debugging code to be
|
||||
included in the compiled parser.
|
||||
|
||||
The code for error recovery has been changed to
|
||||
implement the same algorithm as AT&T Yacc. There will still
|
||||
be differences in the way error recovery works because AT&T
|
||||
Yacc uses more default reductions than Berkeley Yacc.
|
||||
|
||||
The environment variable TMPDIR determines the directory
|
||||
where temporary files will be created. If TMPDIR is defined,
|
||||
temporary files will be created in the directory whose
|
||||
pathname is the value of TMPDIR. By default, temporary files
|
||||
are 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 are
|
||||
treated as commentary.
|
||||
|
||||
Line-end comments, as in BCPL, are permitted. Line-end
|
||||
comments begin with // and end at the next end-of-line.
|
||||
Line-end comments are permitted in C code; they are converted
|
||||
to C comments on output.
|
||||
|
||||
The form of y.output files has been changed to look more
|
||||
like those produced by AT&T Yacc.
|
||||
|
||||
A new kind of declaration has been added.
|
||||
The form of the declaration is
|
||||
|
||||
%ident string
|
||||
|
||||
where string is a sequence of characters beginning with a
|
||||
double quote and ending with either a double quote or the
|
||||
next end-of-line, whichever comes first. The declaration
|
||||
will cause a #ident directive to be written near the start
|
||||
of the output file.
|
||||
|
||||
If a parser has been compiled with debugging code, that
|
||||
code can be enabled by setting an environment variable.
|
||||
If the environment variable YYDEBUG is set to 0, debugging
|
||||
output is suppressed. If it is set to 1, debugging output
|
||||
is written to standard output.
|
||||
|
||||
|
||||
Building BtYacc
|
||||
---------------
|
||||
by Chris Dodd and Vadim Maslov
|
||||
|
||||
We used GCC and GNU make to compile BtYacc both on UNIX and
|
||||
WIN32 paltforms. You are welcome to try different
|
||||
combinations of makes and compilers. Most likely it will
|
||||
work, 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 gawk
|
||||
may 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 Maslov
|
||||
|
||||
In 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 SYSTEMS
|
||||
NOR ANY OF ITS LICENSORS NOR ANY BTYACC CONTRIBUTOR SHALL BE
|
||||
LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL
|
||||
DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE, DATA OR
|
||||
DATA USE, CAUSED BY BTYACC AND INCURRED BY CUSTOMER OR ANY
|
||||
THIRD PARTY, WHETHER IN AN ACTION IN CONTRACT OR TORT, EVEN
|
||||
IF SIBER SYSTEMS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
66
extern/btyacc/README.BYACC
vendored
Normal file
66
extern/btyacc/README.BYACC
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
Berkeley Yacc is an LALR(1) parser generator. Berkeley Yacc has been made
|
||||
as compatible as possible with AT&T Yacc. Berkeley Yacc can accept any input
|
||||
specification that conforms to the AT&T Yacc documentation. Specifications
|
||||
that take advantage of undocumented features of AT&T Yacc will probably be
|
||||
rejected.
|
||||
|
||||
Berkeley Yacc is distributed with no warranty whatever. The code is certain
|
||||
to contain errors. Neither the author nor any contributor takes responsibility
|
||||
for any consequences of its use.
|
||||
|
||||
Berkeley Yacc is in the public domain. The data structures and algorithms
|
||||
used in Berkeley Yacc are all either taken from documents available to the
|
||||
general public or are inventions of the author. Anyone may freely distribute
|
||||
source or binary forms of Berkeley Yacc whether unchanged or modified.
|
||||
Distributers may charge whatever fees they can obtain for Berkeley Yacc.
|
||||
Programs generated by Berkeley Yacc may be distributed freely.
|
||||
|
||||
Please report bugs to
|
||||
|
||||
corbett@berkeley.edu
|
||||
|
||||
Include a small example if possible. Please include the banner string from
|
||||
skeleton.c with the bug report. Do not expect rapid responses.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
ACKNOWLEDGEMENTS
|
||||
================
|
||||
|
||||
Berkeley Yacc owes much to the unflagging efforts of Keith Bostic.
|
||||
His badgering kept me working on it long after I was ready to quit.
|
||||
|
||||
Berkeley Yacc is based on the excellent algorithm for computing LALR(1)
|
||||
lookaheads developed by Tom Pennello and Frank DeRemer. The algorithm is
|
||||
described in their almost impenetrable article in TOPLAS 4,4.
|
||||
|
||||
Finally, much of the credit for the latest version must go to those
|
||||
who pointed out deficiencies of my earlier releases. Among the most
|
||||
prolific contributors were
|
||||
|
||||
Benson I. Margulies
|
||||
Dave Gentzel
|
||||
Antoine Verheijen
|
||||
Peter S. Housel
|
||||
Dale Smith
|
||||
Ozan Yigit
|
||||
John Campbell
|
||||
Bill Sommerfeld
|
||||
Paul Hilfinger
|
||||
Gary Bridgewater
|
||||
Dave Bakken
|
||||
Dan Lanciani
|
||||
Richard Sargent
|
||||
Parag Patel
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The initial idea for BTYACC came to me after reading the paper
|
||||
"Parsing Non-LR(k) Grammars with Yacc"
|
||||
Gary H. Merrill
|
||||
_Software Prctice and Experience_ Vol. 23(8), 829-850
|
||||
(August 1993)
|
||||
this paper talks about the basic idea of using a trial parse to resolve
|
||||
conflicts in the grammar.
|
||||
|
||||
Patches to make things work on MSDOS are courtesy of Pasquale Foggia
|
824
extern/btyacc/btyaccpa.ske
vendored
Normal file
824
extern/btyacc/btyaccpa.ske
vendored
Normal file
@ -0,0 +1,824 @@
|
||||
/* The banner used here should be replaced with an #ident directive */
|
||||
/* if the target C compiler supports #ident directives. */
|
||||
/* */
|
||||
/* If the skeleton is changed, the banner should be changed so that */
|
||||
/* the altered version can easily be distinguished from the original. */
|
||||
|
||||
%% banner
|
||||
|
||||
//
|
||||
// @(#)btyaccpar, based on byacc 1.8 (Berkeley)
|
||||
//
|
||||
#define YYBTYACC 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef int Yshort;
|
||||
|
||||
%% tables
|
||||
|
||||
#define _C_ "C"
|
||||
|
||||
extern _C_ Yshort yylhs[];
|
||||
extern _C_ Yshort yylen[];
|
||||
extern _C_ Yshort yydefred[];
|
||||
extern _C_ Yshort yydgoto[];
|
||||
extern _C_ Yshort yysindex[];
|
||||
extern _C_ Yshort yyrindex[];
|
||||
extern _C_ Yshort yycindex[];
|
||||
extern _C_ Yshort yygindex[];
|
||||
extern _C_ Yshort yytable[];
|
||||
extern _C_ Yshort yycheck[];
|
||||
extern _C_ Yshort yyctable[];
|
||||
|
||||
#if YYDEBUG
|
||||
extern _C_ char *yyname[];
|
||||
extern _C_ char *yyrule[];
|
||||
#endif
|
||||
|
||||
%% header
|
||||
|
||||
//
|
||||
// YYPOSN is user-defined text position type.
|
||||
//
|
||||
#ifndef YYPOSN
|
||||
#define YYPOSN int
|
||||
#endif
|
||||
|
||||
#ifdef YYREDUCEPOSNFUNC
|
||||
#define YYCALLREDUCEPOSN(e) \
|
||||
if(reduce_posn) { \
|
||||
YYREDUCEPOSNFUNC(yyps->pos, &(yyps->psp)[1-yym], &(yyps->vsp)[1-yym], \
|
||||
yym, yyps->psp - yyps->ps, yychar, yyposn, e); \
|
||||
reduce_posn = 0; \
|
||||
}
|
||||
|
||||
#ifndef YYCALLREDUCEPOSNARG
|
||||
#define YYCALLREDUCEPOSNARG yyps->val
|
||||
#endif
|
||||
|
||||
|
||||
#define YYPOSNARG(n) ((yyps->psp)[1-yym+(n)-1])
|
||||
#define YYPOSNOUT (yyps->pos)
|
||||
#endif
|
||||
|
||||
// If delete function is not defined by the user, do not deletions.
|
||||
#ifndef YYDELETEVAL
|
||||
#define YYDELETEVAL(v)
|
||||
#endif
|
||||
|
||||
// If delete function is not defined by the user, do not deletions.
|
||||
#ifndef YYDELETEPOSN
|
||||
#define YYDELETEPOSN(v)
|
||||
#endif
|
||||
|
||||
#define yyclearin (yychar=(-1))
|
||||
|
||||
#define yyerrok (yyps->errflag=0)
|
||||
|
||||
#ifndef YYSTACKGROWTH
|
||||
#define YYSTACKGROWTH 16
|
||||
#endif
|
||||
|
||||
#ifndef YYDEFSTACKSIZE
|
||||
#define YYDEFSTACKSIZE 12
|
||||
#endif
|
||||
|
||||
#ifdef YYDEBUG
|
||||
int yydebug;
|
||||
#endif
|
||||
|
||||
int yynerrs;
|
||||
|
||||
/* These value/posn are taken from the lexer */
|
||||
YYSTYPE yylval;
|
||||
YYPOSN yyposn;
|
||||
|
||||
/* These value/posn of the root non-terminal are returned to the caller */
|
||||
YYSTYPE yyretlval;
|
||||
YYPOSN yyretposn;
|
||||
|
||||
#define YYABORT goto yyabort
|
||||
#define YYACCEPT goto yyaccept
|
||||
#define YYERROR goto yyerrlab
|
||||
#define YYVALID do { if (yyps->save) goto yyvalid; } while(0)
|
||||
#define YYVALID_NESTED do { if (yyps->save && \
|
||||
yyps->save->save==0) goto yyvalid; } while(0)
|
||||
|
||||
struct yyparsestate {
|
||||
yyparsestate *save; // Previously saved parser state
|
||||
int state;
|
||||
int errflag;
|
||||
Yshort *ssp; // state stack pointer
|
||||
YYSTYPE *vsp; // value stack pointer
|
||||
YYPOSN *psp; // position stack pointer
|
||||
YYSTYPE val; // value as returned by actions
|
||||
YYPOSN pos; // position as returned by universal action
|
||||
Yshort *ss; // state stack base
|
||||
YYSTYPE *vs; // values stack base
|
||||
YYPOSN *ps; // position stack base
|
||||
int lexeme; // index of the conflict lexeme in the lexical queue
|
||||
unsigned int stacksize; // current maximum stack size
|
||||
Yshort ctry; // index in yyctable[] for this conflict
|
||||
};
|
||||
|
||||
// Current parser state
|
||||
static yyparsestate *yyps=0;
|
||||
|
||||
// yypath!=NULL: do the full parse, starting at *yypath parser state.
|
||||
static yyparsestate *yypath=0;
|
||||
|
||||
// Base of the lexical value queue
|
||||
static YYSTYPE *yylvals=0;
|
||||
|
||||
// Current posistion at lexical value queue
|
||||
static YYSTYPE *yylvp=0;
|
||||
|
||||
// End position of lexical value queue
|
||||
static YYSTYPE *yylve=0;
|
||||
|
||||
// The last allocated position at the lexical value queue
|
||||
static YYSTYPE *yylvlim=0;
|
||||
|
||||
// Base of the lexical position queue
|
||||
static YYPOSN *yylpsns=0;
|
||||
|
||||
// Current posistion at lexical position queue
|
||||
static YYPOSN *yylpp=0;
|
||||
|
||||
// End position of lexical position queue
|
||||
static YYPOSN *yylpe=0;
|
||||
|
||||
// The last allocated position at the lexical position queue
|
||||
static YYPOSN *yylplim=0;
|
||||
|
||||
// Current position at lexical token queue
|
||||
static Yshort *yylexp=0;
|
||||
|
||||
static Yshort *yylexemes=0;
|
||||
|
||||
//
|
||||
// For use in generated program
|
||||
//
|
||||
#define yytrial (yyps->save)
|
||||
#define yyvsp (yyps->vsp)
|
||||
#define yyval (yyps->val)
|
||||
#define yydepth (yyps->ssp - yyps->ss)
|
||||
|
||||
|
||||
//
|
||||
// Local prototypes.
|
||||
//
|
||||
int yyparse(void);
|
||||
|
||||
int YYLex1();
|
||||
int yyexpand();
|
||||
void YYSCopy(YYSTYPE *to, YYSTYPE *from, int size);
|
||||
void YYPCopy(YYPOSN *to, YYPOSN *from, int size);
|
||||
void YYMoreStack(yyparsestate *yyps);
|
||||
yyparsestate *YYNewState(int size);
|
||||
void YYFreeState(yyparsestate *p);
|
||||
|
||||
|
||||
%% body
|
||||
|
||||
|
||||
//
|
||||
// Parser function
|
||||
//
|
||||
int yyparse() {
|
||||
int yym, yyn, yystate, yychar, yynewerrflag;
|
||||
yyparsestate *yyerrctx = NULL;
|
||||
int reduce_posn;
|
||||
|
||||
#if YYDEBUG
|
||||
char *yys;
|
||||
|
||||
if ((yys = getenv("YYDEBUG"))) {
|
||||
yyn = *yys;
|
||||
if (yyn >= '0' && yyn <= '9')
|
||||
yydebug = yyn - '0';
|
||||
}
|
||||
#endif
|
||||
|
||||
yyps = YYNewState(YYDEFSTACKSIZE);
|
||||
yyps->save = 0;
|
||||
yynerrs = 0;
|
||||
yyps->errflag = 0;
|
||||
yychar = (-1);
|
||||
|
||||
yyps->ssp = yyps->ss;
|
||||
yyps->vsp = yyps->vs;
|
||||
yyps->psp = yyps->ps;
|
||||
*(yyps->ssp) = yystate = 0;
|
||||
|
||||
|
||||
//
|
||||
// Main parsing loop
|
||||
//
|
||||
yyloop:
|
||||
if ((yyn = yydefred[yystate])) {
|
||||
goto yyreduce;
|
||||
}
|
||||
|
||||
//
|
||||
// Read one token
|
||||
//
|
||||
if (yychar < 0) {
|
||||
if ((yychar = YYLex1()) < 0) yychar = 0;
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
yys = 0;
|
||||
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
|
||||
if (!yys) yys = "illegal-symbol";
|
||||
printf("yydebug[%d,%d]: state %d, reading %d (%s)",
|
||||
yydepth, (int)yytrial, yystate, yychar, yys);
|
||||
#ifdef YYDBPR
|
||||
printf("<");
|
||||
YYDBPR(yylval);
|
||||
printf(">");
|
||||
#endif
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Do we have a conflict?
|
||||
//
|
||||
if ((yyn = yycindex[yystate]) &&
|
||||
(yyn += yychar) >= 0 &&
|
||||
yyn <= YYTABLESIZE &&
|
||||
yycheck[yyn] == yychar) {
|
||||
int ctry;
|
||||
|
||||
if (yypath) {
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
printf("yydebug[%d,%d]: CONFLICT in state %d: following successful trial parse\n",
|
||||
yydepth, (int)yytrial, yystate);
|
||||
}
|
||||
#endif
|
||||
// Switch to the next conflict context
|
||||
yyparsestate *save = yypath;
|
||||
yypath = save->save;
|
||||
ctry = save->ctry;
|
||||
if (save->state != yystate)
|
||||
goto yyabort;
|
||||
YYFreeState(save);
|
||||
|
||||
} else {
|
||||
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
printf("yydebug[%d,%d]: CONFLICT in state %d. ",
|
||||
yydepth, (int)yytrial, yystate);
|
||||
if(yyps->save) {
|
||||
printf("ALREADY in conflict. Continue trial parse.");
|
||||
} else {
|
||||
printf("Start trial parse.");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
yyparsestate *save = YYNewState(yyps->ssp - yyps->ss);
|
||||
save->save = yyps->save;
|
||||
save->state = yystate;
|
||||
save->errflag = yyps->errflag;
|
||||
save->ssp = save->ss + (yyps->ssp - yyps->ss);
|
||||
save->vsp = save->vs + (yyps->vsp - yyps->vs);
|
||||
save->psp = save->ps + (yyps->psp - yyps->ps);
|
||||
memcpy (save->ss, yyps->ss, (yyps->ssp - yyps->ss + 1)*sizeof(Yshort));
|
||||
YYSCopy(save->vs, yyps->vs, (yyps->ssp - yyps->ss + 1));
|
||||
YYPCopy(save->ps, yyps->ps, (yyps->ssp - yyps->ss + 1));
|
||||
ctry = yytable[yyn];
|
||||
if (yyctable[ctry] == -1) {
|
||||
#if YYDEBUG
|
||||
if (yydebug && yychar >= 0)
|
||||
printf("yydebug[%d]: backtracking 1 token\n",
|
||||
(int)yytrial);
|
||||
#endif
|
||||
ctry++;
|
||||
}
|
||||
save->ctry = ctry;
|
||||
if (!yyps->save) {
|
||||
// If this is a first conflict in the stack, start saving lexemes
|
||||
if (!yylexemes) {
|
||||
yylexemes = new Yshort[YYSTACKGROWTH];
|
||||
yylvals = new YYSTYPE[YYSTACKGROWTH];
|
||||
yylvlim = yylvals + YYSTACKGROWTH;
|
||||
yylpsns = new YYPOSN[YYSTACKGROWTH];
|
||||
yylplim = yylpsns + YYSTACKGROWTH;
|
||||
}
|
||||
if (yylvp == yylve) {
|
||||
yylvp = yylve = yylvals;
|
||||
yylpp = yylpe = yylpsns;
|
||||
yylexp = yylexemes;
|
||||
if (yychar >= 0) {
|
||||
*yylve++ = yylval;
|
||||
*yylpe++ = yyposn;
|
||||
*yylexp = yychar;
|
||||
yychar = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yychar >= 0) {
|
||||
yylvp--, yylpp--, yylexp--;
|
||||
yychar = -1;
|
||||
}
|
||||
save->lexeme = yylvp - yylvals;
|
||||
yyps->save = save;
|
||||
}
|
||||
if (yytable[yyn] == ctry) {
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug[%d,%d]: state %d, shifting to state %d\n",
|
||||
yydepth, (int)yytrial, yystate, yyctable[ctry]);
|
||||
#endif
|
||||
if (yychar < 0)
|
||||
yylvp++, yylpp++, yylexp++;
|
||||
yychar = -1;
|
||||
if (yyps->errflag > 0) --yyps->errflag;
|
||||
yystate = yyctable[ctry];
|
||||
goto yyshift;
|
||||
} else {
|
||||
yyn = yyctable[ctry];
|
||||
goto yyreduce;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Is action a shift?
|
||||
//
|
||||
if ((yyn = yysindex[yystate]) &&
|
||||
(yyn += yychar) >= 0 &&
|
||||
yyn <= YYTABLESIZE &&
|
||||
yycheck[yyn] == yychar) {
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug[%d,%d]: state %d, shifting to state %d\n",
|
||||
yydepth, (int)yytrial, yystate, yytable[yyn]);
|
||||
#endif
|
||||
yychar = (-1);
|
||||
if (yyps->errflag > 0) --yyps->errflag;
|
||||
yystate = yytable[yyn];
|
||||
yyshift:
|
||||
if (yyps->ssp >= yyps->ss + yyps->stacksize - 1) {
|
||||
YYMoreStack(yyps);
|
||||
}
|
||||
*++(yyps->ssp) = yystate;
|
||||
*++(yyps->vsp) = yylval;
|
||||
*++(yyps->psp) = yyposn;
|
||||
goto yyloop;
|
||||
}
|
||||
if ((yyn = yyrindex[yystate]) &&
|
||||
(yyn += yychar) >= 0 &&
|
||||
yyn <= YYTABLESIZE &&
|
||||
yycheck[yyn] == yychar) {
|
||||
yyn = yytable[yyn];
|
||||
goto yyreduce;
|
||||
}
|
||||
|
||||
//
|
||||
// Action: error
|
||||
//
|
||||
if (yyps->errflag) goto yyinrecovery;
|
||||
yynewerrflag = 1;
|
||||
goto yyerrhandler;
|
||||
yyerrlab:
|
||||
yynewerrflag = 0;
|
||||
yyerrhandler:
|
||||
while (yyps->save) {
|
||||
int ctry;
|
||||
yyparsestate *save = yyps->save;
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug[%d,%d]: ERROR in state %d, CONFLICT BACKTRACKING to state %d, %d tokens\n",
|
||||
yydepth, (int)yytrial, yystate, yyps->save->state, yylvp - yylvals - yyps->save->lexeme);
|
||||
#endif
|
||||
// Memorize most forward-looking error state in case
|
||||
// it's really an error.
|
||||
if(yyerrctx==NULL || yyerrctx->lexeme<yylvp-yylvals) {
|
||||
// Free old saved error context state
|
||||
if(yyerrctx) YYFreeState(yyerrctx);
|
||||
// Create and fill out new saved error context state
|
||||
yyerrctx = YYNewState(yyps->ssp - yyps->ss);
|
||||
yyerrctx->save = yyps->save;
|
||||
yyerrctx->state = yystate;
|
||||
yyerrctx->errflag = yyps->errflag;
|
||||
yyerrctx->ssp = yyerrctx->ss + (yyps->ssp - yyps->ss);
|
||||
yyerrctx->vsp = yyerrctx->vs + (yyps->vsp - yyps->vs);
|
||||
yyerrctx->psp = yyerrctx->ps + (yyps->psp - yyps->ps);
|
||||
memcpy (yyerrctx->ss, yyps->ss, (yyps->ssp - yyps->ss + 1)*sizeof(Yshort));
|
||||
YYSCopy(yyerrctx->vs, yyps->vs, (yyps->ssp - yyps->ss + 1));
|
||||
YYPCopy(yyerrctx->ps, yyps->ps, (yyps->ssp - yyps->ss + 1));
|
||||
yyerrctx->lexeme = yylvp - yylvals;
|
||||
}
|
||||
yylvp = yylvals + save->lexeme;
|
||||
yylpp = yylpsns + save->lexeme;
|
||||
yylexp = yylexemes + save->lexeme;
|
||||
yychar = -1;
|
||||
yyps->ssp = yyps->ss + (save->ssp - save->ss);
|
||||
yyps->vsp = yyps->vs + (save->vsp - save->vs);
|
||||
yyps->psp = yyps->ps + (save->psp - save->ps);
|
||||
memcpy (yyps->ss, save->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort));
|
||||
YYSCopy(yyps->vs, save->vs, yyps->vsp - yyps->vs + 1);
|
||||
YYPCopy(yyps->ps, save->ps, yyps->psp - yyps->ps + 1);
|
||||
ctry = ++save->ctry;
|
||||
yystate = save->state;
|
||||
// We tried shift, try reduce now
|
||||
if ((yyn = yyctable[ctry]) >= 0) {
|
||||
goto yyreduce;
|
||||
}
|
||||
yyps->save = save->save;
|
||||
YYFreeState(save);
|
||||
//
|
||||
// Nothing left on the stack -- error
|
||||
//
|
||||
if (!yyps->save) {
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
printf("yydebug[%d]: trial parse FAILED, entering ERROR mode\n",
|
||||
(int)yytrial);
|
||||
}
|
||||
#endif
|
||||
// Restore state as it was in the most forward-advanced error
|
||||
yylvp = yylvals + yyerrctx->lexeme;
|
||||
yylpp = yylpsns + yyerrctx->lexeme;
|
||||
yylexp = yylexemes + yyerrctx->lexeme;
|
||||
yychar = yylexp[-1];
|
||||
yylval = yylvp[-1];
|
||||
yyposn = yylpp[-1];
|
||||
yyps->ssp = yyps->ss + (yyerrctx->ssp - yyerrctx->ss);
|
||||
yyps->vsp = yyps->vs + (yyerrctx->vsp - yyerrctx->vs);
|
||||
yyps->psp = yyps->ps + (yyerrctx->psp - yyerrctx->ps);
|
||||
memcpy (yyps->ss, yyerrctx->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort));
|
||||
YYSCopy(yyps->vs, yyerrctx->vs, yyps->vsp - yyps->vs + 1);
|
||||
YYPCopy(yyps->ps, yyerrctx->ps, yyps->psp - yyps->ps + 1);
|
||||
yystate = yyerrctx->state;
|
||||
YYFreeState(yyerrctx);
|
||||
yyerrctx = NULL;
|
||||
}
|
||||
yynewerrflag = 1;
|
||||
}
|
||||
if (yynewerrflag) {
|
||||
#ifdef YYERROR_DETAILED
|
||||
yyerror_detailed("syntax error", yychar, yylval, yyposn);
|
||||
#else
|
||||
yyerror("syntax error");
|
||||
#endif
|
||||
}
|
||||
++yynerrs;
|
||||
yyinrecovery:
|
||||
if (yyps->errflag < 3) {
|
||||
yyps->errflag = 3;
|
||||
for (;;) {
|
||||
if ((yyn = yysindex[*(yyps->ssp)]) &&
|
||||
(yyn += YYERRCODE) >= 0 &&
|
||||
yyn <= YYTABLESIZE &&
|
||||
yycheck[yyn] == YYERRCODE) {
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug[%d,%d]: state %d, ERROR recovery shifts to state %d\n",
|
||||
yydepth, (int)yytrial, *(yyps->ssp), yytable[yyn]);
|
||||
#endif
|
||||
/* Use label yyerrlab, so that compiler does not warn */
|
||||
if(yyps->errflag != yyps->errflag) goto yyerrlab;
|
||||
yystate = yytable[yyn];
|
||||
goto yyshift;
|
||||
} else {
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug[%d,%d]: ERROR recovery discards state %d\n",
|
||||
yydepth, (int)yytrial, *(yyps->ssp));
|
||||
#endif
|
||||
if (yyps->ssp <= yyps->ss) {
|
||||
goto yyabort;
|
||||
}
|
||||
if(!yytrial) {
|
||||
YYDELETEVAL(yyps->vsp[0],1);
|
||||
YYDELETEPOSN(yyps->psp[0],1);
|
||||
}
|
||||
--(yyps->ssp);
|
||||
--(yyps->vsp);
|
||||
--(yyps->psp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (yychar == 0) goto yyabort;
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
yys = 0;
|
||||
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
|
||||
if (!yys) yys = "illegal-symbol";
|
||||
printf("yydebug[%d,%d]: state %d, ERROR recovery discards token %d (%s)\n",
|
||||
yydepth, (int)yytrial, yystate, yychar, yys);
|
||||
}
|
||||
#endif
|
||||
if(!yytrial) {
|
||||
YYDELETEVAL(yylval,0);
|
||||
YYDELETEPOSN(yyposn,0);
|
||||
}
|
||||
yychar = (-1);
|
||||
goto yyloop;
|
||||
}
|
||||
|
||||
//
|
||||
// Reduce the rule
|
||||
//
|
||||
yyreduce:
|
||||
yym = yylen[yyn];
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
printf("yydebug[%d,%d]: state %d, reducing by rule %d (%s)",
|
||||
yydepth, (int)yytrial, yystate, yyn, yyrule[yyn]);
|
||||
#ifdef YYDBPR
|
||||
if (yym) {
|
||||
int i;
|
||||
printf("<");
|
||||
for (i=yym; i>0; i--) {
|
||||
if (i!=yym) printf(", ");
|
||||
YYDBPR((yyps->vsp)[1-i]);
|
||||
}
|
||||
printf(">");
|
||||
}
|
||||
#endif
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
if (yyps->ssp + 1 - yym >= yyps->ss + yyps->stacksize) {
|
||||
YYMoreStack(yyps);
|
||||
}
|
||||
|
||||
/* "$$ = NULL" default action */
|
||||
memset(&yyps->val, 0, sizeof(yyps->val));
|
||||
|
||||
/* default reduced position is NULL -- no position at all.
|
||||
no position will be assigned at trial time and if no position handling is present */
|
||||
memset(&yyps->pos, 0, sizeof(yyps->pos));
|
||||
|
||||
reduce_posn = TRUE;
|
||||
|
||||
switch (yyn) {
|
||||
|
||||
%% trailer
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if YYDEBUG && defined(YYDBPR)
|
||||
if (yydebug) {
|
||||
printf("yydebug[%d]: after reduction, result is ", yytrial);
|
||||
YYDBPR(yyps->val);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Perform user-defined position reduction
|
||||
#ifdef YYREDUCEPOSNFUNC
|
||||
if(!yytrial) {
|
||||
YYCALLREDUCEPOSN(YYREDUCEPOSNFUNCARG);
|
||||
}
|
||||
#endif
|
||||
|
||||
yyps->ssp -= yym;
|
||||
yystate = *(yyps->ssp);
|
||||
yyps->vsp -= yym;
|
||||
yyps->psp -= yym;
|
||||
|
||||
yym = yylhs[yyn];
|
||||
if (yystate == 0 && yym == 0) {
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
printf("yydebug[%d,%d]: after reduction, shifting from state 0 to state %d\n",
|
||||
yydepth, (int)yytrial, YYFINAL);
|
||||
}
|
||||
#endif
|
||||
yystate = YYFINAL;
|
||||
*++(yyps->ssp) = YYFINAL;
|
||||
*++(yyps->vsp) = yyps->val;
|
||||
yyretlval = yyps->val; // return value of root non-terminal to yylval
|
||||
*++(yyps->psp) = yyps->pos;
|
||||
yyretposn = yyps->pos; // return value of root position to yyposn
|
||||
if (yychar < 0) {
|
||||
if ((yychar = YYLex1()) < 0) {
|
||||
yychar = 0;
|
||||
}
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
yys = 0;
|
||||
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
|
||||
if (!yys) yys = "illegal-symbol";
|
||||
printf("yydebug[%d,%d]: state %d, reading %d (%s)\n",
|
||||
yydepth, (int)yytrial, YYFINAL, yychar, yys);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (yychar == 0) goto yyaccept;
|
||||
goto yyloop;
|
||||
}
|
||||
|
||||
if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
|
||||
yyn <= YYTABLESIZE && yycheck[yyn] == yystate) {
|
||||
yystate = yytable[yyn];
|
||||
} else {
|
||||
yystate = yydgoto[yym];
|
||||
}
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug[%d,%d]: after reduction, shifting from state %d to state %d\n",
|
||||
yydepth, (int)yytrial, *(yyps->ssp), yystate);
|
||||
#endif
|
||||
if (yyps->ssp >= yyps->ss + yyps->stacksize - 1) {
|
||||
YYMoreStack(yyps);
|
||||
}
|
||||
*++(yyps->ssp) = yystate;
|
||||
*++(yyps->vsp) = yyps->val;
|
||||
*++(yyps->psp) = yyps->pos;
|
||||
goto yyloop;
|
||||
|
||||
|
||||
//
|
||||
// Reduction declares that this path is valid.
|
||||
// Set yypath and do a full parse
|
||||
//
|
||||
yyvalid:
|
||||
if (yypath) {
|
||||
goto yyabort;
|
||||
}
|
||||
while (yyps->save) {
|
||||
yyparsestate *save = yyps->save;
|
||||
yyps->save = save->save;
|
||||
save->save = yypath;
|
||||
yypath = save;
|
||||
}
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug[%d,%d]: CONFLICT trial successful, backtracking to state %d, %d tokens\n",
|
||||
yydepth, (int)yytrial, yypath->state, yylvp - yylvals - yypath->lexeme);
|
||||
#endif
|
||||
if(yyerrctx) {
|
||||
YYFreeState(yyerrctx); yyerrctx = NULL;
|
||||
}
|
||||
yychar = -1;
|
||||
yyps->ssp = yyps->ss + (yypath->ssp - yypath->ss);
|
||||
yyps->vsp = yyps->vs + (yypath->vsp - yypath->vs);
|
||||
yyps->psp = yyps->ps + (yypath->psp - yypath->ps);
|
||||
memcpy (yyps->ss, yypath->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort));
|
||||
YYSCopy(yyps->vs, yypath->vs, yyps->vsp - yyps->vs + 1);
|
||||
YYPCopy(yyps->ps, yypath->ps, yyps->psp - yyps->ps + 1);
|
||||
yylvp = yylvals + yypath->lexeme;
|
||||
yylpp = yylpsns + yypath->lexeme;
|
||||
yylexp = yylexemes + yypath->lexeme;
|
||||
yystate = yypath->state;
|
||||
goto yyloop;
|
||||
|
||||
|
||||
yyabort:
|
||||
if(yyerrctx) {
|
||||
YYFreeState(yyerrctx); yyerrctx = NULL;
|
||||
}
|
||||
|
||||
YYSTYPE *pv;
|
||||
for(pv=yyps->vs; pv<yyps->vsp; pv++) {
|
||||
YYDELETEVAL(*pv,2);
|
||||
}
|
||||
|
||||
YYPOSN *pp;
|
||||
for(pp=yyps->ps; pp<yyps->psp; pp++) {
|
||||
YYDELETEPOSN(*pp,2);
|
||||
}
|
||||
|
||||
while (yyps) {
|
||||
yyparsestate *save = yyps;
|
||||
yyps = save->save;
|
||||
YYFreeState(save);
|
||||
}
|
||||
while (yypath) {
|
||||
yyparsestate *save = yypath;
|
||||
yypath = save->save;
|
||||
YYFreeState(save);
|
||||
}
|
||||
return (1);
|
||||
|
||||
|
||||
yyaccept:
|
||||
if (yyps->save) goto yyvalid;
|
||||
if(yyerrctx) {
|
||||
YYFreeState(yyerrctx); yyerrctx = NULL;
|
||||
}
|
||||
while (yyps) {
|
||||
yyparsestate *save = yyps;
|
||||
yyps = save->save;
|
||||
YYFreeState(save);
|
||||
}
|
||||
while (yypath) {
|
||||
yyparsestate *save = yypath;
|
||||
yypath = save->save;
|
||||
YYFreeState(save);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int YYLex1() {
|
||||
if(yylvp<yylve) {
|
||||
yylval = *yylvp++;
|
||||
yyposn = *yylpp++;
|
||||
return *yylexp++;
|
||||
} else {
|
||||
if(yyps->save) {
|
||||
if(yylvp==yylvlim) {
|
||||
yyexpand();
|
||||
}
|
||||
*yylexp = yylex();
|
||||
*yylvp++ = yylval;
|
||||
yylve++;
|
||||
*yylpp++ = yyposn;
|
||||
yylpe++;
|
||||
return *yylexp++;
|
||||
} else {
|
||||
return yylex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int yyexpand() {
|
||||
int p = yylvp-yylvals;
|
||||
int s = yylvlim-yylvals;
|
||||
s += YYSTACKGROWTH;
|
||||
{ Yshort *tl = yylexemes;
|
||||
YYSTYPE *tv = yylvals;
|
||||
YYPOSN *tp = yylpsns;
|
||||
yylvals = new YYSTYPE[s];
|
||||
yylpsns = new YYPOSN[s];
|
||||
yylexemes = new Yshort[s];
|
||||
memcpy(yylexemes, tl, (s-YYSTACKGROWTH)*sizeof(Yshort));
|
||||
YYSCopy(yylvals, tv, s-YYSTACKGROWTH);
|
||||
YYPCopy(yylpsns, tp, s-YYSTACKGROWTH);
|
||||
delete[] tl;
|
||||
delete[] tv;
|
||||
delete[] tp;
|
||||
}
|
||||
yylvp = yylve = yylvals + p;
|
||||
yylvlim = yylvals + s;
|
||||
yylpp = yylpe = yylpsns + p;
|
||||
yylplim = yylpsns + s;
|
||||
yylexp = yylexemes + p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void YYSCopy(YYSTYPE *to, YYSTYPE *from, int size) {
|
||||
int i;
|
||||
for (i = size-1; i >= 0; i--) {
|
||||
to[i] = from[i];
|
||||
}
|
||||
}
|
||||
|
||||
void YYPCopy(YYPOSN *to, YYPOSN *from, int size) {
|
||||
int i;
|
||||
for (i = size-1; i >= 0; i--) {
|
||||
to[i] = from[i];
|
||||
}
|
||||
}
|
||||
|
||||
void YYMoreStack(yyparsestate *yyps) {
|
||||
int p = yyps->ssp - yyps->ss;
|
||||
Yshort *tss = yyps->ss;
|
||||
YYSTYPE *tvs = yyps->vs;
|
||||
YYPOSN *tps = yyps->ps;
|
||||
yyps->ss = new Yshort [yyps->stacksize + YYSTACKGROWTH];
|
||||
yyps->vs = new YYSTYPE[yyps->stacksize + YYSTACKGROWTH];
|
||||
yyps->ps = new YYPOSN [yyps->stacksize + YYSTACKGROWTH];
|
||||
memcpy(yyps->ss, tss, yyps->stacksize * sizeof(Yshort));
|
||||
YYSCopy(yyps->vs, tvs, yyps->stacksize);
|
||||
YYPCopy(yyps->ps, tps, yyps->stacksize);
|
||||
yyps->stacksize += YYSTACKGROWTH;
|
||||
delete[] tss;
|
||||
delete[] tvs;
|
||||
delete[] tps;
|
||||
yyps->ssp = yyps->ss + p;
|
||||
yyps->vsp = yyps->vs + p;
|
||||
yyps->psp = yyps->ps + p;
|
||||
}
|
||||
|
||||
yyparsestate *YYNewState(int size) {
|
||||
yyparsestate *p = new yyparsestate;
|
||||
p->stacksize = size+4;
|
||||
p->ss = new Yshort [size + 4];
|
||||
p->vs = new YYSTYPE[size + 4];
|
||||
p->ps = new YYPOSN [size + 4];
|
||||
memset(&p->vs[0], 0, (size+4)*sizeof(YYSTYPE));
|
||||
memset(&p->ps[0], 0, (size+4)*sizeof(YYPOSN));
|
||||
return p;
|
||||
}
|
||||
|
||||
void YYFreeState(yyparsestate *p) {
|
||||
delete[] p->ss;
|
||||
delete[] p->vs;
|
||||
delete[] p->ps;
|
||||
delete p;
|
||||
}
|
262
extern/btyacc/closure.c
vendored
Normal file
262
extern/btyacc/closure.c
vendored
Normal file
@ -0,0 +1,262 @@
|
||||
#include "defs.h"
|
||||
|
||||
Yshort *itemset;
|
||||
Yshort *itemsetend;
|
||||
unsigned *ruleset;
|
||||
|
||||
static unsigned *first_derives;
|
||||
static unsigned *EFF;
|
||||
|
||||
|
||||
void set_EFF()
|
||||
{
|
||||
register unsigned *row;
|
||||
register int symbol;
|
||||
register Yshort *sp;
|
||||
register int rowsize;
|
||||
register int i;
|
||||
register int rule;
|
||||
|
||||
rowsize = WORDSIZE(nvars);
|
||||
EFF = NEW2(nvars * rowsize, unsigned);
|
||||
|
||||
row = EFF;
|
||||
for (i = start_symbol; i < nsyms; i++)
|
||||
{
|
||||
sp = derives[i];
|
||||
for (rule = *sp; rule > 0; rule = *++sp)
|
||||
{
|
||||
symbol = ritem[rrhs[rule]];
|
||||
if (ISVAR(symbol))
|
||||
{
|
||||
symbol -= start_symbol;
|
||||
SETBIT(row, symbol);
|
||||
}
|
||||
}
|
||||
row += rowsize;
|
||||
}
|
||||
|
||||
reflexive_transitive_closure(EFF, nvars);
|
||||
|
||||
#ifdef DEBUG
|
||||
print_EFF();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void set_first_derives()
|
||||
{
|
||||
register unsigned *rrow;
|
||||
register unsigned *vrow;
|
||||
register int j;
|
||||
register unsigned mask;
|
||||
register unsigned cword;
|
||||
register Yshort *rp;
|
||||
|
||||
int rule;
|
||||
int i;
|
||||
int rulesetsize;
|
||||
int varsetsize;
|
||||
|
||||
rulesetsize = WORDSIZE(nrules);
|
||||
varsetsize = WORDSIZE(nvars);
|
||||
first_derives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
|
||||
|
||||
set_EFF();
|
||||
|
||||
rrow = first_derives + ntokens * rulesetsize;
|
||||
for (i = start_symbol; i < nsyms; i++)
|
||||
{
|
||||
vrow = EFF + ((i - ntokens) * varsetsize);
|
||||
cword = *vrow++;
|
||||
mask = 1;
|
||||
for (j = start_symbol; j < nsyms; j++)
|
||||
{
|
||||
if (cword & mask)
|
||||
{
|
||||
rp = derives[j];
|
||||
while ((rule = *rp++) >= 0)
|
||||
{
|
||||
SETBIT(rrow, rule);
|
||||
}
|
||||
}
|
||||
|
||||
mask <<= 1;
|
||||
if (mask == 0)
|
||||
{
|
||||
cword = *vrow++;
|
||||
mask = 1;
|
||||
}
|
||||
}
|
||||
|
||||
vrow += varsetsize;
|
||||
rrow += rulesetsize;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
print_first_derives();
|
||||
#endif
|
||||
|
||||
FREE(EFF);
|
||||
}
|
||||
|
||||
|
||||
void closure(Yshort *nucleus, int n)
|
||||
{
|
||||
register int ruleno;
|
||||
register unsigned word;
|
||||
register unsigned mask;
|
||||
register Yshort *csp;
|
||||
register unsigned *dsp;
|
||||
register unsigned *rsp;
|
||||
register int rulesetsize;
|
||||
|
||||
Yshort *csend;
|
||||
unsigned *rsend;
|
||||
int symbol;
|
||||
int itemno;
|
||||
|
||||
rulesetsize = WORDSIZE(nrules);
|
||||
rsp = ruleset;
|
||||
rsend = ruleset + rulesetsize;
|
||||
for (rsp = ruleset; rsp < rsend; rsp++)
|
||||
*rsp = 0;
|
||||
|
||||
csend = nucleus + n;
|
||||
for (csp = nucleus; csp < csend; ++csp)
|
||||
{
|
||||
symbol = ritem[*csp];
|
||||
if (ISVAR(symbol))
|
||||
{
|
||||
dsp = first_derives + symbol * rulesetsize;
|
||||
rsp = ruleset;
|
||||
while (rsp < rsend)
|
||||
*rsp++ |= *dsp++;
|
||||
}
|
||||
}
|
||||
|
||||
ruleno = 0;
|
||||
itemsetend = itemset;
|
||||
csp = nucleus;
|
||||
for (rsp = ruleset; rsp < rsend; ++rsp)
|
||||
{
|
||||
word = *rsp;
|
||||
if (word == 0)
|
||||
ruleno += BITS_PER_WORD;
|
||||
else
|
||||
{
|
||||
mask = 1;
|
||||
while (mask)
|
||||
{
|
||||
if (word & mask)
|
||||
{
|
||||
itemno = rrhs[ruleno];
|
||||
while (csp < csend && *csp < itemno)
|
||||
*itemsetend++ = *csp++;
|
||||
*itemsetend++ = itemno;
|
||||
while (csp < csend && *csp == itemno)
|
||||
++csp;
|
||||
}
|
||||
|
||||
mask <<= 1;
|
||||
++ruleno;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (csp < csend)
|
||||
*itemsetend++ = *csp++;
|
||||
|
||||
#ifdef DEBUG
|
||||
print_closure(n);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void finalize_closure()
|
||||
{
|
||||
FREE(itemset);
|
||||
FREE(ruleset);
|
||||
FREE(first_derives + ntokens * WORDSIZE(nrules));
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
void print_closure(int n)
|
||||
{
|
||||
register Yshort *isp;
|
||||
|
||||
printf("\n\nn = %d\n\n", n);
|
||||
for (isp = itemset; isp < itemsetend; isp++)
|
||||
printf(" %d\n", *isp);
|
||||
}
|
||||
|
||||
|
||||
void print_EFF()
|
||||
{
|
||||
register int i, j;
|
||||
register unsigned *rowp;
|
||||
register unsigned word;
|
||||
register unsigned mask;
|
||||
|
||||
printf("\n\nEpsilon Free Firsts\n");
|
||||
|
||||
for (i = start_symbol; i < nsyms; i++)
|
||||
{
|
||||
printf("\n%s", symbol_name[i]);
|
||||
rowp = EFF + ((i - start_symbol) * WORDSIZE(nvars));
|
||||
word = *rowp++;
|
||||
|
||||
mask = 1;
|
||||
for (j = 0; j < nvars; j++)
|
||||
{
|
||||
if (word & mask)
|
||||
printf(" %s", symbol_name[start_symbol + j]);
|
||||
|
||||
mask <<= 1;
|
||||
if (mask == 0)
|
||||
{
|
||||
word = *rowp++;
|
||||
mask = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_first_derives()
|
||||
{
|
||||
register int i;
|
||||
register int j;
|
||||
register unsigned *rp;
|
||||
register unsigned cword;
|
||||
register unsigned mask;
|
||||
|
||||
printf("\n\n\nFirst Derives\n");
|
||||
|
||||
for (i = start_symbol; i < nsyms; i++)
|
||||
{
|
||||
printf("\n%s derives\n", symbol_name[i]);
|
||||
rp = first_derives + i * WORDSIZE(nrules);
|
||||
cword = *rp++;
|
||||
mask = 1;
|
||||
for (j = 0; j <= nrules; j++)
|
||||
{
|
||||
if (cword & mask)
|
||||
printf(" %d\n", j);
|
||||
|
||||
mask <<= 1;
|
||||
if (mask == 0)
|
||||
{
|
||||
cword = *rp++;
|
||||
mask = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
#endif
|
516
extern/btyacc/defs.h
vendored
Normal file
516
extern/btyacc/defs.h
vendored
Normal file
@ -0,0 +1,516 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* machine-dependent definitions */
|
||||
/* the following definitions are for the Tahoe */
|
||||
/* they might have to be changed for other machines */
|
||||
|
||||
/* MAXCHAR is the largest unsigned character value */
|
||||
/* MAXSHORT is the largest value of a C short */
|
||||
/* MINSHORT is the most negative value of a C short */
|
||||
/* MAXTABLE is the maximum table size */
|
||||
/* BITS_PER_WORD is the number of bits in a C unsigned */
|
||||
/* WORDSIZE computes the number of words needed to */
|
||||
/* store n bits */
|
||||
/* BIT returns the value of the n-th bit starting */
|
||||
/* from r (0-indexed) */
|
||||
/* SETBIT sets the n-th bit starting from r */
|
||||
|
||||
#define MAXCHAR 255
|
||||
#define MAXSHORT ((int)0x7FFFFFFF)
|
||||
#define MINSHORT ((int)0x80000000)
|
||||
#define MAXTABLE 120000
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#define BITS_PER_WORD 16
|
||||
#define LOG2_BPW 4
|
||||
#else /* Real computers... */
|
||||
#define BITS_PER_WORD 32
|
||||
#define LOG2_BPW 5
|
||||
#endif
|
||||
#define BITS_PER_WORD_1 (BITS_PER_WORD-1)
|
||||
|
||||
#define WORDSIZE(n) (((n)+(BITS_PER_WORD_1))/BITS_PER_WORD)
|
||||
#define BIT(r, n) ((((r)[(n)>>LOG2_BPW])>>((n)&BITS_PER_WORD_1))&1)
|
||||
#define SETBIT(r, n) ((r)[(n)>>LOG2_BPW]|=((unsigned)1<<((n)&BITS_PER_WORD_1)))
|
||||
|
||||
/* VM: this is a 32-bit replacement for original 16-bit short */
|
||||
typedef int Yshort;
|
||||
|
||||
|
||||
/* character names */
|
||||
|
||||
#define NUL '\0' /* the null character */
|
||||
#define NEWLINE '\n' /* line feed */
|
||||
#define SP ' ' /* space */
|
||||
#define BS '\b' /* backspace */
|
||||
#define HT '\t' /* horizontal tab */
|
||||
#define VT '\013' /* vertical tab */
|
||||
#define CR '\r' /* carriage return */
|
||||
#define FF '\f' /* form feed */
|
||||
#define QUOTE '\'' /* single quote */
|
||||
#define DOUBLE_QUOTE '\"' /* double quote */
|
||||
#define BACKSLASH '\\' /* backslash */
|
||||
|
||||
|
||||
/* defines for constructing filenames */
|
||||
|
||||
#define DEFINES_SUFFIX "_tab.h"
|
||||
#define OUTPUT_SUFFIX "_tab.c"
|
||||
#define CODE_SUFFIX "_code.c"
|
||||
#define VERBOSE_SUFFIX ".output"
|
||||
|
||||
/* keyword codes */
|
||||
|
||||
#define TOKEN 0
|
||||
#define LEFT 1
|
||||
#define RIGHT 2
|
||||
#define NONASSOC 3
|
||||
#define MARK 4
|
||||
#define TEXT 5
|
||||
#define TYPE 6
|
||||
#define START 7
|
||||
#define UNION 8
|
||||
#define IDENT 9
|
||||
|
||||
|
||||
/* symbol classes */
|
||||
|
||||
#define UNKNOWN 0
|
||||
#define TERM 1
|
||||
#define NONTERM 2
|
||||
#define ACTION 3
|
||||
#define ARGUMENT 4
|
||||
|
||||
|
||||
/* the undefined value */
|
||||
|
||||
#define UNDEFINED (-1)
|
||||
|
||||
|
||||
/* action codes */
|
||||
|
||||
#define SHIFT 1
|
||||
#define REDUCE 2
|
||||
|
||||
|
||||
/* character macros */
|
||||
|
||||
#define IS_IDENT(c) (isalnum(c) || (c) == '_' || (c) == '.' || (c) == '$')
|
||||
#define IS_OCTAL(c) ((c) >= '0' && (c) <= '7')
|
||||
#define NUMERIC_VALUE(c) ((c) - '0')
|
||||
|
||||
|
||||
/* symbol macros */
|
||||
|
||||
#define ISTOKEN(s) ((s) < start_symbol)
|
||||
#define ISVAR(s) ((s) >= start_symbol)
|
||||
|
||||
|
||||
/* storage allocation macros */
|
||||
|
||||
#define CALLOC(k,n) (calloc((unsigned)(k),(unsigned)(n)))
|
||||
#define FREE(x) (free((char*)(x)))
|
||||
#define MALLOC(n) (malloc((unsigned)(n)))
|
||||
#define NEW(t) ((t*)allocate(sizeof(t)))
|
||||
#define NEW2(n,t) ((t*)allocate((unsigned)((n)*sizeof(t))))
|
||||
#define REALLOC(p,n) (realloc((char*)(p),(unsigned)(n)))
|
||||
#define RENEW(p,n,t) ((t*)realloc((char*)(p),(unsigned)((n)*sizeof(t))))
|
||||
|
||||
|
||||
/* the structure of a symbol table entry */
|
||||
|
||||
typedef struct bucket bucket;
|
||||
struct bucket
|
||||
{
|
||||
struct bucket *link;
|
||||
struct bucket *next;
|
||||
char *name;
|
||||
char *tag;
|
||||
char **argnames;
|
||||
char **argtags;
|
||||
Yshort args;
|
||||
Yshort value;
|
||||
Yshort index;
|
||||
Yshort prec;
|
||||
char class;
|
||||
char assoc;
|
||||
};
|
||||
|
||||
|
||||
/* the structure of the LR(0) state machine */
|
||||
|
||||
typedef struct core core;
|
||||
struct core
|
||||
{
|
||||
struct core *next;
|
||||
struct core *link;
|
||||
Yshort number;
|
||||
Yshort accessing_symbol;
|
||||
Yshort nitems;
|
||||
Yshort items[1];
|
||||
};
|
||||
|
||||
|
||||
/* the structure used to record shifts */
|
||||
|
||||
typedef struct shifts shifts;
|
||||
struct shifts
|
||||
{
|
||||
struct shifts *next;
|
||||
Yshort number;
|
||||
Yshort nshifts;
|
||||
Yshort shift[1];
|
||||
};
|
||||
|
||||
|
||||
/* the structure used to store reductions */
|
||||
|
||||
typedef struct reductions reductions;
|
||||
struct reductions
|
||||
{
|
||||
struct reductions *next;
|
||||
Yshort number;
|
||||
Yshort nreds;
|
||||
Yshort rules[1];
|
||||
};
|
||||
|
||||
|
||||
/* the structure used to represent parser actions */
|
||||
|
||||
typedef struct action action;
|
||||
struct action
|
||||
{
|
||||
struct action *next;
|
||||
Yshort symbol;
|
||||
Yshort number;
|
||||
Yshort prec;
|
||||
char action_code;
|
||||
char assoc;
|
||||
char suppressed;
|
||||
};
|
||||
|
||||
struct section {
|
||||
char *name;
|
||||
char **ptr;
|
||||
};
|
||||
|
||||
extern struct section section_list[];
|
||||
|
||||
|
||||
/* global variables */
|
||||
|
||||
extern char dflag;
|
||||
extern char lflag;
|
||||
extern char rflag;
|
||||
extern char tflag;
|
||||
extern char vflag;
|
||||
|
||||
extern char *myname;
|
||||
extern char *cptr;
|
||||
extern char *line;
|
||||
extern int lineno;
|
||||
extern int outline;
|
||||
|
||||
extern char *banner[];
|
||||
extern char *tables[];
|
||||
extern char *header[];
|
||||
extern char *body[];
|
||||
extern char *trailer[];
|
||||
|
||||
extern char *action_file_name;
|
||||
extern char *code_file_name;
|
||||
extern char *defines_file_name;
|
||||
extern char *input_file_name;
|
||||
extern char *output_file_name;
|
||||
extern char *text_file_name;
|
||||
extern char *union_file_name;
|
||||
extern char *verbose_file_name;
|
||||
|
||||
extern FILE *inc_file;
|
||||
extern char inc_file_name[];
|
||||
|
||||
extern FILE *action_file;
|
||||
extern FILE *code_file;
|
||||
extern FILE *defines_file;
|
||||
extern FILE *input_file;
|
||||
extern FILE *output_file;
|
||||
extern FILE *text_file;
|
||||
extern FILE *union_file;
|
||||
extern FILE *verbose_file;
|
||||
|
||||
extern int nitems;
|
||||
extern int nrules;
|
||||
extern int nsyms;
|
||||
extern int ntokens;
|
||||
extern int nvars;
|
||||
extern int ntags;
|
||||
|
||||
extern char unionized;
|
||||
extern char line_format[];
|
||||
|
||||
extern int start_symbol;
|
||||
extern char **symbol_name;
|
||||
extern Yshort *symbol_value;
|
||||
extern Yshort *symbol_prec;
|
||||
extern char *symbol_assoc;
|
||||
|
||||
extern Yshort *ritem;
|
||||
extern Yshort *rlhs;
|
||||
extern Yshort *rrhs;
|
||||
extern Yshort *rprec;
|
||||
extern char *rassoc;
|
||||
|
||||
extern Yshort **derives;
|
||||
extern char *nullable;
|
||||
|
||||
extern bucket *first_symbol;
|
||||
extern bucket *last_symbol;
|
||||
|
||||
extern int nstates;
|
||||
extern core *first_state;
|
||||
extern shifts *first_shift;
|
||||
extern reductions *first_reduction;
|
||||
extern Yshort *accessing_symbol;
|
||||
extern core **state_table;
|
||||
extern shifts **shift_table;
|
||||
extern reductions **reduction_table;
|
||||
extern unsigned *LA;
|
||||
extern Yshort *LAruleno;
|
||||
extern Yshort *lookaheads;
|
||||
extern Yshort *goto_map;
|
||||
extern Yshort *from_state;
|
||||
extern Yshort *to_state;
|
||||
|
||||
extern action **parser;
|
||||
extern int SRtotal;
|
||||
extern int RRtotal;
|
||||
extern Yshort *SRconflicts;
|
||||
extern Yshort *RRconflicts;
|
||||
extern Yshort *defred;
|
||||
extern Yshort *rules_used;
|
||||
extern Yshort nunused;
|
||||
extern Yshort final_state;
|
||||
|
||||
/* system variable */
|
||||
extern int errno;
|
||||
|
||||
/* global functions */
|
||||
|
||||
/* closure.c */
|
||||
void set_EFF(void);
|
||||
void set_first_derives(void);
|
||||
void closure(Yshort *, int);
|
||||
void finalize_closure(void);
|
||||
void print_closure(int);
|
||||
void print_EFF(void);
|
||||
void print_first_derives(void);
|
||||
|
||||
/* error.c */
|
||||
void fatal(char *);
|
||||
void no_space(void);
|
||||
void open_error(char *);
|
||||
void unexpected_EOF(void);
|
||||
void print_pos(char *, char *);
|
||||
void error(int, char *, char *, char *, ...);
|
||||
void syntax_error(int, char *, char *);
|
||||
void unterminated_comment(int, char *, char *);
|
||||
void unterminated_string(int, char *, char *);
|
||||
void unterminated_text(int, char *, char *);
|
||||
void unterminated_union(int, char *, char *);
|
||||
void over_unionized(char *);
|
||||
void illegal_tag(int, char *, char *);
|
||||
void illegal_character(char *);
|
||||
void used_reserved(char *);
|
||||
void tokenized_start(char *);
|
||||
void retyped_warning(char *);
|
||||
void reprec_warning(char *);
|
||||
void revalued_warning(char *);
|
||||
void terminal_start(char *);
|
||||
void restarted_warning(void);
|
||||
void no_grammar(void);
|
||||
void terminal_lhs(int);
|
||||
void prec_redeclared(void);
|
||||
void unterminated_action(int, char *, char *);
|
||||
void unterminated_arglist(int, char *, char *);
|
||||
void bad_formals(void);
|
||||
void dollar_warning(int, int);
|
||||
void dollar_error(int, char *, char *);
|
||||
void untyped_lhs(void);
|
||||
void untyped_rhs(int, char *);
|
||||
void unknown_rhs(int);
|
||||
void default_action_warning(void);
|
||||
void undefined_goal(char *);
|
||||
void undefined_symbol_warning(char *);
|
||||
|
||||
/* lalr.c */
|
||||
void lalr(void);
|
||||
void set_state_table(void);
|
||||
void set_accessing_symbol(void);
|
||||
void set_shift_table(void);
|
||||
void set_reduction_table(void);
|
||||
void set_maxrhs(void);
|
||||
void initialize_LA(void);
|
||||
void set_goto_map(void);
|
||||
int map_goto(int, int);
|
||||
void initialize_F(void);
|
||||
void build_relations(void);
|
||||
void add_lookback_edge(int, int, int);
|
||||
Yshort **transpose(Yshort **, int);
|
||||
void compute_FOLLOWS(void);
|
||||
void compute_lookaheads(void);
|
||||
void digraph(Yshort **);
|
||||
void traverse(int);
|
||||
|
||||
/* lr0.c */
|
||||
void allocate_itemsets(void);
|
||||
void allocate_storage(void);
|
||||
void append_states(void);
|
||||
void free_storage(void);
|
||||
void generate_states(void);
|
||||
int get_state(int);
|
||||
void initialize_states(void);
|
||||
void new_itemsets(void);
|
||||
core *new_state(int);
|
||||
void show_cores(void);
|
||||
void show_ritems(void);
|
||||
void show_rrhs(void);
|
||||
void show_shifts(void);
|
||||
void save_shifts(void);
|
||||
void save_reductions(void);
|
||||
void set_derives(void);
|
||||
void free_derives(void);
|
||||
void print_derives(void);
|
||||
void set_nullable(void);
|
||||
void free_nullable(void);
|
||||
void lr0(void);
|
||||
|
||||
/* main.c */
|
||||
void done(int);
|
||||
void onintr(void);
|
||||
void set_signals(void);
|
||||
void usage(void);
|
||||
void getargs(int, char **);
|
||||
char *allocate(unsigned);
|
||||
void create_file_names(void);
|
||||
void open_files(void);
|
||||
int main(int, char **);
|
||||
|
||||
/* mkpar.c */
|
||||
void make_parser(void);
|
||||
action *parse_actions(int);
|
||||
action *get_shifts(int);
|
||||
action *add_reductions(int, action *);
|
||||
action *add_reduce(action *, int, int);
|
||||
void find_final_state(void);
|
||||
void unused_rules(void);
|
||||
void remove_conflicts(void);
|
||||
void total_conflicts(void);
|
||||
int sole_reduction(int);
|
||||
void defreds(void);
|
||||
void free_action_row(action *);
|
||||
void free_parser(void);
|
||||
|
||||
/* output.c */
|
||||
void output(void);
|
||||
void output_rule_data(void);
|
||||
void output_yydefred(void);
|
||||
void output_actions(void);
|
||||
int find_conflict_base(int);
|
||||
void token_actions(void);
|
||||
void goto_actions(void);
|
||||
int default_goto(int);
|
||||
void save_column(int, int);
|
||||
void sort_actions(void);
|
||||
void pack_table(void);
|
||||
int matching_vector(int);
|
||||
int pack_vector(int);
|
||||
void output_base(void);
|
||||
void output_table(void);
|
||||
void output_check(void);
|
||||
void output_ctable(void);
|
||||
int is_C_identifier(char *);
|
||||
void output_defines(void);
|
||||
void output_stored_text(void);
|
||||
void output_debug(void);
|
||||
void output_stype(void);
|
||||
void output_trailing_text(void);
|
||||
void output_semantic_actions(void);
|
||||
void free_itemsets(void);
|
||||
void free_shifts(void);
|
||||
void free_reductions(void);
|
||||
void write_section(char *section_name);
|
||||
|
||||
|
||||
/* reader.c */
|
||||
int cachec(int);
|
||||
char *get_line(void);
|
||||
char *dup_line(void);
|
||||
char *skip_comment(void);
|
||||
int nextc(void);
|
||||
int keyword(void);
|
||||
void copy_ident(void);
|
||||
void copy_string(int, FILE *, FILE *);
|
||||
void copy_comment(FILE *, FILE *);
|
||||
void copy_text(void);
|
||||
void copy_union(void);
|
||||
int hexval(int);
|
||||
bucket *get_literal(void);
|
||||
int is_reserved(char *);
|
||||
bucket *get_name(void);
|
||||
int get_number(void);
|
||||
char *get_tag(void);
|
||||
void declare_tokens(int);
|
||||
void declare_types(void);
|
||||
void declare_start(void);
|
||||
void read_declarations(void);
|
||||
void initialize_grammar(void);
|
||||
void expand_items(void);
|
||||
void expand_rules(void);
|
||||
void advance_to_start(void);
|
||||
void start_rule(bucket *, int);
|
||||
void end_rule(void);
|
||||
void insert_empty_rule(void);
|
||||
void add_symbol(void);
|
||||
void copy_action(void);
|
||||
int mark_symbol(void);
|
||||
void read_grammar(void);
|
||||
void free_tags(void);
|
||||
void pack_names(void);
|
||||
void check_symbols(void);
|
||||
void pack_symbols(void);
|
||||
void pack_grammar(void);
|
||||
void print_grammar(void);
|
||||
void reader(void);
|
||||
|
||||
/* readskel.c */
|
||||
void read_skel(char *);
|
||||
|
||||
/* symtab.c */
|
||||
int hash(char *);
|
||||
bucket *make_bucket(char *);
|
||||
bucket *lookup(char *);
|
||||
void create_symbol_table(void);
|
||||
void free_symbol_table(void);
|
||||
void free_symbols(void);
|
||||
|
||||
/* verbose.c */
|
||||
void verbose(void);
|
||||
void log_unused(void);
|
||||
void log_conflicts(void);
|
||||
void print_state(int);
|
||||
void print_conflicts(int);
|
||||
void print_core(int);
|
||||
void print_nulls(int);
|
||||
void print_actions(int);
|
||||
void print_shifts(action *);
|
||||
void print_reductions(action *, int);
|
||||
void print_gotos(int);
|
||||
|
||||
/* warshall.c */
|
||||
void transitive_closure(unsigned *, int);
|
||||
void reflexive_transitive_closure(unsigned *, int);
|
3
extern/btyacc/empty.y
vendored
Normal file
3
extern/btyacc/empty.y
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
%%
|
||||
start: ;
|
||||
|
218
extern/btyacc/error.c
vendored
Normal file
218
extern/btyacc/error.c
vendored
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* routines for printing error messages
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
extern FILE *inc_file;
|
||||
extern char inc_file_name[];
|
||||
void FileError(char *fmt, ...);
|
||||
|
||||
/*
|
||||
* VM: print error message with file coordinates.
|
||||
* Do it in style acceptable to emacs.
|
||||
*/
|
||||
void FileError(char *fmt, ...) {
|
||||
va_list args;
|
||||
|
||||
fprintf(stderr, "%s:%d: ", (inc_file?inc_file_name:input_file_name), lineno);
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
void fatal(char *msg)
|
||||
{
|
||||
fprintf(stderr, "fatal - %s\n", msg);
|
||||
done(2);
|
||||
}
|
||||
|
||||
|
||||
void no_space()
|
||||
{
|
||||
fprintf(stderr, "fatal - out of space\n");
|
||||
done(2);
|
||||
}
|
||||
|
||||
|
||||
void open_error(char *filename)
|
||||
{
|
||||
fprintf(stderr, "fatal - cannot open \"%s\"\n", filename);
|
||||
done(2);
|
||||
}
|
||||
|
||||
|
||||
void unexpected_EOF()
|
||||
{
|
||||
FileError("unexpected end-of-file");
|
||||
done(1);
|
||||
}
|
||||
|
||||
|
||||
void print_pos(char *st_line, char *st_cptr)
|
||||
{
|
||||
register char *s;
|
||||
|
||||
if (st_line == 0) return;
|
||||
for (s = st_line; *s != '\n'; ++s)
|
||||
{
|
||||
if (isprint(*s) || *s == '\t')
|
||||
putc(*s, stderr);
|
||||
else
|
||||
putc('?', stderr);
|
||||
}
|
||||
putc('\n', stderr);
|
||||
for (s = st_line; s < st_cptr; ++s)
|
||||
{
|
||||
if (*s == '\t')
|
||||
putc('\t', stderr);
|
||||
else
|
||||
putc(' ', stderr);
|
||||
}
|
||||
putc('^', stderr);
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
int read_errs = 0;
|
||||
|
||||
void error(int lineno, char *line, char *cptr, char *msg, ...)
|
||||
{
|
||||
char sbuf[512];
|
||||
va_list args;
|
||||
|
||||
va_start(args, msg);
|
||||
vsprintf(sbuf, msg, args);
|
||||
va_end(args);
|
||||
FileError("%s", sbuf);
|
||||
read_errs++;
|
||||
}
|
||||
|
||||
void syntax_error(int lineno, char *line, char *cptr) {
|
||||
error(lineno, line, cptr, "syntax error");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void unterminated_comment(int lineno, char *line, char *cptr) {
|
||||
error(lineno, line, cptr, "unmatched /*");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void unterminated_string(int lineno, char *line, char *cptr) {
|
||||
error(lineno, line, cptr, "unterminated string");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void unterminated_text(int lineno, char *line, char *cptr) {
|
||||
error(lineno, line, cptr, "unmatched %%{");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void unterminated_union(int lineno, char *line, char *cptr) {
|
||||
error(lineno, line, cptr, "unterminated %%union");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void over_unionized(char *cptr) {
|
||||
error(lineno, line, cptr, "too many %%union declarations");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void illegal_tag(int lineno, char *line, char *cptr) {
|
||||
error(lineno, line, cptr, "illegal tag");
|
||||
}
|
||||
|
||||
void illegal_character(char *cptr) {
|
||||
error(lineno, line, cptr, "illegal character");
|
||||
}
|
||||
|
||||
void used_reserved(char *s) {
|
||||
error(lineno, 0, 0, "illegal use of reserved symbol %s", s);
|
||||
}
|
||||
|
||||
void tokenized_start(char *s) {
|
||||
error(lineno, 0, 0, "the start symbol %s cannot be declared to be a token", s);
|
||||
}
|
||||
|
||||
void retyped_warning(char *s) {
|
||||
FileError("the type of %s has been redeclared", s);
|
||||
}
|
||||
|
||||
|
||||
void reprec_warning(char *s) {
|
||||
FileError("the precedence of %s has been redeclared", s);
|
||||
}
|
||||
|
||||
|
||||
void revalued_warning(char *s) {
|
||||
FileError("the value of %s has been redeclared", s);
|
||||
}
|
||||
|
||||
|
||||
void terminal_start(char *s) {
|
||||
error(lineno, 0, 0, "the start symbol %s is a token", s);
|
||||
}
|
||||
|
||||
void restarted_warning() {
|
||||
FileError("the start symbol has been redeclared");
|
||||
}
|
||||
|
||||
void no_grammar() {
|
||||
error(lineno, 0, 0, "no grammar has been specified");
|
||||
}
|
||||
|
||||
void terminal_lhs(int lineno) {
|
||||
error(lineno, 0, 0, "a token appears on the lhs of a production");
|
||||
}
|
||||
|
||||
void prec_redeclared() {
|
||||
error(lineno, 0, 0, "conflicting %%prec specifiers");
|
||||
}
|
||||
|
||||
void unterminated_action(int lineno, char *line, char *cptr) {
|
||||
error(lineno, line, cptr, "unterminated action");
|
||||
}
|
||||
|
||||
void unterminated_arglist(int lineno, char *line, char *cptr) {
|
||||
error(lineno, line, cptr, "unterminated argument list");
|
||||
}
|
||||
|
||||
void bad_formals() {
|
||||
error(lineno, 0, 0, "bad formal argument list");
|
||||
}
|
||||
|
||||
void dollar_warning(int a_lineno, int i) {
|
||||
int slineno = lineno;
|
||||
lineno = a_lineno;
|
||||
FileError("$%d references beyond the end of the current rule", i);
|
||||
lineno = slineno;
|
||||
}
|
||||
|
||||
void dollar_error(int lineno, char *line, char *cptr) {
|
||||
error(lineno, line, cptr, "illegal $-name");
|
||||
}
|
||||
|
||||
void untyped_lhs() {
|
||||
error(lineno, 0, 0, "$$ is untyped");
|
||||
}
|
||||
|
||||
void untyped_rhs(int i, char *s) {
|
||||
error(lineno, 0, 0, "$%d (%s) is untyped", i, s);
|
||||
}
|
||||
|
||||
void unknown_rhs(int i) {
|
||||
error(lineno, 0, 0, "$%d is untyped (out of range)", i);
|
||||
}
|
||||
|
||||
void default_action_warning() {
|
||||
FileError("the default action assigns an undefined value to $$");
|
||||
}
|
||||
|
||||
void undefined_goal(char *s) {
|
||||
error(lineno, 0, 0, "the start symbol %s is undefined", s);
|
||||
}
|
||||
|
||||
void undefined_symbol_warning(char *s) {
|
||||
fprintf(stderr, "warning - the symbol %s is undefined\n", s);
|
||||
}
|
625
extern/btyacc/lalr.c
vendored
Normal file
625
extern/btyacc/lalr.c
vendored
Normal file
@ -0,0 +1,625 @@
|
||||
#include "defs.h"
|
||||
|
||||
typedef
|
||||
struct shorts
|
||||
{
|
||||
struct shorts *next;
|
||||
Yshort value;
|
||||
}
|
||||
shorts;
|
||||
|
||||
int tokensetsize;
|
||||
Yshort *lookaheads;
|
||||
Yshort *LAruleno;
|
||||
unsigned *LA;
|
||||
Yshort *accessing_symbol;
|
||||
core **state_table;
|
||||
shifts **shift_table;
|
||||
reductions **reduction_table;
|
||||
Yshort *goto_map;
|
||||
Yshort *from_state;
|
||||
Yshort *to_state;
|
||||
|
||||
static int infinity;
|
||||
static int maxrhs;
|
||||
static int ngotos;
|
||||
static unsigned *F;
|
||||
static Yshort **includes;
|
||||
static shorts **lookback;
|
||||
static Yshort **R;
|
||||
static Yshort *INDEX;
|
||||
static Yshort *VERTICES;
|
||||
static int top;
|
||||
|
||||
|
||||
void lalr()
|
||||
{
|
||||
tokensetsize = WORDSIZE(ntokens);
|
||||
|
||||
set_state_table();
|
||||
set_accessing_symbol();
|
||||
set_shift_table();
|
||||
set_reduction_table();
|
||||
set_maxrhs();
|
||||
initialize_LA();
|
||||
set_goto_map();
|
||||
initialize_F();
|
||||
build_relations();
|
||||
compute_FOLLOWS();
|
||||
compute_lookaheads();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void set_state_table()
|
||||
{
|
||||
register core *sp;
|
||||
|
||||
state_table = NEW2(nstates, core *);
|
||||
for (sp = first_state; sp; sp = sp->next)
|
||||
state_table[sp->number] = sp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void set_accessing_symbol()
|
||||
{
|
||||
register core *sp;
|
||||
|
||||
accessing_symbol = NEW2(nstates, Yshort);
|
||||
for (sp = first_state; sp; sp = sp->next)
|
||||
accessing_symbol[sp->number] = sp->accessing_symbol;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void set_shift_table()
|
||||
{
|
||||
register shifts *sp;
|
||||
|
||||
shift_table = NEW2(nstates, shifts *);
|
||||
for (sp = first_shift; sp; sp = sp->next)
|
||||
shift_table[sp->number] = sp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void set_reduction_table()
|
||||
{
|
||||
register reductions *rp;
|
||||
|
||||
reduction_table = NEW2(nstates, reductions *);
|
||||
for (rp = first_reduction; rp; rp = rp->next)
|
||||
reduction_table[rp->number] = rp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void set_maxrhs()
|
||||
{
|
||||
register Yshort *itemp;
|
||||
register Yshort *item_end;
|
||||
register int length;
|
||||
register int max;
|
||||
|
||||
length = 0;
|
||||
max = 0;
|
||||
item_end = ritem + nitems;
|
||||
for (itemp = ritem; itemp < item_end; itemp++)
|
||||
{
|
||||
if (*itemp >= 0)
|
||||
{
|
||||
length++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (length > max) max = length;
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
maxrhs = max;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void initialize_LA()
|
||||
{
|
||||
register int i, j, k;
|
||||
register reductions *rp;
|
||||
|
||||
lookaheads = NEW2(nstates + 1, Yshort);
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < nstates; i++)
|
||||
{
|
||||
lookaheads[i] = k;
|
||||
rp = reduction_table[i];
|
||||
if (rp)
|
||||
k += rp->nreds;
|
||||
}
|
||||
lookaheads[nstates] = k;
|
||||
|
||||
LA = NEW2(k * tokensetsize, unsigned);
|
||||
LAruleno = NEW2(k, Yshort);
|
||||
lookback = NEW2(k, shorts *);
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < nstates; i++)
|
||||
{
|
||||
rp = reduction_table[i];
|
||||
if (rp)
|
||||
{
|
||||
for (j = 0; j < rp->nreds; j++)
|
||||
{
|
||||
LAruleno[k] = rp->rules[j];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void set_goto_map()
|
||||
{
|
||||
register shifts *sp;
|
||||
register int i;
|
||||
register int symbol;
|
||||
register int k;
|
||||
register Yshort *temp_map;
|
||||
register int state2;
|
||||
register int state1;
|
||||
|
||||
goto_map = NEW2(nvars + 1, Yshort) - ntokens;
|
||||
temp_map = NEW2(nvars + 1, Yshort) - ntokens;
|
||||
|
||||
ngotos = 0;
|
||||
for (sp = first_shift; sp; sp = sp->next)
|
||||
{
|
||||
for (i = sp->nshifts - 1; i >= 0; i--)
|
||||
{
|
||||
symbol = accessing_symbol[sp->shift[i]];
|
||||
|
||||
if (ISTOKEN(symbol)) break;
|
||||
|
||||
if (ngotos == MAXSHORT)
|
||||
fatal("too many gotos");
|
||||
|
||||
ngotos++;
|
||||
goto_map[symbol]++;
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
for (i = ntokens; i < nsyms; i++)
|
||||
{
|
||||
temp_map[i] = k;
|
||||
k += goto_map[i];
|
||||
}
|
||||
|
||||
for (i = ntokens; i < nsyms; i++)
|
||||
goto_map[i] = temp_map[i];
|
||||
|
||||
goto_map[nsyms] = ngotos;
|
||||
temp_map[nsyms] = ngotos;
|
||||
|
||||
from_state = NEW2(ngotos, Yshort);
|
||||
to_state = NEW2(ngotos, Yshort);
|
||||
|
||||
for (sp = first_shift; sp; sp = sp->next)
|
||||
{
|
||||
state1 = sp->number;
|
||||
for (i = sp->nshifts - 1; i >= 0; i--)
|
||||
{
|
||||
state2 = sp->shift[i];
|
||||
symbol = accessing_symbol[state2];
|
||||
|
||||
if (ISTOKEN(symbol)) break;
|
||||
|
||||
k = temp_map[symbol]++;
|
||||
from_state[k] = state1;
|
||||
to_state[k] = state2;
|
||||
}
|
||||
}
|
||||
|
||||
FREE(temp_map + ntokens);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Map_goto maps a state/symbol pair into its numeric representation. */
|
||||
|
||||
int map_goto(int state, int symbol)
|
||||
{
|
||||
register int high;
|
||||
register int low;
|
||||
register int middle;
|
||||
register int s;
|
||||
|
||||
low = goto_map[symbol];
|
||||
high = goto_map[symbol + 1];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
assert(low <= high);
|
||||
middle = (low + high) >> 1;
|
||||
s = from_state[middle];
|
||||
if (s == state)
|
||||
return (middle);
|
||||
else if (s < state)
|
||||
low = middle + 1;
|
||||
else
|
||||
high = middle - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void initialize_F()
|
||||
{
|
||||
register int i;
|
||||
register int j;
|
||||
register int k;
|
||||
register shifts *sp;
|
||||
register Yshort *edge;
|
||||
register unsigned *rowp;
|
||||
register Yshort *rp;
|
||||
register Yshort **reads;
|
||||
register int nedges;
|
||||
register int stateno;
|
||||
register int symbol;
|
||||
register int nwords;
|
||||
|
||||
nwords = ngotos * tokensetsize;
|
||||
F = NEW2(nwords, unsigned);
|
||||
|
||||
reads = NEW2(ngotos, Yshort *);
|
||||
edge = NEW2(ngotos + 1, Yshort);
|
||||
nedges = 0;
|
||||
|
||||
rowp = F;
|
||||
for (i = 0; i < ngotos; i++)
|
||||
{
|
||||
stateno = to_state[i];
|
||||
sp = shift_table[stateno];
|
||||
|
||||
if (sp)
|
||||
{
|
||||
k = sp->nshifts;
|
||||
|
||||
for (j = 0; j < k; j++)
|
||||
{
|
||||
symbol = accessing_symbol[sp->shift[j]];
|
||||
if (ISVAR(symbol))
|
||||
break;
|
||||
SETBIT(rowp, symbol);
|
||||
}
|
||||
|
||||
for (; j < k; j++)
|
||||
{
|
||||
symbol = accessing_symbol[sp->shift[j]];
|
||||
if (nullable[symbol])
|
||||
edge[nedges++] = map_goto(stateno, symbol);
|
||||
}
|
||||
|
||||
if (nedges)
|
||||
{
|
||||
reads[i] = rp = NEW2(nedges + 1, Yshort);
|
||||
|
||||
for (j = 0; j < nedges; j++)
|
||||
rp[j] = edge[j];
|
||||
|
||||
rp[nedges] = -1;
|
||||
nedges = 0;
|
||||
}
|
||||
}
|
||||
|
||||
rowp += tokensetsize;
|
||||
}
|
||||
|
||||
SETBIT(F, 0);
|
||||
digraph(reads);
|
||||
|
||||
for (i = 0; i < ngotos; i++)
|
||||
{
|
||||
if (reads[i])
|
||||
FREE(reads[i]);
|
||||
}
|
||||
|
||||
FREE(reads);
|
||||
FREE(edge);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void build_relations()
|
||||
{
|
||||
register int i;
|
||||
register int j;
|
||||
register int k;
|
||||
register Yshort *rulep;
|
||||
register Yshort *rp;
|
||||
register shifts *sp;
|
||||
register int length;
|
||||
register int nedges;
|
||||
register int done;
|
||||
register int state1;
|
||||
register int stateno;
|
||||
register int symbol1;
|
||||
register int symbol2;
|
||||
register Yshort *shortp;
|
||||
register Yshort *edge;
|
||||
register Yshort *states;
|
||||
register Yshort **new_includes;
|
||||
|
||||
includes = NEW2(ngotos, Yshort *);
|
||||
edge = NEW2(ngotos + 1, Yshort);
|
||||
states = NEW2(maxrhs + 1, Yshort);
|
||||
|
||||
for (i = 0; i < ngotos; i++)
|
||||
{
|
||||
nedges = 0;
|
||||
state1 = from_state[i];
|
||||
symbol1 = accessing_symbol[to_state[i]];
|
||||
|
||||
for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
|
||||
{
|
||||
length = 1;
|
||||
states[0] = state1;
|
||||
stateno = state1;
|
||||
|
||||
for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
|
||||
{
|
||||
symbol2 = *rp;
|
||||
sp = shift_table[stateno];
|
||||
k = sp->nshifts;
|
||||
|
||||
for (j = 0; j < k; j++)
|
||||
{
|
||||
stateno = sp->shift[j];
|
||||
if (accessing_symbol[stateno] == symbol2) break;
|
||||
}
|
||||
|
||||
states[length++] = stateno;
|
||||
}
|
||||
|
||||
add_lookback_edge(stateno, *rulep, i);
|
||||
|
||||
length--;
|
||||
done = 0;
|
||||
while (!done)
|
||||
{
|
||||
done = 1;
|
||||
rp--;
|
||||
if (ISVAR(*rp))
|
||||
{
|
||||
stateno = states[--length];
|
||||
edge[nedges++] = map_goto(stateno, *rp);
|
||||
if (nullable[*rp] && length > 0) done = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nedges)
|
||||
{
|
||||
includes[i] = shortp = NEW2(nedges + 1, Yshort);
|
||||
for (j = 0; j < nedges; j++)
|
||||
shortp[j] = edge[j];
|
||||
shortp[nedges] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
new_includes = transpose(includes, ngotos);
|
||||
|
||||
for (i = 0; i < ngotos; i++)
|
||||
if (includes[i])
|
||||
FREE(includes[i]);
|
||||
|
||||
FREE(includes);
|
||||
|
||||
includes = new_includes;
|
||||
|
||||
FREE(edge);
|
||||
FREE(states);
|
||||
}
|
||||
|
||||
|
||||
void add_lookback_edge(int stateno, int ruleno, int gotono)
|
||||
{
|
||||
register int i, k;
|
||||
register int found;
|
||||
register shorts *sp;
|
||||
|
||||
i = lookaheads[stateno];
|
||||
k = lookaheads[stateno + 1];
|
||||
found = 0;
|
||||
while (!found && i < k)
|
||||
{
|
||||
if (LAruleno[i] == ruleno)
|
||||
found = 1;
|
||||
else
|
||||
++i;
|
||||
}
|
||||
assert(found);
|
||||
|
||||
sp = NEW(shorts);
|
||||
sp->next = lookback[i];
|
||||
sp->value = gotono;
|
||||
lookback[i] = sp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Yshort **transpose(Yshort **R, int n)
|
||||
{
|
||||
register Yshort **new_R;
|
||||
register Yshort **temp_R;
|
||||
register Yshort *nedges;
|
||||
register Yshort *sp;
|
||||
register int i;
|
||||
register int k;
|
||||
|
||||
nedges = NEW2(n, Yshort);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
sp = R[i];
|
||||
if (sp)
|
||||
{
|
||||
while (*sp >= 0)
|
||||
nedges[*sp++]++;
|
||||
}
|
||||
}
|
||||
|
||||
new_R = NEW2(n, Yshort *);
|
||||
temp_R = NEW2(n, Yshort *);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
k = nedges[i];
|
||||
if (k > 0)
|
||||
{
|
||||
sp = NEW2(k + 1, Yshort);
|
||||
new_R[i] = sp;
|
||||
temp_R[i] = sp;
|
||||
sp[k] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
FREE(nedges);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
sp = R[i];
|
||||
if (sp)
|
||||
{
|
||||
while (*sp >= 0)
|
||||
*temp_R[*sp++]++ = i;
|
||||
}
|
||||
}
|
||||
|
||||
FREE(temp_R);
|
||||
|
||||
return (new_R);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void compute_FOLLOWS()
|
||||
{
|
||||
digraph(includes);
|
||||
}
|
||||
|
||||
|
||||
void compute_lookaheads()
|
||||
{
|
||||
register int i, n;
|
||||
register unsigned *fp1, *fp2, *fp3;
|
||||
register shorts *sp, *next;
|
||||
register unsigned *rowp;
|
||||
|
||||
rowp = LA;
|
||||
n = lookaheads[nstates];
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
fp3 = rowp + tokensetsize;
|
||||
for (sp = lookback[i]; sp; sp = sp->next)
|
||||
{
|
||||
fp1 = rowp;
|
||||
fp2 = F + tokensetsize * sp->value;
|
||||
while (fp1 < fp3)
|
||||
*fp1++ |= *fp2++;
|
||||
}
|
||||
rowp = fp3;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
for (sp = lookback[i]; sp; sp = next)
|
||||
{
|
||||
next = sp->next;
|
||||
FREE(sp);
|
||||
}
|
||||
|
||||
FREE(lookback);
|
||||
FREE(F);
|
||||
}
|
||||
|
||||
|
||||
void digraph(Yshort **relation)
|
||||
{
|
||||
register int i;
|
||||
|
||||
infinity = ngotos + 2;
|
||||
INDEX = NEW2(ngotos + 1, Yshort);
|
||||
VERTICES = NEW2(ngotos + 1, Yshort);
|
||||
top = 0;
|
||||
|
||||
R = relation;
|
||||
|
||||
for (i = 0; i < ngotos; i++)
|
||||
INDEX[i] = 0;
|
||||
|
||||
for (i = 0; i < ngotos; i++)
|
||||
{
|
||||
if (INDEX[i] == 0 && R[i])
|
||||
traverse(i);
|
||||
}
|
||||
|
||||
FREE(INDEX);
|
||||
FREE(VERTICES);
|
||||
}
|
||||
|
||||
void traverse(int i)
|
||||
{
|
||||
register unsigned *fp1;
|
||||
register unsigned *fp2;
|
||||
register unsigned *fp3;
|
||||
register int j;
|
||||
register Yshort *rp;
|
||||
|
||||
int height;
|
||||
unsigned *base;
|
||||
|
||||
VERTICES[++top] = i;
|
||||
INDEX[i] = height = top;
|
||||
|
||||
base = F + i * tokensetsize;
|
||||
fp3 = base + tokensetsize;
|
||||
|
||||
rp = R[i];
|
||||
if (rp)
|
||||
{
|
||||
while ((j = *rp++) >= 0)
|
||||
{
|
||||
if (INDEX[j] == 0)
|
||||
traverse(j);
|
||||
|
||||
if (INDEX[i] > INDEX[j])
|
||||
INDEX[i] = INDEX[j];
|
||||
|
||||
fp1 = base;
|
||||
fp2 = F + j * tokensetsize;
|
||||
|
||||
while (fp1 < fp3)
|
||||
*fp1++ |= *fp2++;
|
||||
}
|
||||
}
|
||||
|
||||
if (INDEX[i] == height)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
j = VERTICES[top--];
|
||||
INDEX[j] = infinity;
|
||||
|
||||
if (i == j)
|
||||
break;
|
||||
|
||||
fp1 = base;
|
||||
fp2 = F + j * tokensetsize;
|
||||
|
||||
while (fp1 < fp3)
|
||||
*fp2++ = *fp1++;
|
||||
}
|
||||
}
|
||||
}
|
591
extern/btyacc/lr0.c
vendored
Normal file
591
extern/btyacc/lr0.c
vendored
Normal file
@ -0,0 +1,591 @@
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
extern Yshort *itemset;
|
||||
extern Yshort *itemsetend;
|
||||
extern unsigned *ruleset;
|
||||
|
||||
int nstates;
|
||||
core *first_state;
|
||||
shifts *first_shift;
|
||||
reductions *first_reduction;
|
||||
|
||||
static core **state_set;
|
||||
static core *this_state;
|
||||
static core *last_state;
|
||||
static shifts *last_shift;
|
||||
static reductions *last_reduction;
|
||||
|
||||
static int nshifts;
|
||||
static Yshort *shift_symbol;
|
||||
|
||||
static Yshort *redset;
|
||||
static Yshort *shiftset;
|
||||
|
||||
static Yshort **kernel_base;
|
||||
static Yshort **kernel_end;
|
||||
static Yshort *kernel_items;
|
||||
|
||||
|
||||
void allocate_itemsets()
|
||||
{
|
||||
register Yshort *itemp;
|
||||
register Yshort *item_end;
|
||||
register int symbol;
|
||||
register int i;
|
||||
register int count;
|
||||
register int max;
|
||||
register Yshort *symbol_count;
|
||||
|
||||
count = 0;
|
||||
symbol_count = NEW2(nsyms, Yshort);
|
||||
|
||||
item_end = ritem + nitems;
|
||||
for (itemp = ritem; itemp < item_end; itemp++)
|
||||
{
|
||||
symbol = *itemp;
|
||||
if (symbol >= 0)
|
||||
{
|
||||
count++;
|
||||
symbol_count[symbol]++;
|
||||
}
|
||||
}
|
||||
|
||||
kernel_base = NEW2(nsyms, Yshort *);
|
||||
kernel_items = NEW2(count, Yshort);
|
||||
|
||||
count = 0;
|
||||
max = 0;
|
||||
for (i = 0; i < nsyms; i++)
|
||||
{
|
||||
kernel_base[i] = kernel_items + count;
|
||||
count += symbol_count[i];
|
||||
if (max < symbol_count[i])
|
||||
max = symbol_count[i];
|
||||
}
|
||||
|
||||
shift_symbol = symbol_count;
|
||||
kernel_end = NEW2(nsyms, Yshort *);
|
||||
}
|
||||
|
||||
|
||||
void allocate_storage()
|
||||
{
|
||||
allocate_itemsets();
|
||||
shiftset = NEW2(nsyms, Yshort);
|
||||
redset = NEW2(nrules + 1, Yshort);
|
||||
state_set = NEW2(nitems, core *);
|
||||
}
|
||||
|
||||
|
||||
void append_states()
|
||||
{
|
||||
register int i;
|
||||
register int j;
|
||||
register int symbol;
|
||||
|
||||
#ifdef TRACE
|
||||
fprintf(stderr, "Entering append_states()\n");
|
||||
#endif
|
||||
for (i = 1; i < nshifts; i++)
|
||||
{
|
||||
symbol = shift_symbol[i];
|
||||
j = i;
|
||||
while (j > 0 && shift_symbol[j - 1] > symbol)
|
||||
{
|
||||
shift_symbol[j] = shift_symbol[j - 1];
|
||||
j--;
|
||||
}
|
||||
shift_symbol[j] = symbol;
|
||||
}
|
||||
|
||||
for (i = 0; i < nshifts; i++)
|
||||
{
|
||||
symbol = shift_symbol[i];
|
||||
shiftset[i] = get_state(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void free_storage()
|
||||
{
|
||||
FREE(shift_symbol);
|
||||
FREE(redset);
|
||||
FREE(shiftset);
|
||||
FREE(kernel_base);
|
||||
FREE(kernel_end);
|
||||
FREE(kernel_items);
|
||||
FREE(state_set);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void generate_states()
|
||||
{
|
||||
allocate_storage();
|
||||
itemset = NEW2(nitems, Yshort);
|
||||
ruleset = NEW2(WORDSIZE(nrules), unsigned);
|
||||
set_first_derives();
|
||||
initialize_states();
|
||||
|
||||
while (this_state)
|
||||
{
|
||||
closure(this_state->items, this_state->nitems);
|
||||
save_reductions();
|
||||
new_itemsets();
|
||||
append_states();
|
||||
|
||||
if (nshifts > 0)
|
||||
save_shifts();
|
||||
|
||||
this_state = this_state->next;
|
||||
}
|
||||
|
||||
finalize_closure();
|
||||
free_storage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int get_state(int symbol)
|
||||
{
|
||||
register int key;
|
||||
register Yshort *isp1;
|
||||
register Yshort *isp2;
|
||||
register Yshort *iend;
|
||||
register core *sp;
|
||||
register int found;
|
||||
register int n;
|
||||
|
||||
#ifdef TRACE
|
||||
fprintf(stderr, "Entering get_state(%d)\n", symbol);
|
||||
#endif
|
||||
|
||||
isp1 = kernel_base[symbol];
|
||||
iend = kernel_end[symbol];
|
||||
n = iend - isp1;
|
||||
|
||||
key = *isp1;
|
||||
assert(0 <= key && key < nitems);
|
||||
sp = state_set[key];
|
||||
if (sp)
|
||||
{
|
||||
found = 0;
|
||||
while (!found)
|
||||
{
|
||||
if (sp->nitems == n)
|
||||
{
|
||||
found = 1;
|
||||
isp1 = kernel_base[symbol];
|
||||
isp2 = sp->items;
|
||||
|
||||
while (found && isp1 < iend)
|
||||
{
|
||||
if (*isp1++ != *isp2++)
|
||||
found = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (sp->link)
|
||||
{
|
||||
sp = sp->link;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp = sp->link = new_state(symbol);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state_set[key] = sp = new_state(symbol);
|
||||
}
|
||||
|
||||
return (sp->number);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void initialize_states()
|
||||
{
|
||||
register int i;
|
||||
register Yshort *start_derives;
|
||||
register core *p;
|
||||
|
||||
start_derives = derives[start_symbol];
|
||||
for (i = 0; start_derives[i] >= 0; ++i)
|
||||
continue;
|
||||
|
||||
p = (core *) MALLOC(sizeof(core) + i*sizeof(Yshort));
|
||||
if (p == 0) no_space();
|
||||
|
||||
p->next = 0;
|
||||
p->link = 0;
|
||||
p->number = 0;
|
||||
p->accessing_symbol = 0;
|
||||
p->nitems = i;
|
||||
|
||||
for (i = 0; start_derives[i] >= 0; ++i)
|
||||
p->items[i] = rrhs[start_derives[i]];
|
||||
|
||||
first_state = last_state = this_state = p;
|
||||
nstates = 1;
|
||||
}
|
||||
|
||||
|
||||
void new_itemsets()
|
||||
{
|
||||
register int i;
|
||||
register int shiftcount;
|
||||
register Yshort *isp;
|
||||
register Yshort *ksp;
|
||||
register int symbol;
|
||||
|
||||
for (i = 0; i < nsyms; i++)
|
||||
kernel_end[i] = 0;
|
||||
|
||||
shiftcount = 0;
|
||||
isp = itemset;
|
||||
while (isp < itemsetend)
|
||||
{
|
||||
i = *isp++;
|
||||
symbol = ritem[i];
|
||||
if (symbol > 0)
|
||||
{
|
||||
ksp = kernel_end[symbol];
|
||||
if (!ksp)
|
||||
{
|
||||
shift_symbol[shiftcount++] = symbol;
|
||||
ksp = kernel_base[symbol];
|
||||
}
|
||||
|
||||
*ksp++ = i + 1;
|
||||
kernel_end[symbol] = ksp;
|
||||
}
|
||||
}
|
||||
|
||||
nshifts = shiftcount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
core *new_state(int symbol)
|
||||
{
|
||||
register int n;
|
||||
register core *p;
|
||||
register Yshort *isp1;
|
||||
register Yshort *isp2;
|
||||
register Yshort *iend;
|
||||
|
||||
#ifdef TRACE
|
||||
fprintf(stderr, "Entering new_state(%d)\n", symbol);
|
||||
#endif
|
||||
|
||||
if (nstates >= MAXSHORT)
|
||||
fatal("too many states");
|
||||
|
||||
isp1 = kernel_base[symbol];
|
||||
iend = kernel_end[symbol];
|
||||
n = iend - isp1;
|
||||
|
||||
p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(Yshort)));
|
||||
p->accessing_symbol = symbol;
|
||||
p->number = nstates;
|
||||
p->nitems = n;
|
||||
|
||||
isp2 = p->items;
|
||||
while (isp1 < iend)
|
||||
*isp2++ = *isp1++;
|
||||
|
||||
last_state->next = p;
|
||||
last_state = p;
|
||||
|
||||
nstates++;
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
/* show_cores is used for debugging */
|
||||
|
||||
void show_cores()
|
||||
{
|
||||
core *p;
|
||||
int i, j, k, n;
|
||||
int itemno;
|
||||
|
||||
k = 0;
|
||||
for (p = first_state; p; ++k, p = p->next)
|
||||
{
|
||||
if (k) printf("\n");
|
||||
printf("state %d, number = %d, accessing symbol = %s\n",
|
||||
k, p->number, symbol_name[p->accessing_symbol]);
|
||||
n = p->nitems;
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
itemno = p->items[i];
|
||||
printf("%4d ", itemno);
|
||||
j = itemno;
|
||||
while (ritem[j] >= 0) ++j;
|
||||
printf("%s :", symbol_name[rlhs[-ritem[j]]]);
|
||||
j = rrhs[-ritem[j]];
|
||||
while (j < itemno)
|
||||
printf(" %s", symbol_name[ritem[j++]]);
|
||||
printf(" .");
|
||||
while (ritem[j] >= 0)
|
||||
printf(" %s", symbol_name[ritem[j++]]);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* show_ritems is used for debugging */
|
||||
|
||||
void show_ritems()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nitems; ++i)
|
||||
printf("ritem[%d] = %d\n", i, ritem[i]);
|
||||
}
|
||||
|
||||
|
||||
/* show_rrhs is used for debugging */
|
||||
void show_rrhs()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nrules; ++i)
|
||||
printf("rrhs[%d] = %d\n", i, rrhs[i]);
|
||||
}
|
||||
|
||||
|
||||
/* show_shifts is used for debugging */
|
||||
|
||||
void show_shifts()
|
||||
{
|
||||
shifts *p;
|
||||
int i, j, k;
|
||||
|
||||
k = 0;
|
||||
for (p = first_shift; p; ++k, p = p->next)
|
||||
{
|
||||
if (k) printf("\n");
|
||||
printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
|
||||
p->nshifts);
|
||||
j = p->nshifts;
|
||||
for (i = 0; i < j; ++i)
|
||||
printf("\t%d\n", p->shift[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void save_shifts()
|
||||
{
|
||||
register shifts *p;
|
||||
register Yshort *sp1;
|
||||
register Yshort *sp2;
|
||||
register Yshort *send;
|
||||
|
||||
p = (shifts *) allocate((unsigned) (sizeof(shifts) +
|
||||
(nshifts - 1) * sizeof(Yshort)));
|
||||
|
||||
p->number = this_state->number;
|
||||
p->nshifts = nshifts;
|
||||
|
||||
sp1 = shiftset;
|
||||
sp2 = p->shift;
|
||||
send = shiftset + nshifts;
|
||||
|
||||
while (sp1 < send)
|
||||
*sp2++ = *sp1++;
|
||||
|
||||
if (last_shift)
|
||||
{
|
||||
last_shift->next = p;
|
||||
last_shift = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_shift = p;
|
||||
last_shift = p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void save_reductions()
|
||||
{
|
||||
register Yshort *isp;
|
||||
register Yshort *rp1;
|
||||
register Yshort *rp2;
|
||||
register int item;
|
||||
register int count;
|
||||
register reductions *p;
|
||||
register Yshort *rend;
|
||||
|
||||
count = 0;
|
||||
for (isp = itemset; isp < itemsetend; isp++)
|
||||
{
|
||||
item = ritem[*isp];
|
||||
if (item < 0)
|
||||
{
|
||||
redset[count++] = -item;
|
||||
}
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
p = (reductions *) allocate((unsigned) (sizeof(reductions) +
|
||||
(count - 1) * sizeof(Yshort)));
|
||||
|
||||
p->number = this_state->number;
|
||||
p->nreds = count;
|
||||
|
||||
rp1 = redset;
|
||||
rp2 = p->rules;
|
||||
rend = rp1 + count;
|
||||
|
||||
while (rp1 < rend)
|
||||
*rp2++ = *rp1++;
|
||||
|
||||
if (last_reduction)
|
||||
{
|
||||
last_reduction->next = p;
|
||||
last_reduction = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_reduction = p;
|
||||
last_reduction = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void set_derives()
|
||||
{
|
||||
register int i, k;
|
||||
register int lhs;
|
||||
register Yshort *rules;
|
||||
|
||||
derives = NEW2(nsyms, Yshort *);
|
||||
rules = NEW2(nvars + nrules, Yshort);
|
||||
|
||||
k = 0;
|
||||
for (lhs = start_symbol; lhs < nsyms; lhs++)
|
||||
{
|
||||
derives[lhs] = rules + k;
|
||||
for (i = 0; i < nrules; i++)
|
||||
{
|
||||
if (rlhs[i] == lhs)
|
||||
{
|
||||
rules[k] = i;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
rules[k] = -1;
|
||||
k++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
print_derives();
|
||||
#endif
|
||||
}
|
||||
|
||||
void free_derives()
|
||||
{
|
||||
FREE(derives[start_symbol]);
|
||||
FREE(derives);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void print_derives()
|
||||
{
|
||||
register int i;
|
||||
register Yshort *sp;
|
||||
|
||||
printf("\nDERIVES\n\n");
|
||||
|
||||
for (i = start_symbol; i < nsyms; i++)
|
||||
{
|
||||
printf("%s derives ", symbol_name[i]);
|
||||
for (sp = derives[i]; *sp >= 0; sp++)
|
||||
{
|
||||
printf(" %d", *sp);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void set_nullable()
|
||||
{
|
||||
register int i, j;
|
||||
register int empty;
|
||||
int done;
|
||||
|
||||
nullable = MALLOC(nsyms);
|
||||
if (nullable == 0) no_space();
|
||||
|
||||
for (i = 0; i < nsyms; ++i)
|
||||
nullable[i] = 0;
|
||||
|
||||
done = 0;
|
||||
while (!done)
|
||||
{
|
||||
done = 1;
|
||||
for (i = 1; i < nitems; i++)
|
||||
{
|
||||
empty = 1;
|
||||
while ((j = ritem[i]) >= 0)
|
||||
{
|
||||
if (!nullable[j])
|
||||
empty = 0;
|
||||
++i;
|
||||
}
|
||||
if (empty)
|
||||
{
|
||||
j = rlhs[-j];
|
||||
if (!nullable[j])
|
||||
{
|
||||
nullable[j] = 1;
|
||||
done = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < nsyms; i++)
|
||||
{
|
||||
if (nullable[i])
|
||||
printf("%s is nullable\n", symbol_name[i]);
|
||||
else
|
||||
printf("%s is not nullable\n", symbol_name[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void free_nullable()
|
||||
{
|
||||
FREE(nullable);
|
||||
}
|
||||
|
||||
|
||||
void lr0()
|
||||
{
|
||||
set_derives();
|
||||
set_nullable();
|
||||
generate_states();
|
||||
}
|
418
extern/btyacc/main.c
vendored
Normal file
418
extern/btyacc/main.c
vendored
Normal file
@ -0,0 +1,418 @@
|
||||
#include "defs.h"
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
|
||||
#if !defined(WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
char dflag;
|
||||
char lflag;
|
||||
char rflag;
|
||||
char tflag;
|
||||
char vflag;
|
||||
int Eflag = 0;
|
||||
|
||||
char *file_prefix = "y";
|
||||
char *myname = "yacc";
|
||||
#if defined(__MSDOS__) || defined(WIN32)
|
||||
#define DIR_CHAR '\\'
|
||||
#define DEFAULT_TMPDIR "."
|
||||
#else /* Unix */
|
||||
#define DIR_CHAR '/'
|
||||
#define DEFAULT_TMPDIR "/tmp"
|
||||
#endif
|
||||
char *temp_form = "yacc_t_XXXXXX";
|
||||
|
||||
int lineno;
|
||||
int outline;
|
||||
|
||||
char *action_file_name;
|
||||
char *code_file_name;
|
||||
char *defines_file_name;
|
||||
char *input_file_name = "";
|
||||
char *output_file_name;
|
||||
char *text_file_name;
|
||||
char *union_file_name;
|
||||
char *verbose_file_name;
|
||||
|
||||
FILE *action_file; /* a temp file, used to save actions associated */
|
||||
/* with rules until the parser is written */
|
||||
FILE *code_file; /* y.code.c (used when the -r option is specified) */
|
||||
FILE *defines_file; /* y.tab.h */
|
||||
FILE *input_file; /* the input file */
|
||||
FILE *output_file; /* y.tab.c */
|
||||
FILE *text_file; /* a temp file, used to save text until all */
|
||||
/* symbols have been defined */
|
||||
FILE *union_file; /* a temp file, used to save the union */
|
||||
/* definition until all symbol have been */
|
||||
/* defined */
|
||||
FILE *verbose_file; /* y.output */
|
||||
|
||||
int nitems;
|
||||
int nrules;
|
||||
int nsyms;
|
||||
int ntokens;
|
||||
int nvars;
|
||||
|
||||
int start_symbol;
|
||||
char **symbol_name;
|
||||
Yshort *symbol_value;
|
||||
Yshort *symbol_prec;
|
||||
char *symbol_assoc;
|
||||
|
||||
Yshort *ritem;
|
||||
Yshort *rlhs;
|
||||
Yshort *rrhs;
|
||||
Yshort *rprec;
|
||||
char *rassoc;
|
||||
Yshort **derives;
|
||||
char *nullable;
|
||||
|
||||
|
||||
void done(int k)
|
||||
{
|
||||
if (action_file) { fclose(action_file); unlink(action_file_name); }
|
||||
if (text_file) { fclose(text_file); unlink(text_file_name); }
|
||||
if (union_file) { fclose(union_file); unlink(union_file_name); }
|
||||
exit(k);
|
||||
}
|
||||
|
||||
|
||||
void onintr()
|
||||
{
|
||||
done(1);
|
||||
}
|
||||
|
||||
|
||||
void set_signals()
|
||||
{
|
||||
#ifdef SIGINT
|
||||
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
|
||||
signal(SIGINT, onintr);
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
|
||||
signal(SIGTERM, onintr);
|
||||
#endif
|
||||
#ifdef SIGHUP
|
||||
if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
|
||||
signal(SIGHUP, onintr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void usage()
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-S skeleton file] "
|
||||
"filename\n", myname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void getargs(int argc, char **argv)
|
||||
{
|
||||
register int i;
|
||||
register char *s;
|
||||
|
||||
if (argc > 0) myname = argv[0];
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
s = argv[i];
|
||||
if (*s != '-') break;
|
||||
switch (*++s)
|
||||
{
|
||||
case '\0':
|
||||
input_file = stdin;
|
||||
if (i + 1 < argc) usage();
|
||||
return;
|
||||
|
||||
case '-':
|
||||
++i;
|
||||
goto no_more_options;
|
||||
|
||||
case 'b':
|
||||
if (*++s)
|
||||
file_prefix = s;
|
||||
else if (++i < argc)
|
||||
file_prefix = argv[i];
|
||||
else
|
||||
usage();
|
||||
continue;
|
||||
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
/* Find the preprocessor variable */
|
||||
{ char **ps;
|
||||
char *var_name = s + 1;
|
||||
extern char *defd_vars[];
|
||||
for(ps=&defd_vars[0]; *ps; ps++) {
|
||||
if(strcmp(*ps,var_name)==0) {
|
||||
error(lineno, 0, 0, "Preprocessor variable %s already defined", var_name);
|
||||
}
|
||||
}
|
||||
*ps = MALLOC(strlen(var_name)+1);
|
||||
strcpy(*ps, var_name);
|
||||
*++ps = NULL;
|
||||
}
|
||||
continue;
|
||||
|
||||
case 'E':
|
||||
Eflag = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
lflag = 1;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
rflag = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
tflag = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
vflag = 1;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
if (*++s)
|
||||
read_skel(s);
|
||||
else if (++i < argc)
|
||||
read_skel(argv[i]);
|
||||
else
|
||||
usage();
|
||||
continue;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
switch (*++s)
|
||||
{
|
||||
case '\0':
|
||||
goto end_of_option;
|
||||
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
lflag = 1;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
rflag = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
tflag = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
vflag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
end_of_option:;
|
||||
}
|
||||
|
||||
no_more_options:;
|
||||
if (i + 1 != argc) usage();
|
||||
input_file_name = argv[i];
|
||||
|
||||
if (!file_prefix) {
|
||||
if (input_file_name) {
|
||||
file_prefix = strdup(input_file_name);
|
||||
if ((s = strrchr(file_prefix, '.')))
|
||||
*s = 0;
|
||||
} else {
|
||||
file_prefix = "y";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *allocate(unsigned n)
|
||||
{
|
||||
register char *p;
|
||||
|
||||
p = NULL;
|
||||
if (n)
|
||||
{
|
||||
/* VM: add a few bytes here, cause
|
||||
* Linux calloc does not like sizes like 32768 */
|
||||
p = CALLOC(1, n+10);
|
||||
if (!p) no_space();
|
||||
}
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
void create_file_names()
|
||||
{
|
||||
int i, len;
|
||||
char *tmpdir;
|
||||
|
||||
tmpdir = getenv("TMPDIR");
|
||||
if (tmpdir == 0) tmpdir = DEFAULT_TMPDIR;
|
||||
|
||||
len = strlen(tmpdir);
|
||||
i = len + 13;
|
||||
if (len && tmpdir[len-1] != DIR_CHAR)
|
||||
++i;
|
||||
|
||||
action_file_name = MALLOC(i);
|
||||
if (action_file_name == 0) no_space();
|
||||
text_file_name = MALLOC(i);
|
||||
if (text_file_name == 0) no_space();
|
||||
union_file_name = MALLOC(i);
|
||||
if (union_file_name == 0) no_space();
|
||||
|
||||
strcpy(action_file_name, tmpdir);
|
||||
strcpy(text_file_name, tmpdir);
|
||||
strcpy(union_file_name, tmpdir);
|
||||
|
||||
if (len && tmpdir[len - 1] != DIR_CHAR)
|
||||
{
|
||||
action_file_name[len] = DIR_CHAR;
|
||||
text_file_name[len] = DIR_CHAR;
|
||||
union_file_name[len] = DIR_CHAR;
|
||||
++len;
|
||||
}
|
||||
|
||||
strcpy(action_file_name + len, temp_form);
|
||||
strcpy(text_file_name + len, temp_form);
|
||||
strcpy(union_file_name + len, temp_form);
|
||||
|
||||
action_file_name[len + 5] = 'a';
|
||||
text_file_name[len + 5] = 't';
|
||||
union_file_name[len + 5] = 'u';
|
||||
|
||||
if(mktemp(action_file_name)==NULL) {
|
||||
fprintf(stderr, "btyacc: Cannot create temporary file\n");
|
||||
exit(1);
|
||||
}
|
||||
if(mktemp(text_file_name)==NULL) {
|
||||
fprintf(stderr, "btyacc: Cannot create temporary file\n");
|
||||
exit(1);
|
||||
}
|
||||
if(mktemp(union_file_name)==NULL) {
|
||||
fprintf(stderr, "btyacc: Cannot create temporary file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
len = strlen(file_prefix);
|
||||
|
||||
output_file_name = MALLOC(len + 7);
|
||||
if (output_file_name == 0)
|
||||
no_space();
|
||||
strcpy(output_file_name, file_prefix);
|
||||
strcpy(output_file_name + len, OUTPUT_SUFFIX);
|
||||
|
||||
if (rflag)
|
||||
{
|
||||
code_file_name = MALLOC(len + 8);
|
||||
if (code_file_name == 0)
|
||||
no_space();
|
||||
strcpy(code_file_name, file_prefix);
|
||||
strcpy(code_file_name + len, CODE_SUFFIX);
|
||||
}
|
||||
else
|
||||
code_file_name = output_file_name;
|
||||
|
||||
if (dflag)
|
||||
{
|
||||
defines_file_name = MALLOC(len + 7);
|
||||
if (defines_file_name == 0)
|
||||
no_space();
|
||||
strcpy(defines_file_name, file_prefix);
|
||||
strcpy(defines_file_name + len, DEFINES_SUFFIX);
|
||||
}
|
||||
|
||||
if (vflag)
|
||||
{
|
||||
verbose_file_name = MALLOC(len + 8);
|
||||
if (verbose_file_name == 0)
|
||||
no_space();
|
||||
strcpy(verbose_file_name, file_prefix);
|
||||
strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void open_files()
|
||||
{
|
||||
create_file_names();
|
||||
|
||||
if (input_file == 0)
|
||||
{
|
||||
input_file = fopen(input_file_name, "r");
|
||||
if (input_file == 0)
|
||||
open_error(input_file_name);
|
||||
}
|
||||
|
||||
action_file = fopen(action_file_name, "w");
|
||||
if (action_file == 0)
|
||||
open_error(action_file_name);
|
||||
|
||||
text_file = fopen(text_file_name, "w");
|
||||
if (text_file == 0)
|
||||
open_error(text_file_name);
|
||||
|
||||
if (vflag)
|
||||
{
|
||||
verbose_file = fopen(verbose_file_name, "w");
|
||||
if (verbose_file == 0)
|
||||
open_error(verbose_file_name);
|
||||
}
|
||||
|
||||
if (dflag)
|
||||
{
|
||||
defines_file = fopen(defines_file_name, "w");
|
||||
if (defines_file == 0)
|
||||
open_error(defines_file_name);
|
||||
union_file = fopen(union_file_name, "w");
|
||||
if (union_file == 0)
|
||||
open_error(union_file_name);
|
||||
}
|
||||
|
||||
output_file = fopen(output_file_name, "w");
|
||||
if (output_file == 0)
|
||||
open_error(output_file_name);
|
||||
|
||||
if (rflag)
|
||||
{
|
||||
code_file = fopen(code_file_name, "w");
|
||||
if (code_file == 0)
|
||||
open_error(code_file_name);
|
||||
}
|
||||
else
|
||||
code_file = output_file;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
set_signals();
|
||||
getargs(argc, argv);
|
||||
open_files();
|
||||
reader();
|
||||
lr0();
|
||||
lalr();
|
||||
make_parser();
|
||||
verbose();
|
||||
output();
|
||||
done(0);
|
||||
return 0;
|
||||
}
|
71
extern/btyacc/makefile.dos
vendored
Normal file
71
extern/btyacc/makefile.dos
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
# Makefile for MS-DOS using Borland C (by P. Foggia)
|
||||
#
|
||||
DEST = .
|
||||
|
||||
HDRS = defs.h mstring.h
|
||||
|
||||
CFLAGS = -ml -c
|
||||
|
||||
LDFLAGS = /c
|
||||
|
||||
# Change LIBDIR to your compiler's library path
|
||||
LIBDIR = L:\bc\lib
|
||||
C0 = $(LIBDIR)\c0l.obj
|
||||
CLIB = $(LIBDIR)\cl.lib
|
||||
|
||||
LIBS =
|
||||
|
||||
LINKER = tlink
|
||||
CC = bcc
|
||||
|
||||
MAKEFILE = Makefile.dos
|
||||
|
||||
OBJS1 = closure.obj error.obj lalr.obj lr0.obj main.obj mkpar.obj output.obj
|
||||
OBJS2 = mstring.obj reader.obj skeleton.obj symtab.obj verbose.obj warshall.obj
|
||||
OBJS = $(OBJS1) $(OBJS2)
|
||||
|
||||
|
||||
PROGRAM = btyacc.exe
|
||||
|
||||
SRCS = closure.c error.c lalr.c lr0.c main.c mkpar.c output.c \
|
||||
mstring.c reader.c skeleton.c symtab.c verbose.c warshall.c
|
||||
|
||||
OTHERS = README README.BYACC \
|
||||
Makefile btyaccpa.ske empty.y skel2c manpage
|
||||
|
||||
all: $(PROGRAM)
|
||||
|
||||
$(PROGRAM): $(OBJS) $(LIBS)
|
||||
@echo Linking $(PROGRAM) ...
|
||||
@echo $(LDFLAGS) $(C0) + > link.lst
|
||||
@echo $(OBJS1) + >> link.lst
|
||||
@echo $(OBJS2) >> link.lst
|
||||
@echo $(PROGRAM) >>link.lst
|
||||
@echo nul >> link.lst
|
||||
@echo $(CLIB) >> link.lst
|
||||
@$(LINKER) @link.lst
|
||||
@echo ... done
|
||||
|
||||
|
||||
|
||||
|
||||
program: $(PROGRAM)
|
||||
|
||||
|
||||
skeleton.c: btyaccpa.ske
|
||||
awk -f skel2c btyaccpa.ske >skeleton.c
|
||||
|
||||
###
|
||||
closure.o: defs.h
|
||||
error.o: defs.h
|
||||
lalr.o: defs.h
|
||||
lr0.o: defs.h
|
||||
main.o: defs.h
|
||||
mkpar.o: defs.h
|
||||
mstring.o: mstring.h
|
||||
output.o: defs.h
|
||||
reader.o: defs.h mstring.h
|
||||
skeleton.o: defs.h
|
||||
symtab.o: defs.h
|
||||
verbose.o: defs.h
|
||||
warshall.o: defs.h
|
105
extern/btyacc/manpage
vendored
Normal file
105
extern/btyacc/manpage
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
.\" %W% %R% (Berkeley) %E%
|
||||
.\"
|
||||
.TH YACC 1 "July\ 15,\ 1990"
|
||||
.UC 6
|
||||
.SH NAME
|
||||
Yacc \- an LALR(1) parser generator
|
||||
.SH SYNOPSIS
|
||||
.B yacc [ -dlrtv ] [ -b
|
||||
.I prefix
|
||||
.B ] [ -S
|
||||
.I skeleton file
|
||||
.B ]
|
||||
.I filename
|
||||
.SH DESCRIPTION
|
||||
.I Yacc
|
||||
reads the grammar specification in the file
|
||||
.I filename
|
||||
and generates an LR(1) parser for it.
|
||||
The parsers consist of a set of LALR(1) parsing tables and a driver routine
|
||||
written in the C programming language.
|
||||
.I Yacc
|
||||
normally writes the parse tables and the driver routine to the file
|
||||
.IR y.tab.c.
|
||||
.PP
|
||||
The following options are available:
|
||||
.RS
|
||||
.TP
|
||||
\fB-b \fIprefix\fR
|
||||
The
|
||||
.B -b
|
||||
option changes the prefix prepended to the output file names to
|
||||
the string denoted by
|
||||
.IR prefix.
|
||||
The default prefix is derived from the input filename.
|
||||
.TP
|
||||
.B -d
|
||||
The \fB-d\fR option causes the header file
|
||||
.IR y.tab.h
|
||||
to be written.
|
||||
.TP
|
||||
.B -l
|
||||
If the
|
||||
.B -l
|
||||
option is not specified,
|
||||
.I yacc
|
||||
will insert \fB#line\fR directives in the generated code.
|
||||
The \fB#line\fR directives let the C compiler relate errors in the
|
||||
generated code to the user's original code.
|
||||
If the \fB-l\fR option is specified,
|
||||
.I yacc
|
||||
will not insert the \fB#line\fR directives.
|
||||
\fB#line\fR directives specified by the user will be retained.
|
||||
.TP
|
||||
.B -r
|
||||
The
|
||||
.B -r
|
||||
option causes
|
||||
.I yacc
|
||||
to produce separate files for code and tables. The code file
|
||||
is named
|
||||
.IR y.code.c,
|
||||
and the tables file is named
|
||||
.IR y.tab.c.
|
||||
.TP
|
||||
.B -t
|
||||
The
|
||||
.B -t
|
||||
option changes the preprocessor directives generated by
|
||||
.I yacc
|
||||
so that debugging statements will be incorporated in the compiled code.
|
||||
.TP
|
||||
.B -v
|
||||
The
|
||||
.B -v
|
||||
option causes a human-readable description of the generated parser to
|
||||
be written to the file
|
||||
.IR y.output.
|
||||
.TP
|
||||
\fB-S \fIskeleton file\fR
|
||||
The \fB-S\fR option causes a different skeleton file to be used. The
|
||||
default skeleton file is built in to \fIyacc\fR when it is built.
|
||||
.RE
|
||||
.PP
|
||||
If the environment variable TMPDIR is set, the string denoted by
|
||||
TMPDIR will be used as the name of the directory where the temporary
|
||||
files are created.
|
||||
.SH FILES
|
||||
.IR filename\fB.code.c
|
||||
.br
|
||||
.IR filename\fB.tab.c
|
||||
.br
|
||||
.IR filename\fB.tab.h
|
||||
.br
|
||||
.IR filename\fB.output
|
||||
.br
|
||||
.BR /tmp/yacc.aXXXXXX
|
||||
.br
|
||||
.BR /tmp/yacc.tXXXXXX
|
||||
.br
|
||||
.BR /tmp/yacc.uXXXXXX
|
||||
.SH DIAGNOSTICS
|
||||
If there are rules that are never reduced, the number of such rules is
|
||||
reported on standard error.
|
||||
If there are any LALR(1) conflicts, the number of conflicts is reported
|
||||
on standard error.
|
320
extern/btyacc/mkpar.c
vendored
Normal file
320
extern/btyacc/mkpar.c
vendored
Normal file
@ -0,0 +1,320 @@
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
action **parser;
|
||||
int SRtotal;
|
||||
int RRtotal;
|
||||
Yshort *SRconflicts;
|
||||
Yshort *RRconflicts;
|
||||
Yshort *defred;
|
||||
Yshort *rules_used;
|
||||
Yshort nunused;
|
||||
Yshort final_state;
|
||||
|
||||
static int SRcount;
|
||||
static int RRcount;
|
||||
|
||||
action *parse_actions(int stateno);
|
||||
action *get_shifts(int stateno);
|
||||
action *add_reductions(int stateno, action *actions);
|
||||
action *add_reduce(action *actions, int ruleno, int symbol);
|
||||
|
||||
|
||||
void make_parser()
|
||||
{
|
||||
register int i;
|
||||
|
||||
parser = NEW2(nstates, action *);
|
||||
for (i = 0; i < nstates; i++)
|
||||
parser[i] = parse_actions(i);
|
||||
|
||||
find_final_state();
|
||||
remove_conflicts();
|
||||
unused_rules();
|
||||
if (SRtotal + RRtotal > 0) total_conflicts();
|
||||
defreds();
|
||||
}
|
||||
|
||||
action *parse_actions(int stateno)
|
||||
{
|
||||
register action *actions;
|
||||
|
||||
actions = get_shifts(stateno);
|
||||
actions = add_reductions(stateno, actions);
|
||||
return (actions);
|
||||
}
|
||||
|
||||
action *get_shifts(int stateno)
|
||||
{
|
||||
register action *actions, *temp;
|
||||
register shifts *sp;
|
||||
register Yshort *to_state;
|
||||
register int i, k;
|
||||
register int symbol;
|
||||
|
||||
actions = 0;
|
||||
sp = shift_table[stateno];
|
||||
if (sp)
|
||||
{
|
||||
to_state = sp->shift;
|
||||
for (i = sp->nshifts - 1; i >= 0; i--)
|
||||
{
|
||||
k = to_state[i];
|
||||
symbol = accessing_symbol[k];
|
||||
if (ISTOKEN(symbol))
|
||||
{
|
||||
temp = NEW(action);
|
||||
temp->next = actions;
|
||||
temp->symbol = symbol;
|
||||
temp->number = k;
|
||||
temp->prec = symbol_prec[symbol];
|
||||
temp->action_code = SHIFT;
|
||||
temp->assoc = symbol_assoc[symbol];
|
||||
actions = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (actions);
|
||||
}
|
||||
|
||||
action *add_reductions(int stateno, action *actions)
|
||||
{
|
||||
register int i, j, m, n;
|
||||
register int ruleno, tokensetsize;
|
||||
register unsigned *rowp;
|
||||
|
||||
tokensetsize = WORDSIZE(ntokens);
|
||||
m = lookaheads[stateno];
|
||||
n = lookaheads[stateno + 1];
|
||||
for (i = m; i < n; i++)
|
||||
{
|
||||
ruleno = LAruleno[i];
|
||||
rowp = LA + i * tokensetsize;
|
||||
for (j = ntokens - 1; j >= 0; j--)
|
||||
{
|
||||
if (BIT(rowp, j))
|
||||
actions = add_reduce(actions, ruleno, j);
|
||||
}
|
||||
}
|
||||
return (actions);
|
||||
}
|
||||
|
||||
action *add_reduce(action *actions, int ruleno, int symbol)
|
||||
{
|
||||
register action *temp, *prev, *next;
|
||||
|
||||
prev = 0;
|
||||
for (next = actions; next && next->symbol < symbol; next = next->next)
|
||||
prev = next;
|
||||
|
||||
while (next && next->symbol == symbol && next->action_code == SHIFT)
|
||||
{
|
||||
prev = next;
|
||||
next = next->next;
|
||||
}
|
||||
|
||||
while (next && next->symbol == symbol &&
|
||||
next->action_code == REDUCE && next->number < ruleno)
|
||||
{
|
||||
prev = next;
|
||||
next = next->next;
|
||||
}
|
||||
|
||||
temp = NEW(action);
|
||||
temp->next = next;
|
||||
temp->symbol = symbol;
|
||||
temp->number = ruleno;
|
||||
temp->prec = rprec[ruleno];
|
||||
temp->action_code = REDUCE;
|
||||
temp->assoc = rassoc[ruleno];
|
||||
|
||||
if (prev)
|
||||
prev->next = temp;
|
||||
else
|
||||
actions = temp;
|
||||
|
||||
return (actions);
|
||||
}
|
||||
|
||||
void find_final_state()
|
||||
{
|
||||
register int goal, i;
|
||||
register Yshort *to_state;
|
||||
register shifts *p;
|
||||
|
||||
p = shift_table[0];
|
||||
to_state = p->shift;
|
||||
goal = ritem[1];
|
||||
for (i = p->nshifts - 1; i >= 0; --i)
|
||||
{
|
||||
final_state = to_state[i];
|
||||
if (accessing_symbol[final_state] == goal) break;
|
||||
}
|
||||
}
|
||||
|
||||
void unused_rules()
|
||||
{
|
||||
register int i;
|
||||
register action *p;
|
||||
|
||||
rules_used = (Yshort *) MALLOC(nrules*sizeof(Yshort));
|
||||
if (rules_used == 0) no_space();
|
||||
|
||||
for (i = 0; i < nrules; ++i)
|
||||
rules_used[i] = 0;
|
||||
|
||||
for (i = 0; i < nstates; ++i)
|
||||
{
|
||||
for (p = parser[i]; p; p = p->next)
|
||||
{
|
||||
if (p->action_code == REDUCE && p->suppressed <= 1)
|
||||
rules_used[p->number] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
nunused = 0;
|
||||
for (i = 3; i < nrules; ++i)
|
||||
if (!rules_used[i]) ++nunused;
|
||||
|
||||
if (nunused)
|
||||
if (nunused == 1)
|
||||
fprintf(stderr, "%s: 1 rule never reduced\n", myname);
|
||||
else
|
||||
fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused);
|
||||
}
|
||||
|
||||
|
||||
void remove_conflicts()
|
||||
{
|
||||
register int i;
|
||||
register int symbol;
|
||||
register action *p, *pref;
|
||||
|
||||
SRtotal = 0;
|
||||
RRtotal = 0;
|
||||
SRconflicts = NEW2(nstates, Yshort);
|
||||
RRconflicts = NEW2(nstates, Yshort);
|
||||
for (i = 0; i < nstates; i++) {
|
||||
SRcount = 0;
|
||||
RRcount = 0;
|
||||
symbol = -1;
|
||||
pref = 0;
|
||||
for (p = parser[i]; p; p = p->next) {
|
||||
if (p->symbol != symbol) {
|
||||
pref = p;
|
||||
symbol = p->symbol; }
|
||||
else if (i == final_state && symbol == 0) {
|
||||
SRcount++;
|
||||
p->suppressed = 1;
|
||||
if (!pref->suppressed)
|
||||
pref->suppressed = 1; }
|
||||
else if (pref->action_code == SHIFT) {
|
||||
if (pref->prec > 0 && p->prec > 0) {
|
||||
if (pref->prec < p->prec) {
|
||||
pref->suppressed = 2;
|
||||
pref = p; }
|
||||
else if (pref->prec > p->prec) {
|
||||
p->suppressed = 2; }
|
||||
else if (pref->assoc == LEFT) {
|
||||
pref->suppressed = 2;
|
||||
pref = p; }
|
||||
else if (pref->assoc == RIGHT) {
|
||||
p->suppressed = 2; }
|
||||
else {
|
||||
pref->suppressed = 2;
|
||||
p->suppressed = 2; } }
|
||||
else {
|
||||
SRcount++;
|
||||
p->suppressed = 1;
|
||||
if (!pref->suppressed)
|
||||
pref->suppressed = 1; } }
|
||||
else {
|
||||
RRcount++;
|
||||
p->suppressed = 1;
|
||||
if (!pref->suppressed)
|
||||
pref->suppressed = 1; } }
|
||||
SRtotal += SRcount;
|
||||
RRtotal += RRcount;
|
||||
SRconflicts[i] = SRcount;
|
||||
RRconflicts[i] = RRcount; }
|
||||
}
|
||||
|
||||
|
||||
void total_conflicts()
|
||||
{
|
||||
fprintf(stderr, "%s: ", myname);
|
||||
if (SRtotal == 1)
|
||||
fprintf(stderr, "1 shift/reduce conflict");
|
||||
else if (SRtotal > 1)
|
||||
fprintf(stderr, "%d shift/reduce conflicts", SRtotal);
|
||||
|
||||
if (SRtotal && RRtotal)
|
||||
fprintf(stderr, ", ");
|
||||
|
||||
if (RRtotal == 1)
|
||||
fprintf(stderr, "1 reduce/reduce conflict");
|
||||
else if (RRtotal > 1)
|
||||
fprintf(stderr, "%d reduce/reduce conflicts", RRtotal);
|
||||
|
||||
fprintf(stderr, ".\n");
|
||||
}
|
||||
|
||||
|
||||
int sole_reduction(int stateno)
|
||||
{
|
||||
register int count, ruleno;
|
||||
register action *p;
|
||||
|
||||
count = 0;
|
||||
ruleno = 0;
|
||||
for (p = parser[stateno]; p; p = p->next)
|
||||
{
|
||||
if (p->action_code == SHIFT && p->suppressed <= 1)
|
||||
return (0);
|
||||
else if (p->action_code == REDUCE && p->suppressed <= 1)
|
||||
{
|
||||
if (ruleno > 0 && p->number != ruleno)
|
||||
return (0);
|
||||
if (p->symbol != 1)
|
||||
++count;
|
||||
ruleno = p->number;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
return (0);
|
||||
return (ruleno);
|
||||
}
|
||||
|
||||
|
||||
void defreds()
|
||||
{
|
||||
register int i;
|
||||
|
||||
defred = NEW2(nstates, Yshort);
|
||||
for (i = 0; i < nstates; i++)
|
||||
defred[i] = sole_reduction(i);
|
||||
}
|
||||
|
||||
void free_action_row(action *p)
|
||||
{
|
||||
register action *q;
|
||||
|
||||
while (p)
|
||||
{
|
||||
q = p->next;
|
||||
FREE(p);
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
|
||||
void free_parser()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < nstates; i++)
|
||||
free_action_row(parser[i]);
|
||||
|
||||
FREE(parser);
|
||||
}
|
||||
|
100
extern/btyacc/mstring.c
vendored
Normal file
100
extern/btyacc/mstring.c
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
#include "defs.h"
|
||||
#include "mstring.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/* parameters about string length. START is the starting size and
|
||||
** START+TAIL should be a power of two */
|
||||
#define START 24
|
||||
#define TAIL 8
|
||||
|
||||
void msprintf(struct mstring *s, const char *fmt, ...)
|
||||
{
|
||||
static char buf[4096]; /* a big static buffer */
|
||||
va_list args;
|
||||
int len;
|
||||
|
||||
if (!s || !s->base) return;
|
||||
va_start(args, fmt);
|
||||
vsprintf(buf, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
len = strlen(buf);
|
||||
if (len > (s->end - s->ptr)) {
|
||||
int cp = s->ptr - s->base, cl = s->end - s->base, nl = cl;
|
||||
while (len > (nl - cp))
|
||||
nl = nl + nl + TAIL;
|
||||
if ((s->base = realloc(s->base, nl))) {
|
||||
s->ptr = s->base + cp;
|
||||
s->end = s->base + nl; }
|
||||
else {
|
||||
s->ptr = s->end = 0;
|
||||
return; } }
|
||||
memcpy(s->ptr, buf, len);
|
||||
s->ptr += len;
|
||||
}
|
||||
|
||||
int mputchar(struct mstring *s, int ch)
|
||||
{
|
||||
if (!s || !s->base) return ch;
|
||||
if (s->ptr == s->end) {
|
||||
int len = s->end - s->base;
|
||||
if ((s->base = realloc(s->base, len+len+TAIL))) {
|
||||
s->ptr = s->base + len;
|
||||
s->end = s->base + len+len+TAIL; }
|
||||
else {
|
||||
s->ptr = s->end = 0;
|
||||
return ch; } }
|
||||
*s->ptr++ = ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
struct mstring *msnew(void) {
|
||||
struct mstring *n = malloc(sizeof(struct mstring));
|
||||
|
||||
if (n && (n->base = n->ptr = malloc(START)))
|
||||
n->end = n->base + START;
|
||||
else if (n) {
|
||||
free(n);
|
||||
n = 0; }
|
||||
return n;
|
||||
}
|
||||
|
||||
char *msdone(struct mstring *s)
|
||||
{
|
||||
char *r = 0;
|
||||
if (s) {
|
||||
mputc(s, 0);
|
||||
r = s->base;
|
||||
free(s); }
|
||||
return r;
|
||||
}
|
||||
|
||||
/* compare two strings, ignoring whitespace, except between two letters or
|
||||
** digits (and treat all of these as equal) */
|
||||
int strnscmp(const char *a, const char *b)
|
||||
{
|
||||
while(1) {
|
||||
while (isspace(*a)) a++;
|
||||
while (isspace(*b)) b++;
|
||||
while (*a && *a == *b) a++,b++;
|
||||
if (isspace(*a)) {
|
||||
if (isalnum(a[-1]) && isalnum(*b))
|
||||
break; }
|
||||
else if (isspace(*b)) {
|
||||
if (isalnum(b[-1]) && isalnum(*a))
|
||||
break; }
|
||||
else
|
||||
break; }
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
unsigned int strnshash(const char *s)
|
||||
{
|
||||
unsigned int h = 0;
|
||||
|
||||
while (*s) {
|
||||
if (!isspace(*s))
|
||||
h = (h<<5) - h + *s;
|
||||
s++; }
|
||||
return h;
|
||||
}
|
21
extern/btyacc/mstring.h
vendored
Normal file
21
extern/btyacc/mstring.h
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef _string_h_
|
||||
#define _string_h_
|
||||
|
||||
struct mstring {
|
||||
char *base, *ptr, *end;
|
||||
};
|
||||
|
||||
void msprintf(struct mstring *, const char *, ...);
|
||||
int mputchar(struct mstring *, int);
|
||||
struct mstring *msnew(void);
|
||||
char *msdone(struct mstring *);
|
||||
|
||||
/* compare two strings, ignoring whitespace, except between two letters or
|
||||
** digits (and treat all of these as equal) */
|
||||
int strnscmp(const char *, const char *);
|
||||
/* hash a string, ignoring whitespace */
|
||||
unsigned int strnshash(const char *);
|
||||
|
||||
#define mputc(m, ch) ((m)->ptr==(m)->end?mputchar(m,ch):(*(m)->ptr++=(ch)))
|
||||
|
||||
#endif /* _string_h_ */
|
1295
extern/btyacc/output.c
vendored
Normal file
1295
extern/btyacc/output.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
477
extern/btyacc/push.skel
vendored
Normal file
477
extern/btyacc/push.skel
vendored
Normal file
@ -0,0 +1,477 @@
|
||||
%% banner
|
||||
/*
|
||||
** "@(#)push.skel, based on byacc 1.8 (Berkeley) 01/20/91";
|
||||
*/
|
||||
#define YYBTYACC 1
|
||||
|
||||
%% header
|
||||
#define yyclearin (yychar=(-1))
|
||||
#define yyerrok (yyerrflag=0)
|
||||
/* #ifdef YYSTACKSIZE
|
||||
#ifndef YYMAXDEPTH
|
||||
#define YYMAXDEPTH YYSTACKSIZE
|
||||
#endif
|
||||
#else
|
||||
#ifdef YYMAXDEPTH
|
||||
#define YYSTACKSIZE YYMAXDEPTH
|
||||
#else
|
||||
#define YYSTACKSIZE 500
|
||||
#define YYMAXDEPTH 500
|
||||
#endif
|
||||
#endif */
|
||||
int yydebug;
|
||||
static struct yyparsestate {
|
||||
struct yyparsestate *save;
|
||||
int state;
|
||||
int errflag;
|
||||
short *ssp;
|
||||
YYSTYPE *vsp;
|
||||
YYSTYPE val;
|
||||
short *ss;
|
||||
YYSTYPE *vs;
|
||||
int lexeme;
|
||||
unsigned short stacksize;
|
||||
short ctry;
|
||||
} *yypstate=0, *yypath=0;
|
||||
#define yyerrflag (yypstate->errflag)
|
||||
#define yyssp (yypstate->ssp)
|
||||
#define yyvsp (yypstate->vsp)
|
||||
#define yyval (yypstate->val)
|
||||
#define yyss (yypstate->ss)
|
||||
#define yyvs (yypstate->vs)
|
||||
#define yystacksize (yypstate->stacksize)
|
||||
static YYSTYPE *yylvals=0, *yylvp=0, *yylve=0, *yylvlim=0;
|
||||
static short *yylexemes=0, *yylexp=0;
|
||||
#define YYLEX (yylvp<yylve ? yylval=*yylvp++, *yylexp++ : \
|
||||
yytrial ? (yylvp==yylvlim ? yyexpand() : 0), *yylexp = yylex(), \
|
||||
*yylvp++ = yylval, yylve++, *yylexp++ \
|
||||
: yylex())
|
||||
extern int yylex(), yyparse();
|
||||
#define yytrial (yypstate->save)
|
||||
#ifndef __cplusplus
|
||||
#define YYSCOPY(t, f, s) memcpy(t, f, (s)*sizeof(YYSTYPE))
|
||||
#define YYMORESTACK do { int p = yyssp - yyss; \
|
||||
yystacksize += 16; \
|
||||
yyss = (short *)realloc(yyss, yystacksize * sizeof(short)); \
|
||||
yyvs = (YYSTYPE *)realloc(yyvs, yystacksize * sizeof(YYSTYPE)); \
|
||||
yyssp = yyss + p; \
|
||||
yyvsp = yyvs + p; \
|
||||
} while (0)
|
||||
#else /* C++ */
|
||||
#define YYSCOPY(to, from, size) do { int _i; \
|
||||
for (_i = (size)-1; _i >= 0; _i--) \
|
||||
(to)[_i] = (from)[_i]; \
|
||||
} while(0)
|
||||
#define YYMORESTACK do { int p = yyssp - yyss; \
|
||||
short *tss = yyss; YYSTYPE *tvs = yyvs; \
|
||||
yyss = new short[yystacksize + 16]; \
|
||||
yyvs = new YYSTYPE[yystacksize + 16]; \
|
||||
memcpy(yyss, tss, yystacksize * sizeof(short)); \
|
||||
YYSCOPY(yyvs, tvs, yystacksize); \
|
||||
yystacksize += 16; \
|
||||
delete[] tss; \
|
||||
delete[] tvs; \
|
||||
yyssp = yyss + p; \
|
||||
yyvsp = yyvs + p; \
|
||||
} while (0)
|
||||
#endif /* C++ */
|
||||
|
||||
%% body
|
||||
|
||||
#ifndef YYNEWSTATE
|
||||
#ifdef __oldc
|
||||
static struct yyparsestate *YYNEWSTATE(size)
|
||||
int size;
|
||||
#else
|
||||
static struct yyparsestate *YYNEWSTATE(int size)
|
||||
#endif /* __oldc */
|
||||
{
|
||||
struct yyparsestate *p;
|
||||
|
||||
#ifndef __cplusplus
|
||||
p = (struct yyparsestate *)malloc(sizeof(struct yyparsestate));
|
||||
p->stacksize = size+4;
|
||||
p->ss = (short *)malloc((size+4)*sizeof(short));
|
||||
p->vs = (YYSTYPE *)malloc((size+4)*sizeof(YYSTYPE));
|
||||
#else /* C++ */
|
||||
p = new yyparsestate;
|
||||
p->stacksize = size+4;
|
||||
p->ss = new short[size + 4];
|
||||
p->vs = new YYSTYPE[size + 4];
|
||||
#endif /* C++ */
|
||||
return p;
|
||||
}
|
||||
#endif /* YYNEWSTATE */
|
||||
#ifndef YYFREESTATE
|
||||
#ifndef __cplusplus
|
||||
#define YYFREESTATE(p) (free((p)->ss), free((p)->vs), free(p))
|
||||
#else /* C++ */
|
||||
#define YYFREESTATE(p) (delete[] (p)->ss, delete[] (p)->vs, delete (p))
|
||||
#endif /* C++ */
|
||||
#endif /* YYFREESTATE */
|
||||
static int yyexpand()
|
||||
{
|
||||
int p = yylvp-yylvals;
|
||||
int s = yylvlim-yylvals;
|
||||
s += 16;
|
||||
#ifndef __cplusplus
|
||||
yylvals = (YYSTYPE *)realloc(yylvals, s*sizeof(YYSTYPE));
|
||||
yylexemes = (short *)realloc(yylexemes, s*sizeof(short));
|
||||
#else /* C++ */
|
||||
{ short *tl = yylexemes; YYSTYPE *tv = yylvals;
|
||||
yylvals = new YYSTYPE[s];
|
||||
yylexemes = new short[s];
|
||||
memcpy(yylexemes, tl, (s-16)*sizeof(short));
|
||||
YYSCOPY(yylvals, tv, s-16);
|
||||
delete[] tl;
|
||||
delete[] tv; }
|
||||
#endif /* C++ */
|
||||
yylvp = yylve = yylvals + p;
|
||||
yylvlim = yylvals + s;
|
||||
yylexp = yylexemes + p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define YYABORT goto yyabort
|
||||
#define YYACCEPT goto yyaccept
|
||||
#define YYERROR goto yyerrlab
|
||||
#define YYVALID do { if (yytrial) goto yyvalid; } while(0)
|
||||
#ifdef __cplusplus
|
||||
extern "C" char *getenv(const char *);
|
||||
#else
|
||||
extern char *getenv();
|
||||
#endif
|
||||
int yyparse(int yychar, YYSTYPE yylval)
|
||||
{
|
||||
int yym, yyn, yystate, yynewerrflag;
|
||||
#if YYDEBUG
|
||||
char *yys;
|
||||
#endif
|
||||
|
||||
if (yychar < 0) yychar = 0;
|
||||
if (!yypstate) {
|
||||
/* initialize the parser state */
|
||||
yypstate = YYNEWSTATE(12);
|
||||
yypath = 0;
|
||||
yytrial = 0;
|
||||
yyerrflag = 0;
|
||||
yylvp = yylve = yylvals;
|
||||
yylexp = yylexemes;
|
||||
yyssp = yyss;
|
||||
yyvsp = yyvs;
|
||||
*yyssp = yypstate->state = 0; }
|
||||
yystate = yypstate->state;
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
yys = 0;
|
||||
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
|
||||
if (!yys) yys = "illegal-symbol";
|
||||
printf("yydebug: state %d, input %d (%s)", yystate,
|
||||
yychar, yys);
|
||||
#ifdef YYDBPR
|
||||
printf("<");
|
||||
YYDBPR(yylval);
|
||||
printf(">");
|
||||
#endif
|
||||
printf("\n"); }
|
||||
#endif
|
||||
if (yystate == YYFINAL && yychar == 0)
|
||||
goto yyaccept;
|
||||
if (yytrial) {
|
||||
if (yylvp == yylvlim) yyexpand();
|
||||
*yylvp++ = yylval;
|
||||
yylve++;
|
||||
*yylexp++ = yychar; }
|
||||
yyloop:
|
||||
if ((yyn = yydefred[yystate])) goto yyreduce;
|
||||
if (yychar < 0) {
|
||||
if (yylvp < yylve) {
|
||||
yylval = *yylvp++;
|
||||
yychar = *yylexp++; }
|
||||
else {
|
||||
yypstate->state = yystate;
|
||||
return 0; }
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
yys = 0;
|
||||
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
|
||||
if (!yys) yys = "illegal-symbol";
|
||||
printf("yydebug: state %d, reading %d (%s)", yystate,
|
||||
yychar, yys);
|
||||
#ifdef YYDBPR
|
||||
printf("<");
|
||||
YYDBPR(yylval);
|
||||
printf(">");
|
||||
#endif
|
||||
printf("\n"); }
|
||||
#endif
|
||||
}
|
||||
if ((yyn = yycindex[yystate]) &&
|
||||
(yyn += yychar) >= 0 &&
|
||||
yyn <= YYTABLESIZE &&
|
||||
yycheck[yyn] == yychar) {
|
||||
int ctry;
|
||||
struct yyparsestate *save;
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug: state %d, conflict%s\n", yystate,
|
||||
yypath ? ", following successful trial parse" :
|
||||
yytrial ? "" : ", starting trial parse");
|
||||
#endif
|
||||
if (yypath) {
|
||||
save = yypath;
|
||||
yypath = save->save;
|
||||
ctry = save->ctry;
|
||||
if (save->state != yystate) goto yyabort;
|
||||
YYFREESTATE(save); }
|
||||
else {
|
||||
save = YYNEWSTATE(yyssp - yyss);
|
||||
save->save = yypstate->save;
|
||||
save->state = yystate;
|
||||
save->errflag = yypstate->errflag;
|
||||
save->ssp = save->ss + (yyssp - yyss);
|
||||
save->vsp = save->vs + (yyvsp - yyvs);
|
||||
memcpy(save->ss, yyss, (yyssp - yyss + 1)*sizeof(short));
|
||||
YYSCOPY(save->vs, yyvs, yyssp - yyss + 1);
|
||||
ctry = yytable[yyn];
|
||||
if (yyctable[ctry] == -1) {
|
||||
#if YYDEBUG
|
||||
if (yydebug && yychar >= 0)
|
||||
printf("yydebug: backtracking 1 token\n");
|
||||
#endif
|
||||
ctry++; }
|
||||
save->ctry = ctry;
|
||||
if (!yytrial) {
|
||||
if (!yylexemes) {
|
||||
#ifndef __cplusplus
|
||||
yylexemes = (short *)malloc(16*sizeof(short));
|
||||
yylvals = (YYSTYPE *)malloc(16*sizeof(YYSTYPE));
|
||||
#else /* C++ */
|
||||
yylexemes = new short[16];
|
||||
yylvals = new YYSTYPE[16];
|
||||
#endif /* C++ */
|
||||
yylvlim = yylvals + 16; }
|
||||
if (yylvp == yylve) {
|
||||
yylvp = yylve = yylvals;
|
||||
yylexp = yylexemes;
|
||||
if (yychar >= 0) {
|
||||
*yylve++ = yylval;
|
||||
*yylexp = yychar;
|
||||
yychar = -1; } } }
|
||||
if (yychar >= 0) {
|
||||
yylvp--, yylexp--;
|
||||
yychar = -1; }
|
||||
save->lexeme = yylvp - yylvals;
|
||||
yypstate->save = save; }
|
||||
if (yytable[yyn] == ctry) {
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug: state %d, shifting to state %d\n",
|
||||
yystate, yyctable[ctry]);
|
||||
#endif
|
||||
if (yychar < 0)
|
||||
yylvp++, yylexp++;
|
||||
yychar = -1;
|
||||
if (yyerrflag > 0) --yyerrflag;
|
||||
yystate = yyctable[ctry];
|
||||
goto yyshift; }
|
||||
else {
|
||||
yyn = yyctable[ctry];
|
||||
goto yyreduce; } }
|
||||
if ((yyn = yysindex[yystate]) &&
|
||||
(yyn += yychar) >= 0 &&
|
||||
yyn <= YYTABLESIZE &&
|
||||
yycheck[yyn] == yychar) {
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug: state %d, shifting to state %d\n",
|
||||
yystate, yytable[yyn]);
|
||||
#endif
|
||||
yychar = (-1);
|
||||
if (yyerrflag > 0) --yyerrflag;
|
||||
yystate = yytable[yyn];
|
||||
yyshift:
|
||||
if (yyssp >= yyss + yystacksize - 1)
|
||||
YYMORESTACK;
|
||||
*++yyssp = yystate;
|
||||
*++yyvsp = yylval;
|
||||
goto yyloop; }
|
||||
if ((yyn = yyrindex[yystate]) &&
|
||||
(yyn += yychar) >= 0 &&
|
||||
yyn <= YYTABLESIZE &&
|
||||
yycheck[yyn] == yychar) {
|
||||
yyn = yytable[yyn];
|
||||
goto yyreduce; }
|
||||
if (yyerrflag) goto yyinrecovery;
|
||||
yynewerrflag = 1;
|
||||
goto yyerrhandler;
|
||||
yyerrlab:
|
||||
yynewerrflag = 0;
|
||||
yyerrhandler:
|
||||
while (yytrial) { int ctry; struct yyparsestate *save;
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug: error in state %d, %s state %d, %d tokens\n",
|
||||
yystate, "backtracking to", yypstate->save->state,
|
||||
(int)(yylvp - yylvals - yypstate->save->lexeme));
|
||||
#endif
|
||||
save = yypstate->save;
|
||||
yylvp = yylvals + save->lexeme;
|
||||
yylexp = yylexemes + save->lexeme;
|
||||
yychar = -1;
|
||||
yyssp = yyss + (save->ssp - save->ss);
|
||||
yyvsp = yyvs + (save->vsp - save->vs);
|
||||
memcpy(yyss, save->ss, (yyssp - yyss + 1) * sizeof(short));
|
||||
YYSCOPY(yyvs, save->vs, yyvsp - yyvs + 1);
|
||||
ctry = ++save->ctry;
|
||||
yystate = save->state;
|
||||
if ((yyn = yyctable[ctry]) >= 0) goto yyreduce;
|
||||
yypstate->save = save->save;
|
||||
YYFREESTATE(save);
|
||||
#if YYDEBUG
|
||||
if (yydebug && !yytrial)
|
||||
printf("yydebug: trial parse failed, entering error mode\n");
|
||||
#endif
|
||||
yynewerrflag = 1; }
|
||||
if (yynewerrflag)
|
||||
yyerror("syntax error");
|
||||
yyinrecovery:
|
||||
if (yyerrflag < 3) {
|
||||
yyerrflag = 3;
|
||||
for (;;) {
|
||||
if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
|
||||
yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) {
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug: state %d, error recovery %s state %d\n",
|
||||
*yyssp, "shifting to", yytable[yyn]);
|
||||
#endif
|
||||
yystate = yytable[yyn];
|
||||
goto yyshift; }
|
||||
else {
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug: error recovery discarding state %d\n",
|
||||
*yyssp);
|
||||
#endif
|
||||
if (yyssp <= yyss) goto yyabort;
|
||||
--yyssp;
|
||||
--yyvsp; } } }
|
||||
else {
|
||||
if (yychar == 0) goto yyabort;
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
yys = 0;
|
||||
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
|
||||
if (!yys) yys = "illegal-symbol";
|
||||
printf("yydebug: state %d, error recovery discards token %d (%s)\n",
|
||||
yystate, yychar, yys); }
|
||||
#endif
|
||||
yychar = (-1);
|
||||
goto yyloop; }
|
||||
yyreduce:
|
||||
yym = yylen[yyn];
|
||||
#if YYDEBUG
|
||||
if (yydebug) {
|
||||
printf("yydebug: state %d, reducing by rule %d (%s)",
|
||||
yystate, yyn, yyrule[yyn]);
|
||||
#ifdef YYDBPR
|
||||
if (yym) {
|
||||
int i;
|
||||
printf("<");
|
||||
for (i=yym; i>0; i--) {
|
||||
if (i!=yym) printf(", ");
|
||||
YYDBPR(yyvsp[1-i]); }
|
||||
printf(">"); }
|
||||
#endif
|
||||
printf("\n"); }
|
||||
#endif
|
||||
if (yyssp + 1 - yym >= yyss + yystacksize)
|
||||
YYMORESTACK;
|
||||
yyval = yyvsp[1-yym];
|
||||
switch (yyn) {
|
||||
|
||||
%% trailer
|
||||
}
|
||||
|
||||
#if YYDEBUG && defined(YYDBPR)
|
||||
if (yydebug) {
|
||||
printf("yydebug: after reduction, result is ");
|
||||
YYDBPR(yyval);
|
||||
printf("\n"); }
|
||||
#endif
|
||||
yyssp -= yym;
|
||||
yystate = *yyssp;
|
||||
yyvsp -= yym;
|
||||
yym = yylhs[yyn];
|
||||
if (yystate == 0 && yym == 0) {
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug: after reduction, %s from state 0 to state %d\n",
|
||||
"shifting", YYFINAL);
|
||||
#endif
|
||||
yystate = YYFINAL;
|
||||
*++yyssp = YYFINAL;
|
||||
*++yyvsp = yyval;
|
||||
if (yychar == 0) goto yyaccept;
|
||||
goto yyloop; }
|
||||
if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
|
||||
yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
|
||||
yystate = yytable[yyn];
|
||||
else
|
||||
yystate = yydgoto[yym];
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug: after reduction, %s from state %d to state %d\n",
|
||||
"shifting", *yyssp, yystate);
|
||||
#endif
|
||||
if (yyssp >= yyss + yystacksize - 1)
|
||||
YYMORESTACK;
|
||||
*++yyssp = yystate;
|
||||
*++yyvsp = yyval;
|
||||
goto yyloop;
|
||||
yyvalid:
|
||||
if (yypath)
|
||||
goto yyabort;
|
||||
while (yypstate->save) {
|
||||
struct yyparsestate *save = yypstate->save;
|
||||
yypstate->save = save->save;
|
||||
save->save = yypath;
|
||||
yypath = save; }
|
||||
#if YYDEBUG
|
||||
if (yydebug)
|
||||
printf("yydebug: trial successful, %s state %d, %d tokens\n",
|
||||
"backtracking to", yypath->state,
|
||||
(int)(yylvp - yylvals - yypath->lexeme));
|
||||
#endif
|
||||
yychar = -1;
|
||||
yyssp = yyss + (yypath->ssp - yypath->ss);
|
||||
yyvsp = yyvs + (yypath->vsp - yypath->vs);
|
||||
memcpy(yyss, yypath->ss, (yyssp - yyss + 1) * sizeof(short));
|
||||
YYSCOPY(yyvs, yypath->vs, yyvsp - yyvs + 1);
|
||||
yylvp = yylvals + yypath->lexeme;
|
||||
yylexp = yylexemes + yypath->lexeme;
|
||||
yystate = yypath->state;
|
||||
goto yyloop;
|
||||
yyabort:
|
||||
while (yypstate) {
|
||||
struct yyparsestate *save = yypstate;
|
||||
yypstate = save->save;
|
||||
YYFREESTATE(save); }
|
||||
while (yypath) {
|
||||
struct yyparsestate *save = yypath;
|
||||
yypath = save->save;
|
||||
YYFREESTATE(save); }
|
||||
return -1;
|
||||
yyaccept:
|
||||
if (yytrial) goto yyvalid;
|
||||
while (yypstate) {
|
||||
struct yyparsestate *save = yypstate;
|
||||
yypstate = save->save;
|
||||
YYFREESTATE(save); }
|
||||
while (yypath) {
|
||||
struct yyparsestate *save = yypath;
|
||||
yypath = save->save;
|
||||
YYFREESTATE(save); }
|
||||
return 1;
|
||||
}
|
1895
extern/btyacc/reader.c
vendored
Normal file
1895
extern/btyacc/reader.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
113
extern/btyacc/readskel.c
vendored
Normal file
113
extern/btyacc/readskel.c
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
#include "defs.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/* amount of memeory to allocate at once */
|
||||
#define CHUNK 8192
|
||||
|
||||
static char *cp, *cp_end;
|
||||
static char **ap, **ap_end, **ap_start;
|
||||
|
||||
static void add_ptr(char *p)
|
||||
{
|
||||
if (ap == ap_end) {
|
||||
int size = CHUNK;
|
||||
char **nap;
|
||||
while ((ap-ap_start) * sizeof(char *) >= size)
|
||||
size = size * 2;
|
||||
if (!(nap = malloc(size)))
|
||||
no_space();
|
||||
if (ap > ap_start)
|
||||
memcpy(nap, ap_start, (ap-ap_start) * sizeof(char *));
|
||||
ap = nap + (ap - ap_start);
|
||||
ap_start = nap;
|
||||
ap_end = nap + size/sizeof(char *); }
|
||||
*ap++ = p;
|
||||
}
|
||||
|
||||
static void add_string(char *s)
|
||||
{
|
||||
int len = strlen(s)+1;
|
||||
|
||||
if (len > cp_end - cp) {
|
||||
int size = len > CHUNK ? len : CHUNK;
|
||||
if (!(cp = malloc(size)))
|
||||
no_space();
|
||||
cp_end = cp + size; }
|
||||
memcpy(cp, s, len);
|
||||
add_ptr(cp);
|
||||
cp += len;
|
||||
}
|
||||
|
||||
static void add_fmt(char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[256];
|
||||
|
||||
va_start(args, fmt);
|
||||
vsprintf(buf, fmt, args);
|
||||
va_end(args);
|
||||
add_string(buf);
|
||||
}
|
||||
|
||||
static char **fin_section(void)
|
||||
{
|
||||
char **rv;
|
||||
|
||||
add_ptr(0);
|
||||
rv = ap_start;
|
||||
ap_start = ap;
|
||||
return rv;
|
||||
}
|
||||
|
||||
void read_skel(char *name)
|
||||
{
|
||||
char buf[256];
|
||||
int section = -2;
|
||||
int line = 0, sline = 1, eline = 1;
|
||||
int i;
|
||||
FILE *fp;
|
||||
|
||||
if (!(fp = fopen(name, "r")))
|
||||
open_error(name);
|
||||
while(fgets(buf, 255, fp)) {
|
||||
if ((sline = eline))
|
||||
line++;
|
||||
if ((i = strlen(buf)) == 0)
|
||||
continue;
|
||||
if (buf[i-1] == '\n') {
|
||||
buf[--i] = 0;
|
||||
eline = 1;
|
||||
} else {
|
||||
buf[i++] = '\\';
|
||||
buf[i] = 0;
|
||||
eline = 0;
|
||||
}
|
||||
if (sline && buf[0] == '%' && buf[1] == '%') {
|
||||
char *p = buf+2;
|
||||
if (section >= 0) {
|
||||
section_list[section].ptr = fin_section();
|
||||
}
|
||||
section = -1;
|
||||
while(*p && isspace(*p)) p++;
|
||||
if (isalpha(*p)) {
|
||||
char *e = p;
|
||||
while(isalnum(*++e));
|
||||
*e = 0;
|
||||
for (i=0; section_list[i].name; i++)
|
||||
if (!strcmp(section_list[i].name, p))
|
||||
section = i;
|
||||
}
|
||||
if (section >= 0)
|
||||
add_fmt("#line %d \"%s\"", line+1, name);
|
||||
else if (*p)
|
||||
error(0, buf, p, "line %d of \"%s\", bad section name",
|
||||
line, name);
|
||||
} else if (section >= 0) {
|
||||
add_string(buf);
|
||||
}
|
||||
}
|
||||
if (section >= 0)
|
||||
section_list[section].ptr = fin_section();
|
||||
if (section == -2)
|
||||
error(0, 0, 0, "No sections found in skeleton file \"%s\"", name);
|
||||
}
|
40
extern/btyacc/skel2c
vendored
Normal file
40
extern/btyacc/skel2c
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
BEGIN { havesection = 0;
|
||||
nsec = 0;
|
||||
printf "/*\n** This file generated automatically from %s\n*/\n\n",
|
||||
FILENAME;
|
||||
printf "#include \"defs.h\"\n";
|
||||
}
|
||||
/^%%/ { if (havesection) {
|
||||
printf " 0\n};\n\n";
|
||||
}
|
||||
if (NF >= 2) {
|
||||
havesection = 1;
|
||||
section = $2;
|
||||
seclist[nsec] = section;
|
||||
nsec = nsec + 1;
|
||||
printf "char *%s[] =\n{\n", $2;
|
||||
printf " \"#line %d \\\"%s\\\"\",\n", FNR+1, FILENAME;
|
||||
} else {
|
||||
havesection = 0;
|
||||
}
|
||||
next;
|
||||
}
|
||||
{ if (havesection) {
|
||||
gsub(/\\/, "\\\\");
|
||||
gsub(/\t/, "\\t");
|
||||
gsub(/\"/, "\\\"");
|
||||
printf " \"%s\",\n", $0;
|
||||
} else {
|
||||
print $0;
|
||||
}
|
||||
}
|
||||
END { if (havesection) {
|
||||
printf " 0\n};\n\n";
|
||||
}
|
||||
if (nsec > 0) {
|
||||
printf "struct section section_list[] = {\n";
|
||||
for (i=0; i<nsec; i++)
|
||||
printf "\t{ \"%s\", &%s[0] },\n", seclist[i], seclist[i];
|
||||
printf "\t{ 0, 0 } };\n"
|
||||
}
|
||||
}
|
861
extern/btyacc/skeleton.c
vendored
Normal file
861
extern/btyacc/skeleton.c
vendored
Normal file
@ -0,0 +1,861 @@
|
||||
/*
|
||||
** This file generated automatically from
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
/* The banner used here should be replaced with an #ident directive */
|
||||
/* if the target C compiler supports #ident directives. */
|
||||
/* */
|
||||
/* If the skeleton is changed, the banner should be changed so that */
|
||||
/* the altered version can easily be distinguished from the original. */
|
||||
|
||||
char *banner[] =
|
||||
{
|
||||
"#line 8 \"btyaccpa.ske\"",
|
||||
"",
|
||||
"//",
|
||||
"// @(#)btyaccpar, based on byacc 1.8 (Berkeley)",
|
||||
"//",
|
||||
"#define YYBTYACC 1",
|
||||
"",
|
||||
"#include <stdio.h>",
|
||||
"#include <stdlib.h>",
|
||||
"#include <string.h>",
|
||||
"",
|
||||
"typedef int Yshort;",
|
||||
"",
|
||||
0
|
||||
};
|
||||
|
||||
char *tables[] =
|
||||
{
|
||||
"#line 21 \"btyaccpa.ske\"",
|
||||
"",
|
||||
"#define _C_ \"C\"",
|
||||
"",
|
||||
"extern _C_ Yshort yylhs[];",
|
||||
"extern _C_ Yshort yylen[];",
|
||||
"extern _C_ Yshort yydefred[];",
|
||||
"extern _C_ Yshort yydgoto[];",
|
||||
"extern _C_ Yshort yysindex[];",
|
||||
"extern _C_ Yshort yyrindex[];",
|
||||
"extern _C_ Yshort yycindex[];",
|
||||
"extern _C_ Yshort yygindex[];",
|
||||
"extern _C_ Yshort yytable[];",
|
||||
"extern _C_ Yshort yycheck[];",
|
||||
"extern _C_ Yshort yyctable[];",
|
||||
"",
|
||||
"#if YYDEBUG",
|
||||
"extern _C_ char *yyname[];",
|
||||
"extern _C_ char *yyrule[];",
|
||||
"#endif",
|
||||
"",
|
||||
0
|
||||
};
|
||||
|
||||
char *header[] =
|
||||
{
|
||||
"#line 42 \"btyaccpa.ske\"",
|
||||
"",
|
||||
"//",
|
||||
"// YYPOSN is user-defined text position type.",
|
||||
"//",
|
||||
"#ifndef YYPOSN",
|
||||
"#define YYPOSN int",
|
||||
"#endif",
|
||||
"",
|
||||
"#ifdef YYREDUCEPOSNFUNC",
|
||||
"#define YYCALLREDUCEPOSN(e) \\",
|
||||
"\tif(reduce_posn) { \\",
|
||||
"\t YYREDUCEPOSNFUNC(yyps->pos, &(yyps->psp)[1-yym], &(yyps->vsp)[1-yym], \\",
|
||||
"\t\t\t yym, yyps->psp - yyps->ps, yychar, yyposn, e); \\",
|
||||
"\t reduce_posn = 0; \\",
|
||||
"\t}",
|
||||
"",
|
||||
"#ifndef YYCALLREDUCEPOSNARG",
|
||||
"#define YYCALLREDUCEPOSNARG yyps->val",
|
||||
"#endif",
|
||||
"",
|
||||
"",
|
||||
"#define YYPOSNARG(n) ((yyps->psp)[1-yym+(n)-1])",
|
||||
"#define YYPOSNOUT (yyps->pos)",
|
||||
"#endif",
|
||||
"",
|
||||
"// If delete function is not defined by the user, do not deletions.",
|
||||
"#ifndef YYDELETEVAL",
|
||||
"#define YYDELETEVAL(v) ",
|
||||
"#endif",
|
||||
"",
|
||||
"// If delete function is not defined by the user, do not deletions.",
|
||||
"#ifndef YYDELETEPOSN",
|
||||
"#define YYDELETEPOSN(v) ",
|
||||
"#endif",
|
||||
"",
|
||||
"#define yyclearin (yychar=(-1))",
|
||||
"",
|
||||
"#define yyerrok (yyps->errflag=0)",
|
||||
"",
|
||||
"#ifndef YYSTACKGROWTH",
|
||||
"#define YYSTACKGROWTH 16",
|
||||
"#endif",
|
||||
"",
|
||||
"#ifndef YYDEFSTACKSIZE",
|
||||
"#define YYDEFSTACKSIZE 12",
|
||||
"#endif",
|
||||
"",
|
||||
"#ifdef YYDEBUG",
|
||||
"int yydebug;",
|
||||
"#endif",
|
||||
"",
|
||||
"int yynerrs;",
|
||||
"",
|
||||
"/* These value/posn are taken from the lexer */",
|
||||
"YYSTYPE yylval;",
|
||||
"YYPOSN yyposn;",
|
||||
"",
|
||||
"/* These value/posn of the root non-terminal are returned to the caller */",
|
||||
"YYSTYPE yyretlval;",
|
||||
"YYPOSN yyretposn;",
|
||||
"",
|
||||
"#define YYABORT goto yyabort",
|
||||
"#define YYACCEPT goto yyaccept",
|
||||
"#define YYERROR goto yyerrlab",
|
||||
"#define YYVALID do { if (yyps->save) goto yyvalid; } while(0)",
|
||||
"#define YYVALID_NESTED do { if (yyps->save && \\",
|
||||
" yyps->save->save==0) goto yyvalid; } while(0)",
|
||||
"",
|
||||
"struct yyparsestate {",
|
||||
" yyparsestate *save; // Previously saved parser state",
|
||||
" int state;",
|
||||
" int errflag;",
|
||||
" Yshort *ssp; // state stack pointer",
|
||||
" YYSTYPE *vsp; // value stack pointer",
|
||||
" YYPOSN *psp; // position stack pointer",
|
||||
" YYSTYPE val; // value as returned by actions",
|
||||
" YYPOSN pos; // position as returned by universal action",
|
||||
" Yshort *ss; // state stack base",
|
||||
" YYSTYPE *vs; // values stack base",
|
||||
" YYPOSN *ps; // position stack base",
|
||||
" int lexeme; // index of the conflict lexeme in the lexical queue",
|
||||
" unsigned int stacksize; // current maximum stack size",
|
||||
" Yshort ctry; // index in yyctable[] for this conflict",
|
||||
"};",
|
||||
"",
|
||||
"// Current parser state",
|
||||
"static yyparsestate *yyps=0;",
|
||||
"",
|
||||
"// yypath!=NULL: do the full parse, starting at *yypath parser state.",
|
||||
"static yyparsestate *yypath=0;",
|
||||
"",
|
||||
"// Base of the lexical value queue",
|
||||
"static YYSTYPE *yylvals=0;",
|
||||
"",
|
||||
"// Current posistion at lexical value queue",
|
||||
"static YYSTYPE *yylvp=0;",
|
||||
"",
|
||||
"// End position of lexical value queue",
|
||||
"static YYSTYPE *yylve=0;",
|
||||
"",
|
||||
"// The last allocated position at the lexical value queue",
|
||||
"static YYSTYPE *yylvlim=0;",
|
||||
"",
|
||||
"// Base of the lexical position queue",
|
||||
"static YYPOSN *yylpsns=0;",
|
||||
"",
|
||||
"// Current posistion at lexical position queue",
|
||||
"static YYPOSN *yylpp=0;",
|
||||
"",
|
||||
"// End position of lexical position queue",
|
||||
"static YYPOSN *yylpe=0;",
|
||||
"",
|
||||
"// The last allocated position at the lexical position queue",
|
||||
"static YYPOSN *yylplim=0;",
|
||||
"",
|
||||
"// Current position at lexical token queue",
|
||||
"static Yshort *yylexp=0;",
|
||||
"",
|
||||
"static Yshort *yylexemes=0;",
|
||||
"",
|
||||
"//",
|
||||
"// For use in generated program",
|
||||
"//",
|
||||
"#define yytrial (yyps->save)",
|
||||
"#define yyvsp (yyps->vsp)",
|
||||
"#define yyval (yyps->val)",
|
||||
"#define yydepth (yyps->ssp - yyps->ss)",
|
||||
"",
|
||||
"",
|
||||
"//",
|
||||
"// Local prototypes.",
|
||||
"//",
|
||||
"int yyparse(void);",
|
||||
"",
|
||||
"int YYLex1();",
|
||||
"int yyexpand();",
|
||||
"void YYSCopy(YYSTYPE *to, YYSTYPE *from, int size);",
|
||||
"void YYPCopy(YYPOSN *to, YYPOSN *from, int size);",
|
||||
"void YYMoreStack(yyparsestate *yyps);",
|
||||
"yyparsestate *YYNewState(int size);",
|
||||
"void YYFreeState(yyparsestate *p);",
|
||||
"",
|
||||
"",
|
||||
0
|
||||
};
|
||||
|
||||
char *body[] =
|
||||
{
|
||||
"#line 186 \"btyaccpa.ske\"",
|
||||
"",
|
||||
"",
|
||||
"//",
|
||||
"// Parser function",
|
||||
"//",
|
||||
"int yyparse() {",
|
||||
" int yym, yyn, yystate, yychar, yynewerrflag;",
|
||||
" yyparsestate *yyerrctx = NULL;",
|
||||
" int reduce_posn;",
|
||||
"",
|
||||
"#if YYDEBUG",
|
||||
" char *yys;",
|
||||
" ",
|
||||
" if ((yys = getenv(\"YYDEBUG\"))) {",
|
||||
" yyn = *yys;",
|
||||
" if (yyn >= '0' && yyn <= '9')",
|
||||
" yydebug = yyn - '0'; ",
|
||||
" }",
|
||||
"#endif",
|
||||
" ",
|
||||
" yyps = YYNewState(YYDEFSTACKSIZE);",
|
||||
" yyps->save = 0;",
|
||||
" yynerrs = 0;",
|
||||
" yyps->errflag = 0;",
|
||||
" yychar = (-1);",
|
||||
" ",
|
||||
" yyps->ssp = yyps->ss;",
|
||||
" yyps->vsp = yyps->vs;",
|
||||
" yyps->psp = yyps->ps;",
|
||||
" *(yyps->ssp) = yystate = 0;",
|
||||
" ",
|
||||
"",
|
||||
" //",
|
||||
" // Main parsing loop",
|
||||
" //",
|
||||
" yyloop:",
|
||||
" if ((yyn = yydefred[yystate])) {",
|
||||
" goto yyreduce;",
|
||||
" }",
|
||||
"",
|
||||
" //",
|
||||
" // Read one token",
|
||||
" //",
|
||||
" if (yychar < 0) {",
|
||||
" if ((yychar = YYLex1()) < 0) yychar = 0;",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug) {",
|
||||
" yys = 0;",
|
||||
" if (yychar <= YYMAXTOKEN) yys = yyname[yychar];",
|
||||
" if (!yys) yys = \"illegal-symbol\";",
|
||||
" printf(\"yydebug[%d,%d]: state %d, reading %d (%s)\", ",
|
||||
"\t yydepth, (int)yytrial, yystate, yychar, yys);",
|
||||
"#ifdef YYDBPR",
|
||||
" printf(\"<\");",
|
||||
" YYDBPR(yylval);",
|
||||
" printf(\">\");",
|
||||
"#endif",
|
||||
" printf(\"\\n\"); ",
|
||||
" }",
|
||||
"#endif",
|
||||
" }",
|
||||
"",
|
||||
" //",
|
||||
" // Do we have a conflict?",
|
||||
" //",
|
||||
" if ((yyn = yycindex[yystate]) &&",
|
||||
" (yyn += yychar) >= 0 &&",
|
||||
" yyn <= YYTABLESIZE &&",
|
||||
" yycheck[yyn] == yychar) {",
|
||||
" int ctry;",
|
||||
"",
|
||||
" if (yypath) {",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug) {",
|
||||
" printf(\"yydebug[%d,%d]: CONFLICT in state %d: following successful trial parse\\n\", ",
|
||||
"\t yydepth, (int)yytrial, yystate);",
|
||||
" }",
|
||||
"#endif",
|
||||
" // Switch to the next conflict context",
|
||||
" yyparsestate *save = yypath;",
|
||||
" yypath = save->save;",
|
||||
" ctry = save->ctry;",
|
||||
" if (save->state != yystate) ",
|
||||
" goto yyabort;",
|
||||
" YYFreeState(save); ",
|
||||
"",
|
||||
" } else {",
|
||||
"",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug) {",
|
||||
" printf(\"yydebug[%d,%d]: CONFLICT in state %d. \", ",
|
||||
"\t yydepth, (int)yytrial, yystate);",
|
||||
" if(yyps->save) {",
|
||||
" printf(\"ALREADY in conflict. Continue trial parse.\");",
|
||||
" } else {",
|
||||
" printf(\"Start trial parse.\");",
|
||||
" }",
|
||||
" printf(\"\\n\");",
|
||||
" }",
|
||||
"#endif",
|
||||
" yyparsestate *save = YYNewState(yyps->ssp - yyps->ss);",
|
||||
" save->save = yyps->save;",
|
||||
" save->state = yystate;",
|
||||
" save->errflag = yyps->errflag;",
|
||||
" save->ssp = save->ss + (yyps->ssp - yyps->ss);",
|
||||
" save->vsp = save->vs + (yyps->vsp - yyps->vs);",
|
||||
" save->psp = save->ps + (yyps->psp - yyps->ps);",
|
||||
" memcpy (save->ss, yyps->ss, (yyps->ssp - yyps->ss + 1)*sizeof(Yshort));",
|
||||
" YYSCopy(save->vs, yyps->vs, (yyps->ssp - yyps->ss + 1));",
|
||||
" YYPCopy(save->ps, yyps->ps, (yyps->ssp - yyps->ss + 1));",
|
||||
" ctry = yytable[yyn];",
|
||||
" if (yyctable[ctry] == -1) {",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug && yychar >= 0)",
|
||||
" printf(\"yydebug[%d]: backtracking 1 token\\n\", ",
|
||||
"\t\t (int)yytrial);",
|
||||
"#endif",
|
||||
" ctry++; ",
|
||||
" }",
|
||||
" save->ctry = ctry;",
|
||||
" if (!yyps->save) {",
|
||||
" // If this is a first conflict in the stack, start saving lexemes",
|
||||
" if (!yylexemes) {",
|
||||
" yylexemes = new Yshort[YYSTACKGROWTH];",
|
||||
" yylvals = new YYSTYPE[YYSTACKGROWTH];",
|
||||
" yylvlim = yylvals + YYSTACKGROWTH; ",
|
||||
" yylpsns = new YYPOSN[YYSTACKGROWTH];",
|
||||
" yylplim = yylpsns + YYSTACKGROWTH; ",
|
||||
" }",
|
||||
" if (yylvp == yylve) {",
|
||||
" yylvp = yylve = yylvals;",
|
||||
"\t yylpp = yylpe = yylpsns;",
|
||||
" yylexp = yylexemes;",
|
||||
" if (yychar >= 0) {",
|
||||
" *yylve++ = yylval;",
|
||||
" *yylpe++ = yyposn;",
|
||||
" *yylexp = yychar;",
|
||||
" yychar = -1; ",
|
||||
" } ",
|
||||
" } ",
|
||||
" }",
|
||||
" if (yychar >= 0) {",
|
||||
" yylvp--, yylpp--, yylexp--;",
|
||||
" yychar = -1; ",
|
||||
" }",
|
||||
" save->lexeme = yylvp - yylvals;",
|
||||
" yyps->save = save; ",
|
||||
" }",
|
||||
" if (yytable[yyn] == ctry) {",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug)",
|
||||
" printf(\"yydebug[%d,%d]: state %d, shifting to state %d\\n\",",
|
||||
" yydepth, (int)yytrial, yystate, yyctable[ctry]);",
|
||||
"#endif",
|
||||
" if (yychar < 0)",
|
||||
" yylvp++, yylpp++, yylexp++;",
|
||||
" yychar = -1;",
|
||||
" if (yyps->errflag > 0) --yyps->errflag;",
|
||||
" yystate = yyctable[ctry];",
|
||||
" goto yyshift; ",
|
||||
" } else {",
|
||||
" yyn = yyctable[ctry];",
|
||||
" goto yyreduce; ",
|
||||
" } ",
|
||||
" }",
|
||||
"",
|
||||
" //",
|
||||
" // Is action a shift?",
|
||||
" //",
|
||||
" if ((yyn = yysindex[yystate]) &&",
|
||||
" (yyn += yychar) >= 0 &&",
|
||||
" yyn <= YYTABLESIZE &&",
|
||||
" yycheck[yyn] == yychar) {",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug)",
|
||||
" printf(\"yydebug[%d,%d]: state %d, shifting to state %d\\n\",",
|
||||
" yydepth, (int)yytrial, yystate, yytable[yyn]);",
|
||||
"#endif",
|
||||
" yychar = (-1);",
|
||||
" if (yyps->errflag > 0) --yyps->errflag;",
|
||||
" yystate = yytable[yyn];",
|
||||
" yyshift:",
|
||||
" if (yyps->ssp >= yyps->ss + yyps->stacksize - 1) {",
|
||||
" YYMoreStack(yyps);",
|
||||
" }",
|
||||
" *++(yyps->ssp) = yystate;",
|
||||
" *++(yyps->vsp) = yylval;",
|
||||
" *++(yyps->psp) = yyposn;",
|
||||
" goto yyloop;",
|
||||
" }",
|
||||
" if ((yyn = yyrindex[yystate]) &&",
|
||||
" (yyn += yychar) >= 0 &&",
|
||||
" yyn <= YYTABLESIZE &&",
|
||||
" yycheck[yyn] == yychar) {",
|
||||
" yyn = yytable[yyn];",
|
||||
" goto yyreduce;",
|
||||
" }",
|
||||
"",
|
||||
" //",
|
||||
" // Action: error",
|
||||
" //",
|
||||
" if (yyps->errflag) goto yyinrecovery;",
|
||||
" yynewerrflag = 1;",
|
||||
" goto yyerrhandler;",
|
||||
"yyerrlab:",
|
||||
" yynewerrflag = 0;",
|
||||
"yyerrhandler:",
|
||||
" while (yyps->save) { ",
|
||||
" int ctry; ",
|
||||
" yyparsestate *save = yyps->save;",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug)",
|
||||
" printf(\"yydebug[%d,%d]: ERROR in state %d, CONFLICT BACKTRACKING to state %d, %d tokens\\n\",",
|
||||
" yydepth, (int)yytrial, yystate, yyps->save->state, yylvp - yylvals - yyps->save->lexeme);",
|
||||
"#endif",
|
||||
" // Memorize most forward-looking error state in case",
|
||||
" // it's really an error.",
|
||||
" if(yyerrctx==NULL || yyerrctx->lexeme<yylvp-yylvals) {",
|
||||
" // Free old saved error context state",
|
||||
" if(yyerrctx) YYFreeState(yyerrctx);",
|
||||
" // Create and fill out new saved error context state",
|
||||
" yyerrctx = YYNewState(yyps->ssp - yyps->ss);",
|
||||
" yyerrctx->save = yyps->save;",
|
||||
" yyerrctx->state = yystate;",
|
||||
" yyerrctx->errflag = yyps->errflag;",
|
||||
" yyerrctx->ssp = yyerrctx->ss + (yyps->ssp - yyps->ss);",
|
||||
" yyerrctx->vsp = yyerrctx->vs + (yyps->vsp - yyps->vs);",
|
||||
" yyerrctx->psp = yyerrctx->ps + (yyps->psp - yyps->ps);",
|
||||
" memcpy (yyerrctx->ss, yyps->ss, (yyps->ssp - yyps->ss + 1)*sizeof(Yshort));",
|
||||
" YYSCopy(yyerrctx->vs, yyps->vs, (yyps->ssp - yyps->ss + 1));",
|
||||
" YYPCopy(yyerrctx->ps, yyps->ps, (yyps->ssp - yyps->ss + 1));",
|
||||
" yyerrctx->lexeme = yylvp - yylvals;",
|
||||
" }",
|
||||
" yylvp = yylvals + save->lexeme;",
|
||||
" yylpp = yylpsns + save->lexeme;",
|
||||
" yylexp = yylexemes + save->lexeme;",
|
||||
" yychar = -1;",
|
||||
" yyps->ssp = yyps->ss + (save->ssp - save->ss);",
|
||||
" yyps->vsp = yyps->vs + (save->vsp - save->vs);",
|
||||
" yyps->psp = yyps->ps + (save->psp - save->ps);",
|
||||
" memcpy (yyps->ss, save->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort));",
|
||||
" YYSCopy(yyps->vs, save->vs, yyps->vsp - yyps->vs + 1);",
|
||||
" YYPCopy(yyps->ps, save->ps, yyps->psp - yyps->ps + 1);",
|
||||
" ctry = ++save->ctry;",
|
||||
" yystate = save->state;",
|
||||
" // We tried shift, try reduce now",
|
||||
" if ((yyn = yyctable[ctry]) >= 0) {",
|
||||
" goto yyreduce;",
|
||||
" }",
|
||||
" yyps->save = save->save;",
|
||||
" YYFreeState(save);",
|
||||
" //",
|
||||
" // Nothing left on the stack -- error",
|
||||
" //",
|
||||
" if (!yyps->save) {",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug) {",
|
||||
" printf(\"yydebug[%d]: trial parse FAILED, entering ERROR mode\\n\", ",
|
||||
"\t (int)yytrial);",
|
||||
" }",
|
||||
"#endif",
|
||||
" // Restore state as it was in the most forward-advanced error",
|
||||
" yylvp = yylvals + yyerrctx->lexeme;",
|
||||
" yylpp = yylpsns + yyerrctx->lexeme;",
|
||||
" yylexp = yylexemes + yyerrctx->lexeme;",
|
||||
" yychar = yylexp[-1];",
|
||||
" yylval = yylvp[-1];",
|
||||
" yyposn = yylpp[-1];",
|
||||
" yyps->ssp = yyps->ss + (yyerrctx->ssp - yyerrctx->ss);",
|
||||
" yyps->vsp = yyps->vs + (yyerrctx->vsp - yyerrctx->vs);",
|
||||
" yyps->psp = yyps->ps + (yyerrctx->psp - yyerrctx->ps);",
|
||||
" memcpy (yyps->ss, yyerrctx->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort));",
|
||||
" YYSCopy(yyps->vs, yyerrctx->vs, yyps->vsp - yyps->vs + 1);",
|
||||
" YYPCopy(yyps->ps, yyerrctx->ps, yyps->psp - yyps->ps + 1);",
|
||||
" yystate = yyerrctx->state;",
|
||||
" YYFreeState(yyerrctx);",
|
||||
" yyerrctx = NULL;",
|
||||
" }",
|
||||
" yynewerrflag = 1; ",
|
||||
" }",
|
||||
" if (yynewerrflag) {",
|
||||
"#ifdef YYERROR_DETAILED",
|
||||
" yyerror_detailed(\"syntax error\", yychar, yylval, yyposn);",
|
||||
"#else",
|
||||
" yyerror(\"syntax error\");",
|
||||
"#endif",
|
||||
" }",
|
||||
" ++yynerrs;",
|
||||
" yyinrecovery:",
|
||||
" if (yyps->errflag < 3) {",
|
||||
" yyps->errflag = 3;",
|
||||
" for (;;) {",
|
||||
" if ((yyn = yysindex[*(yyps->ssp)]) && ",
|
||||
"\t (yyn += YYERRCODE) >= 0 &&",
|
||||
" yyn <= YYTABLESIZE && ",
|
||||
"\t yycheck[yyn] == YYERRCODE) {",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug)",
|
||||
" printf(\"yydebug[%d,%d]: state %d, ERROR recovery shifts to state %d\\n\",",
|
||||
" yydepth, (int)yytrial, *(yyps->ssp), yytable[yyn]);",
|
||||
"#endif",
|
||||
" /* Use label yyerrlab, so that compiler does not warn */",
|
||||
" if(yyps->errflag != yyps->errflag) goto yyerrlab;",
|
||||
" yystate = yytable[yyn];",
|
||||
" goto yyshift; ",
|
||||
" } else {",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug)",
|
||||
" printf(\"yydebug[%d,%d]: ERROR recovery discards state %d\\n\",",
|
||||
" yydepth, (int)yytrial, *(yyps->ssp));",
|
||||
"#endif",
|
||||
" if (yyps->ssp <= yyps->ss) {",
|
||||
"\t goto yyabort;",
|
||||
"\t}",
|
||||
"\tif(!yytrial) {",
|
||||
"\t YYDELETEVAL(yyps->vsp[0],1);",
|
||||
"\t YYDELETEPOSN(yyps->psp[0],1);",
|
||||
"\t}",
|
||||
" --(yyps->ssp);",
|
||||
" --(yyps->vsp);",
|
||||
" --(yyps->psp);",
|
||||
" }",
|
||||
" }",
|
||||
" } else {",
|
||||
" if (yychar == 0) goto yyabort;",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug) {",
|
||||
" yys = 0;",
|
||||
" if (yychar <= YYMAXTOKEN) yys = yyname[yychar];",
|
||||
" if (!yys) yys = \"illegal-symbol\";",
|
||||
" printf(\"yydebug[%d,%d]: state %d, ERROR recovery discards token %d (%s)\\n\",",
|
||||
" yydepth, (int)yytrial, yystate, yychar, yys); ",
|
||||
" }",
|
||||
"#endif",
|
||||
" if(!yytrial) {",
|
||||
" YYDELETEVAL(yylval,0);",
|
||||
" YYDELETEPOSN(yyposn,0);",
|
||||
" }",
|
||||
" yychar = (-1);",
|
||||
" goto yyloop;",
|
||||
" }",
|
||||
"",
|
||||
" //",
|
||||
" // Reduce the rule",
|
||||
" //",
|
||||
"yyreduce:",
|
||||
" yym = yylen[yyn];",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug) {",
|
||||
" printf(\"yydebug[%d,%d]: state %d, reducing by rule %d (%s)\",",
|
||||
" yydepth, (int)yytrial, yystate, yyn, yyrule[yyn]);",
|
||||
"#ifdef YYDBPR",
|
||||
" if (yym) {",
|
||||
" int i;",
|
||||
" printf(\"<\");",
|
||||
" for (i=yym; i>0; i--) {",
|
||||
" if (i!=yym) printf(\", \");",
|
||||
" YYDBPR((yyps->vsp)[1-i]);",
|
||||
" }",
|
||||
" printf(\">\");",
|
||||
" }",
|
||||
"#endif",
|
||||
" printf(\"\\n\");",
|
||||
" }",
|
||||
"#endif",
|
||||
" if (yyps->ssp + 1 - yym >= yyps->ss + yyps->stacksize) {",
|
||||
" YYMoreStack(yyps);",
|
||||
" }",
|
||||
"",
|
||||
" /* \"$$ = NULL\" default action */",
|
||||
" memset(&yyps->val, 0, sizeof(yyps->val));",
|
||||
"",
|
||||
" /* default reduced position is NULL -- no position at all.",
|
||||
" no position will be assigned at trial time and if no position handling is present */",
|
||||
" memset(&yyps->pos, 0, sizeof(yyps->pos));",
|
||||
"",
|
||||
" reduce_posn = TRUE;",
|
||||
"",
|
||||
" switch (yyn) {",
|
||||
"",
|
||||
0
|
||||
};
|
||||
|
||||
char *trailer[] =
|
||||
{
|
||||
"#line 567 \"btyaccpa.ske\"",
|
||||
"",
|
||||
" default:",
|
||||
" break;",
|
||||
" }",
|
||||
"",
|
||||
"#if YYDEBUG && defined(YYDBPR)",
|
||||
" if (yydebug) {",
|
||||
" printf(\"yydebug[%d]: after reduction, result is \", yytrial);",
|
||||
" YYDBPR(yyps->val);",
|
||||
" printf(\"\\n\");",
|
||||
" }",
|
||||
"#endif",
|
||||
"",
|
||||
" // Perform user-defined position reduction",
|
||||
"#ifdef YYREDUCEPOSNFUNC",
|
||||
" if(!yytrial) {",
|
||||
" YYCALLREDUCEPOSN(YYREDUCEPOSNFUNCARG);",
|
||||
" }",
|
||||
"#endif",
|
||||
"",
|
||||
" yyps->ssp -= yym;",
|
||||
" yystate = *(yyps->ssp);",
|
||||
" yyps->vsp -= yym;",
|
||||
" yyps->psp -= yym;",
|
||||
"",
|
||||
" yym = yylhs[yyn];",
|
||||
" if (yystate == 0 && yym == 0) {",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug) {",
|
||||
" printf(\"yydebug[%d,%d]: after reduction, shifting from state 0 to state %d\\n\", ",
|
||||
"\t yydepth, (int)yytrial, YYFINAL);",
|
||||
" }",
|
||||
"#endif",
|
||||
" yystate = YYFINAL;",
|
||||
" *++(yyps->ssp) = YYFINAL;",
|
||||
" *++(yyps->vsp) = yyps->val;",
|
||||
" yyretlval = yyps->val;\t// return value of root non-terminal to yylval",
|
||||
" *++(yyps->psp) = yyps->pos;",
|
||||
" yyretposn = yyps->pos;\t// return value of root position to yyposn",
|
||||
" if (yychar < 0) {",
|
||||
" if ((yychar = YYLex1()) < 0) {",
|
||||
" yychar = 0;",
|
||||
" }",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug) {",
|
||||
" yys = 0;",
|
||||
" if (yychar <= YYMAXTOKEN) yys = yyname[yychar];",
|
||||
" if (!yys) yys = \"illegal-symbol\";",
|
||||
" printf(\"yydebug[%d,%d]: state %d, reading %d (%s)\\n\", ",
|
||||
"\t yydepth, (int)yytrial, YYFINAL, yychar, yys); ",
|
||||
" }",
|
||||
"#endif",
|
||||
" }",
|
||||
" if (yychar == 0) goto yyaccept;",
|
||||
" goto yyloop;",
|
||||
" }",
|
||||
"",
|
||||
" if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&",
|
||||
" yyn <= YYTABLESIZE && yycheck[yyn] == yystate) {",
|
||||
" yystate = yytable[yyn];",
|
||||
" } else {",
|
||||
" yystate = yydgoto[yym];",
|
||||
" }",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug)",
|
||||
" printf(\"yydebug[%d,%d]: after reduction, shifting from state %d to state %d\\n\",",
|
||||
" yydepth, (int)yytrial, *(yyps->ssp), yystate);",
|
||||
"#endif",
|
||||
" if (yyps->ssp >= yyps->ss + yyps->stacksize - 1) {",
|
||||
" YYMoreStack(yyps);",
|
||||
" }",
|
||||
" *++(yyps->ssp) = yystate;",
|
||||
" *++(yyps->vsp) = yyps->val;",
|
||||
" *++(yyps->psp) = yyps->pos;",
|
||||
" goto yyloop;",
|
||||
"",
|
||||
"",
|
||||
" //",
|
||||
" // Reduction declares that this path is valid.",
|
||||
" // Set yypath and do a full parse",
|
||||
" //",
|
||||
"yyvalid:",
|
||||
" if (yypath) {",
|
||||
" goto yyabort;",
|
||||
" }",
|
||||
" while (yyps->save) {",
|
||||
" yyparsestate *save = yyps->save;",
|
||||
" yyps->save = save->save;",
|
||||
" save->save = yypath;",
|
||||
" yypath = save;",
|
||||
" }",
|
||||
"#if YYDEBUG",
|
||||
" if (yydebug)",
|
||||
" printf(\"yydebug[%d,%d]: CONFLICT trial successful, backtracking to state %d, %d tokens\\n\",",
|
||||
" yydepth, (int)yytrial, yypath->state, yylvp - yylvals - yypath->lexeme);",
|
||||
"#endif",
|
||||
" if(yyerrctx) {",
|
||||
" YYFreeState(yyerrctx); yyerrctx = NULL;",
|
||||
" }",
|
||||
" yychar = -1;",
|
||||
" yyps->ssp = yyps->ss + (yypath->ssp - yypath->ss);",
|
||||
" yyps->vsp = yyps->vs + (yypath->vsp - yypath->vs);",
|
||||
" yyps->psp = yyps->ps + (yypath->psp - yypath->ps);",
|
||||
" memcpy (yyps->ss, yypath->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort));",
|
||||
" YYSCopy(yyps->vs, yypath->vs, yyps->vsp - yyps->vs + 1);",
|
||||
" YYPCopy(yyps->ps, yypath->ps, yyps->psp - yyps->ps + 1);",
|
||||
" yylvp = yylvals + yypath->lexeme;",
|
||||
" yylpp = yylpsns + yypath->lexeme;",
|
||||
" yylexp = yylexemes + yypath->lexeme;",
|
||||
" yystate = yypath->state;",
|
||||
" goto yyloop;",
|
||||
"",
|
||||
"",
|
||||
"yyabort:",
|
||||
" if(yyerrctx) {",
|
||||
" YYFreeState(yyerrctx); yyerrctx = NULL;",
|
||||
" }",
|
||||
"",
|
||||
" YYSTYPE *pv;",
|
||||
" for(pv=yyps->vs; pv<yyps->vsp; pv++) {",
|
||||
" YYDELETEVAL(*pv,2);",
|
||||
" }",
|
||||
"",
|
||||
" YYPOSN *pp;",
|
||||
" for(pp=yyps->ps; pp<yyps->psp; pp++) {",
|
||||
" YYDELETEPOSN(*pp,2);",
|
||||
" }",
|
||||
"",
|
||||
" while (yyps) {",
|
||||
" yyparsestate *save = yyps;",
|
||||
" yyps = save->save;",
|
||||
" YYFreeState(save);",
|
||||
" }",
|
||||
" while (yypath) {",
|
||||
" yyparsestate *save = yypath;",
|
||||
" yypath = save->save;",
|
||||
" YYFreeState(save); ",
|
||||
" }",
|
||||
" return (1);",
|
||||
"",
|
||||
"",
|
||||
"yyaccept:",
|
||||
" if (yyps->save) goto yyvalid;",
|
||||
" if(yyerrctx) {",
|
||||
" YYFreeState(yyerrctx); yyerrctx = NULL;",
|
||||
" }",
|
||||
" while (yyps) {",
|
||||
" yyparsestate *save = yyps;",
|
||||
" yyps = save->save;",
|
||||
" YYFreeState(save);",
|
||||
" }",
|
||||
" while (yypath) {",
|
||||
" yyparsestate *save = yypath;",
|
||||
" yypath = save->save;",
|
||||
" YYFreeState(save); ",
|
||||
" }",
|
||||
" return (0);",
|
||||
"}",
|
||||
"",
|
||||
"",
|
||||
"int YYLex1() {",
|
||||
" if(yylvp<yylve) {",
|
||||
" yylval = *yylvp++;",
|
||||
" yyposn = *yylpp++;",
|
||||
" return *yylexp++;",
|
||||
" } else {",
|
||||
" if(yyps->save) {",
|
||||
" if(yylvp==yylvlim) {",
|
||||
"\tyyexpand();",
|
||||
" }",
|
||||
" *yylexp = yylex();",
|
||||
" *yylvp++ = yylval;",
|
||||
" yylve++;",
|
||||
" *yylpp++ = yyposn;",
|
||||
" yylpe++;",
|
||||
" return *yylexp++;",
|
||||
" } else {",
|
||||
" return yylex();",
|
||||
" }",
|
||||
" }",
|
||||
"}",
|
||||
"",
|
||||
"int yyexpand() {",
|
||||
" int p = yylvp-yylvals;",
|
||||
" int s = yylvlim-yylvals;",
|
||||
" s += YYSTACKGROWTH;",
|
||||
" { Yshort *tl = yylexemes; ",
|
||||
" YYSTYPE *tv = yylvals;",
|
||||
" YYPOSN *tp = yylpsns;",
|
||||
" yylvals = new YYSTYPE[s];",
|
||||
" yylpsns = new YYPOSN[s];",
|
||||
" yylexemes = new Yshort[s];",
|
||||
" memcpy(yylexemes, tl, (s-YYSTACKGROWTH)*sizeof(Yshort));",
|
||||
" YYSCopy(yylvals, tv, s-YYSTACKGROWTH);",
|
||||
" YYPCopy(yylpsns, tp, s-YYSTACKGROWTH);",
|
||||
" delete[] tl;",
|
||||
" delete[] tv;",
|
||||
" delete[] tp;",
|
||||
" }",
|
||||
" yylvp = yylve = yylvals + p;",
|
||||
" yylvlim = yylvals + s;",
|
||||
" yylpp = yylpe = yylpsns + p;",
|
||||
" yylplim = yylpsns + s;",
|
||||
" yylexp = yylexemes + p;",
|
||||
" return 0;",
|
||||
"}",
|
||||
"",
|
||||
"void YYSCopy(YYSTYPE *to, YYSTYPE *from, int size) {",
|
||||
" int i; ",
|
||||
" for (i = size-1; i >= 0; i--) {",
|
||||
" to[i] = from[i];",
|
||||
" }",
|
||||
"}",
|
||||
"",
|
||||
"void YYPCopy(YYPOSN *to, YYPOSN *from, int size) {",
|
||||
" int i; ",
|
||||
" for (i = size-1; i >= 0; i--) {",
|
||||
" to[i] = from[i];",
|
||||
" }",
|
||||
"}",
|
||||
"",
|
||||
"void YYMoreStack(yyparsestate *yyps) {",
|
||||
" int p = yyps->ssp - yyps->ss; ",
|
||||
" Yshort *tss = yyps->ss;",
|
||||
" YYSTYPE *tvs = yyps->vs;",
|
||||
" YYPOSN *tps = yyps->ps;",
|
||||
" yyps->ss = new Yshort [yyps->stacksize + YYSTACKGROWTH]; ",
|
||||
" yyps->vs = new YYSTYPE[yyps->stacksize + YYSTACKGROWTH]; ",
|
||||
" yyps->ps = new YYPOSN [yyps->stacksize + YYSTACKGROWTH]; ",
|
||||
" memcpy(yyps->ss, tss, yyps->stacksize * sizeof(Yshort)); ",
|
||||
" YYSCopy(yyps->vs, tvs, yyps->stacksize); ",
|
||||
" YYPCopy(yyps->ps, tps, yyps->stacksize); ",
|
||||
" yyps->stacksize += YYSTACKGROWTH; ",
|
||||
" delete[] tss;",
|
||||
" delete[] tvs;",
|
||||
" delete[] tps;",
|
||||
" yyps->ssp = yyps->ss + p; ",
|
||||
" yyps->vsp = yyps->vs + p; ",
|
||||
" yyps->psp = yyps->ps + p; ",
|
||||
"}",
|
||||
"",
|
||||
"yyparsestate *YYNewState(int size) {",
|
||||
" yyparsestate *p = new yyparsestate;",
|
||||
" p->stacksize = size+4;",
|
||||
" p->ss = new Yshort [size + 4];",
|
||||
" p->vs = new YYSTYPE[size + 4];",
|
||||
" p->ps = new YYPOSN [size + 4];",
|
||||
" memset(&p->vs[0], 0, (size+4)*sizeof(YYSTYPE));",
|
||||
" memset(&p->ps[0], 0, (size+4)*sizeof(YYPOSN));",
|
||||
" return p;",
|
||||
"}",
|
||||
"",
|
||||
"void YYFreeState(yyparsestate *p) {",
|
||||
" delete[] p->ss;",
|
||||
" delete[] p->vs;",
|
||||
" delete[] p->ps;",
|
||||
" delete p;",
|
||||
"}",
|
||||
0
|
||||
};
|
||||
|
||||
struct section section_list[] = {
|
||||
{ "banner", &banner[0] },
|
||||
{ "tables", &tables[0] },
|
||||
{ "header", &header[0] },
|
||||
{ "body", &body[0] },
|
||||
{ "trailer", &trailer[0] },
|
||||
{ 0, 0 } };
|
116
extern/btyacc/symtab.c
vendored
Normal file
116
extern/btyacc/symtab.c
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
#include "defs.h"
|
||||
|
||||
|
||||
/* TABLE_SIZE is the number of entries in the symbol table. */
|
||||
/* TABLE_SIZE must be a power of two. */
|
||||
|
||||
#define TABLE_SIZE 1024
|
||||
|
||||
|
||||
bucket **symbol_table;
|
||||
bucket *first_symbol;
|
||||
bucket *last_symbol;
|
||||
|
||||
|
||||
int hash(char *name)
|
||||
{
|
||||
register char *s;
|
||||
register int c, k;
|
||||
|
||||
assert(name && *name);
|
||||
s = name;
|
||||
k = *s;
|
||||
while ((c = *++s))
|
||||
k = (31*k + c) & (TABLE_SIZE - 1);
|
||||
|
||||
return (k);
|
||||
}
|
||||
|
||||
|
||||
bucket *make_bucket(char *name)
|
||||
{
|
||||
register bucket *bp;
|
||||
|
||||
assert(name);
|
||||
bp = (bucket *) MALLOC(sizeof(bucket));
|
||||
if (bp == 0) no_space();
|
||||
bp->link = 0;
|
||||
bp->next = 0;
|
||||
bp->name = MALLOC(strlen(name) + 1);
|
||||
if (bp->name == 0) no_space();
|
||||
bp->tag = 0;
|
||||
bp->value = UNDEFINED;
|
||||
bp->index = 0;
|
||||
bp->prec = 0;
|
||||
bp->class = UNKNOWN;
|
||||
bp->assoc = TOKEN;
|
||||
bp->args = -1;
|
||||
bp->argnames = 0;
|
||||
bp->argtags = 0;
|
||||
|
||||
if (bp->name == 0) no_space();
|
||||
strcpy(bp->name, name);
|
||||
|
||||
return (bp);
|
||||
}
|
||||
|
||||
|
||||
bucket *lookup(char *name)
|
||||
{
|
||||
register bucket *bp, **bpp;
|
||||
|
||||
bpp = symbol_table + hash(name);
|
||||
bp = *bpp;
|
||||
|
||||
while (bp)
|
||||
{
|
||||
if (strcmp(name, bp->name) == 0) return (bp);
|
||||
bpp = &bp->link;
|
||||
bp = *bpp;
|
||||
}
|
||||
|
||||
*bpp = bp = make_bucket(name);
|
||||
last_symbol->next = bp;
|
||||
last_symbol = bp;
|
||||
|
||||
return (bp);
|
||||
}
|
||||
|
||||
|
||||
void create_symbol_table()
|
||||
{
|
||||
register int i;
|
||||
register bucket *bp;
|
||||
|
||||
symbol_table = (bucket **) MALLOC(TABLE_SIZE*sizeof(bucket *));
|
||||
if (symbol_table == 0) no_space();
|
||||
for (i = 0; i < TABLE_SIZE; i++)
|
||||
symbol_table[i] = 0;
|
||||
|
||||
bp = make_bucket("error");
|
||||
bp->index = 1;
|
||||
bp->class = TERM;
|
||||
|
||||
first_symbol = bp;
|
||||
last_symbol = bp;
|
||||
symbol_table[hash("error")] = bp;
|
||||
}
|
||||
|
||||
|
||||
void free_symbol_table()
|
||||
{
|
||||
FREE(symbol_table);
|
||||
symbol_table = 0;
|
||||
}
|
||||
|
||||
|
||||
void free_symbols()
|
||||
{
|
||||
register bucket *p, *q;
|
||||
|
||||
for (p = first_symbol; p; p = q)
|
||||
{
|
||||
q = p->next;
|
||||
FREE(p);
|
||||
}
|
||||
}
|
411
extern/btyacc/test/ansiC.y
vendored
Normal file
411
extern/btyacc/test/ansiC.y
vendored
Normal file
@ -0,0 +1,411 @@
|
||||
%token AUTO REGISTER STATIC EXTERN TYPEDEF VOID CHAR SHORT INT LONG FLOAT
|
||||
DOUBLE SIGNED UNSIGNED CONST VOLATILE STRUCT UNION ENUM CASE DEFAULT
|
||||
IF SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN ELSE
|
||||
MULEQ DIVEQ MODEQ ADDEQ SUBEQ LSHEQ RSHEQ ANDEQ XOREQ OREQ
|
||||
AND OR EQU NEQ LEQ GEQ LSH RSH INC DEC ARROW IDENTIFIER STRING
|
||||
INTCONST CHARCONST FLOATCONST ELIPSIS SIZEOF
|
||||
|
||||
%%
|
||||
|
||||
translation.unit
|
||||
: external.declaration
|
||||
| translation.unit external.declaration
|
||||
;
|
||||
|
||||
external.declaration
|
||||
: function.definition
|
||||
| declaration
|
||||
;
|
||||
|
||||
function.definition
|
||||
: declaration.specifiers declarator declaration.list compound.statement
|
||||
| declarator declaration.list compound.statement
|
||||
| declaration.specifiers declarator compound.statement
|
||||
| declarator compound.statement
|
||||
;
|
||||
|
||||
declaration
|
||||
: declaration.specifiers init.declarator.list ';'
|
||||
| declaration.specifiers ';'
|
||||
;
|
||||
|
||||
declaration.list
|
||||
: declaration
|
||||
| declaration.list declaration
|
||||
;
|
||||
|
||||
declaration.specifiers
|
||||
: storage.class.specifier declaration.specifiers
|
||||
| storage.class.specifier
|
||||
| type.specifier declaration.specifiers
|
||||
| type.specifier
|
||||
| type.qualifier declaration.specifiers
|
||||
| type.qualifier
|
||||
;
|
||||
|
||||
storage.class.specifier
|
||||
: AUTO
|
||||
| REGISTER
|
||||
| STATIC
|
||||
| EXTERN
|
||||
| TYPEDEF
|
||||
;
|
||||
|
||||
type.specifier
|
||||
: VOID
|
||||
| CHAR
|
||||
| SHORT
|
||||
| INT
|
||||
| LONG
|
||||
| FLOAT
|
||||
| DOUBLE
|
||||
| SIGNED
|
||||
| UNSIGNED
|
||||
| struct.or.union.specifier
|
||||
| enum.specifier
|
||||
| typedef.name
|
||||
;
|
||||
|
||||
type.qualifier
|
||||
: CONST
|
||||
| VOLATILE
|
||||
;
|
||||
|
||||
struct.or.union.specifier
|
||||
: struct.or.union IDENTIFIER '{' struct.declaration.list '}'
|
||||
| struct.or.union '{' struct.declaration.list '}'
|
||||
| struct.or.union IDENTIFIER
|
||||
;
|
||||
|
||||
struct.or.union
|
||||
: STRUCT
|
||||
| UNION
|
||||
;
|
||||
|
||||
struct.declaration.list
|
||||
: struct.declaration
|
||||
| struct.declaration.list struct.declaration
|
||||
;
|
||||
|
||||
init.declarator.list
|
||||
: init.declarator
|
||||
| init.declarator.list ',' init.declarator
|
||||
;
|
||||
|
||||
init.declarator
|
||||
: declarator
|
||||
| declarator '=' initializer
|
||||
;
|
||||
|
||||
struct.declaration
|
||||
: specifier.qualifier.list struct.declarator.list ';'
|
||||
;
|
||||
|
||||
specifier.qualifier.list
|
||||
: type.specifier specifier.qualifier.list
|
||||
| type.specifier
|
||||
| type.qualifier specifier.qualifier.list
|
||||
| type.qualifier
|
||||
;
|
||||
|
||||
struct.declarator.list
|
||||
: struct.declarator
|
||||
| struct.declarator.list ',' struct.declarator
|
||||
;
|
||||
|
||||
struct.declarator
|
||||
: declarator
|
||||
| declarator ':' constant.expression
|
||||
| ':' constant.expression
|
||||
;
|
||||
|
||||
enum.specifier
|
||||
: ENUM IDENTIFIER '{' enumerator.list '}'
|
||||
| ENUM '{' enumerator.list '}'
|
||||
| ENUM IDENTIFIER
|
||||
;
|
||||
|
||||
enumerator.list
|
||||
: enumerator
|
||||
| enumerator.list ',' enumerator
|
||||
;
|
||||
|
||||
enumerator
|
||||
: IDENTIFIER
|
||||
| IDENTIFIER '=' constant.expression
|
||||
;
|
||||
|
||||
declarator
|
||||
: pointer direct.declarator
|
||||
| direct.declarator
|
||||
;
|
||||
|
||||
direct.declarator
|
||||
: IDENTIFIER
|
||||
| '(' declarator ')'
|
||||
| direct.declarator '[' constant.expression ']'
|
||||
| direct.declarator '[' ']'
|
||||
| direct.declarator '(' parameter.type.list ')'
|
||||
| direct.declarator '(' identifier.list ')'
|
||||
| direct.declarator '(' ')'
|
||||
;
|
||||
|
||||
pointer : '*' type.qualifier.list
|
||||
| '*'
|
||||
| '*' type.qualifier.list pointer
|
||||
| '*' pointer
|
||||
;
|
||||
|
||||
type.qualifier.list
|
||||
: type.qualifier
|
||||
| type.qualifier.list type.qualifier
|
||||
;
|
||||
|
||||
parameter.type.list
|
||||
: parameter.list
|
||||
| parameter.list ',' ELIPSIS
|
||||
;
|
||||
|
||||
parameter.list
|
||||
: parameter.declaration
|
||||
| parameter.list ',' parameter.declaration
|
||||
;
|
||||
|
||||
parameter.declaration
|
||||
: declaration.specifiers declarator
|
||||
| declaration.specifiers abstract.declarator
|
||||
| declaration.specifiers
|
||||
;
|
||||
|
||||
identifier.list
|
||||
: IDENTIFIER
|
||||
| identifier.list ',' IDENTIFIER
|
||||
;
|
||||
|
||||
initializer
|
||||
: assignment.expression
|
||||
| '{' initializer.list '}'
|
||||
| '{' initializer.list ',' '}'
|
||||
;
|
||||
|
||||
|
||||
initializer.list
|
||||
: initializer
|
||||
| initializer.list ',' initializer
|
||||
;
|
||||
|
||||
type.name
|
||||
: specifier.qualifier.list abstract.declarator
|
||||
| specifier.qualifier.list
|
||||
;
|
||||
|
||||
abstract.declarator
|
||||
: pointer
|
||||
| pointer direct.abstract.declarator
|
||||
| direct.abstract.declarator
|
||||
;
|
||||
|
||||
direct.abstract.declarator
|
||||
: '(' abstract.declarator ')'
|
||||
| direct.abstract.declarator '[' constant.expression ']'
|
||||
| '[' constant.expression ']'
|
||||
| direct.abstract.declarator '[' ']'
|
||||
| '[' ']'
|
||||
| direct.abstract.declarator '(' parameter.type.list ')'
|
||||
| '(' parameter.type.list ')'
|
||||
| direct.abstract.declarator '(' ')'
|
||||
| '(' ')'
|
||||
;
|
||||
|
||||
typedef.name
|
||||
: IDENTIFIER
|
||||
;
|
||||
|
||||
statement
|
||||
: labeled.statement
|
||||
| expression.statement
|
||||
| compound.statement
|
||||
| selection.statement
|
||||
| iteration.statement
|
||||
| jump.statement
|
||||
;
|
||||
|
||||
labeled.statement
|
||||
: IDENTIFIER ':' statement
|
||||
| CASE constant.expression ':' statement
|
||||
| DEFAULT ':' statement
|
||||
;
|
||||
|
||||
expression.statement
|
||||
: expression ';'
|
||||
| ';'
|
||||
;
|
||||
|
||||
compound.statement
|
||||
: '{' declaration.list statement.list '}'
|
||||
| '{' declaration.list '}'
|
||||
| '{' statement.list '}'
|
||||
| '{' '}'
|
||||
;
|
||||
|
||||
statement.list
|
||||
: statement
|
||||
| statement.list statement
|
||||
;
|
||||
|
||||
selection.statement
|
||||
: IF '(' expression ')' statement
|
||||
| IF '(' expression ')' statement ELSE statement
|
||||
| SWITCH '(' expression ')' statement
|
||||
;
|
||||
|
||||
iteration.statement
|
||||
: WHILE '(' expression ')' statement
|
||||
| DO statement WHILE '(' expression ')' ';'
|
||||
| FOR '(' expression ';' expression ';' expression ')' statement
|
||||
| FOR '(' expression ';' expression ';' ')' statement
|
||||
| FOR '(' expression ';' ';' expression ')' statement
|
||||
| FOR '(' expression ';' ';' ')' statement
|
||||
| FOR '(' ';' expression ';' expression ')' statement
|
||||
| FOR '(' ';' expression ';' ')' statement
|
||||
| FOR '(' ';' ';' expression ')' statement
|
||||
| FOR '(' ';' ';' ')' statement
|
||||
;
|
||||
|
||||
jump.statement
|
||||
: GOTO IDENTIFIER ';'
|
||||
| CONTINUE ';'
|
||||
| BREAK ';'
|
||||
| RETURN expression ';'
|
||||
| RETURN ';'
|
||||
;
|
||||
|
||||
constant.expression
|
||||
: assignment.expression
|
||||
;
|
||||
|
||||
expression
|
||||
: assignment.expression
|
||||
| expression ',' assignment.expression
|
||||
;
|
||||
|
||||
assignment.expression
|
||||
: conditional.expression
|
||||
| unary.expression assignment.operator assignment.expression
|
||||
;
|
||||
|
||||
assignment.operator
|
||||
: '=' | MULEQ | DIVEQ | MODEQ | ADDEQ | SUBEQ
|
||||
| LSHEQ | RSHEQ | ANDEQ | XOREQ | OREQ
|
||||
;
|
||||
|
||||
conditional.expression
|
||||
: logical.OR.expression
|
||||
| logical.OR.expression '?' expression ':' conditional.expression
|
||||
;
|
||||
|
||||
logical.OR.expression
|
||||
: logical.AND.expression
|
||||
| logical.OR.expression OR logical.AND.expression
|
||||
;
|
||||
|
||||
logical.AND.expression
|
||||
: inclusive.OR.expression
|
||||
| logical.AND.expression AND inclusive.OR.expression
|
||||
;
|
||||
|
||||
inclusive.OR.expression
|
||||
: exclusive.OR.expression
|
||||
| inclusive.OR.expression '|' exclusive.OR.expression
|
||||
;
|
||||
|
||||
exclusive.OR.expression
|
||||
: AND.expression
|
||||
| exclusive.OR.expression '^' AND.expression
|
||||
;
|
||||
|
||||
AND.expression
|
||||
: equality.expression
|
||||
| AND.expression '&' equality.expression
|
||||
;
|
||||
|
||||
equality.expression
|
||||
: relational.expression
|
||||
| equality.expression EQU relational.expression
|
||||
| equality.expression NEQ relational.expression
|
||||
;
|
||||
|
||||
relational.expression
|
||||
: shift.expression
|
||||
| relational.expression '<' shift.expression
|
||||
| relational.expression '>' shift.expression
|
||||
| relational.expression LEQ shift.expression
|
||||
| relational.expression GEQ shift.expression
|
||||
;
|
||||
|
||||
shift.expression
|
||||
: additive.expression
|
||||
| shift.expression LSH additive.expression
|
||||
| shift.expression RSH additive.expression
|
||||
;
|
||||
|
||||
additive.expression
|
||||
: multiplicative.expression
|
||||
| additive.expression '+' multiplicative.expression
|
||||
| additive.expression '-' multiplicative.expression
|
||||
;
|
||||
|
||||
multiplicative.expression
|
||||
: cast.expression
|
||||
| multiplicative.expression '*' cast.expression
|
||||
| multiplicative.expression '/' cast.expression
|
||||
| multiplicative.expression '%' cast.expression
|
||||
;
|
||||
|
||||
cast.expression
|
||||
: unary.expression
|
||||
| '(' type.name ')' cast.expression
|
||||
;
|
||||
|
||||
unary.expression
|
||||
: postfix.expression
|
||||
| INC unary.expression
|
||||
| DEC unary.expression
|
||||
| unary.operator cast.expression
|
||||
| SIZEOF unary.expression
|
||||
| SIZEOF '(' type.name ')'
|
||||
;
|
||||
|
||||
unary.operator
|
||||
: '&' | '*' | '+' | '-' | '~' | '!'
|
||||
;
|
||||
|
||||
postfix.expression
|
||||
: primary.expression
|
||||
| postfix.expression '[' expression ']'
|
||||
| postfix.expression '(' argument.expression.list ')'
|
||||
| postfix.expression '(' ')'
|
||||
| postfix.expression '.' IDENTIFIER
|
||||
| postfix.expression ARROW IDENTIFIER
|
||||
| postfix.expression INC
|
||||
| postfix.expression DEC
|
||||
;
|
||||
|
||||
primary.expression
|
||||
: IDENTIFIER
|
||||
| constant
|
||||
| STRING
|
||||
| '(' expression ')'
|
||||
;
|
||||
|
||||
argument.expression.list
|
||||
: assignment.expression
|
||||
| argument.expression.list ',' assignment.expression
|
||||
;
|
||||
|
||||
constant
|
||||
: INTCONST
|
||||
| CHARCONST
|
||||
| FLOATCONST
|
||||
;
|
||||
|
454
extern/btyacc/test/ansiC2.y
vendored
Normal file
454
extern/btyacc/test/ansiC2.y
vendored
Normal file
@ -0,0 +1,454 @@
|
||||
%token AUTO REGISTER STATIC EXTERN TYPEDEF VOID CHAR SHORT INT LONG FLOAT
|
||||
DOUBLE SIGNED UNSIGNED CONST VOLATILE STRUCT UNION ENUM CASE DEFAULT
|
||||
IF SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN ELSE
|
||||
MULEQ DIVEQ MODEQ ADDEQ SUBEQ LSHEQ RSHEQ ANDEQ XOREQ OREQ
|
||||
AND OR EQU NEQ LEQ GEQ LSH RSH INC DEC ARROW IDENTIFIER STRING
|
||||
INTCONST CHARCONST FLOATCONST ELIPSIS SIZEOF
|
||||
|
||||
%%
|
||||
|
||||
translation.unit
|
||||
: external.declaration
|
||||
| translation.unit external.declaration
|
||||
;
|
||||
|
||||
external.declaration
|
||||
: function.definition
|
||||
| declaration
|
||||
;
|
||||
|
||||
function.definition
|
||||
: declaration.specifiers declarator declaration.list.opt compound.statement
|
||||
| declarator declaration.list.opt compound.statement
|
||||
;
|
||||
|
||||
declaration.specifiers.opt
|
||||
:
|
||||
| declaration.specifiers
|
||||
;
|
||||
|
||||
declaration.list.opt
|
||||
:
|
||||
| declaration.list
|
||||
;
|
||||
|
||||
declaration
|
||||
: declaration.specifiers init.declarator.list.opt ';'
|
||||
;
|
||||
|
||||
declaration.list
|
||||
: declaration
|
||||
| declaration.list declaration
|
||||
;
|
||||
|
||||
declaration.specifiers
|
||||
: storage.class.specifier declaration.specifiers.opt
|
||||
| type.specifier declaration.specifiers.opt
|
||||
| type.qualifier declaration.specifiers.opt
|
||||
;
|
||||
|
||||
storage.class.specifier
|
||||
: AUTO
|
||||
| REGISTER
|
||||
| STATIC
|
||||
| EXTERN
|
||||
| TYPEDEF
|
||||
;
|
||||
|
||||
type.specifier
|
||||
: VOID
|
||||
| CHAR
|
||||
| SHORT
|
||||
| INT
|
||||
| LONG
|
||||
| FLOAT
|
||||
| DOUBLE
|
||||
| SIGNED
|
||||
| UNSIGNED
|
||||
| struct.or.union.specifier
|
||||
| enum.specifier
|
||||
| typedef.name
|
||||
;
|
||||
|
||||
type.qualifier
|
||||
: CONST
|
||||
| VOLATILE
|
||||
;
|
||||
|
||||
struct.or.union.specifier
|
||||
: struct.or.union identifier.opt '{' struct.declaration.list '}'
|
||||
| struct.or.union IDENTIFIER
|
||||
;
|
||||
|
||||
struct.or.union
|
||||
: STRUCT
|
||||
| UNION
|
||||
;
|
||||
|
||||
struct.declaration.list
|
||||
: struct.declaration
|
||||
| struct.declaration.list struct.declaration
|
||||
;
|
||||
|
||||
init.declarator.list.opt
|
||||
:
|
||||
| init.declarator.list
|
||||
;
|
||||
|
||||
init.declarator.list
|
||||
: init.declarator
|
||||
| init.declarator.list ',' init.declarator
|
||||
;
|
||||
|
||||
init.declarator
|
||||
: declarator
|
||||
| declarator '=' initializer
|
||||
;
|
||||
|
||||
struct.declaration
|
||||
: specifier.qualifier.list struct.declarator.list ';'
|
||||
;
|
||||
|
||||
specifier.qualifier.list.opt
|
||||
:
|
||||
| specifier.qualifier.list
|
||||
;
|
||||
|
||||
specifier.qualifier.list
|
||||
: type.specifier specifier.qualifier.list.opt
|
||||
| type.qualifier specifier.qualifier.list.opt
|
||||
;
|
||||
|
||||
struct.declarator.list
|
||||
: struct.declarator
|
||||
| struct.declarator.list ',' struct.declarator
|
||||
;
|
||||
|
||||
struct.declarator
|
||||
: declarator
|
||||
| declarator.opt ':' constant.expression
|
||||
;
|
||||
|
||||
enum.specifier
|
||||
: ENUM identifier.opt '{' enumerator.list '}'
|
||||
| ENUM IDENTIFIER
|
||||
;
|
||||
|
||||
enumerator.list
|
||||
: enumerator
|
||||
| enumerator.list ',' enumerator
|
||||
;
|
||||
|
||||
enumerator
|
||||
: IDENTIFIER
|
||||
| IDENTIFIER '=' constant.expression
|
||||
;
|
||||
|
||||
declarator.opt
|
||||
:
|
||||
| declarator
|
||||
;
|
||||
|
||||
declarator
|
||||
: pointer.opt direct.declarator
|
||||
;
|
||||
|
||||
direct.declarator
|
||||
: IDENTIFIER
|
||||
| '(' declarator ')'
|
||||
| direct.declarator '[' constant.expression ']'
|
||||
| direct.declarator '(' parameter.type.list ')'
|
||||
| direct.declarator '(' identifier.list.opt ')'
|
||||
;
|
||||
|
||||
pointer.opt
|
||||
:
|
||||
| pointer
|
||||
;
|
||||
|
||||
pointer : '*' type.qualifier.list.opt
|
||||
| '*' type.qualifier.list.opt pointer
|
||||
;
|
||||
|
||||
type.qualifier.list.opt
|
||||
:
|
||||
| type.qualifier.list
|
||||
;
|
||||
|
||||
type.qualifier.list
|
||||
: type.qualifier
|
||||
| type.qualifier.list type.qualifier
|
||||
;
|
||||
|
||||
parameter.type.list.opt
|
||||
:
|
||||
| parameter.type.list
|
||||
;
|
||||
|
||||
parameter.type.list
|
||||
: parameter.list
|
||||
| parameter.list ',' ELIPSIS
|
||||
;
|
||||
|
||||
parameter.list
|
||||
: parameter.declaration
|
||||
| parameter.list ',' parameter.declaration
|
||||
;
|
||||
|
||||
parameter.declaration
|
||||
: declaration.specifiers declarator
|
||||
| declaration.specifiers abstract.declarator.opt
|
||||
;
|
||||
|
||||
identifier.list.opt
|
||||
:
|
||||
| identifier.list
|
||||
;
|
||||
|
||||
identifier.list
|
||||
: IDENTIFIER
|
||||
| identifier.list ',' IDENTIFIER
|
||||
;
|
||||
|
||||
initializer
|
||||
: assignment.expression
|
||||
| '{' initializer.list '}'
|
||||
| '{' initializer.list ',' '}'
|
||||
;
|
||||
|
||||
|
||||
initializer.list
|
||||
: initializer
|
||||
| initializer.list ',' initializer
|
||||
;
|
||||
|
||||
type.name
|
||||
: specifier.qualifier.list abstract.declarator.opt
|
||||
;
|
||||
|
||||
abstract.declarator.opt
|
||||
:
|
||||
| abstract.declarator
|
||||
;
|
||||
|
||||
abstract.declarator
|
||||
: pointer
|
||||
| pointer.opt direct.abstract.declarator
|
||||
;
|
||||
|
||||
direct.abstract.declarator.opt
|
||||
:
|
||||
| direct.abstract.declarator
|
||||
;
|
||||
|
||||
direct.abstract.declarator
|
||||
: '(' abstract.declarator ')'
|
||||
| direct.abstract.declarator.opt '[' constant.expression.opt ']'
|
||||
| direct.abstract.declarator '(' parameter.type.list.opt ')'
|
||||
| '(' parameter.type.list.opt ')'
|
||||
;
|
||||
|
||||
typedef.name
|
||||
: IDENTIFIER
|
||||
;
|
||||
|
||||
identifier.opt
|
||||
:
|
||||
| IDENTIFIER
|
||||
;
|
||||
|
||||
statement
|
||||
: labeled.statement
|
||||
| expression.statement
|
||||
| compound.statement
|
||||
| selection.statement
|
||||
| iteration.statement
|
||||
| jump.statement
|
||||
;
|
||||
|
||||
labeled.statement
|
||||
: IDENTIFIER ':' statement
|
||||
| CASE constant.expression ':' statement
|
||||
| DEFAULT ':' statement
|
||||
;
|
||||
|
||||
expression.statement
|
||||
: expression.opt ';'
|
||||
;
|
||||
|
||||
compound.statement
|
||||
: '{' declaration.list.opt statement.list.opt '}'
|
||||
;
|
||||
|
||||
statement.list.opt
|
||||
:
|
||||
| statement.list
|
||||
;
|
||||
|
||||
statement.list
|
||||
: statement
|
||||
| statement.list statement
|
||||
;
|
||||
|
||||
selection.statement
|
||||
: IF '(' expression ')' statement
|
||||
| IF '(' expression ')' statement ELSE statement
|
||||
| SWITCH '(' expression ')' statement
|
||||
;
|
||||
|
||||
iteration.statement
|
||||
: WHILE '(' expression ')' statement
|
||||
| DO statement WHILE '(' expression ')' ';'
|
||||
| FOR '(' expression.opt ';' expression.opt ';' expression.opt ')' statement
|
||||
;
|
||||
|
||||
jump.statement
|
||||
: GOTO IDENTIFIER ';'
|
||||
| CONTINUE ';'
|
||||
| BREAK ';'
|
||||
| RETURN expression.opt ';'
|
||||
;
|
||||
|
||||
expression.opt
|
||||
:
|
||||
| expression
|
||||
;
|
||||
|
||||
constant.expression.opt
|
||||
:
|
||||
| constant.expression
|
||||
;
|
||||
|
||||
constant.expression
|
||||
: assignment.expression
|
||||
;
|
||||
|
||||
expression
|
||||
: assignment.expression
|
||||
| expression ',' assignment.expression
|
||||
;
|
||||
|
||||
assignment.expression
|
||||
: conditional.expression
|
||||
| unary.expression assignment.operator assignment.expression
|
||||
;
|
||||
|
||||
assignment.operator
|
||||
: '=' | MULEQ | DIVEQ | MODEQ | ADDEQ | SUBEQ
|
||||
| LSHEQ | RSHEQ | ANDEQ | XOREQ | OREQ
|
||||
;
|
||||
|
||||
conditional.expression
|
||||
: logical.OR.expression
|
||||
| logical.OR.expression '?' expression ':' conditional.expression
|
||||
;
|
||||
|
||||
logical.OR.expression
|
||||
: logical.AND.expression
|
||||
| logical.OR.expression OR logical.AND.expression
|
||||
;
|
||||
|
||||
logical.AND.expression
|
||||
: inclusive.OR.expression
|
||||
| logical.AND.expression AND inclusive.OR.expression
|
||||
;
|
||||
|
||||
inclusive.OR.expression
|
||||
: exclusive.OR.expression
|
||||
| inclusive.OR.expression '|' exclusive.OR.expression
|
||||
;
|
||||
|
||||
exclusive.OR.expression
|
||||
: AND.expression
|
||||
| exclusive.OR.expression '^' AND.expression
|
||||
;
|
||||
|
||||
AND.expression
|
||||
: equality.expression
|
||||
| AND.expression '&' equality.expression
|
||||
;
|
||||
|
||||
equality.expression
|
||||
: relational.expression
|
||||
| equality.expression EQU relational.expression
|
||||
| equality.expression NEQ relational.expression
|
||||
;
|
||||
|
||||
relational.expression
|
||||
: shift.expression
|
||||
| relational.expression '<' shift.expression
|
||||
| relational.expression '>' shift.expression
|
||||
| relational.expression LEQ shift.expression
|
||||
| relational.expression GEQ shift.expression
|
||||
;
|
||||
|
||||
shift.expression
|
||||
: additive.expression
|
||||
| shift.expression LSH additive.expression
|
||||
| shift.expression RSH additive.expression
|
||||
;
|
||||
|
||||
additive.expression
|
||||
: multiplicative.expression
|
||||
| additive.expression '+' multiplicative.expression
|
||||
| additive.expression '-' multiplicative.expression
|
||||
;
|
||||
|
||||
multiplicative.expression
|
||||
: cast.expression
|
||||
| multiplicative.expression '*' cast.expression
|
||||
| multiplicative.expression '/' cast.expression
|
||||
| multiplicative.expression '%' cast.expression
|
||||
;
|
||||
|
||||
cast.expression
|
||||
: unary.expression
|
||||
| '(' type.name ')' cast.expression
|
||||
;
|
||||
|
||||
unary.expression
|
||||
: postfix.expression
|
||||
| INC unary.expression
|
||||
| DEC unary.expression
|
||||
| unary.operator cast.expression
|
||||
| SIZEOF unary.expression
|
||||
| SIZEOF '(' type.name ')'
|
||||
;
|
||||
|
||||
unary.operator
|
||||
: '&' | '*' | '+' | '-' | '~' | '!'
|
||||
;
|
||||
|
||||
postfix.expression
|
||||
: primary.expression
|
||||
| postfix.expression '[' expression ']'
|
||||
| postfix.expression '(' argument.expression.list.opt ')'
|
||||
| postfix.expression '.' IDENTIFIER
|
||||
| postfix.expression ARROW IDENTIFIER
|
||||
| postfix.expression INC
|
||||
| postfix.expression DEC
|
||||
;
|
||||
|
||||
primary.expression
|
||||
: IDENTIFIER
|
||||
| constant
|
||||
| STRING
|
||||
| '(' expression ')'
|
||||
;
|
||||
|
||||
argument.expression.list.opt
|
||||
:
|
||||
| argument.expression.list
|
||||
;
|
||||
|
||||
argument.expression.list
|
||||
: assignment.expression
|
||||
| argument.expression.list ',' assignment.expression
|
||||
;
|
||||
|
||||
constant
|
||||
: INTCONST
|
||||
| CHARCONST
|
||||
| FLOATCONST
|
||||
;
|
||||
|
6
extern/btyacc/test/error.y
vendored
Normal file
6
extern/btyacc/test/error.y
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
%%
|
||||
S: error
|
||||
%%
|
||||
main(){printf("yyparse() = %d\n",yyparse());}
|
||||
yylex(){return-1;}
|
||||
yyerror(s)char*s;{printf("%s\n",s);}
|
1180
extern/btyacc/test/ftp.y
vendored
Normal file
1180
extern/btyacc/test/ftp.y
vendored
Normal file
File diff suppressed because it is too large
Load Diff
22
extern/btyacc/test/t1.y
vendored
Normal file
22
extern/btyacc/test/t1.y
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
%left LO '+' '-'
|
||||
%left HI '*' '/' '%'
|
||||
%nonassoc UNARY
|
||||
|
||||
%%
|
||||
|
||||
expr: expr op1 expr %prec LO
|
||||
| expr op2 expr %prec HI
|
||||
| unary expr %prec UNARY
|
||||
;
|
||||
|
||||
op1 : '+'
|
||||
| '-'
|
||||
;
|
||||
|
||||
op2 : '*'
|
||||
| '/'
|
||||
| '%'
|
||||
;
|
||||
|
||||
unary : '+' | '-' | '*' | '&' ;
|
||||
|
136
extern/btyacc/test/t2.y
vendored
Normal file
136
extern/btyacc/test/t2.y
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
|
||||
%union {
|
||||
Scope *scope;
|
||||
Expr *expr;
|
||||
Expr_List *elist;
|
||||
Type *type;
|
||||
Decl *decl;
|
||||
Decl_List *dlist;
|
||||
Code *code;
|
||||
char *id;
|
||||
};
|
||||
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%nonassoc PREFIX
|
||||
%nonassoc POSTFIX '(' '[' '.'
|
||||
|
||||
%token <id> ID
|
||||
%token <expr> CONSTANT
|
||||
%token EXTERN REGISTER STATIC CONST VOLATILE IF THEN ELSE CLCL
|
||||
|
||||
%type <expr> expr(<scope>)
|
||||
%type decl(<scope>) declarator_list(<scope>, <type>)
|
||||
decl_list(<scope>)
|
||||
%type <code> statement(<scope>) statement_list(<scope>)
|
||||
block_statement(<scope>)
|
||||
%type <decl> declarator(<scope>, <type>) formal_arg(<scope>)
|
||||
%type <type> decl_specs(<scope>) decl_spec(<scope>) typename(<scope>)
|
||||
cv_quals cv_qual
|
||||
%type <scope> opt_scope(<scope>)
|
||||
%type <dlist> formal_arg_list(<scope>) nonempty_formal_arg_list(<scope>)
|
||||
|
||||
%start input
|
||||
|
||||
%%
|
||||
|
||||
opt_scope($e): [ $$ = $e; ]
|
||||
| CLCL [ $$ = global_scope; ]
|
||||
| opt_scope ID CLCL [ Decl *d = lookup($1, $2);
|
||||
if (!d || !d->scope) YERROR;
|
||||
$$ = d->scope; ]
|
||||
;
|
||||
|
||||
typename($e): opt_scope ID
|
||||
[ Decl *d = lookup($1, $2);
|
||||
if (!d || !d->istype()) YYERROR;
|
||||
$$ = d->type; ]
|
||||
;
|
||||
|
||||
input: decl_list(global_scope = new_scope(0)) ;
|
||||
decl_list($e): | decl_list decl($e) ;
|
||||
decl($e):
|
||||
decl_specs declarator_list($e,$1) ';' [YYVALID;]
|
||||
| decl_specs declarator($e,$1) block_statement(start_fn_def($e, $2))
|
||||
{ finish_fn_def($2, $3); }
|
||||
;
|
||||
|
||||
decl_specs($e):
|
||||
decl_spec [ $$ = $1; ]
|
||||
| decl_specs decl_spec($e) [ $$ = type_combine($1, $2); ]
|
||||
;
|
||||
|
||||
cv_quals: [ $$ = 0; ]
|
||||
| cv_quals cv_qual [ $$ = type_combine($1, $2); ]
|
||||
;
|
||||
|
||||
decl_spec($e):
|
||||
cv_qual [ $$ = $1; ]
|
||||
| typename [ $$ = $1; ]
|
||||
| EXTERN [ $$ = bare_extern(); ]
|
||||
| REGISTER [ $$ = bare_register(); ]
|
||||
| STATIC [ $$ = bare_static(); ]
|
||||
;
|
||||
|
||||
cv_qual:
|
||||
CONST [ $$ = bare_const(); ]
|
||||
| VOLATILE [ $$ = bare_volatile(); ]
|
||||
;
|
||||
|
||||
declarator_list($e, $t):
|
||||
declarator_list ',' declarator($e, $t)
|
||||
| declarator
|
||||
;
|
||||
|
||||
declarator($e, $t):
|
||||
/* empty */ [ if (!$t) YYERROR; ]
|
||||
{ $$ = declare($e, 0, $t); }
|
||||
| ID { $$ = declare($e, $1, $t); }
|
||||
| '(' declarator($e, $t) ')' { $$ = $2; }
|
||||
| '*' cv_quals declarator($e, $t) %prec PREFIX
|
||||
{ $$ = make_pointer($3, $2); }
|
||||
| declarator '[' expr($e) ']'
|
||||
{ $$ = make_array($1->type, $3); }
|
||||
| declarator '(' formal_arg_list($e) ')' cv_quals
|
||||
{ $$ = build_function($1, $3, $5); }
|
||||
;
|
||||
|
||||
formal_arg_list($e): { $$ = 0; }
|
||||
| nonempty_formal_arg_list { $$ = $1; }
|
||||
;
|
||||
nonempty_formal_arg_list($e):
|
||||
nonempty_formal_arg_list ',' formal_arg($e) { $$ = append_dlist($1, $3); }
|
||||
| formal_arg { $$ = build_dlist($1); }
|
||||
;
|
||||
formal_arg($e):
|
||||
decl_specs declarator($e,$1) { $$ = $2; }
|
||||
;
|
||||
|
||||
expr($e):
|
||||
expr '+' expr($e) { $$ = build_expr($1, ADD, $3); }
|
||||
| expr '-' expr($e) { $$ = build_expr($1, SUB, $3); }
|
||||
| expr '*' expr($e) { $$ = build_expr($1, MUL, $3); }
|
||||
| expr '%' expr($e) { $$ = build_expr($1, MOD, $3); }
|
||||
| expr '/' expr($e) { $$ = build_expr($1, DIV, $3); }
|
||||
| '*' expr($e) %prec PREFIX { $$ = build_expr(0, REF, $2); }
|
||||
| ID { $$ = var_expr($e, $1); }
|
||||
| CONSTANT { $$ = $1; }
|
||||
;
|
||||
|
||||
statement($e):
|
||||
decl { $$ = 0; }
|
||||
| expr($e) ';' [YYVALID;] { $$ = build_expr_code($1); }
|
||||
| IF '(' expr($e) ')' THEN statement($e) ELSE statement($e) [YYVALID;]
|
||||
{ $$ = build_if($3, $6, $8); }
|
||||
| IF '(' expr($e) ')' THEN statement($e) [YYVALID;]
|
||||
{ $$ = build_if($3, $6, 0); }
|
||||
| block_statement(new_scope($e)) [YYVALID;]{ $$ = $1; }
|
||||
;
|
||||
|
||||
statement_list($e): { $$ = 0; }
|
||||
| statement_list statement($e) { $$ = code_append($1, $2); }
|
||||
;
|
||||
|
||||
block_statement($e):
|
||||
'{' statement_list($e) '}' { $$ = $2; }
|
||||
;
|
32
extern/btyacc/test/test.y
vendored
Normal file
32
extern/btyacc/test/test.y
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
%{
|
||||
/* first section */
|
||||
%}
|
||||
%%
|
||||
%{
|
||||
/* second section */
|
||||
%}
|
||||
S : /* empty */ { printf("S -> epsilon\n"); }
|
||||
| '(' S ')' S { printf("S -> ( S ) S\n"); }
|
||||
%ifdef ABC
|
||||
/* see how preprocessor can be used */
|
||||
| '*' { printf("S -> *\n"); }
|
||||
%endif
|
||||
;
|
||||
%%
|
||||
#include <stdio.h>
|
||||
|
||||
main() {
|
||||
printf("yyparse() = %d\n",yyparse());
|
||||
}
|
||||
|
||||
yylex() {
|
||||
int ch;
|
||||
|
||||
do { ch = getchar(); } while (ch == ' ' || ch == '\n' || ch == '\t');
|
||||
if (ch == EOF) return 0;
|
||||
return ch;
|
||||
}
|
||||
|
||||
yyerror(s) char*s; {
|
||||
printf("%s\n",s);
|
||||
}
|
320
extern/btyacc/verbose.c
vendored
Normal file
320
extern/btyacc/verbose.c
vendored
Normal file
@ -0,0 +1,320 @@
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
|
||||
static Yshort *null_rules;
|
||||
|
||||
void verbose()
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (!vflag) return;
|
||||
|
||||
null_rules = (Yshort *) MALLOC(nrules*sizeof(Yshort));
|
||||
if (null_rules == 0) no_space();
|
||||
fprintf(verbose_file, "\f\n");
|
||||
for (i = 0; i < nstates; i++)
|
||||
print_state(i);
|
||||
FREE(null_rules);
|
||||
|
||||
if (nunused)
|
||||
log_unused();
|
||||
if (SRtotal || RRtotal)
|
||||
log_conflicts();
|
||||
|
||||
fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
|
||||
nvars);
|
||||
fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
|
||||
}
|
||||
|
||||
|
||||
void log_unused()
|
||||
{
|
||||
register int i;
|
||||
register Yshort *p;
|
||||
|
||||
fprintf(verbose_file, "\n\nRules never reduced:\n");
|
||||
for (i = 3; i < nrules; ++i)
|
||||
{
|
||||
if (!rules_used[i])
|
||||
{
|
||||
fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]);
|
||||
for (p = ritem + rrhs[i]; *p >= 0; ++p)
|
||||
fprintf(verbose_file, " %s", symbol_name[*p]);
|
||||
fprintf(verbose_file, " (%d)\n", i - 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void log_conflicts()
|
||||
{
|
||||
register int i;
|
||||
|
||||
fprintf(verbose_file, "\n\n");
|
||||
for (i = 0; i < nstates; i++)
|
||||
{
|
||||
if (SRconflicts[i] || RRconflicts[i])
|
||||
{
|
||||
fprintf(verbose_file, "State %d contains ", i);
|
||||
if (SRconflicts[i] == 1)
|
||||
fprintf(verbose_file, "1 shift/reduce conflict");
|
||||
else if (SRconflicts[i] > 1)
|
||||
fprintf(verbose_file, "%d shift/reduce conflicts",
|
||||
SRconflicts[i]);
|
||||
if (SRconflicts[i] && RRconflicts[i])
|
||||
fprintf(verbose_file, ", ");
|
||||
if (RRconflicts[i] == 1)
|
||||
fprintf(verbose_file, "1 reduce/reduce conflict");
|
||||
else if (RRconflicts[i] > 1)
|
||||
fprintf(verbose_file, "%d reduce/reduce conflicts",
|
||||
RRconflicts[i]);
|
||||
fprintf(verbose_file, ".\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_state(int state)
|
||||
{
|
||||
if (state)
|
||||
fprintf(verbose_file, "\n\n");
|
||||
if (SRconflicts[state] || RRconflicts[state])
|
||||
print_conflicts(state);
|
||||
fprintf(verbose_file, "state %d\n", state);
|
||||
print_core(state);
|
||||
print_nulls(state);
|
||||
print_actions(state);
|
||||
}
|
||||
|
||||
|
||||
void print_conflicts(int state)
|
||||
{
|
||||
register int symbol, act, number;
|
||||
register action *p;
|
||||
|
||||
symbol = act = number = -1;
|
||||
for (p = parser[state]; p; p = p->next)
|
||||
{
|
||||
if (p->suppressed == 2)
|
||||
continue;
|
||||
|
||||
if (p->symbol != symbol)
|
||||
{
|
||||
symbol = p->symbol;
|
||||
number = p->number;
|
||||
if (p->action_code == SHIFT)
|
||||
act = SHIFT;
|
||||
else
|
||||
act = REDUCE;
|
||||
}
|
||||
else if (p->suppressed == 1)
|
||||
{
|
||||
if (state == final_state && symbol == 0)
|
||||
{
|
||||
fprintf(verbose_file, "%d: shift/reduce conflict "
|
||||
"(accept, reduce %d) on $end\n", state, p->number - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (act == SHIFT)
|
||||
{
|
||||
fprintf(verbose_file, "%d: shift/reduce conflict "
|
||||
"(shift %d, reduce %d) on %s\n", state, number,
|
||||
p->number - 2, symbol_name[symbol]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(verbose_file, "%d: reduce/reduce conflict "
|
||||
"(reduce %d, reduce %d) on %s\n", state,
|
||||
number - 2, p->number - 2, symbol_name[symbol]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_core(int state)
|
||||
{
|
||||
register int i;
|
||||
register int k;
|
||||
register int rule;
|
||||
register core *statep;
|
||||
register Yshort *sp;
|
||||
register Yshort *sp1;
|
||||
|
||||
statep = state_table[state];
|
||||
k = statep->nitems;
|
||||
|
||||
for (i = 0; i < k; i++)
|
||||
{
|
||||
sp1 = sp = ritem + statep->items[i];
|
||||
|
||||
while (*sp >= 0) ++sp;
|
||||
rule = -(*sp);
|
||||
fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
|
||||
|
||||
for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
|
||||
fprintf(verbose_file, "%s ", symbol_name[*sp]);
|
||||
|
||||
putc('.', verbose_file);
|
||||
|
||||
while (*sp >= 0)
|
||||
{
|
||||
fprintf(verbose_file, " %s", symbol_name[*sp]);
|
||||
sp++;
|
||||
}
|
||||
fprintf(verbose_file, " (%d)\n", -2 - *sp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_nulls(int state)
|
||||
{
|
||||
register action *p;
|
||||
register int i, j, k, nnulls;
|
||||
|
||||
nnulls = 0;
|
||||
for (p = parser[state]; p; p = p->next)
|
||||
{
|
||||
if (p->action_code == REDUCE &&
|
||||
(p->suppressed == 0 || p->suppressed == 1))
|
||||
{
|
||||
i = p->number;
|
||||
if (rrhs[i] + 1 == rrhs[i+1])
|
||||
{
|
||||
for (j = 0; j < nnulls && i > null_rules[j]; ++j)
|
||||
continue;
|
||||
|
||||
if (j == nnulls)
|
||||
{
|
||||
++nnulls;
|
||||
null_rules[j] = i;
|
||||
}
|
||||
else if (i != null_rules[j])
|
||||
{
|
||||
++nnulls;
|
||||
for (k = nnulls - 1; k > j; --k)
|
||||
null_rules[k] = null_rules[k-1];
|
||||
null_rules[j] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nnulls; ++i)
|
||||
{
|
||||
j = null_rules[i];
|
||||
fprintf(verbose_file, "\t%s : . (%d)\n", symbol_name[rlhs[j]],
|
||||
j - 2);
|
||||
}
|
||||
fprintf(verbose_file, "\n");
|
||||
}
|
||||
|
||||
|
||||
void print_actions(int stateno)
|
||||
{
|
||||
register action *p;
|
||||
register shifts *sp;
|
||||
register int as;
|
||||
|
||||
if (stateno == final_state)
|
||||
fprintf(verbose_file, "\t$end accept\n");
|
||||
|
||||
p = parser[stateno];
|
||||
if (p)
|
||||
{
|
||||
print_shifts(p);
|
||||
print_reductions(p, defred[stateno]);
|
||||
}
|
||||
|
||||
sp = shift_table[stateno];
|
||||
if (sp && sp->nshifts > 0)
|
||||
{
|
||||
as = accessing_symbol[sp->shift[sp->nshifts - 1]];
|
||||
if (ISVAR(as))
|
||||
print_gotos(stateno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_shifts(action *p)
|
||||
{
|
||||
register int count;
|
||||
register action *q;
|
||||
|
||||
count = 0;
|
||||
for (q = p; q; q = q->next)
|
||||
{
|
||||
if (q->suppressed < 2 && q->action_code == SHIFT)
|
||||
++count;
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
for (; p; p = p->next)
|
||||
{
|
||||
if (p->action_code == SHIFT && p->suppressed == 0)
|
||||
fprintf(verbose_file, "\t%s shift %d\n",
|
||||
symbol_name[p->symbol], p->number);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_reductions(action *p, int defred)
|
||||
{
|
||||
register int k, anyreds;
|
||||
register action *q;
|
||||
|
||||
anyreds = 0;
|
||||
for (q = p; q ; q = q->next)
|
||||
{
|
||||
if (q->action_code == REDUCE && q->suppressed < 2)
|
||||
{
|
||||
anyreds = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyreds == 0)
|
||||
fprintf(verbose_file, "\t. error\n");
|
||||
else
|
||||
{
|
||||
for (; p; p = p->next)
|
||||
{
|
||||
if (p->action_code == REDUCE && p->number != defred)
|
||||
{
|
||||
k = p->number - 2;
|
||||
if (p->suppressed == 0)
|
||||
fprintf(verbose_file, "\t%s reduce %d\n",
|
||||
symbol_name[p->symbol], k);
|
||||
}
|
||||
}
|
||||
|
||||
if (defred > 0)
|
||||
fprintf(verbose_file, "\t. reduce %d\n", defred - 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_gotos(int stateno)
|
||||
{
|
||||
register int i, k;
|
||||
register int as;
|
||||
register Yshort *to_state;
|
||||
register shifts *sp;
|
||||
|
||||
putc('\n', verbose_file);
|
||||
sp = shift_table[stateno];
|
||||
to_state = sp->shift;
|
||||
for (i = 0; i < sp->nshifts; ++i)
|
||||
{
|
||||
k = to_state[i];
|
||||
as = accessing_symbol[k];
|
||||
if (ISVAR(as))
|
||||
fprintf(verbose_file, "\t%s goto %d\n", symbol_name[as], k);
|
||||
}
|
||||
}
|
||||
|
80
extern/btyacc/warshall.c
vendored
Normal file
80
extern/btyacc/warshall.c
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
#include "defs.h"
|
||||
|
||||
void transitive_closure(unsigned *R, int n)
|
||||
{
|
||||
register int rowsize;
|
||||
register unsigned mask;
|
||||
register unsigned *rowj;
|
||||
register unsigned *rp;
|
||||
register unsigned *rend;
|
||||
register unsigned *ccol;
|
||||
register unsigned *relend;
|
||||
register unsigned *cword;
|
||||
register unsigned *rowi;
|
||||
|
||||
rowsize = WORDSIZE(n);
|
||||
relend = R + n*rowsize;
|
||||
|
||||
cword = R;
|
||||
mask = 1;
|
||||
rowi = R;
|
||||
while (rowi < relend)
|
||||
{
|
||||
ccol = cword;
|
||||
rowj = R;
|
||||
|
||||
while (rowj < relend)
|
||||
{
|
||||
if (*ccol & mask)
|
||||
{
|
||||
rp = rowi;
|
||||
rend = rowj + rowsize;
|
||||
while (rowj < rend)
|
||||
*rowj++ |= *rp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
rowj += rowsize;
|
||||
}
|
||||
|
||||
ccol += rowsize;
|
||||
}
|
||||
|
||||
mask <<= 1;
|
||||
if (mask == 0)
|
||||
{
|
||||
mask = 1;
|
||||
cword++;
|
||||
}
|
||||
|
||||
rowi += rowsize;
|
||||
}
|
||||
}
|
||||
|
||||
void reflexive_transitive_closure(unsigned *R, int n)
|
||||
{
|
||||
register int rowsize;
|
||||
register unsigned mask;
|
||||
register unsigned *rp;
|
||||
register unsigned *relend;
|
||||
|
||||
transitive_closure(R, n);
|
||||
|
||||
rowsize = WORDSIZE(n);
|
||||
relend = R + n*rowsize;
|
||||
|
||||
mask = 1;
|
||||
rp = R;
|
||||
while (rp < relend)
|
||||
{
|
||||
*rp |= mask;
|
||||
mask <<= 1;
|
||||
if (mask == 0)
|
||||
{
|
||||
mask = 1;
|
||||
rp++;
|
||||
}
|
||||
|
||||
rp += rowsize;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user