+++ /dev/null
-# The "checkoutlist" file is used to support additional version controlled
-# administrative files in $CVSROOT/CVSROOT, such as template files.
-#
-# The first entry on a line is a filename which will be checked out from
-# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
-# The remainder of the line is an error message to use if the file cannot
-# be checked out.
-#
-# File format:
-#
-# [<whitespace>]<filename>[<whitespace><error message>]<end-of-line>
-#
-# comment lines begin with '#'
-cvslog
-cvsprep
-
-
+++ /dev/null
-# The "commitinfo" file is used to control pre-commit checks.
-# The filter on the right is invoked with the repository and a list
-# of files to check. A non-zero exit of the filter program will
-# cause the commit to be aborted.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being committed to, relative
-# to the $CVSROOT. For the first match that is found, then the remainder
-# of the line is the name of the filter to run.
-#
-# Format strings present in the filter will be replaced as follows:
-# %p = path relative to repository
-# %r = repository (path portion of $CVSROOT)
-# %{s} = file name, file name, ...
-#
-# If no format strings are present in the filter string, a default of
-# " %r %s" will be appended to the filter string, but this usage is
-# deprecated.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
-#ALL $CVSROOT/CVSROOT/commit_prep -u -r
-DEFAULT $CVSROOT/CVSROOT/cvsprep -- %r/%p
\ No newline at end of file
+++ /dev/null
-# Set this to "no" if pserver shouldn't check system users/passwords
-#SystemAuth=no
-
-# Put CVS lock files in this directory rather than directly in the repository.
-LockDir=/var/lock
-
-# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
-# level of the new working directory when using the `cvs checkout'
-# command.
-#TopLevelAdmin=no
-
-# Set `LogHistory' to `all' or `TOEFWUPCGMAR' to log all transactions to the
-# history file, or a subset as needed (ie `TMAR' logs all write operations)
-#LogHistory=TOEFWUPCGMAR
-
-# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg
-# script to change the log message. Set it to `stat' to force CVS to verify
-# that the file has changed before reading it (this can take up to an extra
-# second per directory being committed, so it is not recommended for large
-# repositories. Set it to `never' (the previous CVS behavior) to prevent
-# verifymsg scripts from changing the log message.
-#RereadLogAfterVerify=always
-
-# Set `UserAdminOptions' to the list of `cvs admin' commands (options)
-# that users not in the `cvsadmin' group are allowed to run. This
-# defaults to `k', or only allowing the changing of the default
-# keyword expansion mode for files for users not in the `cvsadmin' group.
-# This value is ignored if the `cvsadmin' group does not exist.
-#
-# The following string would enable all `cvs admin' commands for all
-# users:
-#UserAdminOptions=aAbceIklLmnNostuU
-
-# Set `UseNewInfoFmtStrings' to `no' if you must support a legacy system by
-# enabling the deprecated old style info file command line format strings.
-# Be warned that these strings could be disabled in any new version of CVS.
-UseNewInfoFmtStrings=yes
+++ /dev/null
-#!/usr/bin/perl -w
-$ID = q(cvslog,v 1.51 2005/04/16 22:39:39 eagle Exp );
-#
-# cvslog -- Mail CVS commit notifications.
-#
-# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
-# Board of Trustees, Leland Stanford Jr. University
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-##############################################################################
-# Modules and declarations
-##############################################################################
-
-# The path to the repository. If your platform or CVS implementation doesn't
-# pass the full path to the cvslog script in $0 (or if your cvslog script
-# isn't in the CVSROOT directory of your repository for some reason), you will
-# need to explicitly set $REPOSITORY to the root directory of your repository
-# (the same thing that you would set CVSROOT to).
-($REPOSITORY) = ($0 =~ m%^(.*)/CVSROOT/cvslog$%);
-$REPOSITORY ||= '';
-
-require 5.004;
-
-use Getopt::Long qw(GetOptions);
-use IPC::Open2 qw(open2);
-use POSIX qw(SEEK_SET strftime);
-
-use strict;
-use vars qw($DEBUG $ID $REPOSITORY);
-
-# Clean up $0 for errors.
-$0 =~ s%^.*/%%;
-
-##############################################################################
-# Utility functions
-##############################################################################
-
-# Given a prefix and a reference to an array, return a list of all strings in
-# that array with the common prefix stripped off. Also strip off any leading
-# ./ if present.
-sub simplify {
- my ($prefix, $list) = @_;
- my @stripped = @$list;
- for (@stripped) {
- s%^\Q$prefix\E/*%%;
- s%^\./+%%;
- }
- return @stripped;
-}
-
-# Return the next version for a CVS version, incrementing the last number.
-sub next_version {
- my $version = shift;
- my @version = split (/\./, $version);
- $version[-1]++;
- return join ('.', @version);
-}
-
-# Given a directory name, find the corresponding CVS module. We do this by
-# looking in the modules file, finding the last "word" on each line, making
-# sure it contains a / (and is therefore assumed to be a directory), and
-# seeing if it's a prefix of the module path.
-sub find_module {
- my $module = shift;
- if (open (MODULES, "$REPOSITORY/CVSROOT/modules")) {
- local $_;
- while (<MODULES>) {
- next if /^\s*\#/;
- next if /^\s*$/;
- my ($name, @rest) = split;
- my $path = pop @rest;
- next unless ($path =~ m%/%);
- if ($module =~ s%^$path(\Z|/)%%) {
- $module = '/' . $module if $module;
- $module = "<$name>$module";
- last;
- }
- }
- close MODULES;
- }
- return $module;
-}
-
-##############################################################################
-# Multidirectory commit I/O
-##############################################################################
-
-# Recalculate the file prefix and module after having loaded a new set of
-# data. We do this by starting with the prefix from the last set of data and
-# then stripping off one directory at a time until we find something that is a
-# common prefix of every affected file.
-sub recalculate_prefix {
- my $data = shift;
- my $prefix = $$data{prefix};
- for (keys %{ $$data{files} }) {
- while ($prefix && index ($_, $prefix) != 0) {
- $prefix =~ s%/*([^/]+)$%%;
- my $last = $1;
- $$data{repository} =~ s%/*\Q$last\E$%%;
- $$data{localpath} =~ s%/*\Q$last\E$%%;
- }
- }
- $$data{prefix} = $prefix;
- $$data{module} = find_module $prefix;
-}
-
-# Build the directory in which we'll find our data.
-sub build_tmpdir {
- my $tmpdir = $ENV{TMPDIR} || '/tmp';
- $tmpdir .= '/cvs.' . $< . '.' . getpgrp;
- return $tmpdir;
-}
-
-# Delete all of the accumulated data for multidirectory commits.
-sub cleanup_data {
- my $tmpdir = build_tmpdir;
- unless (opendir (D, $tmpdir)) {
- warn "$0: can't open $tmpdir: $!\n";
- return;
- }
- for (grep { $_ ne '.' && $_ ne '..' } readdir D) {
- unlink "$tmpdir/$_";
- }
- closedir D;
- rmdir $tmpdir or warn "$0: can't remove $tmpdir: $!\n";
-}
-
-# Read the file containing the last directory noticed by the commitinfo script
-# and return that directory name.
-sub read_lastdir {
- my $tmpdir = build_tmpdir;
- my $last;
- if (!-l $tmpdir && -d _ && (lstat _)[4] == $<) {
- if (open (LAST, $tmpdir . '/directory')) {
- $last = <LAST>;
- chomp $last;
- close LAST;
- }
- }
- return $last;
-}
-
-# Read in a list of files with revisions, one per line, and fill in the
-# provided hashes. The first one gets the file information put into its files
-# key, and the second gets lists of added, removed, and modified files.
-# Returns success or failure.
-sub read_files {
- my ($file, $data, $message) = @_;
- unless (open (FILES, $file)) {
- warn "$0: can't open $file: $!\n";
- return;
- }
- my (@added, @removed, @modified);
- local $_;
- while (<FILES>) {
- chomp;
- my ($name, $old, $new) = /^(.*),([^,]+),([^,]+)$/;
- next unless $new;
- $$data{files}{$name} = [ $old, $new ];
- if ($old eq 'NONE') { push (@added, $name) }
- elsif ($new eq 'NONE') { push (@removed, $name) }
- else { push (@modified, $name) }
- }
- close FILES;
- $$message{added} = [ @added ];
- $$message{removed} = [ @removed ];
- $$message{modified} = [ @modified ];
- return 1;
-}
-
-# Read in message text from a file and put it in the provided hash.
-sub read_text {
- my ($file, $message) = @_;
- my @text;
- if (open (TEXT, $file)) {
- @text = <TEXT>;
- close TEXT;
- }
- $$message{text} = [ @text ];
-}
-
-# Given a list of message hashes and a new one, merge the new one into the
-# list. This is done by checking its commit message against the existing ones
-# and merging the list of affected files if a match is found. If a match
-# isn't found, the new message is appended to the end of the list.
-sub merge_message {
- my ($list, $message) = @_;
- my $done;
- for (@$list) {
- if ("@{ $$_{text} }" eq "@{ $$message{text} }") {
- push (@{ $$_{added} }, @{ $$message{added} });
- push (@{ $$_{removed} }, @{ $$message{removed} });
- push (@{ $$_{modified} }, @{ $$message{modified} });
- $done = 1;
- }
- }
- push (@$list, $message) unless $done;
-}
-
-# Read in saved data from previous directories. This involves reading in its
-# affected files and its commit message, merging this with the previous list
-# of affected files and commit messages, and then recalculating the common
-# prefix for all the files and deleting all the data we read in.
-sub read_data {
- my $data = shift;
- my $tmpdir = build_tmpdir;
- $$data{messages} = [];
- for (my $i = 1; -f "$tmpdir/files.$i"; $i++) {
- my %message;
- read_files ("$tmpdir/files.$i", $data, \%message);
- read_text ("$tmpdir/text.$i", \%message);
- merge_message ($$data{messages}, \%message);
- }
- merge_message ($$data{messages}, $$data{message});
- recalculate_prefix ($data);
- cleanup_data;
-}
-
-# Save data for the files modified in this invocation to be picked up later.
-sub save_data {
- my $data = shift;
- my $tmpdir = build_tmpdir;
- if (-l $tmpdir || !-d _ || (lstat _)[4] != $<) {
- warn "$0: invalid directory $tmpdir\n";
- return undef;
- }
- my $i = 1;
- $i++ while -f "$tmpdir/files.$i";
- unless (open (FILES, "> $tmpdir/files.$i")
- && open (TEXT, "> $tmpdir/text.$i")) {
- warn "$0: can't save to $tmpdir/files: $!\n";
- return undef;
- }
- for (keys %{ $$data{files} }) {
- my ($old, $new) = @{ $$data{files}{$_} };
- print FILES join (',', $_, $old, $new), "\n";
- }
- print TEXT @{ $$data{message}{text} };
- unless (close (FILES) && close (TEXT)) {
- warn "$0: can't save to $tmpdir/files: $!\n";
- return undef;
- }
-}
-
-##############################################################################
-# Parsing functions
-##############################################################################
-
-# Split apart the file names that are passed to cvslog. Unfortunately, CVS
-# passes all the affected files as one string rather than as separate
-# arguments, which means that file names that contain spaces and commas pose
-# problems. Returns the path in the repository and then a list of files with
-# attached version information; that list may be just a couple of special-case
-# strings indicating a cvs add of a directory or a cvs import.
-#
-# The complexity here is purely the fault of CVS, which doesn't have a good
-# interface to logging hooks.
-sub split_files {
- my ($files) = @_;
-
- # This ugly hack is here to deal with files at the top level of the
- # repository; CVS reports those files without including a directory
- # before the file list. Check to see if what would normally be the
- # directory name looks more like a file with revisions.
- my ($root, $rest) = split (' ', $files, 2);
- if ($rest && $root !~ /(,(\d+(\.\d+)*|NONE)){2}$/) {
- $files = $rest;
- } else {
- $root = '.';
- }
-
- # Special-case directory adds and imports.
- if ($files =~ /^- New directory(,NONE,NONE)?$/) {
- return ($root, 'directory');
- } elsif ($files =~ /^- Imported sources(,NONE,NONE)?$/) {
- return ($root, 'import');
- }
-
- # Now, split apart $files, which contains just the files, at the spaces
- # after version information.
- my @files;
- while ($files =~ s/^((?:.*?)(?:,(?:\d+(?:\.\d+)*|NONE)){2})( |\z)//) {
- push (@files, $1);
- }
- push (@files, $files) if $files;
- return ($root, 'commit', @files);
-}
-
-# Given the summary line passed to the script, parse it into file names and
-# version numbers (if available). Takes the log information hash and adds a
-# key for the type of change (directory, import, or commit) and for commits a
-# hash of file names with values being a list of the previous and the now-
-# current version number. Also finds the module and stores that in the hash.
-#
-# The path in the repository (the first argument) is prepended to all of the
-# file names; we'll pull off the common prefix later.
-sub parse_files {
- my ($data, @args) = @_;
- my ($directory, $type, @files);
- if (@args == 1) {
- ($directory, $type, @files) = split_files ($args[0]);
- if ($type eq 'commit') {
- @files = map { [ /^(.*),([^,]+),([^,]+)$/ ] } @files;
- }
- } else {
- $directory = shift @args;
- if ($args[0] eq '- New directory') {
- $type = 'directory';
- } elsif ($args[0] eq '- Imported sources') {
- $type = 'import';
- } else {
- $type = 'commit';
- while (@args) {
- push (@files, [ splice (@args, 0, 3) ]);
- }
- }
- }
- die "$0: no module given by CVS (no \%{sVv}?)\n" unless $directory;
- $$data{prefix} = $directory;
- $$data{module} = find_module $directory;
- $$data{message}{added} ||= [];
- $$data{message}{modified} ||= [];
- $$data{message}{removed} ||= [];
- if ($type eq 'directory') {
- $$data{type} = 'directory';
- $$data{root} = $directory;
- } elsif ($type eq 'import') {
- $$data{type} = 'import';
- $$data{root} = $directory;
- } elsif (!@files) {
- die "$0: no files given by CVS (no \%{sVv}?)\n";
- } else {
- $$data{type} = 'commit';
- my $added = $$data{message}{added};
- my $modified = $$data{message}{modified};
- my $removed = $$data{message}{removed};
- for (@files) {
- my ($name, $prev, $cur) = @$_;
- warn "$0: no version numbers given by CVS (no \%{sVv}?)\n"
- unless defined $cur;
- $$data{files}{"$directory/$name"} = [ $prev, $cur ];
- if ($prev eq 'NONE') { push (@$added, "$directory/$name") }
- elsif ($cur eq 'NONE') { push (@$removed, "$directory/$name") }
- else { push (@$modified, "$directory/$name") }
- }
- }
-}
-
-# Parse the header of the CVS log message (containing the path information)
-# and puts the path information into the data hash.
-sub parse_paths {
- my $data = shift;
-
- # The first line of the log message will be "Update of <path>".
- my $path = <STDIN>;
- print $path if $DEBUG;
- $path =~ s/^Update of //;
- $path =~ s/\s*$//;
- $$data{repository} = $path;
-
- # Now comes the path to the local working directory. Grab it and clean it
- # up, and then ignore the next blank line.
- local $_ = <STDIN>;
- print if $DEBUG;
- my ($local) = /directory (\S+)/;
- $$data{localpath} = $local;
- $_ = <STDIN>;
- print if $DEBUG;
-}
-
-# Extract the tag. We assume that all files will be committed with the same
-# tag; probably not the best assumption, but it seems workable. Note that we
-# ignore all of the file lists, since we build those ourself from the version
-# information (saving the hard challenge of parsing a whitespace-separated
-# list that could contain filenames with whitespace).
-sub parse_filelist {
- my $data = shift;
- my ($current, @added, @modified, @removed);
- local $_;
- while (<STDIN>) {
- print if $DEBUG;
- last if /^Log Message/;
- $$data{tag} = $1, next if /^\s*Tag: (\S+)\s*$/;
- }
-}
-
-# Extract the commit message, stripping leading and trailing whitespace.
-sub parse_message {
- my $data = shift;
- my @message = <STDIN>;
- print @message if $DEBUG;
- shift @message while (@message && $message[0] =~ /^\s*$/);
- pop @message while (@message && $message[-1] =~ /^\s*$/);
- $$data{message}{text} = [ @message ];
-}
-
-##############################################################################
-# Formatting functions
-##############################################################################
-
-# Determine the From header of the message. If CVSUSER is set, we're running
-# from inside a CVS server, and the From header should reflect information
-# from the CVS passwd file. Otherwise, pull the information from the system
-# passwd file.
-sub build_from {
- my $cvsuser = $ENV{CVSUSER} || scalar (getpwuid $<);
- my $name = '';
- my $address = '';
- if ($cvsuser) {
- if (open (PASSWD, "$REPOSITORY/CVSROOT/passwd")) {
- local $_;
- while (<PASSWD>) {
- chomp;
- next unless /:/;
- my @info = split ':';
- if ($info[0] eq $cvsuser) {
- $name = $info[3];
- $address = $info[4];
- }
- }
- close PASSWD;
- }
- $name ||= (getpwnam $cvsuser)[6];
- }
- $address ||= $cvsuser || 'cvs';
- $name =~ s/,.*//;
- if ($name =~ /[^\w ]/) {
- $name = '"' . $name . '"';
- }
- return "From: " . ($name ? "$name <$address>" : $address) . "\n";
-}
-
-# Takes the data hash, a prefix to add to the subject header, and a flag
-# saying whether to give a full list of files no matter how long it is. Form
-# the subject line of our message. Try to keep the subject under 78
-# characters by just giving a count of files if there are a lot of them.
-sub build_subject {
- my ($data, $prefix, $long) = @_;
- $prefix = "Subject: " . $prefix;
- my $length = 78 - length ($prefix) - length ($$data{module});
- $length = 8 if $length < 8;
- my $subject;
- if ($$data{type} eq 'directory') {
- $subject = "[new]";
- } elsif ($$data{type} eq 'import') {
- $subject = "[import]";
- } else {
- my @files = sort keys %{ $$data{files} };
- @files = simplify ($$data{prefix}, \@files);
- my $files = join (' ', @files);
- $files =~ s/[\n\r]/ /g;
- if (!$long && length ($files) > $length) {
- $subject = '(' . @files . (@files > 1 ? " files" : " file") . ')';
- } else {
- $subject = "($files)";
- }
- }
- if ($$data{module}) {
- $subject = "$$data{module} $subject";
- }
- if ($$data{tag} && $$data{tag} =~ /[^\d.]/) {
- $subject = "$$data{tag} $subject";
- }
- return "$prefix$subject\n";
-}
-
-# Generate file lists, wrapped at 74 columns, with the right prefix for what
-# type of file they are.
-sub build_filelist {
- my ($prefix, @files) = @_;
- local $_ = join (' ', @files);
- my $output = '';
- while (length > 64) {
- if (s/^(.{0,64})\s+// || s/^(\S+)//) {
- $output .= (' ' x 10) . $1 . "\n";
- } else {
- last;
- }
- }
- $output .= (' ' x 10) . $_;
- $output =~ s/\s*$/\n/;
- $prefix = (' ' x (8 - length ($prefix))) . $prefix;
- $output =~ s/^ {10}/$prefix: /;
- return $output;
-}
-
-# Build the subheader of the report, listing the files changed and some other
-# information about the change. Returns the header as a list.
-sub build_header {
- my ($data, $showdir, $showauthor) = @_;
- my $user = $ENV{CVSUSER} || (getpwuid $<)[0] || $<;
- my $date = strftime ('%A, %B %e, %Y @ %T', localtime time);
- $date =~ s/ / /;
- my @header = (" Date: $date\n");
- push (@header, " Author: $user\n") if $showauthor;
-
- # If the paths are too long, trim them by taking off a leading path
- # component until the length is under 70 characters.
- my $path = $$data{repository};
- my $local = $$data{localpath};
- while (length ($path) > 69) {
- $path =~ s%^\.\.\.%%;
- last unless $path =~ s%^/[^/]+%...%;
- }
- while (length ($local) > 69) {
- $local =~ s%^([\w.-]+:)\.\.\.%$1%;
- last unless $local =~ s%^([\w.-]+:)/[^/]+%$1...%;
- }
-
- if ($showdir) {
- push (@header, " Tag: $$data{tag}\n") if $$data{tag};
- push (@header, "\n", "Update of $path\n",
- " from $local\n");
- } else {
- push (@header, " Path: $path\n");
- push (@header, " Tag: $$data{tag}\n") if $$data{tag};
- }
- return @header;
-}
-
-# Build a report for a particular commit; this includes the list of affected
-# files and the commit message. Returns the report as a list. Takes the
-# data, the commit message, and a flag saying whether to add version numbers
-# to the file names.
-sub build_message {
- my ($data, $message, $versions) = @_;
- my @added = sort @{ $$message{added} };
- my @modified = sort @{ $$message{modified} };
- my @removed = sort @{ $$message{removed} };
- if ($versions) {
- @added = map { "$_ ($$data{files}{$_}[1])" } @added;
- @removed = map { "$_ ($$data{files}{$_}[0])" } @removed;
- @modified = map {
- print "$_\n";
- "$_ ($$data{files}{$_}[0] -> $$data{files}{$_}[1])"
- } @modified;
- }
- @added = simplify ($$data{prefix}, \@added);
- @modified = simplify ($$data{prefix}, \@modified);
- @removed = simplify ($$data{prefix}, \@removed);
- my @message;
- push (@message, build_filelist ('Added', @added)) if @added;
- push (@message, build_filelist ('Modified', @modified)) if @modified;
- push (@message, build_filelist ('Removed', @removed)) if @removed;
- if (@{ $$message{text} }) {
- push (@message, "\n") if (@added || @modified || @removed);
- push (@message, @{ $$message{text} });
- }
- return @message;
-}
-
-# Builds an array of -r flags to pass to CVS to get diffs between the
-# appropriate versions, given a reference to the %data hash and the name of
-# the file.
-sub build_version_flags {
- my ($data, $file) = @_;
- my @versions = @{ $$data{files}{$file} };
- return unless $versions[1] && ($versions[0] ne $versions[1]);
- if ($versions[0] eq 'NONE') {
- @versions = ('-r', '0.0', '-r', $versions[1]);
- } elsif ($versions[1] eq 'NONE') {
- @versions = ('-r', $versions[0], '-r', next_version $versions[0]);
- } else {
- @versions = map { ('-r', $_) } @versions;
- }
- return @versions;
-}
-
-# Build cvsweb diff URLs. Right now, this is very specific to cvsweb, but
-# could probably be extended for other web interfaces to CVS. Takes the data
-# hash and the base URL for cvsweb.
-sub build_cvsweb {
- my ($data, $cvsweb) = @_;
- my $options = 'f=h';
- my @cvsweb = ("Diff URLs:\n");
- my $file;
- for (sort keys %{ $$data{files} }) {
- my @versions = @{ $$data{files}{$_} };
- next unless @versions;
- my $file = $_;
- for ($file, @versions) {
- s{([^a-zA-Z0-9\$_.+!*\'(),/-])} {sprintf "%%%x", ord ($1)}ge;
- }
- my $url = "$cvsweb/$file.diff?$options&r1=$versions[0]"
- . "&r2=$versions[1]\n";
- push (@cvsweb, $url);
- }
- return @cvsweb;
-}
-
-# Run a cvs rdiff between the old and new versions and return the output.
-# This is useful for small changes where you want to see the changes in
-# e-mail, but probably creates too large of messages when the changes get
-# bigger. Note that this stores the full diff output in memory.
-sub build_diff {
- my $data = shift;
- my @difflines;
- for my $file (sort keys %{ $$data{files} }) {
- my @versions = build_version_flags ($data, $file);
- next unless @versions;
- my $pid = open (CVS, '-|');
- if (!defined $pid) {
- die "$0: can't fork cvs: $!\n";
- } elsif ($pid == 0) {
- open (STDERR, '>&STDOUT') or die "$0: can't reopen stderr: $!\n";
- exec ('cvs', '-fnQq', '-d', $REPOSITORY, 'rdiff', '-u',
- @versions, $file) or die "$0: can't fork cvs: $!\n";
- } else {
- my @diff = <CVS>;
- close CVS;
- if ($diff[1] =~ /failed to read diff file header/) {
- @diff = ($diff[0], "<<Binary file>>\n");
- }
- push (@difflines, @diff);
- }
- }
- return @difflines;
-}
-
-# Build a summary of the changes by building the patch it represents in /tmp
-# and then running diffstat on it. This gives a basic idea of the order of
-# magnitude of the changes. Takes the data hash and the path to diffstat as
-# arguments.
-sub build_summary {
- my ($data, $diffstat) = @_;
- $diffstat ||= 'diffstat';
- open2 (\*OUT, \*IN, $diffstat, '-w', '78')
- or die "$0: can't fork $diffstat: $!\n";
- my @binary;
- for my $file (sort keys %{ $$data{files} }) {
- my @versions = build_version_flags ($data, $file);
- next unless @versions;
- my $pid = open (CVS, '-|');
- if (!defined $pid) {
- die "$0: can't fork cvs: $!\n";
- } elsif ($pid == 0) {
- open (STDERR, '>&STDOUT') or die "$0: can't reopen stderr: $!\n";
- exec ('cvs', '-fnQq', '-d', $REPOSITORY, 'rdiff', '-u',
- @versions, $file) or die "$0: can't fork cvs: $!\n";
- }
- local $_;
- while (<CVS>) {
- s%^(\*\*\*|---|\+\+\+) \Q$$data{prefix}\E/*%$1 %;
- s%^Index: \Q$$data{prefix}\E/*%Index: %;
- if (/^diff -c/) { s% \Q$$data{prefix}\E/*% %g }
- if (/: failed to read diff file header/) {
- my $short = $file;
- $short =~ s%^\Q$$data{prefix}\E/*%%;
- my $date = localtime;
- print IN "Index: $short\n";
- print IN "--- $short\t$date\n+++ $short\t$date\n";
- print IN "@@ -1,1 +1,1 @@\n+<<Binary file>>\n";
- push (@binary, $short);
- last;
- } else {
- print IN $_;
- }
- }
- close CVS;
- }
- close IN;
- my @stats = <OUT>;
- close OUT;
- my $offset = index ($stats[0], '|');
- for my $file (@binary) {
- @stats = map {
- s/^( +\Q$file\E +\| +).*/$1<\<Binary file>>/;
- $_;
- } @stats;
- }
- unshift (@stats, '-' x $offset, "+\n");
- return @stats;
-}
-
-##############################################################################
-# Configuration file handling
-##############################################################################
-
-# Load defaults from a configuration file, if any. The syntax is keyword
-# colon value, where value may be enclosed in quotes. Returns a list
-# containing the address to which to send all commits (defaults to not sending
-# any message), the base URL for cvsweb (defaults to not including cvsweb
-# URLs), the full path to diffstat (defaults to just "diffstat", meaning the
-# user's path will be searched), the subject prefix, a default host for
-# unqualified e-mail addresses, additional headers to add to the mail message,
-# and the full path to sendmail.
-sub load_config {
- my $file = $REPOSITORY . '/CVSROOT/cvslog.conf';
- my $address = '';
- my $cvsweb = '';
- my $diffstat = 'diffstat';
- my $headers = '';
- my $mailhost = '';
- my ($sendmail) = grep { -x $_ } qw(/usr/sbin/sendmail /usr/lib/sendmail);
- $sendmail ||= '/usr/lib/sendmail';
- my $subject = 'CVS update of ';
- if (open (CONFIG, $file)) {
- local $_;
- while (<CONFIG>) {
- next if /^\s*\#/;
- next if /^\s*$/;
- chomp;
- my ($key, $value) = /^\s*(\S+):\s+(.*)/;
- unless ($value) {
- warn "$0:$file:$.: invalid config syntax: $_\n";
- next;
- }
- $value =~ s/\s+$//;
- $value =~ s/^\"(.*)\"$/$1/;
- if (lc $key eq 'address') { $address = $value }
- elsif (lc $key eq 'cvsweb') { $cvsweb = $value }
- elsif (lc $key eq 'diffstat') { $diffstat = $value }
- elsif (lc $key eq 'mailhost') { $mailhost = $value }
- elsif (lc $key eq 'sendmail') { $sendmail = $value }
- elsif (lc $key eq 'subject') { $subject = $value }
- elsif (lc $key eq 'header') { $headers .= $value . "\n" }
- else { warn "$0:$file:$.: unrecognized config line: $_\n" }
- }
- close CONFIG;
- }
- return ($address, $cvsweb, $diffstat, $subject, $mailhost, $headers,
- $sendmail);
-}
-
-##############################################################################
-# Main routine
-##############################################################################
-
-# Load the configuration file for defaults.
-my ($address, $cvsweburl, $diffstat, $subject, $mailhost, $headers, $sendmail)
- = load_config;
-
-# Parse command-line options.
-my (@addresses, $cvsweb, $diff, $help, $longsubject, $merge, $omitauthor,
- $showdir, $summary, $version, $versions);
-Getopt::Long::config ('bundling', 'no_ignore_case', 'require_order');
-GetOptions ('address|a=s' => \@addresses,
- 'cvsweb|c' => \$cvsweb,
- 'debug|D' => \$DEBUG,
- 'diff|d' => \$diff,
- 'help|h' => \$help,
- 'include-versions|i' => \$versions,
- 'long-subject|l' => \$longsubject,
- 'merge|m' => \$merge,
- 'omit-author|o' => \$omitauthor,
- 'show-directory|w' => \$showdir,
- 'summary|s' => \$summary,
- 'version|v' => \$version) or exit 1;
-if ($help) {
- print "Feeding myself to perldoc, please wait....\n";
- exec ('perldoc', '-t', $0);
-} elsif ($version) {
- my @version = split (' ', $ID);
- shift @version if $ID =~ /^\$Id/;
- my $version = join (' ', @version[0..2]);
- $version =~ s/,v\b//;
- $version =~ s/(\S+)$/($1)/;
- $version =~ tr%/%-%;
- print $version, "\n";
- exit;
-}
-die "$0: no addresses specified\n" unless ($address || @addresses);
-die "$0: unable to determine the repository path\n" unless $REPOSITORY;
-die "$0: no cvsweb URL specified in the configuration file\n"
- if $cvsweb && !$cvsweburl;
-my $showauthor = !$omitauthor;
-
-# Parse the input.
-print "Options: ", join ('|', @ARGV), "\n" if $DEBUG;
-print '-' x 78, "\n" if $DEBUG;
-my %data;
-parse_files (\%data, @ARGV);
-parse_paths (\%data);
-parse_filelist (\%data);
-parse_message (\%data);
-print '-' x 78, "\n" if $DEBUG;
-
-# Check to see if this is part of a multipart commit. If so, just save the
-# data for later. Otherwise, read in any saved data and add it to our data.
-if ($merge && $data{type} eq 'commit') {
- my $lastdir = read_lastdir;
- if ($lastdir && $data{repository} ne $lastdir) {
- save_data (\%data) and exit 0;
- # Fall through and send a notification if save_data fails.
- } else {
- read_data (\%data);
- }
-}
-$data{messages} = [ $data{message} ] unless $data{messages};
-
-# Exit if there are no addresses to send the message to.
-exit 0 if (!$address && !@addresses);
-
-# Open our mail program.
-open (MAIL, "| $sendmail -t -oi -oem")
- or die "$0: can't fork $sendmail: $!\n";
-my $oldfh = select MAIL;
-$| = 1;
-select $oldfh;
-
-# Build the mail headers.
-if ($mailhost) {
- for ($address, @addresses) {
- if ($_ && !/\@/) {
- $_ .= '@' . $mailhost unless /\@/;
- }
- }
-}
-if (@addresses) {
- print MAIL "To: ", join (', ', @addresses), "\n";
- print MAIL "Cc: $address\n" if $address;
-} else {
- print MAIL "To: $address\n";
-}
-print MAIL build_from;
-print MAIL $headers if $headers;
-print MAIL build_subject (\%data, $subject, $longsubject), "\n";
-
-# Build the message and write it out.
-print MAIL build_header (\%data, $showdir, $showauthor);
-for (@{ $data{messages} }) {
- print MAIL "\n", build_message (\%data, $_, $versions);
-}
-if ($data{type} eq 'commit') {
- print MAIL "\n\n", build_summary (\%data, $diffstat) if $summary;
- print MAIL "\n\n", build_cvsweb (\%data, $cvsweburl) if $cvsweb;
- print MAIL "\n\n", build_diff (\%data) if $diff;
-}
-
-# Make sure sending mail succeeded.
-close MAIL;
-unless ($? == 0) { die "$0: sendmail exit status " . ($? >> 8) . "\n" }
-exit 0;
-__END__
-
-##############################################################################
-# Documentation
-##############################################################################
-
-=head1 NAME
-
-cvslog - Mail CVS commit notifications
-
-=head1 SYNOPSIS
-
-B<cvslog> [B<-cDdhilmosvw>] [B<-a> I<address> ...] %{sVv}
-
-=head1 REQUIREMENTS
-
-CVS 1.10 or later, Perl 5.004 or later, diffstat for the B<-s> option, and a
-sendmail command that can accept formatted mail messages for delivery.
-
-=head1 DESCRIPTION
-
-B<cvslog> is intended to be run out of CVS's F<loginfo> administrative file.
-It parses the (undocumented) format of CVS's commit notifications, cleans it
-up and reformats it, and mails the notification to one or more e-mail
-addresses. Optionally, a diffstat(1) summary of the changes can be added to
-the notification, and a CVS commit spanning multiple directories can be
-combined into a single notification (by default, CVS generates a separate
-notification for each directory).
-
-To combine a commit spanning multiple directories into a single notification,
-B<cvslog> needs the help of an additional program run from the F<commitinfo>
-administrative file that records the last directory affected by the commit.
-See the description in L<"FILES"> for what files and directories must be
-created. One such suitable program is B<cvsprep> by the same author.
-
-For information on how to add B<cvslog> to your CVS repository, see
-L<"INSTALLATION"> below. B<cvslog> also looks for a configuration file named
-F<cvslog.conf>; for details on the format of that file, see
-L<"CONFIGURATION">.
-
-The From: header of the mail message sent by B<cvslog> is formed from the user
-making the commit. The contents of the environment variable CVSUSER or the
-name of the user doing the commit if CVSUSER isn't set is looked up in the
-F<passwd> file in the CVS repository, if present, and the fourth field is used
-as the full name and the fifth as the user's e-mail address. If that user
-isn't found in F<passwd>, it's looked up in the system password file instead
-to try to find a full name. Otherwise, that user is just used as an e-mail
-address.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-a> I<address>, B<--address>=I<address>
-
-Send the commit notification to I<address> (possibly in addition to the
-address defined in F<cvslog.conf>). This option may occur more than once,
-and all specified addresses will receive a copy of the notification.
-
-=item B<-c>, B<--cvsweb>
-
-Append the cvsweb URLs for all the diffs covered in the commit message to
-the message. The base cvsweb URL must be set in the configuration file.
-The file name will be added and the C<r1> and C<r2> parameters will be
-appended with the appropriate values, along with C<f=h> to request formatted
-diff output. Currently, the cvsweb URLs are not further configurable.
-
-=item B<-D>, B<--debug>
-
-Prints out the information B<cvslog> got from CVS as it works. This option
-is mostly useful for developing B<cvslog> and checking exactly what data CVS
-provides. The first line of output will be the options passed to B<cvsweb>,
-separated by C<|>.
-
-=item B<-d>, B<--diff>
-
-Append the full diff output for each change to the notification message.
-This is probably only useful if you know that all changes for which
-B<cvslog> is run will be small. Note that the entire diff output is
-temporarily stored in memory, so this could result in excessive memory usage
-in B<cvslog> for very large changes.
-
-When this option is given, B<cvslog> needs to be able to find B<cvs> in the
-user's PATH.
-
-If one of the committed files is binary and this is detected by B<cvs>,
-B<cvslog> will suppress the diff and replace it with a note that the file is
-binary.
-
-=item B<-h>, B<--help>
-
-Print out this documentation (which is done simply by feeding the script to
-C<perldoc -t>).
-
-=item B<-i>, B<--include-versions>
-
-Include version numbers (in parentheses) after the file names in the lists
-of added, removed, and changed files. By default, only the file names are
-given.
-
-=item B<-l>, B<--long-subject>
-
-Normally, B<cvslog> will just list the number of changed files rather than the
-complete list of them if the subject would otherwise be too long. This flag
-disables that behavior and includes the full list of modified files in the
-subject header of the mail, no matter how long it is.
-
-=item B<-m>, B<--merge>
-
-Merge multidirectory commits into a single notification. This requires that a
-program be run from F<commitinfo> to record the last directory affected by the
-commit. Using this option will cause B<cvslog> to temporarily record
-information about a commit in progress in TMPDIR or /tmp; see L<"FILES">.
-
-=item B<-o>, B<--omit-author>
-
-Omit the author information from the commit notification. This is useful
-where all commits are done by the same person (so the author information is
-just noise) or where the author information isn't actually available.
-
-=item B<-s>, B<--summary>
-
-Append to each commit notification a summary of the changes, produced by
-generating diffs and feeding those diffs to diffstat(1). diffstat(1) must be
-installed to use this option; see also the B<diffstat> configuration parameter
-in L<"CONFIGURATION">.
-
-When this option is given, B<cvslog> needs to be able to find B<cvs> in the
-user's PATH.
-
-If one of the committed files is binary and this is detected by B<cvs>,
-B<cvslog> will replace the uninformative B<diffstat> line corresponding to
-that file (B<diffstat> will indicate that nothing changed) with a note that
-the file is binary.
-
-=item B<-v>, B<--version>
-
-Print out the version of B<cvslog> and exit.
-
-=item B<-w>, B<--show-directory>
-
-Show the working directory from which the commit was made. This is usually
-not enlightening and when running CVS in server mode will always be some
-uninteresting directory in /tmp, so the default is to not include this
-information.
-
-=back
-
-=head1 CONFIGURATION
-
-B<cvslog> will look for a configuration file named F<cvslog.conf> in the
-CVSROOT directory of your repository. Absence of this file is not an error;
-it just means that all of the defaults will be used. The syntax of this file
-is one configuration parameter per line in the format:
-
- parameter: value
-
-The value may be enclosed in double-quotes and must be enclosed in
-double-quotes if there is trailing whitespace that should be part of the
-value. There is no way to continue a line; each parameter must be a single
-line. Lines beginning with C<#> are comments.
-
-The following configuration parameters are supported:
-
-=over 4
-
-=item address
-
-The address or comma-separated list of addresses to which all commit messages
-should be sent. If this parameter is not given, the default is to send the
-commit message only to those addresses specified with B<-a> options on the
-command line, and there must be at least one B<-a> option on the command line.
-
-=item cvsweb
-
-The base URL for cvsweb diffs for this repository. Only used if the B<-c>
-option is given; see the description of that option for more information
-about how the full URL is constructed.
-
-=item diffstat
-
-The full path to the diffstat(1) program. If this parameter is not given, the
-default is to look for diffstat(1) on the user's PATH. Only used if the B<-s>
-option is given.
-
-=item header
-
-The value should be a valid mail header, such as "X-Ticket: cvs". This header
-will be added to the mail message sent. This configuration parameter may
-occur multiple times, and all of those headers will be added to the message.
-
-=item mailhost
-
-The hostname to append to unqualified addresses given on the command line with
-B<-a>. If set, an C<@> and this value will be appended to any address given
-with B<-a> that doesn't contain C<@>. This parameter exists solely to allow
-for shorter lines in the F<loginfo> file.
-
-=item sendmail
-
-The full path to the sendmail binary. If not given, this setting defaults to
-either C</usr/sbin/sendmail> or C</usr/lib/sendmail>, whichever is found,
-falling back on C</usr/lib/sendmail>.
-
-=item subject
-
-The subject prefix to use for the mailed notifications. Appended to this
-prefix will be the module or path in the repository of the affected directory
-and then either a list of files or a count of files depending on the available
-space. The default is C<"CVS update of ">.
-
-=back
-
-=head1 INSTALLATION
-
-Follow these steps to add cvslog to your project:
-
-=over 4
-
-=item 1.
-
-Check out CVSROOT for your repository (see the CVS manual if you're not sure
-how to do this), copy this script into that directory, change the first line
-to point to your installation of Perl if necessary, and cvs add and commit it.
-
-=item 2.
-
-Add a line like:
-
- cvslog Unable to check out CVS log notification script cvslog
-
-to F<checkoutlist> in CVSROOT and commit it.
-
-=item 3.
-
-If needed, create a F<cvslog.conf> file as described above and cvs add and
-commit it. Most installations will probably want to set B<address>, since the
-most common CVS configuration is a single repository per project with all
-commit notifications sent to the same address. If you don't set B<address>,
-you'll need to add B<-a> options to every invocation of B<cvslog> in
-F<loginfo>.
-
-=item 4.
-
-If you created a F<cvslog.conf> file, add a line like:
-
- cvslog.conf Unable to check out cvslog configuration cvslog.conf
-
-to F<checkoutlist> in CVSROOT and commit it.
-
-=item 5.
-
-Set up your rules in F<loginfo> for those portions of the repository you want
-to send CVS commit notifications for. A good starting rule is:
-
- DEFAULT $CVSROOT/CVSROOT/cvslog %{sVv}
-
-which will send notifications for every commit to your repository that doesn't
-have a separate, more specific rule to the value of B<address> in
-F<cvslog.conf>. You must always invoke B<cvslog> as $CVSROOT/CVSROOT/cvslog;
-B<cvslog> uses the path it was invoked as to find the root of the repository.
-If you have different portions of your repository that should send
-notifications to different places, you can use a series of rules like:
-
- ^foo/ $CVSROOT/CVSROOT/cvslog -a foo-commit %{sVv}
- ^bar/ $CVSROOT/CVSROOT/cvslog -a bar-commit %{sVv}
-
-This will send notification of commits to anything in the C<foo> directory
-tree in the repository to foo-commit (possibly qualified with B<mailhost> from
-F<cvslog.conf>) and everything in C<bar> to bar-commit. No commit
-notifications will be sent for any other commits. The C<%{sVv}> string is
-replaced by CVS with information about the committed files and should always
-be present.
-
-If you are using CVS version 1.12.6 or later, the format strings for
-F<loginfo> rules have changed. Instead of C<%{sVv}>, use C<-- %p %{sVv}>,
-once you've set UseNewInfoFmtStrings=yes in F<config>. For example:
-
- DEFAULT $CVSROOT/CVSROOT/cvslog -- %p %{sVv}
-
-Any options to B<cvslog> should go before C<-->. See the CVS documentation
-for more details on the new F<loginfo> format.
-
-=item 6.
-
-If you want summaries of changes, obtain and compile diffstat and add B<-s> to
-the appropriate lines in F<loginfo>. You may also need to set B<diffstat> in
-F<cvslog.conf>.
-
-diffstat is at L<http://dickey.his.com/diffstat/diffstat.html>.
-
-=item 7.
-
-If you want merging of multidirectory commits, add B<-m> to the invocations of
-B<cvslog>, copy B<cvsprep> into your checked out copy of CVSROOT, change the
-first line of the script if necessary to point to your installation of Perl,
-and cvs add and cvs commit it. Then, a line like:
-
- cvsprep Unable to check out CVS log notification script cvsprep
-
-to F<checkoutlist> in CVSROOT and commit it.
-
-See L<"WARNINGS"> for some warnings about the security of multi-directory
-commit merging.
-
-=item 8.
-
-If your operating system doesn't pass the full path to the B<cvslog>
-executable to this script when it runs, you'll need to edit the beginning of
-this script and set $REPOSITORY to the correct path to the root of your
-repository. This should not normally be necessary. See the comments in this
-script for additional explanation.
-
-=back
-
-=head1 EXAMPLES
-
-Send all commits under the baz directory to B<address> defined in
-F<cvslog.conf>:
-
- ^baz/ $CVSROOT/CVSROOT/cvslog -msw %{sVv}
-
-Multidirectory commits will be merged if B<cvsprep> is also installed, a
-diffstat(1) summary will be appended to the notification, and the working
-directory from which the files were committed will also be included. This
-line should be put in F<loginfo>.
-
-See L<"INSTALLATION"> for more examples.
-
-=head1 DIAGNOSTICS
-
-=over 4
-
-=item can't fork %s: %s
-
-(Fatal) B<cvslog> was unable to run a program that it wanted to run. This may
-result in no notification being sent or in information missing. Generally
-this means that the program in question was missing or B<cvslog> couldn't find
-it for some reason.
-
-=item can't open %s: %s
-
-(Warning) B<cvslog> was unable to open a file. For the modules file, this
-means that B<cvslog> won't do any directory to module mapping. For files
-related to multidirectory commits, this means that B<cvslog> can't gather
-together information about such a commit and will instead send an individual
-notification for the files affected in the current directory. (This means
-that some information may have been lost.)
-
-=item can't remove %s: %s
-
-(Warning) B<cvslog> was unable to clean up after itself for some reason, and
-the temporary files from a multidirectory commit have been left behind in
-TMPDIR or F</tmp>.
-
-=item can't save to %s: %s
-
-(Warning) B<cvslog> encountered an error saving information about a
-multidirectory commit and will instead send an individual notification for the
-files affected in the current directory.
-
-=item invalid directory %s
-
-(Warning) Something was strange about the given directory when B<cvslog> went
-to use it to store information about a multidirectory commit, so instead a
-separate notification for the affected files in the current directory will be
-sent. This means that the directory was actually a symlink, wasn't a
-directory, or wasn't owned by the right user.
-
-=item invalid config syntax: %s
-
-(Warning) The given line in F<cvslog.conf> was syntactically invalid. See
-L<"CONFIGURATION"> for the correct syntax.
-
-=item no %s given by CVS (no %{sVv}?)
-
-(Fatal) The arguments CVS passes to B<cvslog> should be the directory within
-the repository that's being changed and a list of files being changed with
-version information for each file. Something in that was missing. This error
-generally means that the invocation of B<cvslog> in F<loginfo> doesn't have
-the magic C<%{sVv}> variable at the end but instead has no variables or some
-other variable like C<%s>, or means that you're using a version of CVS older
-than 1.10.
-
-=item no addresses specified
-
-(Fatal) There was no B<address> parameter in F<cvslog.conf> and no B<-a>
-options on the command line. At least one recipient address must be specified
-for the CVS commit notification.
-
-=item sendmail exit status %d
-
-(Fatal) sendmail exited with a non-zero status. This may mean that the
-notification message wasn't sent.
-
-=item unable to determine the repository path
-
-(Fatal) B<cvslog> was unable to find the root of your CVS repository from the
-path by which it was invoked. See L<"INSTALLATION"> for hints on how to fix
-this.
-
-=item unrecognized config line: %s
-
-(Warning) The given configuration parameter isn't one of the ones that
-B<cvslog> knows about.
-
-=back
-
-=head1 FILES
-
-All files relative to $CVSROOT will be found by looking at the full path
-B<cvslog> was invoked as and pulling off the path before C<CVSROOT/cvslog>.
-If this doesn't work on your operating system, you'll need to edit this script
-to set $REPOSITORY.
-
-=over 4
-
-=item $CVSROOT/CVSROOT/cvslog.conf
-
-Read for configuration directives if it exists. See L<"CONFIGURATION">.
-
-=item $CVSROOT/CVSROOT/modules
-
-Read to find the module a given file is part of. Rather than always giving
-the full path relative to $CVSROOT of the changed files, B<cvslog> tries to
-find the module that that directory belongs to and replaces the path of that
-module with the name of the module in angle brackets. Modules are found by
-reading this file, looking at the last white-space-separated word on each
-line, and if it contains a C</>, checking to see if it is a prefix of the path
-to the files affected by a commit. If so, the first white-space-separated
-word on that line of F<modules> is taken to be the affected module. The first
-matching entry is used.
-
-=item $CVSROOT/CVSROOT/passwd
-
-Read to find the full name and e-mail address corresponding to a particular
-user. The full name is expected to be the fourth field colon-separated field
-and the e-mail address the fifth. Defaults derived from the system password
-file are used if these are not provided.
-
-=item TMPDIR/cvs.%d.%d
-
-Information about multidirectory commits is read from and stored in this
-directory. This script will never create this directory (the helper script
-B<cvsprep> that runs from F<commitinfo> has to do that), but it will read and
-store information in it and when the commit message is sent, it will delete
-everything in this directory and remove the directory.
-
-The first %d is the numeric UID of the user running B<cvslog>. The second %d
-is the process group B<cvslog> is part of. The process group is included in
-the directory name so that if you're running a shell that calls setpgrp() (any
-modern shell with job control should), multiple commits won't collide with
-each other even when done from the same shell.
-
-If TMPDIR isn't set in the environment, F</tmp> is used for TMPDIR.
-
-=item TMPDIR/cvs.%d.%d/directory
-
-B<cvslog> expects this file to contain the name of the final directory
-affected by a multidirectory commit. Each B<cvslog> invocation will save the
-data that it's given until B<cvslog> is invoked for this directory, and then
-all of the saved data will be combined with the data for that directory and
-sent out as a single notification.
-
-This file must be created by a script such as B<cvsprep> run from
-F<commitinfo>. If it isn't present, B<cvslog> doesn't attempt to combine
-multidirectory commits, even if B<-m> is used.
-
-=back
-
-=head1 ENVIRONMENT
-
-=over 4
-
-=item PATH
-
-Used to find cvs and diffstat when the B<-s> option is in effect. If the
-B<diffstat> configuration option is set, diffstat isn't searched for on the
-user's PATH, but cvs must always be found on the user's PATH in order for
-diffstat summaries to work.
-
-=item TMPDIR
-
-If set, specifies the temporary directory to use instead of F</tmp> for
-storing information about multidirectory commits. Setting this to some
-private directory is recommended if you're doing CVS commits on a multiuser
-machine with other untrusted users due to the standard troubles with safely
-creating files in F</tmp>. (Note that other programs besides B<cvslog> also
-use TMPDIR.)
-
-=back
-
-=head1 WARNINGS
-
-Merging multidirectory commits requires creating predictably-named files to
-communicate information between different processes. By default, those files
-are created in F</tmp> in a directory created for that purpose. While this
-should be reasonably safe on systems that don't allow one to remove
-directories owned by other people in F</tmp>, since a directory is used rather
-than an individual file and since various sanity checks are made on the
-directory before using it, this is still inherently risky on a multiuser
-machine with a world-writeable F</tmp> directory if any of the other users
-aren't trusted.
-
-For this reason, I highly recommend setting TMPDIR to some directory, perhaps
-in your home directory, that only you have access to if you're in that
-situation. Not only will this make B<cvslog> more secure, it may make some of
-the other programs you run somewhat more secure (lots of programs will use the
-value of TMPDIR if set). I really don't trust the security of creating any
-predictably-named files or directories in F</tmp> and neither should you.
-
-Multiple separate B<cvslog> invocations in F<loginfo> interact oddly with
-merging of multidirectory commits. The commit notification will be sent to
-the addresses and in the style configured for the last invocation of
-B<cvslog>, even if some of the earlier directories had different notification
-configurations. As a general rule, it's best not to merge multidirectory
-commits that span separate portions of the repository with different
-notification policies.
-
-B<cvslog> doesn't support using B<commit_prep> (which comes with CVS) as a
-F<commitinfo> script to provide information about multidirectory commits
-because it writes files directly in F</tmp> rather than using a subdirectory.
-
-Some file names simply cannot be supported correctly in CVS versions prior
-to 1.12.6 (with new-style info format strings turned on) because of
-ambiguities in the output from CVS. For example, file names beginning with
-spaces are unlikely to produce the correct output, and file names containing
-newlines will likely result in odd-looking mail messages.
-
-=head1 BUGS
-
-There probably should be a way to specify the path to cvs for generating
-summaries and diffs, to turn off the automatic module detection stuff, to
-provide for transformations of the working directory (stripping the domain
-off the hostname, shortening directory paths in AFS), and to configure the
-maximum subject length. The cvsweb support could stand to be more
-customizable.
-
-Many of the logging scripts out there are based on B<log_accum>, which comes
-with CVS and uses a different output format for multidirectory commits. I
-prefer the one in B<cvslog>, but it would be nice if B<cvslog> could support
-either.
-
-File names containing spaces may be wrapped at the space in the lists of
-files added, modified, or removed. The lists may also be wrapped in the
-middle of the appended version information if B<-i> is used.
-
-Multi-directory commit merging may mishandle file names that contain
-embedded newlines even with CVS version 1.12.6 or later due to the file
-format that B<cvslog> uses to save the intermediate data.
-
-=head1 NOTES
-
-Some parts of this script are horrible hacks because the entirety of commit
-notification handling in CVS is a horrible, undocumented hack. Better commit
-notification support in CVS proper would be welcome, even if it would make
-this script obsolete.
-
-=head1 SEE ALSO
-
-cvs(1), diffstat(1), cvsprep(1).
-
-diffstat is at L<http://dickey.his.com/diffstat/diffstat.html>.
-
-Current versions of this program are available from its web site at
-L<http://www.eyrie.org/~eagle/software/cvslog/>. B<cvsprep> is available
-from this same location.
-
-=head1 AUTHOR
-
-Russ Allbery <rra@stanford.edu>.
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Board of Trustees, Leland
-Stanford Jr. University.
-
-This program is free software; you can redistribute it and/or modify it
-under the same terms as Perl itself.
-
-=cut
+++ /dev/null
-#!/usr/bin/perl
-$ID = q(cvsprep,v 1.6 2004/06/12 02:07:09 eagle Exp );
-#
-# cvsprep -- Prep a multi-directory commit.
-#
-# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2001, 2002, 2003, 2004
-# Board of Trustees, Leland Stanford Jr. University
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-use Getopt::Long qw(GetOptions);
-use vars qw($ID);
-
-Getopt::Long::config ('require_order');
-GetOptions ('help|h' => \$help, 'version|v' => \$version) or exit 1;
-if ($help) {
- print "Feeding myself to perldoc, please wait....\n";
- exec ('perldoc', '-t', $0);
-} elsif ($version) {
- my @version = split (' ', $ID);
- shift @version if $ID =~ /^\$Id/;
- my $version = join (' ', @version[0..2]);
- $version =~ s/,v\b//;
- $version =~ s/(\S+)$/($1)/;
- $version =~ tr%/%-%;
- print $version, "\n";
- exit;
-}
-
-my $directory = shift;
-die "$0: CVS didn't provide a directory\n" unless $directory;
-my $tmp = $ENV{TMPDIR} || '/tmp';
-$tmp .= '/cvs.' . $< . '.' . getpgrp;
-if (!mkdir ($tmp, 0700)) {
- if (-l $tmp || !-d _ || (lstat _)[4] != $<) {
- die "$0: can't create $tmp: $!\n";
- }
-}
-open (LOG, "> $tmp/directory") or die "$0: can't create $tmp/directory: $!\n";
-print LOG "$directory\n";
-close LOG;
-exit 0;
-__END__
-
-=head1 NAME
-
-cvsprep - Prep for a multi-directory CVS commit
-
-=head1 SYNOPSIS
-
-B<cvsprep>
-
-=head1 DESCRIPTION
-
-This program is designed to run from CVS's F<commitinfo> administrative file
-and make a note of the last directorie involved in the commit. It is used to
-support merging of multi-directory CVS commits into a single notification by
-B<cvslog> (B<cvslog> knows to stop merging commits when it sees the
-notification for the final directory recorded by B<cvsprep>).
-
-It should be run from F<commitinfo> with something like:
-
- DEFAULT $CVSROOT/CVSROOT/cvsprep
-
-If you are using CVS version 1.12.6 or later, the format strings for
-F<commitinfo> rules have changed. This line should instead be:
-
- DEFAULT $CVSROOT/CVSROOT/cvsprep -- %r/%p
-
-once you've set UseNewInfoFmtStrings=yes in F<config>.
-
-The directory in which the commit is occurring is saved in a file named
-F<directory> in a directory in TMPDIR named cvs.<uid>.<group>, where <uid> is
-the UID of the committing user and <group> is the process group of the commit
-process. If TMPDIR is not used, F</tmp> is used as the parent directory.
-
-For details on how to install this program as part of a B<cvslog>
-installation, see cvslog(1).
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Print out this documentation (which is done simply by feeding the script to
-C<perldoc -t>).
-
-=item B<-v>, B<--version>
-
-Print out the version of B<cvsprep> and exit.
-
-=head1 DIAGNOSTICS
-
-=item can't create %s: %s
-
-(Fatal) B<cvsprep> was unable to create either the directory or the file in
-that directory needed to pass information to B<cvslog>, or the directory
-already exists and is owned by someone other than the current user. The
-directory for this commit won't be recorded, and B<cvslog> will therefore not
-merge this multi-directory commit.
-
-=item CVS didn't provide a directory
-
-(Fatal) No directory was given on the B<cvsprep> command line. If run out of
-F<commitinfo> as described above, CVS should pass the name of the directory in
-which the commit is happening as the first argument to B<cvsprep>.
-
-=back
-
-=head1 FILES
-
-=over 4
-
-=item TMPDIR/cvs.%d.%d/directory
-
-B<cvslog> expects this file to contain the name of the final directory
-affected by a multidirectory commit. B<cvsprep> creates the parent directory
-and stores its first argument in this file.
-
-The first %d is the numeric UID of the user running B<cvslog>. The second %d
-is the process group B<cvslog> is part of. The process group is included in
-the directory name so that if you're running a shell that calls setpgrp() (any
-modern shell with job control should), multiple commits won't collide with
-each other even when done from the same shell.
-
-If TMPDIR isn't set in the environment, F</tmp> is used for TMPDIR.
-
-=back
-
-=head1 ENVIRONMENT
-
-=over 4
-
-=item TMPDIR
-
-If set, specifies the temporary directory to use instead of F</tmp> for
-storing information about multidirectory commits. Setting this to some
-private directory is recommended if you're doing CVS commits on a multiuser
-machine with other untrusted users due to the standard troubles with safely
-creating files in F</tmp>. (Note that other programs besides B<cvslog> also
-use TMPDIR.)
-
-=back
-
-=head1 WARNINGS
-
-B<cvsprep> inherently creates directories in TMPDIR (F</tmp> by default) with
-very predictable names. It creates directories rather than files because this
-should be less risky, but this is still something of a security risk. Because
-of this, I highly recommend that you set TMPDIR to some other directory that
-only you have write access to, such as a subdirectory of your home directory.
-
-For more warnings, see cvslog(1).
-
-=head1 NOTES
-
-This process of noting the final directory of a commit so that B<cvslog> knows
-when to stop merging is a horrible hack. There's just no better way to do it
-given how CVS handles commit notification, which is completely undocumented
-and truly bizarre.
-
-=head1 SEE ALSO
-
-cvs(1), cvsprep(1).
-
-Current versions of this program are available from the cvslog web site at
-L<http://www.eyrie.org/~eagle/software/cvslog/>. B<cvslog> is available from
-this same location.
-
-=head1 AUTHOR
-
-Russ Allbery <rra@stanford.edu>.
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2001, 2002, 2003, 2004 Board of Trustees, Leland Stanford Jr.
-University.
-
-This program is free software; you can redistribute it and/or modify it under
-the same terms as Perl itself.
-
-=cut
+++ /dev/null
-# This file affects handling of files based on their names.
-#
-# The -m option specifies whether CVS attempts to merge files.
-#
-# The -k option specifies keyword expansion (e.g. -kb for binary).
-#
-# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
-#
-# wildcard [option value][option value]...
-#
-# where option is one of
-# -f from cvs filter value: path to filter
-# -t to cvs filter value: path to filter
-# -m update methodology value: MERGE or COPY
-# -k expansion mode value: b, o, kkv, &c
-#
-# and value is a single-quote delimited value.
-# For example:
-#*.gif -k 'b'
+++ /dev/null
-# The "loginfo" file controls where "cvs commit" log information
-# is sent. The first entry on a line is a regular expression which must match
-# the directory that the change is being made to, relative to the
-# $CVSROOT. If a match is found, then the remainder of the line is a filter
-# program that should expect log information on its standard input.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name ALL appears as a regular expression it is always used
-# in addition to the first matching regex or DEFAULT.
-#
-# If any format strings are present in the filter, they will be replaced as follows:
-# %p = path relative to repository
-# %r = repository (path portion of $CVSROOT)
-# %{sVv} = attribute list = file name, old version number (pre-checkin),
-# new version number (post-checkin). When either old or new revision is
-# unknown, doesn't exist, or isn't applicable, the string "NONE" will be
-# placed on the command line instead.
-#
-# Note that %{sVv} is a list operator and not all elements are necessary. Thus %{sv} is
-# a legal format string, but will only be replaced with file name and new revision.
-# it also generates multiple arguments for each file being operated upon. i.e. if two
-# files, file1 & file2, are being commited from 1.1 to version 1.1.2.1 and from 1.1.2.2
-# to 1.1.2.3, respectively, %{sVv} will generate the following six arguments in this
-# order: file1, 1.1, 1.1.2.1, file2, 1.1.2.2, 1.1.2.3.
-#
-# For example:
-#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
-# or
-#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
-#ALL $CVSROOT/CVSROOT/log_accum -u -s -d -m bdemsky %s
-ALL ( chgrp -R -f cvs $CVSROOT/Robust/. ; chmod -R -f go+rX,o-w $CVSROOT/Robust/. )
-DEFAULT $CVSROOT/CVSROOT/cvslog -m -d -a bdemsky -a adash@uci.edu -a erubow -a william.montaz@ensta.fr -- %p %{sVv}
-
+++ /dev/null
-# Three different line formats are valid:
-# key -a aliases...
-# key [options] directory
-# key [options] directory files...
-#
-# Where "options" are composed of:
-# -i prog Run "prog" on "cvs commit" from top-level of module.
-# -o prog Run "prog" on "cvs checkout" of module.
-# -e prog Run "prog" on "cvs export" of module.
-# -t prog Run "prog" on "cvs rtag" of module.
-# -u prog Run "prog" on "cvs update" of module.
-# -d dir Place module in directory "dir" instead of module name.
-# -l Top-level directory only -- do not recurse.
-#
-# NOTE: If you change any of the "Run" options above, you'll have to
-# release and re-checkout any working directories of these modules.
-#
-# And "directory" is a path to a directory relative to $CVSROOT.
-#
-# The "-a" option specifies an alias. An alias is interpreted as if
-# everything on the right of the "-a" had been typed on the command line.
-#
-# You can encode a module within a module by using the special '&'
-# character to interpose another module into the current module. This
-# can be useful for creating a module that consists of many directories
-# spread out over the entire source repository.
+++ /dev/null
-# The "notify" file controls where notifications from watches set by
-# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
-# a regular expression which is tested against the directory that the
-# change is being made to, relative to the $CVSROOT. If it matches,
-# then the remainder of the line is a filter program that should contain
-# one occurrence of %s for the user to notify, and information on its
-# standard input.
-#
-# "ALL" or "DEFAULT" can be used in place of the regular expression.
-#
-# format strings are replaceed as follows:
-# %p = path relative to repository
-# %r = repository (path portion of $CVSROOT)
-# %s = user to notify
-#
-# For example:
-#ALL (echo Committed to %r/%p; cat) |mail %s -s "CVS notification"
+++ /dev/null
-# The "rcsinfo" file is used to control templates with which the editor
-# is invoked on commit and import.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being made to, relative to the
-# $CVSROOT. For the first match that is found, then the remainder of the
-# line is the name of the file that contains the template.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
+++ /dev/null
-# The "taginfo" file is used to control pre-tag checks.
-# The filter on the right is invoked with the following arguments if no format strings are present:
-#
-# $1 -- tagname
-# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
-# $3 -- tagtype "?" on delete, "T" for branch, "N" for static
-# $4 -- repository
-# $5-> file revision [file revision ...]
-#
-# If any format strings are present in the filter, they will be replaced as follows:
-# %b = branch mode = "?" (delete ops - unknown) | "T" (branch) | "N" (not branch)
-# %o = operation = "add" | "mov" | "del"
-# %p = path relative to repository
-# %r = repository (path portion of $CVSROOT)
-# %t = tagname
-# %{sVv} = attribute list = file name, old version tag will be deleted from,
-# new version tag will be added to (or deleted from, but this feature is
-# deprecated. When either old or new revision is unknown, doesn't exist,
-# or isn't applicable, the string "NONE" will be placed on the command
-# line.
-#
-# Note that %{sVv} is a list operator and not all elements are necessary. Thus %{sV} is
-# a legal format string, but will only be replaced with file name and old revision.
-# it also generates multiple arguments for each file being operated upon. i.e. if two
-# files, file1 & file2, are having a tag moved from version 1.1 to versoin 1.1.2.9, %{sVv}
-# will generate the following six arguments in this order: file1, 1.1, 1.1.2.9, file2, 1.1,
-# 1.1.2.9.
-#
-# A non-zero exit of the filter program will cause the tag to be aborted.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being committed to, relative
-# to the $CVSROOT. For the first match that is found, then the remainder
-# of the line is the name of the filter to run.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
+++ /dev/null
-# The "verifymsg" file is used to allow verification of logging
-# information. It works best when a template (as specified in the
-# rcsinfo file) is provided for the logging procedure. Given a
-# template with locations for, a bug-id number, a list of people who
-# reviewed the code before it can be checked in, and an external
-# process to catalog the differences that were code reviewed, the
-# following test can be applied to the code:
-#
-# Making sure that the entered bug-id number is correct.
-# Validating that the code that was reviewed is indeed the code being
-# checked in (using the bug-id number or a seperate review
-# number to identify this particular code set.).
-#
-# If any of the above test failed, then the commit would be aborted.
-#
-# Format strings present in the filter will be replaced as follows:
-# %p = path relative to repository
-# %r = repository (path portion of $CVSROOT)
-# %l = name of log file to be verified.
-#
-# If no format strings are present in the filter, a default " %l" will
-# be appended to the filter, but this usage is deprecated.
-#
-# Actions such as mailing a copy of the report to each reviewer are
-# better handled by an entry in the loginfo file.
-#
-# One thing that should be noted is the the ALL keyword is not
-# supported. There can be only one entry that matches a given
-# repository.
+++ /dev/null
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-\f
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-\f
- Appendix: How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-class BooleanLiteral extends Literal {
- Boolean val;
- BooleanLiteral(boolean b) { this.val = new Boolean(b); }
-
- Symbol token() { return new Symbol(Sym.BOOLEAN_LITERAL, val); }
-
- public String toString() { return "BooleanLiteral <"+val.toString()+">"; }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-class CharacterLiteral extends Literal {
- Character val;
- CharacterLiteral(char c) { this.val = new Character(c); }
-
- Symbol token() { return new Symbol(Sym.CHARACTER_LITERAL, val); }
-
- public String toString() {
- return "CharacterLiteral <"+Token.escape(val.toString())+">";
- }
-}
+++ /dev/null
-package Lex;
-
-abstract class Comment extends InputElement {
- private StringBuffer comment = new StringBuffer();
-
- String getComment() { return comment.toString(); }
-
- void appendLine(String more) { // 'more' is '\n' terminated.
- int i=0;
-
- // skip leading white space.
- for (; i<more.length(); i++)
- if (!Character.isSpaceChar(more.charAt(i)))
- break;
-
- // skip any leading stars.
- for (; i<more.length(); i++)
- if (more.charAt(i)!='*')
- break;
-
- // the rest of the string belongs to the comment.
- if (i<more.length())
- comment.append(more.substring(i));
- }
-
-}
+++ /dev/null
-package Lex;
-
-class DocumentationComment extends Comment {
- DocumentationComment() { }
-}
-
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-class DoubleLiteral extends NumericLiteral {
- DoubleLiteral(double d) { this.val = new Double(d); }
-
- Symbol token() { return new Symbol(Sym.FLOATING_POINT_LITERAL, val); }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-class EOF extends Token {
- EOF() {}
- Symbol token() { return new Symbol(Sym.EOF); }
- public String toString() { return "EOF"; }
-}
+++ /dev/null
-package Lex;
-
-class EndOfLineComment extends Comment {
- EndOfLineComment(String comment) { appendLine(comment); }
-}
+++ /dev/null
-package Lex;
-
-import java.io.Reader;
-import java.io.FilterReader;
-import java.io.IOException;
-
-public class EscapedUnicodeReader extends FilterReader {
-
- int pushback=-1;
- boolean isEvenSlash = true;
-
- public EscapedUnicodeReader(Reader in) {
- super(in);
- }
- public int read() throws IOException {
- int r = (pushback==-1)?in.read():pushback; pushback=-1;
-
- if (r!='\\') {
- isEvenSlash=true;
- return r;
- } else { // found a backslash;
- if (!isEvenSlash) { // Only even slashes are eligible unicode escapes.
- isEvenSlash=true;
- return r;
- }
-
- // Check for the trailing u.
- pushback=in.read();
- if (pushback!='u') {
- isEvenSlash=false;
- return '\\';
- }
-
- // OK, we've found backslash-u.
- // Reset pushback and snarf up all trailing u's.
- pushback=-1;
- while((r=in.read())=='u')
- ;
- // Now we should find 4 hex digits.
- // If we don't, we can raise bloody hell.
- int val=0;
- for (int i=0; i<4; i++, r=in.read()) {
- int d=Character.digit((char)r, 16);
- if (r<0 || d<0)
- throw new Error("Invalid unicode escape character.");
- val = (val*16) + d;
- }
- // yeah, we made it.
- pushback = r;
- isEvenSlash=true;
- return val;
- }
- }
- // synthesize array read from single-character read.
- public int read(char cbuf[], int off, int len) throws IOException {
- for (int i=0; i<len; i++) {
- int c = read();
- if (c==-1) return (i==0)?-1:i; // end of stream reached.
- else cbuf[i+off] = (char) c;
- }
- return len;
- }
-
- public boolean markSupported() { return false; }
-
- public boolean ready() throws IOException {
- if (pushback!=-1) return true;
- else return in.ready();
- }
-}
+++ /dev/null
-package Lex;
-
-/** FIFO class. This helps implement the lookahead we need for JSR-14.
- * Copyright (C) 2002 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This program is released under the terms of the GPL; see the file
- * COPYING for more details. There is NO WARRANTY on this code.
- */
-
-class FIFO {
- java_cup.runtime.Symbol[] backing = new java_cup.runtime.Symbol[10];
- int start=0, end=0;
- final Getter getter;
- FIFO(Getter getter) { this.getter = getter; }
- public boolean isEmpty() { return start==end; }
- private boolean isFull() {
- return start==end+1 || (start==0 && end==backing.length-1);
- }
- private int size() {
- return ((end<start)?end+backing.length:end)-start;
- }
- public void put(java_cup.runtime.Symbol o) {
- if (isFull()) {
- java_cup.runtime.Symbol[] nbacking =
- new java_cup.runtime.Symbol[backing.length*2];
- System.arraycopy(backing, start, nbacking, 0, backing.length-start);
- System.arraycopy(backing, 0, nbacking, backing.length-start, start);
- start = 0;
- end = backing.length-1;
- backing = nbacking;
- }
- ASSERT(!isFull());
- backing[end++] = o;
- if (end == backing.length)
- end = 0;
- ASSERT(!isEmpty());
- }
- public java_cup.runtime.Symbol get() throws java.io.IOException {
- if (isEmpty())
- put(getter.next());
- ASSERT(!isEmpty());
- java_cup.runtime.Symbol o = backing[start++];
- if (start == backing.length)
- start = 0;
- ASSERT(!isFull());
- return o;
- }
- public java_cup.runtime.Symbol peek(int i) throws java.io.IOException {
- while (i >= size())
- put(getter.next());
- int index = start+i;
- if (index >= backing.length) index -= backing.length;
- ASSERT(0<= index && index < backing.length);
- return backing[index];
- }
- abstract static class Getter {
- abstract java_cup.runtime.Symbol next()
- throws java.io.IOException;
- }
- private static void ASSERT(boolean b) {
- if (!b) throw new RuntimeException();
- }
-}
-
-
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-class FloatLiteral extends NumericLiteral {
- FloatLiteral(float f) { this.val = new Float(f); }
-
- Symbol token() { return new Symbol(Sym.FLOATING_POINT_LITERAL, val); }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-public class Identifier extends Token {
- String identifier;
- public Identifier(String identifier) { this.identifier=identifier; }
-
- public String toString() { return "Identifier <"+identifier+">"; }
-
- /* Ben Walter <bwalter@mit.edu> correctly pointed out that
- * the first released version of this grammar/lexer did not
- * return the string value of the identifier in the parser token.
- * Should be fixed now. ;-) <cananian@alumni.princeton.edu>
- */
- Symbol token() { return new Symbol(Sym.IDENTIFIER, identifier); }
-}
+++ /dev/null
-package Lex;
-
-abstract class InputElement {}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-class IntegerLiteral extends NumericLiteral {
- IntegerLiteral(int i) { this.val = new Integer(i); }
-
- Symbol token() { return new Symbol(Sym.INTEGER_LITERAL, val); }
-}
+++ /dev/null
-package Lex;
-
-import java.util.Hashtable;
-import java_cup.runtime.Symbol;
-
-class Keyword extends Token {
- String keyword;
- Keyword(String s) { keyword = s; }
-
- Symbol token() {
- Integer i = (Integer) key_table.get(keyword);
- return new Symbol(i.intValue());
- }
- public String toString() { return "Keyword <"+keyword+">"; }
-
- static private final Hashtable key_table = new Hashtable();
- static {
- key_table.put("abstract", new Integer(Sym.ABSTRACT));
- key_table.put("assert", new Integer(Sym.ASSERT));
- key_table.put("boolean", new Integer(Sym.BOOLEAN));
- key_table.put("break", new Integer(Sym.BREAK));
- key_table.put("byte", new Integer(Sym.BYTE));
- key_table.put("case", new Integer(Sym.CASE));
- key_table.put("catch", new Integer(Sym.CATCH));
- key_table.put("char", new Integer(Sym.CHAR));
- key_table.put("class", new Integer(Sym.CLASS));
- key_table.put("const", new Integer(Sym.CONST));
- key_table.put("continue", new Integer(Sym.CONTINUE));
- key_table.put("default", new Integer(Sym.DEFAULT));
- key_table.put("do", new Integer(Sym.DO));
- key_table.put("double", new Integer(Sym.DOUBLE));
- key_table.put("else", new Integer(Sym.ELSE));
- key_table.put("enum", new Integer(Sym.ENUM));
- key_table.put("extends", new Integer(Sym.EXTENDS));
- key_table.put("final", new Integer(Sym.FINAL));
- key_table.put("finally", new Integer(Sym.FINALLY));
- key_table.put("float", new Integer(Sym.FLOAT));
- key_table.put("for", new Integer(Sym.FOR));
- key_table.put("goto", new Integer(Sym.GOTO));
- key_table.put("if", new Integer(Sym.IF));
- key_table.put("implements", new Integer(Sym.IMPLEMENTS));
- key_table.put("import", new Integer(Sym.IMPORT));
- key_table.put("instanceof", new Integer(Sym.INSTANCEOF));
- key_table.put("int", new Integer(Sym.INT));
- key_table.put("interface", new Integer(Sym.INTERFACE));
- key_table.put("long", new Integer(Sym.LONG));
- key_table.put("native", new Integer(Sym.NATIVE));
- key_table.put("new", new Integer(Sym.NEW));
- key_table.put("package", new Integer(Sym.PACKAGE));
- key_table.put("private", new Integer(Sym.PRIVATE));
- key_table.put("protected", new Integer(Sym.PROTECTED));
- key_table.put("public", new Integer(Sym.PUBLIC));
- key_table.put("return", new Integer(Sym.RETURN));
- key_table.put("short", new Integer(Sym.SHORT));
- key_table.put("static", new Integer(Sym.STATIC));
- key_table.put("strictfp", new Integer(Sym.STRICTFP));
- key_table.put("super", new Integer(Sym.SUPER));
- key_table.put("switch", new Integer(Sym.SWITCH));
- key_table.put("synchronized", new Integer(Sym.SYNCHRONIZED));
- key_table.put("this", new Integer(Sym.THIS));
- key_table.put("throw", new Integer(Sym.THROW));
- key_table.put("throws", new Integer(Sym.THROWS));
- key_table.put("transient", new Integer(Sym.TRANSIENT));
- key_table.put("try", new Integer(Sym.TRY));
- key_table.put("void", new Integer(Sym.VOID));
- key_table.put("volatile", new Integer(Sym.VOLATILE));
- key_table.put("while", new Integer(Sym.WHILE));
- }
-}
+++ /dev/null
-package Lex;
-
-import java.io.Reader;
-import java.io.LineNumberReader;
-
-/* Java lexer.
- * Copyright (C) 2002 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This program is released under the terms of the GPL; see the file
- * COPYING for more details. There is NO WARRANTY on this code.
- */
-
-public class Lexer implements Parse.Lexer {
- LineNumberReader reader;
- boolean isJava12;
- boolean isJava14;
- boolean isJava15;
- String line = null;
- int line_pos = 1;
- int line_num = 0;
- LineList lineL = new LineList(-line_pos, null); // sentinel for line #0
-
- public Lexer(Reader reader) {
- this(reader, 2); // by default, use a Java 1.2-compatible lexer.
- }
- public Lexer(Reader reader, int java_minor_version) {
- this.reader = new LineNumberReader(new EscapedUnicodeReader(reader));
- this.isJava12 = java_minor_version >= 2;
- this.isJava14 = java_minor_version >= 4;
- this.isJava15 = java_minor_version >= 5;
- }
-
- public java_cup.runtime.Symbol nextToken() throws java.io.IOException {
- java_cup.runtime.Symbol sym =
- lookahead==null ? _nextToken() : lookahead.get();
- /* Old "smart lexer" hack to parse JSR-14 syntax. New, better, grammar
- * makes this unnecessary. (Credit to Eric Blake for its discovery.)
- *
- if (isJava15 && sym.sym==Sym.LT && shouldBePLT())
- sym.sym=Sym.PLT;
- */
- last = sym;
- return sym;
- }
- private boolean shouldBePLT() throws java.io.IOException {
- // look ahead to see if this LT should be changed to a PLT
- if (last==null || last.sym!=Sym.IDENTIFIER)
- return false;
- if (lookahead==null) lookahead = new FIFO(new FIFO.Getter() {
- java_cup.runtime.Symbol next() throws java.io.IOException
- { return _nextToken(); }
- });
- int i=0;
- // skip past IDENTIFIER (DOT IDENTIFIER)*
- if (lookahead.peek(i++).sym != Sym.IDENTIFIER)
- return false;
- while (lookahead.peek(i).sym == Sym.DOT) {
- i++;
- if (lookahead.peek(i++).sym != Sym.IDENTIFIER)
- return false;
- }
- // skip past (LBRACK RBRACK)*
- while (lookahead.peek(i).sym == Sym.LBRACK) {
- i++;
- if (lookahead.peek(i++).sym != Sym.RBRACK)
- return false;
- }
- // now the next sym has to be one of LT GT COMMA EXTENDS IMPLEMENTS
- switch(lookahead.peek(i).sym) {
- default:
- return false;
- case Sym.LT:
- case Sym.GT:
- case Sym.COMMA:
- case Sym.EXTENDS:
- case Sym.IMPLEMENTS:
- return true;
- }
- }
- private java_cup.runtime.Symbol last = null;
- private FIFO lookahead = null;
- public java_cup.runtime.Symbol _nextToken() throws java.io.IOException {
- /* tokens are:
- * Identifiers/Keywords/true/false/null (start with java letter)
- * numeric literal (start with number)
- * character literal (start with single quote)
- * string (start with double quote)
- * separator (parens, braces, brackets, semicolon, comma, period)
- * operator (equals, plus, minus, etc)
- * whitespace
- * comment (start with slash)
- */
- InputElement ie;
- int startpos, endpos;
- do {
- startpos = lineL.head + line_pos;
- ie = getInputElement();
- if (ie instanceof DocumentationComment)
- comment = ((Comment)ie).getComment();
- } while (!(ie instanceof Token));
- endpos = lineL.head + line_pos - 1;
-
- //System.out.println(ie.toString()); // uncomment to debug lexer.
- java_cup.runtime.Symbol sym = ((Token)ie).token();
- // fix up left/right positions.
- sym.left = startpos; sym.right = endpos;
- // return token.
- return sym;
- }
- public boolean debug_lex() throws java.io.IOException {
- InputElement ie = getInputElement();
- System.out.println(ie);
- return !(ie instanceof EOF);
- }
-
- String comment;
- public String lastComment() { return comment; }
- public void clearComment() { comment=""; }
-
- InputElement getInputElement() throws java.io.IOException {
- if (line_num == 0)
- nextLine();
- if (line==null)
- return new EOF();
- if (line.length()<=line_pos) { // end of line.
- nextLine();
- if (line==null)
- return new EOF();
- }
-
- switch (line.charAt(line_pos)) {
-
- // White space:
- case ' ': // ASCII SP
- case '\t': // ASCII HT
- case '\f': // ASCII FF
- case '\n': // LineTerminator
- return new WhiteSpace(consume());
-
- // EOF character:
- case '\020': // ASCII SUB
- consume();
- return new EOF();
-
- // Comment prefix:
- case '/':
- return getComment();
-
- // else, a Token
- default:
- return getToken();
- }
- }
- // May get Token instead of Comment.
- InputElement getComment() throws java.io.IOException {
- String comment;
- // line.charAt(line_pos+0) is '/'
- switch (line.charAt(line_pos+1)) {
- case '/': // EndOfLineComment
- comment = line.substring(line_pos+2);
- line_pos = line.length();
- return new EndOfLineComment(comment);
- case '*': // TraditionalComment or DocumentationComment
- line_pos += 2;
- if (line.charAt(line_pos)=='*') { // DocumentationComment
- return snarfComment(new DocumentationComment());
- } else { // TraditionalComment
- return snarfComment(new TraditionalComment());
- }
- default: // it's a token, not a comment.
- return getToken();
- }
- }
-
- Comment snarfComment(Comment c) throws java.io.IOException {
- StringBuffer text=new StringBuffer();
- while(true) { // Grab CommentTail
- while (line.charAt(line_pos)!='*') { // Add NotStar to comment.
- int star_pos = line.indexOf('*', line_pos);
- if (star_pos<0) {
- text.append(line.substring(line_pos));
- c.appendLine(text.toString()); text.setLength(0);
- line_pos = line.length();
- nextLine();
- if (line==null)
- throw new Error("Unterminated comment at end of file.");
- } else {
- text.append(line.substring(line_pos, star_pos));
- line_pos=star_pos;
- }
- }
- // At this point, line.charAt(line_pos)=='*'
- // Grab CommentTailStar starting at line_pos+1.
- if (line.charAt(line_pos+1)=='/') { // safe because line ends with '\n'
- c.appendLine(text.toString()); line_pos+=2; return c;
- }
- text.append(line.charAt(line_pos++)); // add the '*'
- }
- }
-
- Token getToken() {
- // Tokens are: Identifiers, Keywords, Literals, Separators, Operators.
- switch (line.charAt(line_pos)) {
- // Separators: (period is a special case)
- case '(':
- case ')':
- case '{':
- case '}':
- case '[':
- case ']':
- case ';':
- case ',':
- return new Separator(consume());
-
- // Operators:
- case '=':
- case '>':
- case '<':
- case '!':
- case '~':
- case '?':
- case ':':
- case '&':
- case '|':
- case '+':
- case '-':
- case '*':
- case '/':
- case '^':
- case '%':
- return getOperator();
- case '\'':
- return getCharLiteral();
- case '\"':
- return getStringLiteral();
-
- // a period is a special case:
- case '.':
- if (Character.digit(line.charAt(line_pos+1),10)!=-1)
- return getNumericLiteral();
- else if (isJava15 &&
- line.charAt(line_pos+1)=='.' &&
- line.charAt(line_pos+2)=='.') {
- consume(); consume(); consume();
- return new Separator('\u2026'); // unicode ellipsis character.
- } else return new Separator(consume());
- default:
- break;
- }
- if (Character.isJavaIdentifierStart(line.charAt(line_pos)))
- return getIdentifier();
- if (Character.isDigit(line.charAt(line_pos)))
- return getNumericLiteral();
- throw new Error("Illegal character on line "+line_num);
- }
-
- static final String[] keywords = new String[] {
- "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char",
- "class", "const", "continue", "default", "do", "double", "else", "enum",
- "extends", "final", "finally", "float", "for", "goto", "if",
- "implements", "import", "instanceof", "int", "interface", "long",
- "native", "new", "package", "private", "protected", "public",
- "return", "short", "static", "strictfp", "super", "switch",
- "synchronized", "this", "throw", "throws", "transient", "try", "void",
- "volatile", "while" };
- Token getIdentifier() {
- // Get id string.
- StringBuffer sb = new StringBuffer().append(consume());
-
- if (!Character.isJavaIdentifierStart(sb.charAt(0)))
- throw new Error("Invalid Java Identifier on line "+line_num);
- while (Character.isJavaIdentifierPart(line.charAt(line_pos)))
- sb.append(consume());
- String s = sb.toString();
- // Now check against boolean literals and null literal.
- if (s.equals("null")) return new NullLiteral();
- if (s.equals("true")) return new BooleanLiteral(true);
- if (s.equals("false")) return new BooleanLiteral(false);
- // Check against keywords.
- // pre-java 1.5 compatibility:
- if (!isJava15 && s.equals("enum")) return new Identifier(s);
- // pre-java 1.4 compatibility:
- if (!isJava14 && s.equals("assert")) return new Identifier(s);
- // pre-java 1.2 compatibility:
- if (!isJava12 && s.equals("strictfp")) return new Identifier(s);
- // use binary search.
- for (int l=0, r=keywords.length; r > l; ) {
- int x = (l+r)/2, cmp = s.compareTo(keywords[x]);
- if (cmp < 0) r=x; else l=x+1;
- if (cmp== 0) return new Keyword(s);
- }
- // not a keyword.
- return new Identifier(s);
- }
- NumericLiteral getNumericLiteral() {
- int i;
- // leading decimal indicates float.
- if (line.charAt(line_pos)=='.')
- return getFloatingPointLiteral();
- // 0x indicates Hex.
- if (line.charAt(line_pos)=='0' &&
- (line.charAt(line_pos+1)=='x' ||
- line.charAt(line_pos+1)=='X')) {
- line_pos+=2; return getIntegerLiteral(/*base*/16);
- }
- // otherwise scan to first non-numeric
- for (i=line_pos; Character.digit(line.charAt(i),10)!=-1; )
- i++;
- switch(line.charAt(i)) { // discriminate based on first non-numeric
- case '.':
- case 'f':
- case 'F':
- case 'd':
- case 'D':
- case 'e':
- case 'E':
- return getFloatingPointLiteral();
- case 'L':
- case 'l':
- default:
- if (line.charAt(line_pos)=='0')
- return getIntegerLiteral(/*base*/8);
- return getIntegerLiteral(/*base*/10);
- }
- }
- NumericLiteral getIntegerLiteral(int radix) {
- long val=0;
- while (Character.digit(line.charAt(line_pos),radix)!=-1)
- val = (val*radix) + Character.digit(consume(),radix);
- if (line.charAt(line_pos) == 'l' ||
- line.charAt(line_pos) == 'L') {
- consume();
- return new LongLiteral(val);
- }
- // we compare MAX_VALUE against val/2 to allow constants like
- // 0xFFFF0000 to get past the test. (unsigned long->signed int)
- if ((val/2) > Integer.MAX_VALUE ||
- val < Integer.MIN_VALUE)
- throw new Error("Constant does not fit in integer on line "+line_num);
- return new IntegerLiteral((int)val);
- }
- NumericLiteral getFloatingPointLiteral() {
- String rep = getDigits();
- if (line.charAt(line_pos)=='.')
- rep+=consume() + getDigits();
- if (line.charAt(line_pos)=='e' ||
- line.charAt(line_pos)=='E') {
- rep+=consume();
- if (line.charAt(line_pos)=='+' ||
- line.charAt(line_pos)=='-')
- rep+=consume();
- rep+=getDigits();
- }
- try {
- switch (line.charAt(line_pos)) {
- case 'f':
- case 'F':
- consume();
- return new FloatLiteral(Float.valueOf(rep).floatValue());
- case 'd':
- case 'D':
- consume();
- /* falls through */
- default:
- return new DoubleLiteral(Double.valueOf(rep).doubleValue());
- }
- } catch (NumberFormatException e) {
- throw new Error("Illegal floating-point on line "+line_num+": "+e);
- }
- }
- String getDigits() {
- StringBuffer sb = new StringBuffer();
- while (Character.digit(line.charAt(line_pos),10)!=-1)
- sb.append(consume());
- return sb.toString();
- }
-
- Operator getOperator() {
- char first = consume();
- char second= line.charAt(line_pos);
-
- switch(first) {
- // single-character operators.
- case '~':
- case '?':
- case ':':
- return new Operator(new String(new char[] {first}));
- // doubled operators
- case '+':
- case '-':
- case '&':
- case '|':
- if (first==second)
- return new Operator(new String(new char[] {first, consume()}));
- default:
- break;
- }
- // Check for trailing '='
- if (second=='=')
- return new Operator(new String(new char[] {first, consume()}));
-
- // Special-case '<<', '>>' and '>>>'
- if ((first=='<' && second=='<') || // <<
- (first=='>' && second=='>')) { // >>
- String op = new String(new char[] {first, consume()});
- if (first=='>' && line.charAt(line_pos)=='>') // >>>
- op += consume();
- if (line.charAt(line_pos)=='=') // <<=, >>=, >>>=
- op += consume();
- return new Operator(op);
- }
-
- // Otherwise return single operator.
- return new Operator(new String(new char[] {first}));
- }
-
- CharacterLiteral getCharLiteral() {
- char firstquote = consume();
- char val;
- switch (line.charAt(line_pos)) {
- case '\\':
- val = getEscapeSequence();
- break;
- case '\'':
- throw new Error("Invalid character literal on line "+line_num);
- case '\n':
- throw new Error("Invalid character literal on line "+line_num);
- default:
- val = consume();
- break;
- }
- char secondquote = consume();
- if (firstquote != '\'' || secondquote != '\'')
- throw new Error("Invalid character literal on line "+line_num);
- return new CharacterLiteral(val);
- }
- StringLiteral getStringLiteral() {
- char openquote = consume();
- StringBuffer val = new StringBuffer();
- while (line.charAt(line_pos)!='\"') {
- switch(line.charAt(line_pos)) {
- case '\\':
- val.append(getEscapeSequence());
- break;
- case '\n':
- throw new Error("Invalid string literal on line " + line_num);
- default:
- val.append(consume());
- break;
- }
- }
- char closequote = consume();
- if (openquote != '\"' || closequote != '\"')
- throw new Error("Invalid string literal on line " + line_num);
-
- return new StringLiteral(val.toString().intern());
- }
-
- char getEscapeSequence() {
- if (consume() != '\\')
- throw new Error("Invalid escape sequence on line " + line_num);
- switch(line.charAt(line_pos)) {
- case 'b':
- consume(); return '\b';
- case 't':
- consume(); return '\t';
- case 'n':
- consume(); return '\n';
- case 'f':
- consume(); return '\f';
- case 'r':
- consume(); return '\r';
- case '\"':
- consume(); return '\"';
- case '\'':
- consume(); return '\'';
- case '\\':
- consume(); return '\\';
- case '0':
- case '1':
- case '2':
- case '3':
- return (char) getOctal(3);
- case '4':
- case '5':
- case '6':
- case '7':
- return (char) getOctal(2);
- default:
- throw new Error("Invalid escape sequence on line " + line_num);
- }
- }
- int getOctal(int maxlength) {
- int i, val=0;
- for (i=0; i<maxlength; i++)
- if (Character.digit(line.charAt(line_pos), 8)!=-1) {
- val = (8*val) + Character.digit(consume(), 8);
- } else break;
- if ((i==0) || (val>0xFF)) // impossible.
- throw new Error("Invalid octal escape sequence in line " + line_num);
- return val;
- }
-
- char consume() { return line.charAt(line_pos++); }
- void nextLine() throws java.io.IOException {
- line=reader.readLine();
- if (line!=null) line=line+'\n';
- lineL = new LineList(lineL.head+line_pos, lineL); // for error reporting
- line_pos=0;
- line_num++;
- }
-
- // Deal with error messages.
- public void errorMsg(String msg, java_cup.runtime.Symbol info) {
- int n=line_num, c=info.left-lineL.head;
- for (LineList p = lineL; p!=null; p=p.tail, n--)
- if (p.head<=info.left) { c=info.left-p.head; break; }
- System.err.println(msg+" at line "+n);
- num_errors++;
- }
- private int num_errors = 0;
- public int numErrors() { return num_errors; }
-
- class LineList {
- int head;
- LineList tail;
- LineList(int head, LineList tail) { this.head = head; this.tail = tail; }
- }
-}
+++ /dev/null
-package Lex;
-
-abstract class Literal extends Token { }
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-class LongLiteral extends NumericLiteral {
- LongLiteral(long l) { this.val = new Long(l); }
-
- Symbol token() { return new Symbol(Sym.INTEGER_LITERAL, val); }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-class NullLiteral extends Literal {
- NullLiteral() { }
-
- Symbol token() { return new Symbol(Sym.NULL_LITERAL); }
-
- public String toString() { return "NullLiteral <null>"; }
-}
+++ /dev/null
-package Lex;
-
-abstract class NumericLiteral extends Literal {
- Number val;
-
- public String toString() { return "NumericLiteral <"+val.toString()+">"; }
-}
+++ /dev/null
-package Lex;
-
-import java.util.Hashtable;
-import java_cup.runtime.Symbol;
-
-class Operator extends Token {
- String which;
- Operator(String which) { this.which = which; }
-
- public String toString() { return "Operator <"+which+">"; }
-
- Symbol token() {
- Integer i = (Integer) op_table.get(which);
- return new Symbol(i.intValue());
- }
-
- static private final Hashtable op_table = new Hashtable();
- static {
- op_table.put("=", new Integer(Sym.EQ));
- op_table.put(">", new Integer(Sym.GT));
- op_table.put("<", new Integer(Sym.LT));
- op_table.put("!", new Integer(Sym.NOT));
- op_table.put("~", new Integer(Sym.COMP));
- op_table.put("?", new Integer(Sym.QUESTION));
- op_table.put(":", new Integer(Sym.COLON));
- op_table.put("==", new Integer(Sym.EQEQ));
- op_table.put("<=", new Integer(Sym.LTEQ));
- op_table.put(">=", new Integer(Sym.GTEQ));
- op_table.put("!=", new Integer(Sym.NOTEQ));
- op_table.put("&&", new Integer(Sym.ANDAND));
- op_table.put("||", new Integer(Sym.OROR));
- op_table.put("++", new Integer(Sym.PLUSPLUS));
- op_table.put("--", new Integer(Sym.MINUSMINUS));
- op_table.put("+", new Integer(Sym.PLUS));
- op_table.put("-", new Integer(Sym.MINUS));
- op_table.put("*", new Integer(Sym.MULT));
- op_table.put("/", new Integer(Sym.DIV));
- op_table.put("&", new Integer(Sym.AND));
- op_table.put("|", new Integer(Sym.OR));
- op_table.put("^", new Integer(Sym.XOR));
- op_table.put("%", new Integer(Sym.MOD));
- op_table.put("<<", new Integer(Sym.LSHIFT));
- op_table.put(">>", new Integer(Sym.RSHIFT));
- op_table.put(">>>", new Integer(Sym.URSHIFT));
- op_table.put("+=", new Integer(Sym.PLUSEQ));
- op_table.put("-=", new Integer(Sym.MINUSEQ));
- op_table.put("*=", new Integer(Sym.MULTEQ));
- op_table.put("/=", new Integer(Sym.DIVEQ));
- op_table.put("&=", new Integer(Sym.ANDEQ));
- op_table.put("|=", new Integer(Sym.OREQ));
- op_table.put("^=", new Integer(Sym.XOREQ));
- op_table.put("%=", new Integer(Sym.MODEQ));
- op_table.put("<<=", new Integer(Sym.LSHIFTEQ));
- op_table.put(">>=", new Integer(Sym.RSHIFTEQ));
- op_table.put(">>>=", new Integer(Sym.URSHIFTEQ));
- }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-class Separator extends Token {
- char which;
- Separator(char which) { this.which = which; }
-
- Symbol token() {
- switch(which) {
- case '(': return new Symbol(Sym.LPAREN);
- case ')': return new Symbol(Sym.RPAREN);
- case '{': return new Symbol(Sym.LBRACE);
- case '}': return new Symbol(Sym.RBRACE);
- case '[': return new Symbol(Sym.LBRACK);
- case ']': return new Symbol(Sym.RBRACK);
- case ';': return new Symbol(Sym.SEMICOLON);
- case ',': return new Symbol(Sym.COMMA);
- case '.': return new Symbol(Sym.DOT);
- case '\u2026': return new Symbol(Sym.ELLIPSIS);
- default:
- throw new Error("Invalid separator.");
- }
- }
-
- public String toString() {
- return "Separator <"+which+">";
- }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-
-class StringLiteral extends Literal {
- String val;
- StringLiteral(String s) { this.val = s; }
-
- Symbol token() { return new Symbol(Sym.STRING_LITERAL, val); }
-
- public String toString() {
- return "StringLiteral <"+Token.escape(val)+">";
- }
-}
+++ /dev/null
-package Lex;
-
-abstract class Token extends InputElement {
- abstract java_cup.runtime.Symbol token();
-
- protected static String escape(String s) {
- StringBuffer sb = new StringBuffer();
- for (int i=0; i<s.length(); i++)
- switch(s.charAt(i)) {
- case '\t': sb.append("\\t"); break;
- case '\f': sb.append("\\f"); break;
- case '\n': sb.append("\\n"); break;
- default:
- if ((int)s.charAt(i)<32)
- sb.append("\\"+Integer.toOctalString((int)s.charAt(i)));
- else
- sb.append(s.charAt(i));
- }
- return sb.toString();
- }
-}
+++ /dev/null
-package Lex;
-
-class TraditionalComment extends Comment {
- TraditionalComment() { }
-}
+++ /dev/null
-package Lex;
-
-class WhiteSpace extends InputElement {
- char whitespace;
- WhiteSpace(char which) { this.whitespace=which; }
-
- public String toString() {
- String s;
- switch(whitespace) {
- case ' ': s = "SP"; break;
- case '\t': s = "HT"; break;
- case '\f': s = "FF"; break;
- case '\n': s = "LT"; break;
- default: s = "Unknown Whitespace character."; break;
- }
- return "Whitespace <"+s+">";
- }
-}
+++ /dev/null
-package Main;
-
-import java.io.Reader;
-import java.io.BufferedReader;
-import java.io.FileReader;
-
-/* Test skeleton for java parser/lexer.
- * Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This is released under the terms of the GPL with NO WARRANTY.
- * See the file COPYING for more details.
- */
-
-public class Main {
- public static void main(String args[]) throws Exception {
- Reader fr = new BufferedReader(new FileReader(args[0]));
- // the integer in the next line specifies the java minor version.
- // for example, for a java 1.0 lexer specify '0'
- // for a java 1.1 lexer specify '1'
- // etc.
- // As far as the lexer's concerned, 'strictfp' was added in Java 1.2,
- // 'assert' in Java 1.4, and we need a "lookahead <" token PLT
- // to correctly parse Java 1.5.
- int java_minor_version = 5;
- if (args.length>1) java_minor_version = Integer.parseInt(args[1]);
- Lex.Lexer l = new Lex.Lexer(fr, java_minor_version);
- java_cup.runtime.lr_parser g;
- switch (java_minor_version) {
- default:
- case 5: g = new Parse.Grm15(l); break;
- case 4: g = new Parse.Grm14(l); break;
- case 3:
- case 2: g = new Parse.Grm12(l); break;
- case 1: g = new Parse.Grm11(l); break;
- case 0: g = new Parse.Grm10(l); break;
- }
- g./*debug_*/parse();
- System.exit(l.numErrors());
- }
-}
+++ /dev/null
-# Makefile to create simple test framework for the java parsers.
-# Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
-# Released under the terms of the GPL with NO WARRANTY. See COPYING.
-
-# java environment.
-JAVA=java
-JAVAC=javac
-JFLAGS=-g
-#CUPFLAGS=-dump_states
-
-# list the available java grammar versions
-JAVA_GRAMMARS=10 11 12 14 15
-
-all: $(foreach j,$(JAVA_GRAMMARS),Parse/Grm$(j).class) \
- Lex/Lex.class Main/Main.class
-
-# Feed the appropriate CUP specification to javaCUP.
-Parse/Grm%.java Parse/Sym%.java: Parse/java%.cup
- cd Parse && \
- ${JAVA} java_cup.Main ${CUPFLAGS} -parser Grm$* -symbols Sym$* \
- < java$*.cup 2>Grm$*.err && tail Grm$*.err
-
-# Compile the java source for the parser.
-Parse/Grm%.class: Parse/Lexer.java Parse/Grm%.java Parse/Sym%.java
- ${JAVAC} ${JFLAGS} $^
-
-# Make the lexer symbols from the parser symbols.
-Lex/Sym.java: $(foreach j,$(JAVA_GRAMMARS),Parse/Sym$(j).java)
-# verify that these are all identical!
- @if cat $^ | sed -e 's/Sym[0-9][0-9]/Sym/g' | sort | uniq -c | \
- egrep -v '^[ ]*[0-9]*[05] ' | grep -v "^[ ]*[0-9]*[ ]*//"\
- ; then \
- echo $^ "are not identical;" ;\
- echo "we won't be able to build a single lexer for all of these." ;\
- exit 1;\
- fi
-# now make a generic version.
- sed -e "s/package Parse/package Lex/" -e "s/Sym10/Sym/g" \
- < Parse/Sym10.java > $@
-
-# Compile the java source for the (unified) lexer.
-Lex/Lex.class: Lex/*.java Lex/Sym.java
- ${JAVAC} ${JFLAGS} Lex/*.java
-
-# Compile the java source for the driver.
-Main/Main.class: Main/Main.java
- ${JAVAC} ${JFLAGS} Main/*.java
-
-# run some quick tests.
-test: Parse/Lexer.java Parse/Grm14.java all phony
- for n in 1 2 3 4 5; do \
- ( ${JAVA} Main.Main Parse/Lexer.java $$n && \
- ${JAVA} Main.Main Parse/Grm14.java $$n && \
- ${JAVA} Main.Main tests/Escape.java) || exit 1; \
- done
- for n in 2 3 4 5; do \
- ${JAVA} Main.Main tests/Eric.java $$n || exit 1; \
- done
- ${JAVA} Main.Main tests/TestJSR201.java 5
- ${JAVA} Main.Main tests/Test15.java 5
- ${JAVA} Main.Main tests/Eric15.java 5
-# always run the test.
-phony:
-
-# target to make the distributed files.
-dist:
- -$(RM) -rf JavaGrammar javagrm.tar.gz javagrm.zip
- cvs -d `cat CVS/Root` co -A -P JavaGrammar
- find JavaGrammar -type d -name CVS | xargs $(RM) -rf
- tar czvf javagrm.tar.gz JavaGrammar
- zip -r javagrm.zip JavaGrammar
- cp javagrm.tar.gz `date +javagrm-%d-%b-%Y.tar.gz`
- cp README javagrm-README.txt
- $(RM) -rf JavaGrammar
-upload: dist
- chmod a+r javagrm*
- scp javagrm* shades.cs.princeton.edu:/u/appel/public_html/modern/java/CUP
-
-# clean up after ourselves.
-clean:
- $(RM) Lex/Sym.java \
- $(foreach j,$(JAVA_GRAMMARS),Parse/Grm$(j).err) \
- $(foreach j,$(JAVA_GRAMMARS),Parse/Grm$(j).java) \
- $(foreach j,$(JAVA_GRAMMARS),Parse/Sym$(j).java) \
- Parse/parser.java Parse/sym.java \
- */*.class
-
-veryclean: clean
- $(RM) *~ */*~ javagrm*
+++ /dev/null
-package Parse;
-
-/* Lexer.java. Copyright (C) 1998 C. Scott Ananian.
- * This program is free software; see the file COPYING for more details.
- */
-
-public interface Lexer {
- public java_cup.runtime.Symbol nextToken() throws java.io.IOException;
- /** report an error */
- public void errorMsg(String msg, java_cup.runtime.Symbol info);
- /** return the number of errors reported */
- public int numErrors();
-}
+++ /dev/null
-package Parse;
-
-import java_cup.runtime.*;
-
-/* Java 1.0 parser for CUP.
- * Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This program is released under the terms of the GPL; see the file
- * COPYING for more details. There is NO WARRANTY on this code.
- */
-
-parser code {:
- Lexer lexer;
-
- public Grm10(Lexer l) {
- this();
- lexer=l;
- }
-
- public void syntax_error(java_cup.runtime.Symbol current) {
- report_error("Syntax error (" + current.sym + ")", current);
- }
- public void report_error(String message, java_cup.runtime.Symbol info) {
- lexer.errorMsg(message, info);
- }
-:};
-
-scan with {: return lexer.nextToken(); :};
-
-terminal BOOLEAN; // primitive_type
-terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
-terminal FLOAT, DOUBLE; // floating_point_type
-terminal LBRACK, RBRACK; // array_type
-terminal java.lang.String IDENTIFIER; // name
-terminal DOT; // qualified_name
-terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
-terminal PACKAGE; // package_declaration
-terminal IMPORT; // import_declaration
-terminal PUBLIC, PROTECTED, PRIVATE; // modifier
-terminal STATIC; // modifier
-terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
-terminal CLASS; // class_declaration
-terminal EXTENDS; // super
-terminal IMPLEMENTS; // interfaces
-terminal VOID; // method_header
-terminal THROWS; // throws
-terminal THIS, SUPER; // explicit_constructor_invocation
-terminal INTERFACE; // interface_declaration
-terminal IF, ELSE; // if_then_statement, if_then_else_statement
-terminal SWITCH; // switch_statement
-terminal CASE, DEFAULT; // switch_label
-terminal DO, WHILE; // while_statement, do_statement
-terminal FOR; // for_statement
-terminal BREAK; // break_statement
-terminal CONTINUE; // continue_statement
-terminal RETURN; // return_statement
-terminal THROW; // throw_statement
-terminal TRY; // try_statement
-terminal CATCH; // catch_clause
-terminal FINALLY; // finally
-terminal NEW; // class_instance_creation_expression
-terminal PLUSPLUS; // postincrement_expression
-terminal MINUSMINUS; // postdecrement_expression
-terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
-terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
-terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
-terminal EQEQ, NOTEQ; // equality_expression
-terminal AND; // and_expression
-terminal XOR; // exclusive_or_expression
-terminal OR; // inclusive_or_expression
-terminal ANDAND; // conditional_and_expression
-terminal OROR; // conditional_or_expression
-terminal QUESTION; // conditional_expression
-terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
-terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
-terminal ANDEQ, XOREQ, OREQ; // assignment_operator
-
-terminal java.lang.Number INTEGER_LITERAL;
-terminal java.lang.Number FLOATING_POINT_LITERAL;
-terminal java.lang.Boolean BOOLEAN_LITERAL;
-terminal java.lang.Character CHARACTER_LITERAL;
-terminal java.lang.String STRING_LITERAL;
-terminal NULL_LITERAL;
-
-// Reserved but unused:
-terminal CONST, GOTO;
-// lexer compatibility with Java 1.2:
-terminal STRICTFP;
-// lexer compatibility with Java 1.4
-terminal ASSERT;
-// lexer compatibility with Java 1.5
-terminal ELLIPSIS;
-terminal ENUM;
-
-// 19.2) The Syntactic Grammar
-non terminal goal;
-// 19.3) Lexical Structure
-non terminal literal;
-// 19.4) Types, Values, and Variables
-non terminal type, primitive_type, numeric_type;
-non terminal integral_type, floating_point_type;
-non terminal reference_type;
-non terminal class_or_interface_type;
-non terminal class_type, interface_type;
-non terminal array_type;
-// 19.5) Names
-non terminal name, simple_name, qualified_name;
-// 19.6) Packages
-non terminal compilation_unit;
-non terminal package_declaration_opt, package_declaration;
-non terminal import_declarations_opt, import_declarations;
-non terminal type_declarations_opt, type_declarations;
-non terminal import_declaration;
-non terminal single_type_import_declaration;
-non terminal type_import_on_demand_declaration;
-non terminal type_declaration;
-// 19.7) Productions used only in the LALR(1) grammar
-non terminal modifiers_opt, modifiers, modifier;
-// 19.8.1) Class Declaration
-non terminal class_declaration, super, super_opt;
-non terminal interfaces, interfaces_opt, interface_type_list;
-non terminal class_body;
-non terminal class_body_declarations, class_body_declarations_opt;
-non terminal class_body_declaration, class_member_declaration;
-// 19.8.2) Field Declarations
-non terminal field_declaration, variable_declarators, variable_declarator;
-non terminal variable_declarator_id, variable_initializer;
-// 19.8.3) Method Declarations
-non terminal method_declaration, method_header, method_declarator;
-non terminal formal_parameter_list_opt, formal_parameter_list;
-non terminal formal_parameter;
-non terminal throws_opt, throws;
-non terminal class_type_list, method_body;
-// 19.8.4) Static Initializers
-non terminal static_initializer;
-// 19.8.5) Constructor Declarations
-non terminal constructor_declaration, constructor_declarator;
-non terminal constructor_body;
-non terminal explicit_constructor_invocation;
-// 19.9.1) Interface Declarations
-non terminal interface_declaration;
-non terminal extends_interfaces_opt, extends_interfaces;
-non terminal interface_body;
-non terminal interface_member_declarations_opt, interface_member_declarations;
-non terminal interface_member_declaration, constant_declaration;
-non terminal abstract_method_declaration;
-// 19.10) Arrays
-non terminal array_initializer;
-non terminal variable_initializers;
-// 19.11) Blocks and Statements
-non terminal block;
-non terminal block_statements_opt, block_statements, block_statement;
-non terminal local_variable_declaration_statement, local_variable_declaration;
-non terminal statement, statement_no_short_if;
-non terminal statement_without_trailing_substatement;
-non terminal empty_statement;
-non terminal labeled_statement, labeled_statement_no_short_if;
-non terminal expression_statement, statement_expression;
-non terminal if_then_statement;
-non terminal if_then_else_statement, if_then_else_statement_no_short_if;
-non terminal switch_statement, switch_block;
-non terminal switch_block_statement_groups;
-non terminal switch_block_statement_group;
-non terminal switch_labels, switch_label;
-non terminal while_statement, while_statement_no_short_if;
-non terminal do_statement;
-non terminal for_statement, for_statement_no_short_if;
-non terminal for_init_opt, for_init;
-non terminal for_update_opt, for_update;
-non terminal statement_expression_list;
-non terminal identifier_opt;
-non terminal break_statement, continue_statement;
-non terminal return_statement, throw_statement;
-non terminal synchronized_statement, try_statement;
-non terminal catches_opt, catches, catch_clause;
-non terminal finally;
-// 19.12) Expressions
-non terminal primary, primary_no_new_array;
-non terminal class_instance_creation_expression;
-non terminal argument_list_opt, argument_list;
-non terminal array_creation_expression;
-non terminal dim_exprs, dim_expr, dims_opt, dims;
-non terminal field_access, method_invocation, array_access;
-non terminal postfix_expression;
-non terminal postincrement_expression, postdecrement_expression;
-non terminal unary_expression, unary_expression_not_plus_minus;
-non terminal preincrement_expression, predecrement_expression;
-non terminal cast_expression;
-non terminal multiplicative_expression, additive_expression;
-non terminal shift_expression, relational_expression, equality_expression;
-non terminal and_expression, exclusive_or_expression, inclusive_or_expression;
-non terminal conditional_and_expression, conditional_or_expression;
-non terminal conditional_expression, assignment_expression;
-non terminal assignment;
-non terminal left_hand_side;
-non terminal assignment_operator;
-non terminal expression_opt, expression;
-non terminal constant_expression;
-
-start with goal;
-
-// 19.2) The Syntactic Grammar
-goal ::= compilation_unit
- ;
-
-// 19.3) Lexical Structure.
-literal ::= INTEGER_LITERAL
- | FLOATING_POINT_LITERAL
- | BOOLEAN_LITERAL
- | CHARACTER_LITERAL
- | STRING_LITERAL
- | NULL_LITERAL
- ;
-
-// 19.4) Types, Values, and Variables
-type ::= primitive_type
- | reference_type
- ;
-primitive_type ::=
- numeric_type
- | BOOLEAN
- ;
-numeric_type::= integral_type
- | floating_point_type
- ;
-integral_type ::=
- BYTE
- | SHORT
- | INT
- | LONG
- | CHAR
- ;
-floating_point_type ::=
- FLOAT
- | DOUBLE
- ;
-
-reference_type ::=
- class_or_interface_type
- | array_type
- ;
-class_or_interface_type ::= name;
-
-class_type ::= class_or_interface_type;
-interface_type ::= class_or_interface_type;
-
-array_type ::= primitive_type LBRACK RBRACK
- | name LBRACK RBRACK
- | array_type LBRACK RBRACK
- ;
-
-// 19.5) Names
-name ::= simple_name
- | qualified_name
- ;
-simple_name ::= IDENTIFIER
- ;
-qualified_name ::=
- name DOT IDENTIFIER
- ;
-
-// 19.6) Packages
-compilation_unit ::=
- package_declaration_opt
- import_declarations_opt
- type_declarations_opt
- ;
-package_declaration_opt ::= package_declaration | ;
-import_declarations_opt ::= import_declarations | ;
-type_declarations_opt ::= type_declarations | ;
-
-import_declarations ::=
- import_declaration
- | import_declarations import_declaration
- ;
-type_declarations ::=
- type_declaration
- | type_declarations type_declaration
- ;
-package_declaration ::=
- PACKAGE name SEMICOLON
- ;
-import_declaration ::=
- single_type_import_declaration
- | type_import_on_demand_declaration
- ;
-single_type_import_declaration ::=
- IMPORT name SEMICOLON
- ;
-type_import_on_demand_declaration ::=
- IMPORT name DOT MULT SEMICOLON
- ;
-type_declaration ::=
- class_declaration
- | interface_declaration
- | SEMICOLON
- ;
-
-// 19.7) Productions used only in the LALR(1) grammar
-modifiers_opt::=
- | modifiers
- ;
-modifiers ::= modifier
- | modifiers modifier
- ;
-modifier ::= PUBLIC | PROTECTED | PRIVATE
- | STATIC
- | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
- ;
-
-// 19.8) Classes
-
-// 19.8.1) Class Declaration:
-class_declaration ::=
- modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
- ;
-super ::= EXTENDS class_type
- ;
-super_opt ::=
- | super
- ;
-interfaces ::= IMPLEMENTS interface_type_list
- ;
-interfaces_opt::=
- | interfaces
- ;
-interface_type_list ::=
- interface_type
- | interface_type_list COMMA interface_type
- ;
-class_body ::= LBRACE class_body_declarations_opt RBRACE
- ;
-class_body_declarations_opt ::=
- | class_body_declarations ;
-class_body_declarations ::=
- class_body_declaration
- | class_body_declarations class_body_declaration
- ;
-class_body_declaration ::=
- class_member_declaration
- | static_initializer
- | constructor_declaration
- ;
-class_member_declaration ::=
- field_declaration
- | method_declaration
- | SEMICOLON
- ;
-
-// 19.8.2) Field Declarations
-field_declaration ::=
- modifiers_opt type variable_declarators SEMICOLON
- ;
-variable_declarators ::=
- variable_declarator
- | variable_declarators COMMA variable_declarator
- ;
-variable_declarator ::=
- variable_declarator_id
- | variable_declarator_id EQ variable_initializer
- ;
-variable_declarator_id ::=
- IDENTIFIER
- | variable_declarator_id LBRACK RBRACK
- ;
-variable_initializer ::=
- expression
- | array_initializer
- ;
-
-// 19.8.3) Method Declarations
-method_declaration ::=
- method_header method_body
- ;
-method_header ::=
- modifiers_opt type method_declarator throws_opt
- | modifiers_opt VOID method_declarator throws_opt
- ;
-method_declarator ::=
- IDENTIFIER LPAREN formal_parameter_list_opt RPAREN
- | method_declarator LBRACK RBRACK
- ;
-formal_parameter_list_opt ::=
- | formal_parameter_list
- ;
-formal_parameter_list ::=
- formal_parameter
- | formal_parameter_list COMMA formal_parameter
- ;
-formal_parameter ::=
- type variable_declarator_id
- ;
-throws_opt ::=
- | throws
- ;
-throws ::= THROWS class_type_list
- ;
-class_type_list ::=
- class_type
- | class_type_list COMMA class_type
- ;
-method_body ::= block
- | SEMICOLON
- ;
-
-// 19.8.4) Static Initializers
-static_initializer ::=
- STATIC block
- ;
-
-// 19.8.5) Constructor Declarations
-constructor_declaration ::=
- modifiers_opt constructor_declarator throws_opt
- constructor_body
- ;
-constructor_declarator ::=
- simple_name LPAREN formal_parameter_list_opt RPAREN
- ;
-constructor_body ::=
- LBRACE explicit_constructor_invocation
- block_statements RBRACE
- | LBRACE explicit_constructor_invocation RBRACE
- | LBRACE block_statements RBRACE
- | LBRACE RBRACE
- ;
-explicit_constructor_invocation ::=
- THIS LPAREN argument_list_opt RPAREN SEMICOLON
- | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- ;
-
-// 19.9) Interfaces
-
-// 19.9.1) Interface Declarations
-interface_declaration ::=
- modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt
- interface_body
- ;
-extends_interfaces_opt ::=
- | extends_interfaces
- ;
-extends_interfaces ::=
- EXTENDS interface_type
- | extends_interfaces COMMA interface_type
- ;
-interface_body ::=
- LBRACE interface_member_declarations_opt RBRACE
- ;
-interface_member_declarations_opt ::=
- | interface_member_declarations
- ;
-interface_member_declarations ::=
- interface_member_declaration
- | interface_member_declarations interface_member_declaration
- ;
-interface_member_declaration ::=
- constant_declaration
- | abstract_method_declaration
- | SEMICOLON
- ;
-constant_declaration ::=
- field_declaration
- ;
-abstract_method_declaration ::=
- method_header SEMICOLON
- ;
-
-// 19.10) Arrays
-array_initializer ::=
- LBRACE variable_initializers COMMA RBRACE
- | LBRACE variable_initializers RBRACE
- | LBRACE COMMA RBRACE
- | LBRACE RBRACE
- ;
-variable_initializers ::=
- variable_initializer
- | variable_initializers COMMA variable_initializer
- ;
-
-// 19.11) Blocks and Statements
-block ::= LBRACE block_statements_opt RBRACE
- ;
-block_statements_opt ::=
- | block_statements
- ;
-block_statements ::=
- block_statement
- | block_statements block_statement
- ;
-block_statement ::=
- local_variable_declaration_statement
- | statement
- ;
-local_variable_declaration_statement ::=
- local_variable_declaration SEMICOLON
- ;
-local_variable_declaration ::=
- type variable_declarators
- ;
-statement ::= statement_without_trailing_substatement
- | labeled_statement
- | if_then_statement
- | if_then_else_statement
- | while_statement
- | for_statement
- ;
-statement_no_short_if ::=
- statement_without_trailing_substatement
- | labeled_statement_no_short_if
- | if_then_else_statement_no_short_if
- | while_statement_no_short_if
- | for_statement_no_short_if
- ;
-statement_without_trailing_substatement ::=
- block
- | empty_statement
- | expression_statement
- | switch_statement
- | do_statement
- | break_statement
- | continue_statement
- | return_statement
- | synchronized_statement
- | throw_statement
- | try_statement
- ;
-empty_statement ::=
- SEMICOLON
- ;
-labeled_statement ::=
- IDENTIFIER COLON statement
- ;
-labeled_statement_no_short_if ::=
- IDENTIFIER COLON statement_no_short_if
- ;
-expression_statement ::=
- statement_expression SEMICOLON
- ;
-statement_expression ::=
- assignment
- | preincrement_expression
- | predecrement_expression
- | postincrement_expression
- | postdecrement_expression
- | method_invocation
- | class_instance_creation_expression
- ;
-if_then_statement ::=
- IF LPAREN expression RPAREN statement
- ;
-if_then_else_statement ::=
- IF LPAREN expression RPAREN statement_no_short_if
- ELSE statement
- ;
-if_then_else_statement_no_short_if ::=
- IF LPAREN expression RPAREN statement_no_short_if
- ELSE statement_no_short_if
- ;
-switch_statement ::=
- SWITCH LPAREN expression RPAREN switch_block
- ;
-switch_block ::=
- LBRACE switch_block_statement_groups switch_labels RBRACE
- | LBRACE switch_block_statement_groups RBRACE
- | LBRACE switch_labels RBRACE
- | LBRACE RBRACE
- ;
-switch_block_statement_groups ::=
- switch_block_statement_group
- | switch_block_statement_groups switch_block_statement_group
- ;
-switch_block_statement_group ::=
- switch_labels block_statements
- ;
-switch_labels ::=
- switch_label
- | switch_labels switch_label
- ;
-switch_label ::=
- CASE constant_expression COLON
- | DEFAULT COLON
- ;
-
-while_statement ::=
- WHILE LPAREN expression RPAREN statement
- ;
-while_statement_no_short_if ::=
- WHILE LPAREN expression RPAREN statement_no_short_if
- ;
-do_statement ::=
- DO statement WHILE LPAREN expression RPAREN SEMICOLON
- ;
-for_statement ::=
- FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
- for_update_opt RPAREN statement
- ;
-for_statement_no_short_if ::=
- FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
- for_update_opt RPAREN statement_no_short_if
- ;
-for_init_opt ::=
- | for_init
- ;
-for_init ::= statement_expression_list
- | local_variable_declaration
- ;
-for_update_opt ::=
- | for_update
- ;
-for_update ::= statement_expression_list
- ;
-statement_expression_list ::=
- statement_expression
- | statement_expression_list COMMA statement_expression
- ;
-
-identifier_opt ::=
- | IDENTIFIER
- ;
-
-break_statement ::=
- BREAK identifier_opt SEMICOLON
- ;
-
-continue_statement ::=
- CONTINUE identifier_opt SEMICOLON
- ;
-return_statement ::=
- RETURN expression_opt SEMICOLON
- ;
-throw_statement ::=
- THROW expression SEMICOLON
- ;
-synchronized_statement ::=
- SYNCHRONIZED LPAREN expression RPAREN block
- ;
-try_statement ::=
- TRY block catches
- | TRY block catches_opt finally
- ;
-catches_opt ::=
- | catches
- ;
-catches ::= catch_clause
- | catches catch_clause
- ;
-catch_clause ::=
- CATCH LPAREN formal_parameter RPAREN block
- ;
-finally ::= FINALLY block
- ;
-
-// 19.12) Expressions
-primary ::= primary_no_new_array
- | array_creation_expression
- ;
-primary_no_new_array ::=
- literal
- | THIS
- | LPAREN expression RPAREN
- | class_instance_creation_expression
- | field_access
- | method_invocation
- | array_access
- ;
-class_instance_creation_expression ::=
- NEW class_type LPAREN argument_list_opt RPAREN
- ;
-argument_list_opt ::=
- | argument_list
- ;
-argument_list ::=
- expression
- | argument_list COMMA expression
- ;
-array_creation_expression ::=
- NEW primitive_type dim_exprs dims_opt
- | NEW class_or_interface_type dim_exprs dims_opt
- ;
-dim_exprs ::= dim_expr
- | dim_exprs dim_expr
- ;
-dim_expr ::= LBRACK expression RBRACK
- ;
-dims_opt ::=
- | dims
- ;
-dims ::= LBRACK RBRACK
- | dims LBRACK RBRACK
- ;
-field_access ::=
- primary DOT IDENTIFIER
- | SUPER DOT IDENTIFIER
- ;
-method_invocation ::=
- name LPAREN argument_list_opt RPAREN
- | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- ;
-array_access ::=
- name LBRACK expression RBRACK
- | primary_no_new_array LBRACK expression RBRACK
- ;
-postfix_expression ::=
- primary
- | name
- | postincrement_expression
- | postdecrement_expression
- ;
-postincrement_expression ::=
- postfix_expression PLUSPLUS
- ;
-postdecrement_expression ::=
- postfix_expression MINUSMINUS
- ;
-unary_expression ::=
- preincrement_expression
- | predecrement_expression
- | PLUS unary_expression
- | MINUS unary_expression
- | unary_expression_not_plus_minus
- ;
-preincrement_expression ::=
- PLUSPLUS unary_expression
- ;
-predecrement_expression ::=
- MINUSMINUS unary_expression
- ;
-unary_expression_not_plus_minus ::=
- postfix_expression
- | COMP unary_expression
- | NOT unary_expression
- | cast_expression
- ;
-cast_expression ::=
- LPAREN primitive_type dims_opt RPAREN unary_expression
- | LPAREN expression RPAREN unary_expression_not_plus_minus
- | LPAREN name dims RPAREN unary_expression_not_plus_minus
- ;
-multiplicative_expression ::=
- unary_expression
- | multiplicative_expression MULT unary_expression
- | multiplicative_expression DIV unary_expression
- | multiplicative_expression MOD unary_expression
- ;
-additive_expression ::=
- multiplicative_expression
- | additive_expression PLUS multiplicative_expression
- | additive_expression MINUS multiplicative_expression
- ;
-shift_expression ::=
- additive_expression
- | shift_expression LSHIFT additive_expression
- | shift_expression RSHIFT additive_expression
- | shift_expression URSHIFT additive_expression
- ;
-relational_expression ::=
- shift_expression
- | relational_expression LT shift_expression
- | relational_expression GT shift_expression
- | relational_expression LTEQ shift_expression
- | relational_expression GTEQ shift_expression
- | relational_expression INSTANCEOF reference_type
- ;
-equality_expression ::=
- relational_expression
- | equality_expression EQEQ relational_expression
- | equality_expression NOTEQ relational_expression
- ;
-and_expression ::=
- equality_expression
- | and_expression AND equality_expression
- ;
-exclusive_or_expression ::=
- and_expression
- | exclusive_or_expression XOR and_expression
- ;
-inclusive_or_expression ::=
- exclusive_or_expression
- | inclusive_or_expression OR exclusive_or_expression
- ;
-conditional_and_expression ::=
- inclusive_or_expression
- | conditional_and_expression ANDAND inclusive_or_expression
- ;
-conditional_or_expression ::=
- conditional_and_expression
- | conditional_or_expression OROR conditional_and_expression
- ;
-conditional_expression ::=
- conditional_or_expression
- | conditional_or_expression QUESTION expression
- COLON conditional_expression
- ;
-assignment_expression ::=
- conditional_expression
- | assignment
- ;
-assignment ::= left_hand_side assignment_operator assignment_expression
- ;
-left_hand_side ::=
- name
- | field_access
- | array_access
- ;
-assignment_operator ::=
- EQ
- | MULTEQ
- | DIVEQ
- | MODEQ
- | PLUSEQ
- | MINUSEQ
- | LSHIFTEQ
- | RSHIFTEQ
- | URSHIFTEQ
- | ANDEQ
- | XOREQ
- | OREQ
- ;
-expression_opt ::=
- | expression
- ;
-expression ::= assignment_expression
- ;
-constant_expression ::=
- expression
- ;
+++ /dev/null
-package Parse;
-
-import java_cup.runtime.*;
-
-/* Java 1.1 parser for CUP.
- * Copyright (C) 1998-2003 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This program is released under the terms of the GPL; see the file
- * COPYING for more details. There is NO WARRANTY on this code.
- */
-
-/*
-JDK 1.1 Features added:
- instance initializers
- anonymous array expressions.
- class literals.
- blank finals; final local variables.
- inner classes:
- block ::= class/interface decl
- primary_no_new_array ::= class_name DOT THIS
- class_instance_creation_expresion ::= ...
- explicit_constructor_invocation ::= ...
-*/
-parser code {:
- Lexer lexer;
-
- public Grm11(Lexer l) {
- this();
- lexer=l;
- }
-
- public void syntax_error(java_cup.runtime.Symbol current) {
- report_error("Syntax error (" + current.sym + ")", current);
- }
- public void report_error(String message, java_cup.runtime.Symbol info) {
- lexer.errorMsg(message, info);
- }
-:};
-
-scan with {: return lexer.nextToken(); :};
-
-terminal BOOLEAN; // primitive_type
-terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
-terminal FLOAT, DOUBLE; // floating_point_type
-terminal LBRACK, RBRACK; // array_type
-terminal java.lang.String IDENTIFIER; // name
-terminal DOT; // qualified_name
-terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
-terminal PACKAGE; // package_declaration
-terminal IMPORT; // import_declaration
-terminal PUBLIC, PROTECTED, PRIVATE; // modifier
-terminal STATIC; // modifier
-terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
-terminal CLASS; // class_declaration
-terminal EXTENDS; // super
-terminal IMPLEMENTS; // interfaces
-terminal VOID; // method_header
-terminal THROWS; // throws
-terminal THIS, SUPER; // explicit_constructor_invocation
-terminal INTERFACE; // interface_declaration
-terminal IF, ELSE; // if_then_statement, if_then_else_statement
-terminal SWITCH; // switch_statement
-terminal CASE, DEFAULT; // switch_label
-terminal DO, WHILE; // while_statement, do_statement
-terminal FOR; // for_statement
-terminal BREAK; // break_statement
-terminal CONTINUE; // continue_statement
-terminal RETURN; // return_statement
-terminal THROW; // throw_statement
-terminal TRY; // try_statement
-terminal CATCH; // catch_clause
-terminal FINALLY; // finally
-terminal NEW; // class_instance_creation_expression
-terminal PLUSPLUS; // postincrement_expression
-terminal MINUSMINUS; // postdecrement_expression
-terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
-terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
-terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
-terminal EQEQ, NOTEQ; // equality_expression
-terminal AND; // and_expression
-terminal XOR; // exclusive_or_expression
-terminal OR; // inclusive_or_expression
-terminal ANDAND; // conditional_and_expression
-terminal OROR; // conditional_or_expression
-terminal QUESTION; // conditional_expression
-terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
-terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
-terminal ANDEQ, XOREQ, OREQ; // assignment_operator
-
-terminal java.lang.Number INTEGER_LITERAL;
-terminal java.lang.Number FLOATING_POINT_LITERAL;
-terminal java.lang.Boolean BOOLEAN_LITERAL;
-terminal java.lang.Character CHARACTER_LITERAL;
-terminal java.lang.String STRING_LITERAL;
-terminal NULL_LITERAL;
-
-// Reserved but unused:
-terminal CONST, GOTO;
-// lexer compatibility with Java 1.2:
-terminal STRICTFP;
-// lexer compatibility with Java 1.4
-terminal ASSERT;
-// lexer compatibility with Java 1.5
-terminal ELLIPSIS;
-terminal ENUM;
-
-// 19.2) The Syntactic Grammar
-non terminal goal;
-// 19.3) Lexical Structure
-non terminal literal;
-// 19.4) Types, Values, and Variables
-non terminal type, primitive_type, numeric_type;
-non terminal integral_type, floating_point_type;
-non terminal reference_type;
-non terminal class_or_interface_type;
-non terminal class_type, interface_type;
-non terminal array_type;
-// 19.5) Names
-non terminal name, simple_name, qualified_name;
-// 19.6) Packages
-non terminal compilation_unit;
-non terminal package_declaration_opt, package_declaration;
-non terminal import_declarations_opt, import_declarations;
-non terminal type_declarations_opt, type_declarations;
-non terminal import_declaration;
-non terminal single_type_import_declaration;
-non terminal type_import_on_demand_declaration;
-non terminal type_declaration;
-// 19.7) Productions used only in the LALR(1) grammar
-non terminal modifiers_opt, modifiers, modifier;
-// 19.8.1) Class Declaration
-non terminal class_declaration, super, super_opt;
-non terminal interfaces, interfaces_opt, interface_type_list;
-non terminal class_body;
-non terminal class_body_declarations, class_body_declarations_opt;
-non terminal class_body_declaration, class_member_declaration;
-// 19.8.2) Field Declarations
-non terminal field_declaration, variable_declarators, variable_declarator;
-non terminal variable_declarator_id, variable_initializer;
-// 19.8.3) Method Declarations
-non terminal method_declaration, method_header, method_declarator;
-non terminal formal_parameter_list_opt, formal_parameter_list;
-non terminal formal_parameter;
-non terminal throws_opt, throws;
-non terminal class_type_list, method_body;
-// 19.8.4) Static Initializers
-non terminal static_initializer;
-// 19.8.5) Constructor Declarations
-non terminal constructor_declaration, constructor_declarator;
-non terminal constructor_body;
-non terminal explicit_constructor_invocation;
-// 19.9.1) Interface Declarations
-non terminal interface_declaration;
-non terminal extends_interfaces_opt, extends_interfaces;
-non terminal interface_body;
-non terminal interface_member_declarations_opt, interface_member_declarations;
-non terminal interface_member_declaration, constant_declaration;
-non terminal abstract_method_declaration;
-// 19.10) Arrays
-non terminal array_initializer;
-non terminal variable_initializers;
-// 19.11) Blocks and Statements
-non terminal block;
-non terminal block_statements_opt, block_statements, block_statement;
-non terminal local_variable_declaration_statement, local_variable_declaration;
-non terminal statement, statement_no_short_if;
-non terminal statement_without_trailing_substatement;
-non terminal empty_statement;
-non terminal labeled_statement, labeled_statement_no_short_if;
-non terminal expression_statement, statement_expression;
-non terminal if_then_statement;
-non terminal if_then_else_statement, if_then_else_statement_no_short_if;
-non terminal switch_statement, switch_block;
-non terminal switch_block_statement_groups;
-non terminal switch_block_statement_group;
-non terminal switch_labels, switch_label;
-non terminal while_statement, while_statement_no_short_if;
-non terminal do_statement;
-non terminal for_statement, for_statement_no_short_if;
-non terminal for_init_opt, for_init;
-non terminal for_update_opt, for_update;
-non terminal statement_expression_list;
-non terminal identifier_opt;
-non terminal break_statement, continue_statement;
-non terminal return_statement, throw_statement;
-non terminal synchronized_statement, try_statement;
-non terminal catches_opt, catches, catch_clause;
-non terminal finally;
-// 19.12) Expressions
-non terminal primary, primary_no_new_array;
-non terminal class_instance_creation_expression;
-non terminal argument_list_opt, argument_list;
-non terminal array_creation_expression;
-non terminal dim_exprs, dim_expr, dims_opt, dims;
-non terminal field_access, method_invocation, array_access;
-non terminal postfix_expression;
-non terminal postincrement_expression, postdecrement_expression;
-non terminal unary_expression, unary_expression_not_plus_minus;
-non terminal preincrement_expression, predecrement_expression;
-non terminal cast_expression;
-non terminal multiplicative_expression, additive_expression;
-non terminal shift_expression, relational_expression, equality_expression;
-non terminal and_expression, exclusive_or_expression, inclusive_or_expression;
-non terminal conditional_and_expression, conditional_or_expression;
-non terminal conditional_expression, assignment_expression;
-non terminal assignment;
-non terminal left_hand_side;
-non terminal assignment_operator;
-non terminal expression_opt, expression;
-non terminal constant_expression;
-
-start with goal;
-
-// 19.2) The Syntactic Grammar
-goal ::= compilation_unit
- ;
-
-// 19.3) Lexical Structure.
-literal ::= INTEGER_LITERAL
- | FLOATING_POINT_LITERAL
- | BOOLEAN_LITERAL
- | CHARACTER_LITERAL
- | STRING_LITERAL
- | NULL_LITERAL
- ;
-
-// 19.4) Types, Values, and Variables
-type ::= primitive_type
- | reference_type
- ;
-primitive_type ::=
- numeric_type
- | BOOLEAN
- ;
-numeric_type::= integral_type
- | floating_point_type
- ;
-integral_type ::=
- BYTE
- | SHORT
- | INT
- | LONG
- | CHAR
- ;
-floating_point_type ::=
- FLOAT
- | DOUBLE
- ;
-
-reference_type ::=
- class_or_interface_type
- | array_type
- ;
-class_or_interface_type ::= name;
-
-class_type ::= class_or_interface_type;
-interface_type ::= class_or_interface_type;
-
-array_type ::= primitive_type dims
- | name dims
- ;
-
-// 19.5) Names
-name ::= simple_name
- | qualified_name
- ;
-simple_name ::= IDENTIFIER
- ;
-qualified_name ::=
- name DOT IDENTIFIER
- ;
-
-// 19.6) Packages
-compilation_unit ::=
- package_declaration_opt
- import_declarations_opt
- type_declarations_opt
- ;
-package_declaration_opt ::= package_declaration | ;
-import_declarations_opt ::= import_declarations | ;
-type_declarations_opt ::= type_declarations | ;
-
-import_declarations ::=
- import_declaration
- | import_declarations import_declaration
- ;
-type_declarations ::=
- type_declaration
- | type_declarations type_declaration
- ;
-package_declaration ::=
- PACKAGE name SEMICOLON
- ;
-import_declaration ::=
- single_type_import_declaration
- | type_import_on_demand_declaration
- ;
-single_type_import_declaration ::=
- IMPORT name SEMICOLON
- ;
-type_import_on_demand_declaration ::=
- IMPORT name DOT MULT SEMICOLON
- ;
-type_declaration ::=
- class_declaration
- | interface_declaration
- | SEMICOLON
- ;
-
-// 19.7) Productions used only in the LALR(1) grammar
-modifiers_opt::=
- | modifiers
- ;
-modifiers ::= modifier
- | modifiers modifier
- ;
-modifier ::= PUBLIC | PROTECTED | PRIVATE
- | STATIC
- | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
- ;
-
-// 19.8) Classes
-
-// 19.8.1) Class Declaration:
-class_declaration ::=
- modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
- ;
-super ::= EXTENDS class_type
- ;
-super_opt ::=
- | super
- ;
-interfaces ::= IMPLEMENTS interface_type_list
- ;
-interfaces_opt::=
- | interfaces
- ;
-interface_type_list ::=
- interface_type
- | interface_type_list COMMA interface_type
- ;
-class_body ::= LBRACE class_body_declarations_opt RBRACE
- ;
-class_body_declarations_opt ::=
- | class_body_declarations ;
-class_body_declarations ::=
- class_body_declaration
- | class_body_declarations class_body_declaration
- ;
-class_body_declaration ::=
- class_member_declaration
- | static_initializer
- | constructor_declaration
- | block
- ;
-class_member_declaration ::=
- field_declaration
- | method_declaration
- /* repeat the prod for 'class_declaration' here: */
- | modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
- | interface_declaration
- | SEMICOLON
- ;
-
-// 19.8.2) Field Declarations
-field_declaration ::=
- modifiers_opt type variable_declarators SEMICOLON
- ;
-variable_declarators ::=
- variable_declarator
- | variable_declarators COMMA variable_declarator
- ;
-variable_declarator ::=
- variable_declarator_id
- | variable_declarator_id EQ variable_initializer
- ;
-variable_declarator_id ::=
- IDENTIFIER
- | variable_declarator_id LBRACK RBRACK
- ;
-variable_initializer ::=
- expression
- | array_initializer
- ;
-
-// 19.8.3) Method Declarations
-method_declaration ::=
- method_header method_body
- ;
-method_header ::=
- modifiers_opt type method_declarator throws_opt
- | modifiers_opt VOID method_declarator throws_opt
- ;
-method_declarator ::=
- IDENTIFIER LPAREN formal_parameter_list_opt RPAREN
- | method_declarator LBRACK RBRACK
- ;
-formal_parameter_list_opt ::=
- | formal_parameter_list
- ;
-formal_parameter_list ::=
- formal_parameter
- | formal_parameter_list COMMA formal_parameter
- ;
-formal_parameter ::=
- type variable_declarator_id
- | FINAL type variable_declarator_id
- ;
-throws_opt ::=
- | throws
- ;
-throws ::= THROWS class_type_list
- ;
-class_type_list ::=
- class_type
- | class_type_list COMMA class_type
- ;
-method_body ::= block
- | SEMICOLON
- ;
-
-// 19.8.4) Static Initializers
-static_initializer ::=
- STATIC block
- ;
-
-// 19.8.5) Constructor Declarations
-constructor_declaration ::=
- modifiers_opt constructor_declarator throws_opt
- constructor_body
- ;
-constructor_declarator ::=
- simple_name LPAREN formal_parameter_list_opt RPAREN
- ;
-constructor_body ::=
- LBRACE explicit_constructor_invocation
- block_statements RBRACE
- | LBRACE explicit_constructor_invocation RBRACE
- | LBRACE block_statements RBRACE
- | LBRACE RBRACE
- ;
-explicit_constructor_invocation ::=
- THIS LPAREN argument_list_opt RPAREN SEMICOLON
- | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- ;
-
-// 19.9) Interfaces
-
-// 19.9.1) Interface Declarations
-interface_declaration ::=
- modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt
- interface_body
- ;
-extends_interfaces_opt ::=
- | extends_interfaces
- ;
-extends_interfaces ::=
- EXTENDS interface_type
- | extends_interfaces COMMA interface_type
- ;
-interface_body ::=
- LBRACE interface_member_declarations_opt RBRACE
- ;
-interface_member_declarations_opt ::=
- | interface_member_declarations
- ;
-interface_member_declarations ::=
- interface_member_declaration
- | interface_member_declarations interface_member_declaration
- ;
-interface_member_declaration ::=
- constant_declaration
- | abstract_method_declaration
- | class_declaration
- | interface_declaration
- | SEMICOLON
- ;
-constant_declaration ::=
- field_declaration
- // need to semantically check that modifiers of field declaration
- // include only PUBLIC, STATIC, or FINAL. Other modifiers are
- // disallowed.
- ;
-abstract_method_declaration ::=
- method_header SEMICOLON
- ;
-
-// 19.10) Arrays
-array_initializer ::=
- LBRACE variable_initializers COMMA RBRACE
- | LBRACE variable_initializers RBRACE
- | LBRACE COMMA RBRACE
- | LBRACE RBRACE
- ;
-variable_initializers ::=
- variable_initializer
- | variable_initializers COMMA variable_initializer
- ;
-
-// 19.11) Blocks and Statements
-block ::= LBRACE block_statements_opt RBRACE
- ;
-block_statements_opt ::=
- | block_statements
- ;
-block_statements ::=
- block_statement
- | block_statements block_statement
- ;
-block_statement ::=
- local_variable_declaration_statement
- | statement
- | class_declaration
- | interface_declaration
- ;
-local_variable_declaration_statement ::=
- local_variable_declaration SEMICOLON
- ;
-local_variable_declaration ::=
- type variable_declarators
- | FINAL type variable_declarators
- ;
-statement ::= statement_without_trailing_substatement
- | labeled_statement
- | if_then_statement
- | if_then_else_statement
- | while_statement
- | for_statement
- ;
-statement_no_short_if ::=
- statement_without_trailing_substatement
- | labeled_statement_no_short_if
- | if_then_else_statement_no_short_if
- | while_statement_no_short_if
- | for_statement_no_short_if
- ;
-statement_without_trailing_substatement ::=
- block
- | empty_statement
- | expression_statement
- | switch_statement
- | do_statement
- | break_statement
- | continue_statement
- | return_statement
- | synchronized_statement
- | throw_statement
- | try_statement
- ;
-empty_statement ::=
- SEMICOLON
- ;
-labeled_statement ::=
- IDENTIFIER COLON statement
- ;
-labeled_statement_no_short_if ::=
- IDENTIFIER COLON statement_no_short_if
- ;
-expression_statement ::=
- statement_expression SEMICOLON
- ;
-statement_expression ::=
- assignment
- | preincrement_expression
- | predecrement_expression
- | postincrement_expression
- | postdecrement_expression
- | method_invocation
- | class_instance_creation_expression
- ;
-if_then_statement ::=
- IF LPAREN expression RPAREN statement
- ;
-if_then_else_statement ::=
- IF LPAREN expression RPAREN statement_no_short_if
- ELSE statement
- ;
-if_then_else_statement_no_short_if ::=
- IF LPAREN expression RPAREN statement_no_short_if
- ELSE statement_no_short_if
- ;
-switch_statement ::=
- SWITCH LPAREN expression RPAREN switch_block
- ;
-switch_block ::=
- LBRACE switch_block_statement_groups switch_labels RBRACE
- | LBRACE switch_block_statement_groups RBRACE
- | LBRACE switch_labels RBRACE
- | LBRACE RBRACE
- ;
-switch_block_statement_groups ::=
- switch_block_statement_group
- | switch_block_statement_groups switch_block_statement_group
- ;
-switch_block_statement_group ::=
- switch_labels block_statements
- ;
-switch_labels ::=
- switch_label
- | switch_labels switch_label
- ;
-switch_label ::=
- CASE constant_expression COLON
- | DEFAULT COLON
- ;
-
-while_statement ::=
- WHILE LPAREN expression RPAREN statement
- ;
-while_statement_no_short_if ::=
- WHILE LPAREN expression RPAREN statement_no_short_if
- ;
-do_statement ::=
- DO statement WHILE LPAREN expression RPAREN SEMICOLON
- ;
-for_statement ::=
- FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
- for_update_opt RPAREN statement
- ;
-for_statement_no_short_if ::=
- FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
- for_update_opt RPAREN statement_no_short_if
- ;
-for_init_opt ::=
- | for_init
- ;
-for_init ::= statement_expression_list
- | local_variable_declaration
- ;
-for_update_opt ::=
- | for_update
- ;
-for_update ::= statement_expression_list
- ;
-statement_expression_list ::=
- statement_expression
- | statement_expression_list COMMA statement_expression
- ;
-
-identifier_opt ::=
- | IDENTIFIER
- ;
-
-break_statement ::=
- BREAK identifier_opt SEMICOLON
- ;
-
-continue_statement ::=
- CONTINUE identifier_opt SEMICOLON
- ;
-return_statement ::=
- RETURN expression_opt SEMICOLON
- ;
-throw_statement ::=
- THROW expression SEMICOLON
- ;
-synchronized_statement ::=
- SYNCHRONIZED LPAREN expression RPAREN block
- ;
-try_statement ::=
- TRY block catches
- | TRY block catches_opt finally
- ;
-catches_opt ::=
- | catches
- ;
-catches ::= catch_clause
- | catches catch_clause
- ;
-catch_clause ::=
- CATCH LPAREN formal_parameter RPAREN block
- ;
-finally ::= FINALLY block
- ;
-
-// 19.12) Expressions
-primary ::= primary_no_new_array
- | array_creation_expression
- ;
-primary_no_new_array ::=
- literal
- | THIS
- | LPAREN expression RPAREN
- | class_instance_creation_expression
- | field_access
- | method_invocation
- | array_access
- | primitive_type DOT CLASS
- | VOID DOT CLASS
- | array_type DOT CLASS
- | name DOT CLASS
- | name DOT THIS
- ;
-class_instance_creation_expression ::=
- NEW class_type LPAREN argument_list_opt RPAREN
- | NEW class_type LPAREN argument_list_opt RPAREN class_body
- | primary DOT NEW IDENTIFIER
- LPAREN argument_list_opt RPAREN
- | primary DOT NEW IDENTIFIER
- LPAREN argument_list_opt RPAREN class_body
- ;
-argument_list_opt ::=
- | argument_list
- ;
-argument_list ::=
- expression
- | argument_list COMMA expression
- ;
-array_creation_expression ::=
- NEW primitive_type dim_exprs dims_opt
- | NEW class_or_interface_type dim_exprs dims_opt
- | NEW primitive_type dims array_initializer
- | NEW class_or_interface_type dims array_initializer
- ;
-dim_exprs ::= dim_expr
- | dim_exprs dim_expr
- ;
-dim_expr ::= LBRACK expression RBRACK
- ;
-dims_opt ::=
- | dims
- ;
-dims ::= LBRACK RBRACK
- | dims LBRACK RBRACK
- ;
-field_access ::=
- primary DOT IDENTIFIER
- | SUPER DOT IDENTIFIER
- ;
-method_invocation ::=
- name LPAREN argument_list_opt RPAREN
- | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- ;
-array_access ::=
- name LBRACK expression RBRACK
- | primary_no_new_array LBRACK expression RBRACK
- ;
-postfix_expression ::=
- primary
- | name
- | postincrement_expression
- | postdecrement_expression
- ;
-postincrement_expression ::=
- postfix_expression PLUSPLUS
- ;
-postdecrement_expression ::=
- postfix_expression MINUSMINUS
- ;
-unary_expression ::=
- preincrement_expression
- | predecrement_expression
- | PLUS unary_expression
- | MINUS unary_expression
- | unary_expression_not_plus_minus
- ;
-preincrement_expression ::=
- PLUSPLUS unary_expression
- ;
-predecrement_expression ::=
- MINUSMINUS unary_expression
- ;
-unary_expression_not_plus_minus ::=
- postfix_expression
- | COMP unary_expression
- | NOT unary_expression
- | cast_expression
- ;
-cast_expression ::=
- LPAREN primitive_type dims_opt RPAREN unary_expression
- | LPAREN expression RPAREN unary_expression_not_plus_minus
- | LPAREN name dims RPAREN unary_expression_not_plus_minus
- ;
-multiplicative_expression ::=
- unary_expression
- | multiplicative_expression MULT unary_expression
- | multiplicative_expression DIV unary_expression
- | multiplicative_expression MOD unary_expression
- ;
-additive_expression ::=
- multiplicative_expression
- | additive_expression PLUS multiplicative_expression
- | additive_expression MINUS multiplicative_expression
- ;
-shift_expression ::=
- additive_expression
- | shift_expression LSHIFT additive_expression
- | shift_expression RSHIFT additive_expression
- | shift_expression URSHIFT additive_expression
- ;
-relational_expression ::=
- shift_expression
- | relational_expression LT shift_expression
- | relational_expression GT shift_expression
- | relational_expression LTEQ shift_expression
- | relational_expression GTEQ shift_expression
- | relational_expression INSTANCEOF reference_type
- ;
-equality_expression ::=
- relational_expression
- | equality_expression EQEQ relational_expression
- | equality_expression NOTEQ relational_expression
- ;
-and_expression ::=
- equality_expression
- | and_expression AND equality_expression
- ;
-exclusive_or_expression ::=
- and_expression
- | exclusive_or_expression XOR and_expression
- ;
-inclusive_or_expression ::=
- exclusive_or_expression
- | inclusive_or_expression OR exclusive_or_expression
- ;
-conditional_and_expression ::=
- inclusive_or_expression
- | conditional_and_expression ANDAND inclusive_or_expression
- ;
-conditional_or_expression ::=
- conditional_and_expression
- | conditional_or_expression OROR conditional_and_expression
- ;
-conditional_expression ::=
- conditional_or_expression
- | conditional_or_expression QUESTION expression
- COLON conditional_expression
- ;
-assignment_expression ::=
- conditional_expression
- | assignment
- ;
-assignment ::= left_hand_side assignment_operator assignment_expression
- ;
-left_hand_side ::=
- name
- | field_access
- | array_access
- ;
-assignment_operator ::=
- EQ
- | MULTEQ
- | DIVEQ
- | MODEQ
- | PLUSEQ
- | MINUSEQ
- | LSHIFTEQ
- | RSHIFTEQ
- | URSHIFTEQ
- | ANDEQ
- | XOREQ
- | OREQ
- ;
-expression_opt ::=
- | expression
- ;
-expression ::= assignment_expression
- ;
-constant_expression ::=
- expression
- ;
+++ /dev/null
-package Parse;
-
-import java_cup.runtime.*;
-
-/* Java 1.2 parser for CUP.
- * Copyright (C) 1998-2003 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This program is released under the terms of the GPL; see the file
- * COPYING for more details. There is NO WARRANTY on this code.
- */
-
-/*
-JDK 1.2 Features added:
- strictfp modifier.
- explicit_constructor_invocation ::= ...
- | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON ;
- field_access ::= ...
- | name DOT SUPER DOT IDENTIFIER ;
- method_invocation ::= ...
- | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN ;
- parenthesized expression, plain identifiers qualifying instance
- creation and explicit constructors, and array creation expression
- fixes from JLS2 (thanks to Eric Blake for pointing these out)
-*/
-parser code {:
- Lexer lexer;
-
- public Grm12(Lexer l) {
- this();
- lexer=l;
- }
-
- public void syntax_error(java_cup.runtime.Symbol current) {
- report_error("Syntax error (" + current.sym + ")", current);
- }
- public void report_error(String message, java_cup.runtime.Symbol info) {
- lexer.errorMsg(message, info);
- }
-:};
-
-scan with {: return lexer.nextToken(); :};
-
-terminal BOOLEAN; // primitive_type
-terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
-terminal FLOAT, DOUBLE; // floating_point_type
-terminal LBRACK, RBRACK; // array_type
-terminal java.lang.String IDENTIFIER; // name
-terminal DOT; // qualified_name
-terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
-terminal PACKAGE; // package_declaration
-terminal IMPORT; // import_declaration
-terminal PUBLIC, PROTECTED, PRIVATE; // modifier
-terminal STATIC; // modifier
-terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
-terminal CLASS; // class_declaration
-terminal EXTENDS; // super
-terminal IMPLEMENTS; // interfaces
-terminal VOID; // method_header
-terminal THROWS; // throws
-terminal THIS, SUPER; // explicit_constructor_invocation
-terminal INTERFACE; // interface_declaration
-terminal IF, ELSE; // if_then_statement, if_then_else_statement
-terminal SWITCH; // switch_statement
-terminal CASE, DEFAULT; // switch_label
-terminal DO, WHILE; // while_statement, do_statement
-terminal FOR; // for_statement
-terminal BREAK; // break_statement
-terminal CONTINUE; // continue_statement
-terminal RETURN; // return_statement
-terminal THROW; // throw_statement
-terminal TRY; // try_statement
-terminal CATCH; // catch_clause
-terminal FINALLY; // finally
-terminal NEW; // class_instance_creation_expression
-terminal PLUSPLUS; // postincrement_expression
-terminal MINUSMINUS; // postdecrement_expression
-terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
-terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
-terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
-terminal EQEQ, NOTEQ; // equality_expression
-terminal AND; // and_expression
-terminal XOR; // exclusive_or_expression
-terminal OR; // inclusive_or_expression
-terminal ANDAND; // conditional_and_expression
-terminal OROR; // conditional_or_expression
-terminal QUESTION; // conditional_expression
-terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
-terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
-terminal ANDEQ, XOREQ, OREQ; // assignment_operator
-
-terminal java.lang.Number INTEGER_LITERAL;
-terminal java.lang.Number FLOATING_POINT_LITERAL;
-terminal java.lang.Boolean BOOLEAN_LITERAL;
-terminal java.lang.Character CHARACTER_LITERAL;
-terminal java.lang.String STRING_LITERAL;
-terminal NULL_LITERAL;
-
-// Reserved but unused:
-terminal CONST, GOTO;
-// strictfp keyword, new in Java 1.2
-terminal STRICTFP;
-// lexer compatibility with Java 1.4
-terminal ASSERT;
-// lexer compatibility with Java 1.5
-terminal ELLIPSIS;
-terminal ENUM;
-
-// 19.2) The Syntactic Grammar
-non terminal goal;
-// 19.3) Lexical Structure
-non terminal literal;
-// 19.4) Types, Values, and Variables
-non terminal type, primitive_type, numeric_type;
-non terminal integral_type, floating_point_type;
-non terminal reference_type;
-non terminal class_or_interface_type;
-non terminal class_type, interface_type;
-non terminal array_type;
-// 19.5) Names
-non terminal name, simple_name, qualified_name;
-// 19.6) Packages
-non terminal compilation_unit;
-non terminal package_declaration_opt, package_declaration;
-non terminal import_declarations_opt, import_declarations;
-non terminal type_declarations_opt, type_declarations;
-non terminal import_declaration;
-non terminal single_type_import_declaration;
-non terminal type_import_on_demand_declaration;
-non terminal type_declaration;
-// 19.7) Productions used only in the LALR(1) grammar
-non terminal modifiers_opt, modifiers, modifier;
-// 19.8.1) Class Declaration
-non terminal class_declaration, super, super_opt;
-non terminal interfaces, interfaces_opt, interface_type_list;
-non terminal class_body;
-non terminal class_body_declarations, class_body_declarations_opt;
-non terminal class_body_declaration, class_member_declaration;
-// 19.8.2) Field Declarations
-non terminal field_declaration, variable_declarators, variable_declarator;
-non terminal variable_declarator_id, variable_initializer;
-// 19.8.3) Method Declarations
-non terminal method_declaration, method_header, method_declarator;
-non terminal formal_parameter_list_opt, formal_parameter_list;
-non terminal formal_parameter;
-non terminal throws_opt, throws;
-non terminal class_type_list, method_body;
-// 19.8.4) Static Initializers
-non terminal static_initializer;
-// 19.8.5) Constructor Declarations
-non terminal constructor_declaration, constructor_declarator;
-non terminal constructor_body;
-non terminal explicit_constructor_invocation;
-// 19.9.1) Interface Declarations
-non terminal interface_declaration;
-non terminal extends_interfaces_opt, extends_interfaces;
-non terminal interface_body;
-non terminal interface_member_declarations_opt, interface_member_declarations;
-non terminal interface_member_declaration, constant_declaration;
-non terminal abstract_method_declaration;
-// 19.10) Arrays
-non terminal array_initializer;
-non terminal variable_initializers;
-// 19.11) Blocks and Statements
-non terminal block;
-non terminal block_statements_opt, block_statements, block_statement;
-non terminal local_variable_declaration_statement, local_variable_declaration;
-non terminal statement, statement_no_short_if;
-non terminal statement_without_trailing_substatement;
-non terminal empty_statement;
-non terminal labeled_statement, labeled_statement_no_short_if;
-non terminal expression_statement, statement_expression;
-non terminal if_then_statement;
-non terminal if_then_else_statement, if_then_else_statement_no_short_if;
-non terminal switch_statement, switch_block;
-non terminal switch_block_statement_groups;
-non terminal switch_block_statement_group;
-non terminal switch_labels, switch_label;
-non terminal while_statement, while_statement_no_short_if;
-non terminal do_statement;
-non terminal for_statement, for_statement_no_short_if;
-non terminal for_init_opt, for_init;
-non terminal for_update_opt, for_update;
-non terminal statement_expression_list;
-non terminal identifier_opt;
-non terminal break_statement, continue_statement;
-non terminal return_statement, throw_statement;
-non terminal synchronized_statement, try_statement;
-non terminal catches_opt, catches, catch_clause;
-non terminal finally;
-// 19.12) Expressions
-non terminal primary, primary_no_new_array;
-non terminal class_instance_creation_expression;
-non terminal argument_list_opt, argument_list;
-non terminal array_creation_init, array_creation_uninit;
-non terminal dim_exprs, dim_expr, dims_opt, dims;
-non terminal field_access, method_invocation, array_access;
-non terminal postfix_expression;
-non terminal postincrement_expression, postdecrement_expression;
-non terminal unary_expression, unary_expression_not_plus_minus;
-non terminal preincrement_expression, predecrement_expression;
-non terminal cast_expression;
-non terminal multiplicative_expression, additive_expression;
-non terminal shift_expression, relational_expression, equality_expression;
-non terminal and_expression, exclusive_or_expression, inclusive_or_expression;
-non terminal conditional_and_expression, conditional_or_expression;
-non terminal conditional_expression, assignment_expression;
-non terminal assignment;
-non terminal assignment_operator;
-non terminal expression_opt, expression;
-non terminal constant_expression;
-
-start with goal;
-
-// 19.2) The Syntactic Grammar
-goal ::= compilation_unit
- ;
-
-// 19.3) Lexical Structure.
-literal ::= INTEGER_LITERAL
- | FLOATING_POINT_LITERAL
- | BOOLEAN_LITERAL
- | CHARACTER_LITERAL
- | STRING_LITERAL
- | NULL_LITERAL
- ;
-
-// 19.4) Types, Values, and Variables
-type ::= primitive_type
- | reference_type
- ;
-primitive_type ::=
- numeric_type
- | BOOLEAN
- ;
-numeric_type::= integral_type
- | floating_point_type
- ;
-integral_type ::=
- BYTE
- | SHORT
- | INT
- | LONG
- | CHAR
- ;
-floating_point_type ::=
- FLOAT
- | DOUBLE
- ;
-
-reference_type ::=
- class_or_interface_type
- | array_type
- ;
-class_or_interface_type ::= name;
-
-class_type ::= class_or_interface_type;
-interface_type ::= class_or_interface_type;
-
-array_type ::= primitive_type dims
- | name dims
- ;
-
-// 19.5) Names
-name ::= simple_name
- | qualified_name
- ;
-simple_name ::= IDENTIFIER
- ;
-qualified_name ::=
- name DOT IDENTIFIER
- ;
-
-// 19.6) Packages
-compilation_unit ::=
- package_declaration_opt
- import_declarations_opt
- type_declarations_opt
- ;
-package_declaration_opt ::= package_declaration | ;
-import_declarations_opt ::= import_declarations | ;
-type_declarations_opt ::= type_declarations | ;
-
-import_declarations ::=
- import_declaration
- | import_declarations import_declaration
- ;
-type_declarations ::=
- type_declaration
- | type_declarations type_declaration
- ;
-package_declaration ::=
- PACKAGE name SEMICOLON
- ;
-import_declaration ::=
- single_type_import_declaration
- | type_import_on_demand_declaration
- ;
-single_type_import_declaration ::=
- IMPORT name SEMICOLON
- ;
-type_import_on_demand_declaration ::=
- IMPORT name DOT MULT SEMICOLON
- ;
-type_declaration ::=
- class_declaration
- | interface_declaration
- | SEMICOLON
- ;
-
-// 19.7) Productions used only in the LALR(1) grammar
-modifiers_opt::=
- | modifiers
- ;
-modifiers ::= modifier
- | modifiers modifier
- ;
-modifier ::= PUBLIC | PROTECTED | PRIVATE
- | STATIC
- | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
- | STRICTFP // note that semantic analysis must check that the
- // context of the modifier allows strictfp.
- ;
-
-// 19.8) Classes
-
-// 19.8.1) Class Declaration:
-class_declaration ::=
- modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
- ;
-super ::= EXTENDS class_type
- ;
-super_opt ::=
- | super
- ;
-interfaces ::= IMPLEMENTS interface_type_list
- ;
-interfaces_opt::=
- | interfaces
- ;
-interface_type_list ::=
- interface_type
- | interface_type_list COMMA interface_type
- ;
-class_body ::= LBRACE class_body_declarations_opt RBRACE
- ;
-class_body_declarations_opt ::=
- | class_body_declarations ;
-class_body_declarations ::=
- class_body_declaration
- | class_body_declarations class_body_declaration
- ;
-class_body_declaration ::=
- class_member_declaration
- | static_initializer
- | constructor_declaration
- | block
- ;
-class_member_declaration ::=
- field_declaration
- | method_declaration
- /* repeat the prod for 'class_declaration' here: */
- | modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
- | interface_declaration
- | SEMICOLON
- ;
-
-// 19.8.2) Field Declarations
-field_declaration ::=
- modifiers_opt type variable_declarators SEMICOLON
- ;
-variable_declarators ::=
- variable_declarator
- | variable_declarators COMMA variable_declarator
- ;
-variable_declarator ::=
- variable_declarator_id
- | variable_declarator_id EQ variable_initializer
- ;
-variable_declarator_id ::=
- IDENTIFIER
- | variable_declarator_id LBRACK RBRACK
- ;
-variable_initializer ::=
- expression
- | array_initializer
- ;
-
-// 19.8.3) Method Declarations
-method_declaration ::=
- method_header method_body
- ;
-method_header ::=
- modifiers_opt type method_declarator throws_opt
- | modifiers_opt VOID method_declarator throws_opt
- ;
-method_declarator ::=
- IDENTIFIER LPAREN formal_parameter_list_opt RPAREN
- | method_declarator LBRACK RBRACK // deprecated
- // be careful; the above production also allows 'void foo() []'
- ;
-formal_parameter_list_opt ::=
- | formal_parameter_list
- ;
-formal_parameter_list ::=
- formal_parameter
- | formal_parameter_list COMMA formal_parameter
- ;
-formal_parameter ::=
- type variable_declarator_id
- | FINAL type variable_declarator_id
- ;
-throws_opt ::=
- | throws
- ;
-throws ::= THROWS class_type_list
- ;
-class_type_list ::=
- class_type
- | class_type_list COMMA class_type
- ;
-method_body ::= block
- | SEMICOLON
- ;
-
-// 19.8.4) Static Initializers
-static_initializer ::=
- STATIC block
- ;
-
-// 19.8.5) Constructor Declarations
-constructor_declaration ::=
- modifiers_opt constructor_declarator throws_opt
- constructor_body
- ;
-constructor_declarator ::=
- simple_name LPAREN formal_parameter_list_opt RPAREN
- ;
-constructor_body ::=
- LBRACE explicit_constructor_invocation
- block_statements RBRACE
- | LBRACE explicit_constructor_invocation RBRACE
- | LBRACE block_statements RBRACE
- | LBRACE RBRACE
- ;
-explicit_constructor_invocation ::=
- THIS LPAREN argument_list_opt RPAREN SEMICOLON
- | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- | name DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- ;
-
-// 19.9) Interfaces
-
-// 19.9.1) Interface Declarations
-interface_declaration ::=
- modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt
- interface_body
- ;
-extends_interfaces_opt ::=
- | extends_interfaces
- ;
-extends_interfaces ::=
- EXTENDS interface_type
- | extends_interfaces COMMA interface_type
- ;
-interface_body ::=
- LBRACE interface_member_declarations_opt RBRACE
- ;
-interface_member_declarations_opt ::=
- | interface_member_declarations
- ;
-interface_member_declarations ::=
- interface_member_declaration
- | interface_member_declarations interface_member_declaration
- ;
-interface_member_declaration ::=
- constant_declaration
- | abstract_method_declaration
- | class_declaration
- | interface_declaration
- | SEMICOLON
- ;
-constant_declaration ::=
- field_declaration
- // need to semantically check that modifiers of field declaration
- // include only PUBLIC, STATIC, or FINAL. Other modifiers are
- // disallowed.
- ;
-abstract_method_declaration ::=
- method_header SEMICOLON
- ;
-
-// 19.10) Arrays
-array_initializer ::=
- LBRACE variable_initializers COMMA RBRACE
- | LBRACE variable_initializers RBRACE
- | LBRACE COMMA RBRACE
- | LBRACE RBRACE
- ;
-variable_initializers ::=
- variable_initializer
- | variable_initializers COMMA variable_initializer
- ;
-
-// 19.11) Blocks and Statements
-block ::= LBRACE block_statements_opt RBRACE
- ;
-block_statements_opt ::=
- | block_statements
- ;
-block_statements ::=
- block_statement
- | block_statements block_statement
- ;
-block_statement ::=
- local_variable_declaration_statement
- | statement
- | class_declaration
- | interface_declaration
- ;
-local_variable_declaration_statement ::=
- local_variable_declaration SEMICOLON
- ;
-local_variable_declaration ::=
- type variable_declarators
- | FINAL type variable_declarators
- ;
-statement ::= statement_without_trailing_substatement
- | labeled_statement
- | if_then_statement
- | if_then_else_statement
- | while_statement
- | for_statement
- ;
-statement_no_short_if ::=
- statement_without_trailing_substatement
- | labeled_statement_no_short_if
- | if_then_else_statement_no_short_if
- | while_statement_no_short_if
- | for_statement_no_short_if
- ;
-statement_without_trailing_substatement ::=
- block
- | empty_statement
- | expression_statement
- | switch_statement
- | do_statement
- | break_statement
- | continue_statement
- | return_statement
- | synchronized_statement
- | throw_statement
- | try_statement
- ;
-empty_statement ::=
- SEMICOLON
- ;
-labeled_statement ::=
- IDENTIFIER COLON statement
- ;
-labeled_statement_no_short_if ::=
- IDENTIFIER COLON statement_no_short_if
- ;
-expression_statement ::=
- statement_expression SEMICOLON
- ;
-statement_expression ::=
- assignment
- | preincrement_expression
- | predecrement_expression
- | postincrement_expression
- | postdecrement_expression
- | method_invocation
- | class_instance_creation_expression
- ;
-if_then_statement ::=
- IF LPAREN expression RPAREN statement
- ;
-if_then_else_statement ::=
- IF LPAREN expression RPAREN statement_no_short_if
- ELSE statement
- ;
-if_then_else_statement_no_short_if ::=
- IF LPAREN expression RPAREN statement_no_short_if
- ELSE statement_no_short_if
- ;
-switch_statement ::=
- SWITCH LPAREN expression RPAREN switch_block
- ;
-switch_block ::=
- LBRACE switch_block_statement_groups switch_labels RBRACE
- | LBRACE switch_block_statement_groups RBRACE
- | LBRACE switch_labels RBRACE
- | LBRACE RBRACE
- ;
-switch_block_statement_groups ::=
- switch_block_statement_group
- | switch_block_statement_groups switch_block_statement_group
- ;
-switch_block_statement_group ::=
- switch_labels block_statements
- ;
-switch_labels ::=
- switch_label
- | switch_labels switch_label
- ;
-switch_label ::=
- CASE constant_expression COLON
- | DEFAULT COLON
- ;
-
-while_statement ::=
- WHILE LPAREN expression RPAREN statement
- ;
-while_statement_no_short_if ::=
- WHILE LPAREN expression RPAREN statement_no_short_if
- ;
-do_statement ::=
- DO statement WHILE LPAREN expression RPAREN SEMICOLON
- ;
-for_statement ::=
- FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
- for_update_opt RPAREN statement
- ;
-for_statement_no_short_if ::=
- FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
- for_update_opt RPAREN statement_no_short_if
- ;
-for_init_opt ::=
- | for_init
- ;
-for_init ::= statement_expression_list
- | local_variable_declaration
- ;
-for_update_opt ::=
- | for_update
- ;
-for_update ::= statement_expression_list
- ;
-statement_expression_list ::=
- statement_expression
- | statement_expression_list COMMA statement_expression
- ;
-
-identifier_opt ::=
- | IDENTIFIER
- ;
-
-break_statement ::=
- BREAK identifier_opt SEMICOLON
- ;
-
-continue_statement ::=
- CONTINUE identifier_opt SEMICOLON
- ;
-return_statement ::=
- RETURN expression_opt SEMICOLON
- ;
-throw_statement ::=
- THROW expression SEMICOLON
- ;
-synchronized_statement ::=
- SYNCHRONIZED LPAREN expression RPAREN block
- ;
-try_statement ::=
- TRY block catches
- | TRY block catches_opt finally
- ;
-catches_opt ::=
- | catches
- ;
-catches ::= catch_clause
- | catches catch_clause
- ;
-catch_clause ::=
- CATCH LPAREN formal_parameter RPAREN block
- ;
-finally ::= FINALLY block
- ;
-
-// 19.12) Expressions
-primary ::= primary_no_new_array
- | array_creation_init
- | array_creation_uninit
- ;
-primary_no_new_array ::=
- literal
- | THIS
- | LPAREN expression RPAREN
- | class_instance_creation_expression
- | field_access
- | method_invocation
- | array_access
- | primitive_type DOT CLASS
- | VOID DOT CLASS
- | array_type DOT CLASS
- | name DOT CLASS
- | name DOT THIS
- ;
-class_instance_creation_expression ::=
- NEW class_or_interface_type LPAREN argument_list_opt RPAREN
- | NEW class_or_interface_type LPAREN argument_list_opt RPAREN class_body
- | primary DOT NEW IDENTIFIER
- LPAREN argument_list_opt RPAREN
- | primary DOT NEW IDENTIFIER
- LPAREN argument_list_opt RPAREN class_body
- | name DOT NEW IDENTIFIER
- LPAREN argument_list_opt RPAREN
- | name DOT NEW IDENTIFIER
- LPAREN argument_list_opt RPAREN class_body
- ;
-argument_list_opt ::=
- | argument_list
- ;
-argument_list ::=
- expression
- | argument_list COMMA expression
- ;
-array_creation_uninit ::=
- NEW primitive_type dim_exprs dims_opt
- | NEW class_or_interface_type dim_exprs dims_opt
- ;
-array_creation_init ::=
- NEW primitive_type dims array_initializer
- | NEW class_or_interface_type dims array_initializer
- ;
-dim_exprs ::= dim_expr
- | dim_exprs dim_expr
- ;
-dim_expr ::= LBRACK expression RBRACK
- ;
-dims_opt ::=
- | dims
- ;
-dims ::= LBRACK RBRACK
- | dims LBRACK RBRACK
- ;
-field_access ::=
- primary DOT IDENTIFIER
- | SUPER DOT IDENTIFIER
- | name DOT SUPER DOT IDENTIFIER
- ;
-method_invocation ::=
- name LPAREN argument_list_opt RPAREN
- | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- ;
-array_access ::=
- name LBRACK expression RBRACK
- | primary_no_new_array LBRACK expression RBRACK
- | array_creation_init LBRACK expression RBRACK
- ;
-postfix_expression ::=
- primary
- | name
- | postincrement_expression
- | postdecrement_expression
- ;
-postincrement_expression ::=
- postfix_expression PLUSPLUS
- ;
-postdecrement_expression ::=
- postfix_expression MINUSMINUS
- ;
-unary_expression ::=
- preincrement_expression
- | predecrement_expression
- | PLUS unary_expression
- | MINUS unary_expression
- | unary_expression_not_plus_minus
- ;
-preincrement_expression ::=
- PLUSPLUS unary_expression
- ;
-predecrement_expression ::=
- MINUSMINUS unary_expression
- ;
-unary_expression_not_plus_minus ::=
- postfix_expression
- | COMP unary_expression
- | NOT unary_expression
- | cast_expression
- ;
-cast_expression ::=
- LPAREN primitive_type dims_opt RPAREN unary_expression
- | LPAREN expression RPAREN unary_expression_not_plus_minus
- | LPAREN name dims RPAREN unary_expression_not_plus_minus
- ;
-multiplicative_expression ::=
- unary_expression
- | multiplicative_expression MULT unary_expression
- | multiplicative_expression DIV unary_expression
- | multiplicative_expression MOD unary_expression
- ;
-additive_expression ::=
- multiplicative_expression
- | additive_expression PLUS multiplicative_expression
- | additive_expression MINUS multiplicative_expression
- ;
-shift_expression ::=
- additive_expression
- | shift_expression LSHIFT additive_expression
- | shift_expression RSHIFT additive_expression
- | shift_expression URSHIFT additive_expression
- ;
-relational_expression ::=
- shift_expression
- | relational_expression LT shift_expression
- | relational_expression GT shift_expression
- | relational_expression LTEQ shift_expression
- | relational_expression GTEQ shift_expression
- | relational_expression INSTANCEOF reference_type
- ;
-equality_expression ::=
- relational_expression
- | equality_expression EQEQ relational_expression
- | equality_expression NOTEQ relational_expression
- ;
-and_expression ::=
- equality_expression
- | and_expression AND equality_expression
- ;
-exclusive_or_expression ::=
- and_expression
- | exclusive_or_expression XOR and_expression
- ;
-inclusive_or_expression ::=
- exclusive_or_expression
- | inclusive_or_expression OR exclusive_or_expression
- ;
-conditional_and_expression ::=
- inclusive_or_expression
- | conditional_and_expression ANDAND inclusive_or_expression
- ;
-conditional_or_expression ::=
- conditional_and_expression
- | conditional_or_expression OROR conditional_and_expression
- ;
-conditional_expression ::=
- conditional_or_expression
- | conditional_or_expression QUESTION expression
- COLON conditional_expression
- ;
-assignment_expression ::=
- conditional_expression
- | assignment
- ;
-// semantic check necessary here to ensure a valid left-hand side.
-// allowing a parenthesized variable here on the lhs was introduced in
-// JLS 2; thanks to Eric Blake for pointing this out.
-assignment ::= postfix_expression assignment_operator assignment_expression
- ;
-assignment_operator ::=
- EQ
- | MULTEQ
- | DIVEQ
- | MODEQ
- | PLUSEQ
- | MINUSEQ
- | LSHIFTEQ
- | RSHIFTEQ
- | URSHIFTEQ
- | ANDEQ
- | XOREQ
- | OREQ
- ;
-expression_opt ::=
- | expression
- ;
-expression ::= assignment_expression
- ;
-constant_expression ::=
- expression
- ;
+++ /dev/null
-package Parse;
-
-import java_cup.runtime.*;
-
-/* Java 1.4 parser for CUP.
- * Copyright (C) 2002-2003 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This program is released under the terms of the GPL; see the file
- * COPYING for more details. There is NO WARRANTY on this code.
- */
-
-/*
-JDK 1.4 Features added:
- assertion statement.
- statement_without_trailing_substatement ::= ...
- | assert_statement ;
- assert_statement ::=
- ASSERT expression SEMICOLON
- | ASSERT expression COLON expression SEMICOLON
- ;
-*/
-parser code {:
- Lexer lexer;
-
- public Grm14(Lexer l) {
- this();
- lexer=l;
- }
-
- public void syntax_error(java_cup.runtime.Symbol current) {
- report_error("Syntax error (" + current.sym + ")", current);
- }
- public void report_error(String message, java_cup.runtime.Symbol info) {
- lexer.errorMsg(message, info);
- }
-:};
-
-scan with {: return lexer.nextToken(); :};
-
-terminal BOOLEAN; // primitive_type
-terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
-terminal FLOAT, DOUBLE; // floating_point_type
-terminal LBRACK, RBRACK; // array_type
-terminal java.lang.String IDENTIFIER; // name
-terminal DOT; // qualified_name
-terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
-terminal PACKAGE; // package_declaration
-terminal IMPORT; // import_declaration
-terminal PUBLIC, PROTECTED, PRIVATE; // modifier
-terminal STATIC; // modifier
-terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
-terminal CLASS; // class_declaration
-terminal EXTENDS; // super
-terminal IMPLEMENTS; // interfaces
-terminal VOID; // method_header
-terminal THROWS; // throws
-terminal THIS, SUPER; // explicit_constructor_invocation
-terminal INTERFACE; // interface_declaration
-terminal IF, ELSE; // if_then_statement, if_then_else_statement
-terminal SWITCH; // switch_statement
-terminal CASE, DEFAULT; // switch_label
-terminal DO, WHILE; // while_statement, do_statement
-terminal FOR; // for_statement
-terminal BREAK; // break_statement
-terminal CONTINUE; // continue_statement
-terminal RETURN; // return_statement
-terminal THROW; // throw_statement
-terminal TRY; // try_statement
-terminal CATCH; // catch_clause
-terminal FINALLY; // finally
-terminal NEW; // class_instance_creation_expression
-terminal PLUSPLUS; // postincrement_expression
-terminal MINUSMINUS; // postdecrement_expression
-terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
-terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
-terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
-terminal EQEQ, NOTEQ; // equality_expression
-terminal AND; // and_expression
-terminal XOR; // exclusive_or_expression
-terminal OR; // inclusive_or_expression
-terminal ANDAND; // conditional_and_expression
-terminal OROR; // conditional_or_expression
-terminal QUESTION; // conditional_expression
-terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
-terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
-terminal ANDEQ, XOREQ, OREQ; // assignment_operator
-
-terminal java.lang.Number INTEGER_LITERAL;
-terminal java.lang.Number FLOATING_POINT_LITERAL;
-terminal java.lang.Boolean BOOLEAN_LITERAL;
-terminal java.lang.Character CHARACTER_LITERAL;
-terminal java.lang.String STRING_LITERAL;
-terminal NULL_LITERAL;
-
-// Reserved but unused:
-terminal CONST, GOTO;
-// strictfp keyword, new in Java 1.2
-terminal STRICTFP;
-// assert keyword, new in Java 1.4
-terminal ASSERT; // assert_statement
-// lexer compatibility with Java 1.5
-terminal ELLIPSIS;
-terminal ENUM;
-
-// 19.2) The Syntactic Grammar
-non terminal goal;
-// 19.3) Lexical Structure
-non terminal literal;
-// 19.4) Types, Values, and Variables
-non terminal type, primitive_type, numeric_type;
-non terminal integral_type, floating_point_type;
-non terminal reference_type;
-non terminal class_or_interface_type;
-non terminal class_type, interface_type;
-non terminal array_type;
-// 19.5) Names
-non terminal name, simple_name, qualified_name;
-// 19.6) Packages
-non terminal compilation_unit;
-non terminal package_declaration_opt, package_declaration;
-non terminal import_declarations_opt, import_declarations;
-non terminal type_declarations_opt, type_declarations;
-non terminal import_declaration;
-non terminal single_type_import_declaration;
-non terminal type_import_on_demand_declaration;
-non terminal type_declaration;
-// 19.7) Productions used only in the LALR(1) grammar
-non terminal modifiers_opt, modifiers, modifier;
-// 19.8.1) Class Declaration
-non terminal class_declaration, super, super_opt;
-non terminal interfaces, interfaces_opt, interface_type_list;
-non terminal class_body;
-non terminal class_body_declarations, class_body_declarations_opt;
-non terminal class_body_declaration, class_member_declaration;
-// 19.8.2) Field Declarations
-non terminal field_declaration, variable_declarators, variable_declarator;
-non terminal variable_declarator_id, variable_initializer;
-// 19.8.3) Method Declarations
-non terminal method_declaration, method_header, method_declarator;
-non terminal formal_parameter_list_opt, formal_parameter_list;
-non terminal formal_parameter;
-non terminal throws_opt, throws;
-non terminal class_type_list, method_body;
-// 19.8.4) Static Initializers
-non terminal static_initializer;
-// 19.8.5) Constructor Declarations
-non terminal constructor_declaration, constructor_declarator;
-non terminal constructor_body;
-non terminal explicit_constructor_invocation;
-// 19.9.1) Interface Declarations
-non terminal interface_declaration;
-non terminal extends_interfaces_opt, extends_interfaces;
-non terminal interface_body;
-non terminal interface_member_declarations_opt, interface_member_declarations;
-non terminal interface_member_declaration, constant_declaration;
-non terminal abstract_method_declaration;
-// 19.10) Arrays
-non terminal array_initializer;
-non terminal variable_initializers;
-// 19.11) Blocks and Statements
-non terminal block;
-non terminal block_statements_opt, block_statements, block_statement;
-non terminal local_variable_declaration_statement, local_variable_declaration;
-non terminal statement, statement_no_short_if;
-non terminal statement_without_trailing_substatement;
-non terminal empty_statement;
-non terminal labeled_statement, labeled_statement_no_short_if;
-non terminal expression_statement, statement_expression;
-non terminal if_then_statement;
-non terminal if_then_else_statement, if_then_else_statement_no_short_if;
-non terminal switch_statement, switch_block;
-non terminal switch_block_statement_groups;
-non terminal switch_block_statement_group;
-non terminal switch_labels, switch_label;
-non terminal while_statement, while_statement_no_short_if;
-non terminal do_statement;
-non terminal for_statement, for_statement_no_short_if;
-non terminal for_init_opt, for_init;
-non terminal for_update_opt, for_update;
-non terminal statement_expression_list;
-non terminal identifier_opt;
-non terminal break_statement, continue_statement;
-non terminal return_statement, throw_statement;
-non terminal synchronized_statement, try_statement;
-non terminal catches_opt, catches, catch_clause;
-non terminal finally;
-non terminal assert_statement;
-// 19.12) Expressions
-non terminal primary, primary_no_new_array;
-non terminal class_instance_creation_expression;
-non terminal argument_list_opt, argument_list;
-non terminal array_creation_init, array_creation_uninit;
-non terminal dim_exprs, dim_expr, dims_opt, dims;
-non terminal field_access, method_invocation, array_access;
-non terminal postfix_expression;
-non terminal postincrement_expression, postdecrement_expression;
-non terminal unary_expression, unary_expression_not_plus_minus;
-non terminal preincrement_expression, predecrement_expression;
-non terminal cast_expression;
-non terminal multiplicative_expression, additive_expression;
-non terminal shift_expression, relational_expression, equality_expression;
-non terminal and_expression, exclusive_or_expression, inclusive_or_expression;
-non terminal conditional_and_expression, conditional_or_expression;
-non terminal conditional_expression, assignment_expression;
-non terminal assignment;
-non terminal assignment_operator;
-non terminal expression_opt, expression;
-non terminal constant_expression;
-
-start with goal;
-
-// 19.2) The Syntactic Grammar
-goal ::= compilation_unit
- ;
-
-// 19.3) Lexical Structure.
-literal ::= INTEGER_LITERAL
- | FLOATING_POINT_LITERAL
- | BOOLEAN_LITERAL
- | CHARACTER_LITERAL
- | STRING_LITERAL
- | NULL_LITERAL
- ;
-
-// 19.4) Types, Values, and Variables
-type ::= primitive_type
- | reference_type
- ;
-primitive_type ::=
- numeric_type
- | BOOLEAN
- ;
-numeric_type::= integral_type
- | floating_point_type
- ;
-integral_type ::=
- BYTE
- | SHORT
- | INT
- | LONG
- | CHAR
- ;
-floating_point_type ::=
- FLOAT
- | DOUBLE
- ;
-
-reference_type ::=
- class_or_interface_type
- | array_type
- ;
-class_or_interface_type ::= name;
-
-class_type ::= class_or_interface_type;
-interface_type ::= class_or_interface_type;
-
-array_type ::= primitive_type dims
- | name dims
- ;
-
-// 19.5) Names
-name ::= simple_name
- | qualified_name
- ;
-simple_name ::= IDENTIFIER
- ;
-qualified_name ::=
- name DOT IDENTIFIER
- ;
-
-// 19.6) Packages
-compilation_unit ::=
- package_declaration_opt
- import_declarations_opt
- type_declarations_opt
- ;
-package_declaration_opt ::= package_declaration | ;
-import_declarations_opt ::= import_declarations | ;
-type_declarations_opt ::= type_declarations | ;
-
-import_declarations ::=
- import_declaration
- | import_declarations import_declaration
- ;
-type_declarations ::=
- type_declaration
- | type_declarations type_declaration
- ;
-package_declaration ::=
- PACKAGE name SEMICOLON
- ;
-import_declaration ::=
- single_type_import_declaration
- | type_import_on_demand_declaration
- ;
-single_type_import_declaration ::=
- IMPORT name SEMICOLON
- ;
-type_import_on_demand_declaration ::=
- IMPORT name DOT MULT SEMICOLON
- ;
-type_declaration ::=
- class_declaration
- | interface_declaration
- | SEMICOLON
- ;
-
-// 19.7) Productions used only in the LALR(1) grammar
-modifiers_opt::=
- | modifiers
- ;
-modifiers ::= modifier
- | modifiers modifier
- ;
-modifier ::= PUBLIC | PROTECTED | PRIVATE
- | STATIC
- | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
- | STRICTFP // note that semantic analysis must check that the
- // context of the modifier allows strictfp.
- ;
-
-// 19.8) Classes
-
-// 19.8.1) Class Declaration:
-class_declaration ::=
- modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
- ;
-super ::= EXTENDS class_type
- ;
-super_opt ::=
- | super
- ;
-interfaces ::= IMPLEMENTS interface_type_list
- ;
-interfaces_opt::=
- | interfaces
- ;
-interface_type_list ::=
- interface_type
- | interface_type_list COMMA interface_type
- ;
-class_body ::= LBRACE class_body_declarations_opt RBRACE
- ;
-class_body_declarations_opt ::=
- | class_body_declarations ;
-class_body_declarations ::=
- class_body_declaration
- | class_body_declarations class_body_declaration
- ;
-class_body_declaration ::=
- class_member_declaration
- | static_initializer
- | constructor_declaration
- | block
- ;
-class_member_declaration ::=
- field_declaration
- | method_declaration
- /* repeat the prod for 'class_declaration' here: */
- | modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
- | interface_declaration
- | SEMICOLON
- ;
-
-// 19.8.2) Field Declarations
-field_declaration ::=
- modifiers_opt type variable_declarators SEMICOLON
- ;
-variable_declarators ::=
- variable_declarator
- | variable_declarators COMMA variable_declarator
- ;
-variable_declarator ::=
- variable_declarator_id
- | variable_declarator_id EQ variable_initializer
- ;
-variable_declarator_id ::=
- IDENTIFIER
- | variable_declarator_id LBRACK RBRACK
- ;
-variable_initializer ::=
- expression
- | array_initializer
- ;
-
-// 19.8.3) Method Declarations
-method_declaration ::=
- method_header method_body
- ;
-method_header ::=
- modifiers_opt type method_declarator throws_opt
- | modifiers_opt VOID method_declarator throws_opt
- ;
-method_declarator ::=
- IDENTIFIER LPAREN formal_parameter_list_opt RPAREN
- | method_declarator LBRACK RBRACK // deprecated
- // be careful; the above production also allows 'void foo() []'
- ;
-formal_parameter_list_opt ::=
- | formal_parameter_list
- ;
-formal_parameter_list ::=
- formal_parameter
- | formal_parameter_list COMMA formal_parameter
- ;
-formal_parameter ::=
- type variable_declarator_id
- | FINAL type variable_declarator_id
- ;
-throws_opt ::=
- | throws
- ;
-throws ::= THROWS class_type_list
- ;
-class_type_list ::=
- class_type
- | class_type_list COMMA class_type
- ;
-method_body ::= block
- | SEMICOLON
- ;
-
-// 19.8.4) Static Initializers
-static_initializer ::=
- STATIC block
- ;
-
-// 19.8.5) Constructor Declarations
-constructor_declaration ::=
- modifiers_opt constructor_declarator throws_opt
- constructor_body
- ;
-constructor_declarator ::=
- simple_name LPAREN formal_parameter_list_opt RPAREN
- ;
-constructor_body ::=
- LBRACE explicit_constructor_invocation
- block_statements RBRACE
- | LBRACE explicit_constructor_invocation RBRACE
- | LBRACE block_statements RBRACE
- | LBRACE RBRACE
- ;
-explicit_constructor_invocation ::=
- THIS LPAREN argument_list_opt RPAREN SEMICOLON
- | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON
- | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- ;
-
-// 19.9) Interfaces
-
-// 19.9.1) Interface Declarations
-interface_declaration ::=
- modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt
- interface_body
- ;
-extends_interfaces_opt ::=
- | extends_interfaces
- ;
-extends_interfaces ::=
- EXTENDS interface_type
- | extends_interfaces COMMA interface_type
- ;
-interface_body ::=
- LBRACE interface_member_declarations_opt RBRACE
- ;
-interface_member_declarations_opt ::=
- | interface_member_declarations
- ;
-interface_member_declarations ::=
- interface_member_declaration
- | interface_member_declarations interface_member_declaration
- ;
-interface_member_declaration ::=
- constant_declaration
- | abstract_method_declaration
- | class_declaration
- | interface_declaration
- | SEMICOLON
- ;
-constant_declaration ::=
- field_declaration
- // need to semantically check that modifiers of field declaration
- // include only PUBLIC, STATIC, or FINAL. Other modifiers are
- // disallowed.
- ;
-abstract_method_declaration ::=
- method_header SEMICOLON
- ;
-
-// 19.10) Arrays
-array_initializer ::=
- LBRACE variable_initializers COMMA RBRACE
- | LBRACE variable_initializers RBRACE
- | LBRACE COMMA RBRACE
- | LBRACE RBRACE
- ;
-variable_initializers ::=
- variable_initializer
- | variable_initializers COMMA variable_initializer
- ;
-
-// 19.11) Blocks and Statements
-block ::= LBRACE block_statements_opt RBRACE
- ;
-block_statements_opt ::=
- | block_statements
- ;
-block_statements ::=
- block_statement
- | block_statements block_statement
- ;
-block_statement ::=
- local_variable_declaration_statement
- | statement
- | class_declaration
- | interface_declaration
- ;
-local_variable_declaration_statement ::=
- local_variable_declaration SEMICOLON
- ;
-local_variable_declaration ::=
- type variable_declarators
- | FINAL type variable_declarators
- ;
-statement ::= statement_without_trailing_substatement
- | labeled_statement
- | if_then_statement
- | if_then_else_statement
- | while_statement
- | for_statement
- ;
-statement_no_short_if ::=
- statement_without_trailing_substatement
- | labeled_statement_no_short_if
- | if_then_else_statement_no_short_if
- | while_statement_no_short_if
- | for_statement_no_short_if
- ;
-statement_without_trailing_substatement ::=
- block
- | empty_statement
- | expression_statement
- | switch_statement
- | do_statement
- | break_statement
- | continue_statement
- | return_statement
- | synchronized_statement
- | throw_statement
- | try_statement
- | assert_statement
- ;
-empty_statement ::=
- SEMICOLON
- ;
-labeled_statement ::=
- IDENTIFIER COLON statement
- ;
-labeled_statement_no_short_if ::=
- IDENTIFIER COLON statement_no_short_if
- ;
-expression_statement ::=
- statement_expression SEMICOLON
- ;
-statement_expression ::=
- assignment
- | preincrement_expression
- | predecrement_expression
- | postincrement_expression
- | postdecrement_expression
- | method_invocation
- | class_instance_creation_expression
- ;
-if_then_statement ::=
- IF LPAREN expression RPAREN statement
- ;
-if_then_else_statement ::=
- IF LPAREN expression RPAREN statement_no_short_if
- ELSE statement
- ;
-if_then_else_statement_no_short_if ::=
- IF LPAREN expression RPAREN statement_no_short_if
- ELSE statement_no_short_if
- ;
-switch_statement ::=
- SWITCH LPAREN expression RPAREN switch_block
- ;
-switch_block ::=
- LBRACE switch_block_statement_groups switch_labels RBRACE
- | LBRACE switch_block_statement_groups RBRACE
- | LBRACE switch_labels RBRACE
- | LBRACE RBRACE
- ;
-switch_block_statement_groups ::=
- switch_block_statement_group
- | switch_block_statement_groups switch_block_statement_group
- ;
-switch_block_statement_group ::=
- switch_labels block_statements
- ;
-switch_labels ::=
- switch_label
- | switch_labels switch_label
- ;
-switch_label ::=
- CASE constant_expression COLON
- | DEFAULT COLON
- ;
-
-while_statement ::=
- WHILE LPAREN expression RPAREN statement
- ;
-while_statement_no_short_if ::=
- WHILE LPAREN expression RPAREN statement_no_short_if
- ;
-do_statement ::=
- DO statement WHILE LPAREN expression RPAREN SEMICOLON
- ;
-for_statement ::=
- FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
- for_update_opt RPAREN statement
- ;
-for_statement_no_short_if ::=
- FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
- for_update_opt RPAREN statement_no_short_if
- ;
-for_init_opt ::=
- | for_init
- ;
-for_init ::= statement_expression_list
- | local_variable_declaration
- ;
-for_update_opt ::=
- | for_update
- ;
-for_update ::= statement_expression_list
- ;
-statement_expression_list ::=
- statement_expression
- | statement_expression_list COMMA statement_expression
- ;
-
-identifier_opt ::=
- | IDENTIFIER
- ;
-
-break_statement ::=
- BREAK identifier_opt SEMICOLON
- ;
-
-continue_statement ::=
- CONTINUE identifier_opt SEMICOLON
- ;
-return_statement ::=
- RETURN expression_opt SEMICOLON
- ;
-throw_statement ::=
- THROW expression SEMICOLON
- ;
-synchronized_statement ::=
- SYNCHRONIZED LPAREN expression RPAREN block
- ;
-try_statement ::=
- TRY block catches
- | TRY block catches_opt finally
- ;
-catches_opt ::=
- | catches
- ;
-catches ::= catch_clause
- | catches catch_clause
- ;
-catch_clause ::=
- CATCH LPAREN formal_parameter RPAREN block
- ;
-finally ::= FINALLY block
- ;
-assert_statement ::=
- ASSERT expression SEMICOLON
- | ASSERT expression COLON expression SEMICOLON
- ;
-
-// 19.12) Expressions
-primary ::= primary_no_new_array
- | array_creation_init
- | array_creation_uninit
- ;
-primary_no_new_array ::=
- literal
- | THIS
- | LPAREN expression RPAREN
- | class_instance_creation_expression
- | field_access
- | method_invocation
- | array_access
- | primitive_type DOT CLASS
- | VOID DOT CLASS
- | array_type DOT CLASS
- | name DOT CLASS
- | name DOT THIS
- ;
-class_instance_creation_expression ::=
- NEW class_or_interface_type LPAREN argument_list_opt RPAREN
- | NEW class_or_interface_type LPAREN argument_list_opt RPAREN class_body
- | primary DOT NEW IDENTIFIER
- LPAREN argument_list_opt RPAREN
- | primary DOT NEW IDENTIFIER
- LPAREN argument_list_opt RPAREN class_body
- | name DOT NEW IDENTIFIER
- LPAREN argument_list_opt RPAREN
- | name DOT NEW IDENTIFIER
- LPAREN argument_list_opt RPAREN class_body
- ;
-argument_list_opt ::=
- | argument_list
- ;
-argument_list ::=
- expression
- | argument_list COMMA expression
- ;
-array_creation_uninit ::=
- NEW primitive_type dim_exprs dims_opt
- | NEW class_or_interface_type dim_exprs dims_opt
- ;
-array_creation_init ::=
- NEW primitive_type dims array_initializer
- | NEW class_or_interface_type dims array_initializer
- ;
-dim_exprs ::= dim_expr
- | dim_exprs dim_expr
- ;
-dim_expr ::= LBRACK expression RBRACK
- ;
-dims_opt ::=
- | dims
- ;
-dims ::= LBRACK RBRACK
- | dims LBRACK RBRACK
- ;
-field_access ::=
- primary DOT IDENTIFIER
- | SUPER DOT IDENTIFIER
- | name DOT SUPER DOT IDENTIFIER
- ;
-method_invocation ::=
- name LPAREN argument_list_opt RPAREN
- | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- ;
-array_access ::=
- name LBRACK expression RBRACK
- | primary_no_new_array LBRACK expression RBRACK
- | array_creation_init LBRACK expression RBRACK
- ;
-postfix_expression ::=
- primary
- | name
- | postincrement_expression
- | postdecrement_expression
- ;
-postincrement_expression ::=
- postfix_expression PLUSPLUS
- ;
-postdecrement_expression ::=
- postfix_expression MINUSMINUS
- ;
-unary_expression ::=
- preincrement_expression
- | predecrement_expression
- | PLUS unary_expression
- | MINUS unary_expression
- | unary_expression_not_plus_minus
- ;
-preincrement_expression ::=
- PLUSPLUS unary_expression
- ;
-predecrement_expression ::=
- MINUSMINUS unary_expression
- ;
-unary_expression_not_plus_minus ::=
- postfix_expression
- | COMP unary_expression
- | NOT unary_expression
- | cast_expression
- ;
-cast_expression ::=
- LPAREN primitive_type dims_opt RPAREN unary_expression
- | LPAREN expression RPAREN unary_expression_not_plus_minus
- | LPAREN name dims RPAREN unary_expression_not_plus_minus
- ;
-multiplicative_expression ::=
- unary_expression
- | multiplicative_expression MULT unary_expression
- | multiplicative_expression DIV unary_expression
- | multiplicative_expression MOD unary_expression
- ;
-additive_expression ::=
- multiplicative_expression
- | additive_expression PLUS multiplicative_expression
- | additive_expression MINUS multiplicative_expression
- ;
-shift_expression ::=
- additive_expression
- | shift_expression LSHIFT additive_expression
- | shift_expression RSHIFT additive_expression
- | shift_expression URSHIFT additive_expression
- ;
-relational_expression ::=
- shift_expression
- | relational_expression LT shift_expression
- | relational_expression GT shift_expression
- | relational_expression LTEQ shift_expression
- | relational_expression GTEQ shift_expression
- | relational_expression INSTANCEOF reference_type
- ;
-equality_expression ::=
- relational_expression
- | equality_expression EQEQ relational_expression
- | equality_expression NOTEQ relational_expression
- ;
-and_expression ::=
- equality_expression
- | and_expression AND equality_expression
- ;
-exclusive_or_expression ::=
- and_expression
- | exclusive_or_expression XOR and_expression
- ;
-inclusive_or_expression ::=
- exclusive_or_expression
- | inclusive_or_expression OR exclusive_or_expression
- ;
-conditional_and_expression ::=
- inclusive_or_expression
- | conditional_and_expression ANDAND inclusive_or_expression
- ;
-conditional_or_expression ::=
- conditional_and_expression
- | conditional_or_expression OROR conditional_and_expression
- ;
-conditional_expression ::=
- conditional_or_expression
- | conditional_or_expression QUESTION expression
- COLON conditional_expression
- ;
-assignment_expression ::=
- conditional_expression
- | assignment
- ;
-// semantic check necessary here to ensure a valid left-hand side.
-// allowing a parenthesized variable here on the lhs was introduced in
-// JLS 2; thanks to Eric Blake for pointing this out.
-assignment ::= postfix_expression assignment_operator assignment_expression
- ;
-assignment_operator ::=
- EQ
- | MULTEQ
- | DIVEQ
- | MODEQ
- | PLUSEQ
- | MINUSEQ
- | LSHIFTEQ
- | RSHIFTEQ
- | URSHIFTEQ
- | ANDEQ
- | XOREQ
- | OREQ
- ;
-expression_opt ::=
- | expression
- ;
-expression ::= assignment_expression
- ;
-constant_expression ::=
- expression
- ;
+++ /dev/null
-package Parse;
-
-import java_cup.runtime.*;
-
-/* Java 1.5 (JSR-14 + JSR-201) parser for CUP.
- * (Well, Java 1.5 as of 28 Jul 2003; it may change before official release)
- * Copyright (C) 2003 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This program is released under the terms of the GPL; see the file
- * COPYING for more details. There is NO WARRANTY on this code.
- */
-
-/*
-JSR-14 Features added:
-* parameterized types, including corrections from the spec released
- with the 2.2 prototype of the JSR-14 compiler. Arrays of parameterized
- types bounded by wildcards are slated to be added to Java 1.5 (although
- they are not supported by the 2.2 prototype); this grammar supports them.
- "Wildcard" types are supported as of the 28 jul 2003 release.
-
-JSR-201 Features added:
-* no changes for autoboxing
-* new-style for:
- foreach_statement ::=
- FOR LPAREN type variable_declarator_id COLON expression RPAREN
- statement
- // must check that first IDENTIFIER is 'each' and second IDENTIFIER
- // is 'in' -- CSA extension; not (yet?) officially adopted
- | FOR IDENTIFIER LPAREN type variable_declarator_id IDENTIFIER
- expression RPAREN statement
- ;
- foreach_statement_no_short_if ::=
- FOR LPAREN type variable_declarator_id COLON expression RPAREN
- statement_no_short_if
- // must check that first IDENTIFIER is 'each' and second IDENTIFIER
- // is 'in' -- CSA extension; not (yet?) officially adopted
- | FOR IDENTIFIER LPAREN type variable_declarator_id IDENTIFIER
- expression RPAREN statement_no_short_if
- ;
- statement ::= ...
- | foreach_statement ;
- statement_no_short_if ::= ...
- | foreach_statement_no_short_if ;
-
-* static import:
- static_single_type_import_declaration ::=
- IMPORT STATIC name SEMICOLON
- ;
- static_type_import_on_demand_declaration ::=
- IMPORT STATIC name DOT MULT SEMICOLON
- ;
- import_declaration ::= ...
- | static_single_type_import_declaration
- | static_type_import_on_demand_declaration
- ;
-* varargs:
- formal_parameter ::= ...
- | type ELLIPSIS IDENTIFIER
- | FINAL type ELLIPSIS IDENTIFIER
- ;
-* enum:
- enum_declaration ::=
- modifiers_opt ENUM IDENTIFIER interfaces_opt enum_body
- ;
- enum_body ::=
- LBRACE enum_constants_opt enum_body_declarations_opt RBRACE
- ;
- enum_constants_opt ::=
- | enum_constants
- ;
- enum_constants ::=
- enum_constant
- | enum_constants COMMA enum_constant
- ;
- enum_constant ::=
- IDENTIFIER enum_arguments_opt
- | IDENTIFIER enum_arguments_opt class_body
- ;
- enum_arguments_opt ::=
- | LPAREN argument_list_opt RPAREN
- ;
- enum_body_declarations_opt ::=
- | SEMICOLON class_body_declarations_opt
- ;
-*/
-parser code {:
- Lexer lexer;
-
- public Grm15(Lexer l) {
- this();
- lexer=l;
- }
-
- public void syntax_error(java_cup.runtime.Symbol current) {
- report_error("Syntax error (" + current.sym + ")", current);
- }
- public void report_error(String message, java_cup.runtime.Symbol info) {
- lexer.errorMsg(message, info);
- }
-:};
-
-scan with {: return lexer.nextToken(); :};
-
-terminal BOOLEAN; // primitive_type
-terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
-terminal FLOAT, DOUBLE; // floating_point_type
-terminal LBRACK, RBRACK; // array_type
-terminal java.lang.String IDENTIFIER; // name
-terminal DOT; // qualified_name
-terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
-terminal PACKAGE; // package_declaration
-terminal IMPORT; // import_declaration
-terminal PUBLIC, PROTECTED, PRIVATE; // modifier
-terminal STATIC; // modifier
-terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
-terminal CLASS; // class_declaration
-terminal EXTENDS; // super
-terminal IMPLEMENTS; // interfaces
-terminal VOID; // method_header
-terminal THROWS; // throws
-terminal THIS, SUPER; // explicit_constructor_invocation
-terminal INTERFACE; // interface_declaration
-terminal IF, ELSE; // if_then_statement, if_then_else_statement
-terminal SWITCH; // switch_statement
-terminal CASE, DEFAULT; // switch_label
-terminal DO, WHILE; // while_statement, do_statement
-terminal FOR; // for_statement
-terminal BREAK; // break_statement
-terminal CONTINUE; // continue_statement
-terminal RETURN; // return_statement
-terminal THROW; // throw_statement
-terminal TRY; // try_statement
-terminal CATCH; // catch_clause
-terminal FINALLY; // finally
-terminal NEW; // class_instance_creation_expression
-terminal PLUSPLUS; // postincrement_expression
-terminal MINUSMINUS; // postdecrement_expression
-terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
-terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
-terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
-terminal EQEQ, NOTEQ; // equality_expression
-terminal AND; // and_expression
-terminal XOR; // exclusive_or_expression
-terminal OR; // inclusive_or_expression
-terminal ANDAND; // conditional_and_expression
-terminal OROR; // conditional_or_expression
-terminal QUESTION; // conditional_expression
-terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
-terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
-terminal ANDEQ, XOREQ, OREQ; // assignment_operator
-
-terminal java.lang.Number INTEGER_LITERAL;
-terminal java.lang.Number FLOATING_POINT_LITERAL;
-terminal java.lang.Boolean BOOLEAN_LITERAL;
-terminal java.lang.Character CHARACTER_LITERAL;
-terminal java.lang.String STRING_LITERAL;
-terminal NULL_LITERAL;
-
-// Reserved but unused:
-terminal CONST, GOTO;
-// strictfp keyword, new in Java 1.2
-terminal STRICTFP;
-// assert keyword, new in Java 1.4
-terminal ASSERT; // assert_statement
-// ellipsis token for varargs, new in Java 1.5 (JSR-201)
-terminal ELLIPSIS;
-// enum keyword, new in Java 1.5 (JSR-201)
-terminal ENUM;
-
-// 19.2) The Syntactic Grammar
-non terminal goal;
-// 19.3) Lexical Structure
-non terminal literal;
-// 19.4) Types, Values, and Variables
-non terminal type, primitive_type, numeric_type;
-non terminal integral_type, floating_point_type;
-non terminal reference_type;
-non terminal class_or_interface_type;
-non terminal class_type, interface_type;
-non terminal array_type;
-// 19.5) Names
-non terminal name, simple_name, qualified_name;
-// 19.6) Packages
-non terminal compilation_unit;
-non terminal package_declaration_opt, package_declaration;
-non terminal import_declarations_opt, import_declarations;
-non terminal type_declarations_opt, type_declarations;
-non terminal import_declaration;
-non terminal single_type_import_declaration;
-non terminal type_import_on_demand_declaration;
-non terminal static_single_type_import_declaration;
-non terminal static_type_import_on_demand_declaration;
-non terminal type_declaration;
-// 19.7) Productions used only in the LALR(1) grammar
-non terminal modifiers_opt, modifiers, modifier;
-// 19.8.1) Class Declaration
-non terminal class_declaration, super, super_opt;
-non terminal interfaces, interfaces_opt, interface_type_list;
-non terminal class_body, class_body_opt;
-non terminal class_body_declarations, class_body_declarations_opt;
-non terminal class_body_declaration, class_member_declaration;
-// JSR-201) Enum Declaration
-non terminal enum_declaration;
-non terminal enum_body, enum_constants_opt, enum_constants, enum_constant;
-non terminal enum_arguments_opt, enum_body_declarations_opt;
-// 19.8.2) Field Declarations
-non terminal field_declaration, variable_declarators, variable_declarator;
-non terminal variable_declarator_id, variable_initializer;
-// 19.8.3) Method Declarations
-non terminal method_declaration, method_header, method_declarator;
-non terminal formal_parameter_list_opt, formal_parameter_list;
-non terminal formal_parameter;
-non terminal throws_opt, throws;
-non terminal class_type_list, method_body;
-// 19.8.4) Static Initializers
-non terminal static_initializer;
-// 19.8.5) Constructor Declarations
-non terminal constructor_declaration, constructor_declarator;
-non terminal constructor_body;
-non terminal explicit_constructor_invocation;
-// 19.9.1) Interface Declarations
-non terminal interface_declaration;
-non terminal extends_interfaces_opt, extends_interfaces;
-non terminal interface_body;
-non terminal interface_member_declarations_opt, interface_member_declarations;
-non terminal interface_member_declaration, constant_declaration;
-non terminal abstract_method_declaration;
-// 19.10) Arrays
-non terminal array_initializer;
-non terminal variable_initializers;
-// 19.11) Blocks and Statements
-non terminal block;
-non terminal block_statements_opt, block_statements, block_statement;
-non terminal local_variable_declaration_statement, local_variable_declaration;
-non terminal statement, statement_no_short_if;
-non terminal statement_without_trailing_substatement;
-non terminal empty_statement;
-non terminal labeled_statement, labeled_statement_no_short_if;
-non terminal expression_statement, statement_expression;
-non terminal if_then_statement;
-non terminal if_then_else_statement, if_then_else_statement_no_short_if;
-non terminal switch_statement, switch_block;
-non terminal switch_block_statement_groups;
-non terminal switch_block_statement_group;
-non terminal switch_labels, switch_label;
-non terminal while_statement, while_statement_no_short_if;
-non terminal do_statement;
-non terminal foreach_statement, foreach_statement_no_short_if;
-non terminal for_statement, for_statement_no_short_if;
-non terminal for_init_opt, for_init;
-non terminal for_update_opt, for_update;
-non terminal statement_expression_list;
-non terminal identifier_opt;
-non terminal break_statement, continue_statement;
-non terminal return_statement, throw_statement;
-non terminal synchronized_statement, try_statement;
-non terminal catches_opt, catches, catch_clause;
-non terminal finally;
-non terminal assert_statement;
-// 19.12) Expressions
-non terminal primary, primary_no_new_array;
-non terminal class_instance_creation_expression;
-non terminal argument_list_opt, argument_list;
-non terminal array_creation_init, array_creation_uninit;
-non terminal dim_exprs, dim_expr, dims_opt, dims;
-non terminal field_access, method_invocation, array_access;
-non terminal postfix_expression;
-non terminal postincrement_expression, postdecrement_expression;
-non terminal unary_expression, unary_expression_not_plus_minus;
-non terminal preincrement_expression, predecrement_expression;
-non terminal cast_expression;
-non terminal multiplicative_expression, additive_expression;
-non terminal shift_expression, relational_expression, equality_expression;
-non terminal and_expression, exclusive_or_expression, inclusive_or_expression;
-non terminal conditional_and_expression, conditional_or_expression;
-non terminal conditional_expression, assignment_expression;
-non terminal assignment;
-non terminal assignment_operator;
-non terminal expression_opt, expression;
-non terminal constant_expression;
-// JSR-14 2.1) Type Syntax 2.3) Handling Consecutive Type Brackets
-non terminal class_or_interface;
-non terminal type_variable;
-non terminal type_arguments, type_arguments_opt;
-non terminal type_argument_list;
-non terminal type_argument_list_1, reference_type_1;
-non terminal type_argument_list_2, reference_type_2;
-non terminal type_argument_list_3, reference_type_3;
-// JSR-14 2.2) Parameterized Type Declarations 2.3) Handling Consecutive...
-non terminal type_parameters, type_parameters_opt;
-non terminal type_parameter, type_parameter_list;
-non terminal type_parameter_1, type_parameter_list_1;
-non terminal type_bound, type_bound_opt;
-non terminal type_bound_1;
-non terminal additional_bound_list, additional_bound_list_opt;
-non terminal additional_bound_list_1;
-non terminal additional_bound;
-non terminal additional_bound_1;
-non terminal wildcard, wildcard_1, wildcard_2, wildcard_3;
-non terminal type_argument, type_argument_1, type_argument_2, type_argument_3;
-// not mentioned in JSR-14: need to reduce the precedence of instanceof
-// Alternatively, you can tweak the relational_expression production a little.
-non terminal instanceof_expression;
-//// expressions which are Not a Name
-non terminal postfix_expression_nn;
-non terminal unary_expression_nn;
-non terminal unary_expression_not_plus_minus_nn;
-non terminal multiplicative_expression_nn;
-non terminal additive_expression_nn;
-non terminal shift_expression_nn;
-non terminal relational_expression_nn;
-non terminal instanceof_expression_nn;
-non terminal equality_expression_nn;
-non terminal and_expression_nn;
-non terminal exclusive_or_expression_nn;
-non terminal inclusive_or_expression_nn;
-non terminal conditional_and_expression_nn;
-non terminal conditional_or_expression_nn;
-non terminal conditional_expression_nn;
-non terminal assignment_expression_nn;
-non terminal expression_nn;
-
-start with goal;
-
-// 19.2) The Syntactic Grammar
-goal ::= compilation_unit
- ;
-
-// 19.3) Lexical Structure.
-literal ::= INTEGER_LITERAL
- | FLOATING_POINT_LITERAL
- | BOOLEAN_LITERAL
- | CHARACTER_LITERAL
- | STRING_LITERAL
- | NULL_LITERAL
- ;
-
-// 19.4) Types, Values, and Variables
-type ::= primitive_type
- | reference_type
- ;
-primitive_type ::=
- numeric_type
- | BOOLEAN
- ;
-numeric_type::= integral_type
- | floating_point_type
- ;
-integral_type ::=
- BYTE
- | SHORT
- | INT
- | LONG
- | CHAR
- ;
-floating_point_type ::=
- FLOAT
- | DOUBLE
- ;
-
-reference_type ::=
- class_or_interface_type
-/* note that the 'type_variable' production will come out of the grammar
- * as a 'class_or_interface_type' with a 'simple_name'. The semantic
- * checker will have to resolve whether this is a class name or a type
- * variable */
- | array_type
- ;
-type_variable ::=
- IDENTIFIER
- ;
-class_or_interface ::=
- name
- | class_or_interface LT type_argument_list_1 DOT name
- ;
-class_or_interface_type ::=
- class_or_interface
- | class_or_interface LT type_argument_list_1
- ;
-
-class_type ::= class_or_interface_type;
-interface_type ::= class_or_interface_type;
-
-array_type ::= primitive_type dims
- // we have class_or_interface_type here even though only unbounded
- // wildcards are really allowed in the parameterization.
- // we have to expand this to avoid lookahead problems.
- | name dims
- | class_or_interface LT type_argument_list_1 DOT name dims
- | class_or_interface LT type_argument_list_1 dims
- ;
-
-type_arguments_opt ::= type_arguments | ;
-
-type_arguments ::=
- LT type_argument_list_1
- ;
-wildcard ::= QUESTION
- | QUESTION EXTENDS reference_type
- | QUESTION SUPER reference_type
- ;
-wildcard_1 ::= QUESTION GT
- | QUESTION EXTENDS reference_type_1
- | QUESTION SUPER reference_type_1
- ;
-wildcard_2 ::= QUESTION RSHIFT
- | QUESTION EXTENDS reference_type_2
- | QUESTION SUPER reference_type_2
- ;
-wildcard_3 ::= QUESTION URSHIFT
- | QUESTION EXTENDS reference_type_3
- | QUESTION SUPER reference_type_3
- ;
-reference_type_1 ::=
- reference_type GT
- | class_or_interface LT type_argument_list_2
- ;
-reference_type_2 ::=
- reference_type RSHIFT
- | class_or_interface LT type_argument_list_3
- ;
-reference_type_3 ::=
- reference_type URSHIFT
- ;
-type_argument_list ::=
- type_argument
- | type_argument_list COMMA type_argument
- ;
-type_argument_list_1 ::=
- type_argument_1
- | type_argument_list COMMA type_argument_1
- ;
-type_argument_list_2 ::=
- type_argument_2
- | type_argument_list COMMA type_argument_2
- ;
-type_argument_list_3 ::=
- type_argument_3
- | type_argument_list COMMA type_argument_3
- ;
-type_argument ::=
- reference_type
- | wildcard
- ;
-type_argument_1 ::=
- reference_type_1
- | wildcard_1
- ;
-type_argument_2 ::=
- reference_type_2
- | wildcard_2
- ;
-type_argument_3 ::=
- reference_type_3
- | wildcard_3
- ;
-
-// 19.5) Names
-name ::= simple_name
- | qualified_name
- ;
-simple_name ::= IDENTIFIER
- ;
-qualified_name ::=
- name DOT IDENTIFIER
- ;
-
-// 19.6) Packages
-compilation_unit ::=
- package_declaration_opt
- import_declarations_opt
- type_declarations_opt
- ;
-package_declaration_opt ::= package_declaration | ;
-import_declarations_opt ::= import_declarations | ;
-type_declarations_opt ::= type_declarations | ;
-
-import_declarations ::=
- import_declaration
- | import_declarations import_declaration
- ;
-type_declarations ::=
- type_declaration
- | type_declarations type_declaration
- ;
-package_declaration ::=
- PACKAGE name SEMICOLON
- ;
-import_declaration ::=
- single_type_import_declaration
- | type_import_on_demand_declaration
- | static_single_type_import_declaration
- | static_type_import_on_demand_declaration
- ;
-single_type_import_declaration ::=
- IMPORT name SEMICOLON
- ;
-static_single_type_import_declaration ::=
- IMPORT STATIC name SEMICOLON
- ;
-type_import_on_demand_declaration ::=
- IMPORT name DOT MULT SEMICOLON
- ;
-static_type_import_on_demand_declaration ::=
- IMPORT STATIC name DOT MULT SEMICOLON
- ;
-type_declaration ::=
- class_declaration
- | enum_declaration
- | interface_declaration
- | SEMICOLON
- ;
-
-// 19.7) Productions used only in the LALR(1) grammar
-modifiers_opt::=
- | modifiers
- ;
-modifiers ::= modifier
- | modifiers modifier
- ;
-modifier ::= PUBLIC | PROTECTED | PRIVATE
- | STATIC
- | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
- | STRICTFP // note that semantic analysis must check that the
- // context of the modifier allows strictfp.
- ;
-
-// 19.8) Classes
-
-// 19.8.1) Class Declaration:
-class_declaration ::=
- modifiers_opt CLASS IDENTIFIER type_parameters_opt
- super_opt interfaces_opt class_body
- ;
-super ::= EXTENDS class_type
- ;
-super_opt ::=
- | super
- ;
-interfaces ::= IMPLEMENTS interface_type_list
- ;
-interfaces_opt::=
- | interfaces
- ;
-interface_type_list ::=
- interface_type
- | interface_type_list COMMA interface_type
- ;
-class_body ::= LBRACE class_body_declarations_opt RBRACE
- ;
-class_body_opt ::=
- | class_body ;
-class_body_declarations_opt ::=
- | class_body_declarations ;
-class_body_declarations ::=
- class_body_declaration
- | class_body_declarations class_body_declaration
- ;
-class_body_declaration ::=
- class_member_declaration
- | static_initializer
- | constructor_declaration
- | block
- ;
-class_member_declaration ::=
- field_declaration
- | method_declaration
- /* repeat the prod for 'class_declaration' here: */
- | modifiers_opt CLASS IDENTIFIER type_parameters_opt super_opt interfaces_opt class_body
- | enum_declaration
- | interface_declaration
- | SEMICOLON
- ;
-
-// JSR-201) Enum Declaration
-enum_declaration ::=
- modifiers_opt ENUM IDENTIFIER interfaces_opt enum_body
- ;
-enum_body ::=
- LBRACE enum_constants_opt enum_body_declarations_opt RBRACE
- ;
-enum_constants_opt ::=
- | enum_constants
- ;
-enum_constants ::=
- enum_constant
- | enum_constants COMMA enum_constant
- ;
-enum_constant ::=
- IDENTIFIER enum_arguments_opt
- | IDENTIFIER enum_arguments_opt class_body
- ;
-enum_arguments_opt ::=
- | LPAREN argument_list_opt RPAREN
- ;
-enum_body_declarations_opt ::=
- | SEMICOLON class_body_declarations_opt
- ;
-
-// 19.8.2) Field Declarations
-field_declaration ::=
- modifiers_opt type variable_declarators SEMICOLON
- ;
-variable_declarators ::=
- variable_declarator
- | variable_declarators COMMA variable_declarator
- ;
-variable_declarator ::=
- variable_declarator_id
- | variable_declarator_id EQ variable_initializer
- ;
-variable_declarator_id ::=
- IDENTIFIER
- | variable_declarator_id LBRACK RBRACK
- ;
-variable_initializer ::=
- expression
- | array_initializer
- ;
-
-// 19.8.3) Method Declarations
-method_declaration ::=
- method_header method_body
- ;
-method_header ::=
- // have to expand type_parameters_opt here so that we don't
- // force an early decision of whether this is a field_declaration
- // or a method_declaration (the type_parameters_opt would have to
- // be reduced when we see the 'type' if this was a method declaration,
- // but it might still turn out to be a field declaration).
- modifiers_opt type method_declarator throws_opt
- | modifiers_opt LT type_parameter_list_1 type method_declarator throws_opt
- | modifiers_opt VOID method_declarator throws_opt
- | modifiers_opt LT type_parameter_list_1 VOID method_declarator throws_opt
- ;
-method_declarator ::=
- IDENTIFIER LPAREN formal_parameter_list_opt RPAREN
- | method_declarator LBRACK RBRACK // deprecated
- // be careful; the above production also allows 'void foo() []'
- ;
-formal_parameter_list_opt ::=
- | formal_parameter_list
- ;
-formal_parameter_list ::=
- formal_parameter
- | formal_parameter_list COMMA formal_parameter
- ;
-formal_parameter ::=
- type variable_declarator_id
- | FINAL type variable_declarator_id
- // careful, productions below allow varargs in non-final positions.
- | type ELLIPSIS IDENTIFIER
- | FINAL type ELLIPSIS IDENTIFIER
- ;
-throws_opt ::=
- | throws
- ;
-throws ::= THROWS class_type_list
- ;
-class_type_list ::=
- class_type
- | class_type_list COMMA class_type
- ;
-method_body ::= block
- | SEMICOLON
- ;
-
-// 19.8.4) Static Initializers
-static_initializer ::=
- STATIC block
- ;
-
-// 19.8.5) Constructor Declarations
-constructor_declaration ::=
- modifiers_opt constructor_declarator
- throws_opt constructor_body
- | modifiers_opt LT type_parameter_list_1 constructor_declarator
- throws_opt constructor_body
- ;
-constructor_declarator ::=
- simple_name LPAREN formal_parameter_list_opt RPAREN
- ;
-constructor_body ::=
- LBRACE explicit_constructor_invocation
- block_statements RBRACE
- | LBRACE explicit_constructor_invocation RBRACE
- | LBRACE block_statements RBRACE
- | LBRACE RBRACE
- ;
-explicit_constructor_invocation ::=
- THIS LPAREN argument_list_opt RPAREN SEMICOLON
- | type_arguments THIS LPAREN argument_list_opt RPAREN SEMICOLON
- | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- | type_arguments SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- | primary DOT type_arguments SUPER
- LPAREN argument_list_opt RPAREN SEMICOLON
- | name DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- | name DOT type_arguments SUPER LPAREN argument_list_opt RPAREN SEMICOLON
- ;
-
-// 19.9) Interfaces
-
-// 19.9.1) Interface Declarations
-interface_declaration ::=
- modifiers_opt INTERFACE IDENTIFIER type_parameters_opt
- extends_interfaces_opt interface_body
- ;
-extends_interfaces_opt ::=
- | extends_interfaces
- ;
-extends_interfaces ::=
- EXTENDS interface_type
- | extends_interfaces COMMA interface_type
- ;
-interface_body ::=
- LBRACE interface_member_declarations_opt RBRACE
- ;
-interface_member_declarations_opt ::=
- | interface_member_declarations
- ;
-interface_member_declarations ::=
- interface_member_declaration
- | interface_member_declarations interface_member_declaration
- ;
-interface_member_declaration ::=
- constant_declaration
- | abstract_method_declaration
- | class_declaration
- | enum_declaration
- | interface_declaration
- | SEMICOLON
- ;
-constant_declaration ::=
- field_declaration
- // need to semantically check that modifiers of field declaration
- // include only PUBLIC, STATIC, or FINAL. Other modifiers are
- // disallowed.
- ;
-abstract_method_declaration ::=
- method_header SEMICOLON
- ;
-
-// 19.10) Arrays
-array_initializer ::=
- LBRACE variable_initializers COMMA RBRACE
- | LBRACE variable_initializers RBRACE
- | LBRACE COMMA RBRACE
- | LBRACE RBRACE
- ;
-variable_initializers ::=
- variable_initializer
- | variable_initializers COMMA variable_initializer
- ;
-
-// 19.11) Blocks and Statements
-block ::= LBRACE block_statements_opt RBRACE
- ;
-block_statements_opt ::=
- | block_statements
- ;
-block_statements ::=
- block_statement
- | block_statements block_statement
- ;
-block_statement ::=
- local_variable_declaration_statement
- | statement
- | class_declaration
- | enum_declaration
- | interface_declaration
- ;
-local_variable_declaration_statement ::=
- local_variable_declaration SEMICOLON
- ;
-/* jikes expands 'type' in production for local_variable_declaration to
- * avoid reduce-reduce conflict: given 'name [' the grammar can't decide
- * whether this is going to be a type (starting the local_variable_declaration)
- * or an array access expression. */
-local_variable_declaration ::=
- type variable_declarators
- // you may want to accept 'modifiers' here instead of just FINAL
- // to produce better error messages.
- | FINAL type variable_declarators
- ;
-statement ::= statement_without_trailing_substatement
- | labeled_statement
- | if_then_statement
- | if_then_else_statement
- | while_statement
- | for_statement
- | foreach_statement
- ;
-statement_no_short_if ::=
- statement_without_trailing_substatement
- | labeled_statement_no_short_if
- | if_then_else_statement_no_short_if
- | while_statement_no_short_if
- | for_statement_no_short_if
- | foreach_statement_no_short_if
- ;
-statement_without_trailing_substatement ::=
- block
- | empty_statement
- | expression_statement
- | switch_statement
- | do_statement
- | break_statement
- | continue_statement
- | return_statement
- | synchronized_statement
- | throw_statement
- | try_statement
- | assert_statement
- ;
-empty_statement ::=
- SEMICOLON
- ;
-labeled_statement ::=
- IDENTIFIER COLON statement
- ;
-labeled_statement_no_short_if ::=
- IDENTIFIER COLON statement_no_short_if
- ;
-expression_statement ::=
- statement_expression SEMICOLON
- ;
-statement_expression ::=
- assignment
- | preincrement_expression
- | predecrement_expression
- | postincrement_expression
- | postdecrement_expression
- | method_invocation
- | class_instance_creation_expression
- ;
-if_then_statement ::=
- IF LPAREN expression RPAREN statement
- ;
-if_then_else_statement ::=
- IF LPAREN expression RPAREN statement_no_short_if
- ELSE statement
- ;
-if_then_else_statement_no_short_if ::=
- IF LPAREN expression RPAREN statement_no_short_if
- ELSE statement_no_short_if
- ;
-switch_statement ::=
- SWITCH LPAREN expression RPAREN switch_block
- ;
-switch_block ::=
- LBRACE switch_block_statement_groups switch_labels RBRACE
- | LBRACE switch_block_statement_groups RBRACE
- | LBRACE switch_labels RBRACE
- | LBRACE RBRACE
- ;
-switch_block_statement_groups ::=
- switch_block_statement_group
- | switch_block_statement_groups switch_block_statement_group
- ;
-switch_block_statement_group ::=
- switch_labels block_statements
- ;
-switch_labels ::=
- switch_label
- | switch_labels switch_label
- ;
-switch_label ::=
- CASE constant_expression COLON
- | DEFAULT COLON
- ;
-
-while_statement ::=
- WHILE LPAREN expression RPAREN statement
- ;
-while_statement_no_short_if ::=
- WHILE LPAREN expression RPAREN statement_no_short_if
- ;
-do_statement ::=
- DO statement WHILE LPAREN expression RPAREN SEMICOLON
- ;
-foreach_statement ::=
- FOR LPAREN type variable_declarator_id COLON expression RPAREN
- statement
- // must check that first IDENTIFIER is 'each' and second IDENTIFIER
- // is 'in'
- | FOR IDENTIFIER LPAREN type variable_declarator_id IDENTIFIER
- expression RPAREN statement
- ;
-foreach_statement_no_short_if ::=
- FOR LPAREN type variable_declarator_id COLON expression RPAREN
- statement_no_short_if
- // must check that first IDENTIFIER is 'each' and second IDENTIFIER
- // is 'in'
- | FOR IDENTIFIER LPAREN type variable_declarator_id IDENTIFIER
- expression RPAREN statement_no_short_if
- ;
-for_statement ::=
- FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
- for_update_opt RPAREN statement
- ;
-for_statement_no_short_if ::=
- FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
- for_update_opt RPAREN statement_no_short_if
- ;
-for_init_opt ::=
- | for_init
- ;
-for_init ::= statement_expression_list
- | local_variable_declaration
- ;
-for_update_opt ::=
- | for_update
- ;
-for_update ::= statement_expression_list
- ;
-statement_expression_list ::=
- statement_expression
- | statement_expression_list COMMA statement_expression
- ;
-
-identifier_opt ::=
- | IDENTIFIER
- ;
-
-break_statement ::=
- BREAK identifier_opt SEMICOLON
- ;
-
-continue_statement ::=
- CONTINUE identifier_opt SEMICOLON
- ;
-return_statement ::=
- RETURN expression_opt SEMICOLON
- ;
-throw_statement ::=
- THROW expression SEMICOLON
- ;
-synchronized_statement ::=
- SYNCHRONIZED LPAREN expression RPAREN block
- ;
-try_statement ::=
- TRY block catches
- | TRY block catches_opt finally
- ;
-catches_opt ::=
- | catches
- ;
-catches ::= catch_clause
- | catches catch_clause
- ;
-catch_clause ::=
- CATCH LPAREN formal_parameter RPAREN block
- ;
-finally ::= FINALLY block
- ;
-assert_statement ::=
- ASSERT expression SEMICOLON
- | ASSERT expression COLON expression SEMICOLON
- ;
-
-// 19.12) Expressions
-primary ::= primary_no_new_array
- | array_creation_init
- | array_creation_uninit
- ;
-primary_no_new_array ::=
- literal
- | THIS
- | LPAREN name RPAREN
- | LPAREN expression_nn RPAREN
- | class_instance_creation_expression
- | field_access
- | method_invocation
- | array_access
- | name DOT THIS
- | VOID DOT CLASS
- // "Type DOT CLASS", but expanded
- | primitive_type DOT CLASS
- | primitive_type dims DOT CLASS
- | name DOT CLASS
- | name dims DOT CLASS
-// the following two productions are part of the expansion of
-// 'type DOT CLASS' but are not actually allowed, as they involve params.
-// [see msg from Neal Gafter <3F219367.3070903@sun.com> 25-jul-2003]
-// | class_or_interface type_arguments DOT name dims DOT CLASS
-// | class_or_interface LT type_argument_list_1 dims DOT CLASS
- ;
-// grammar distributed with prototype 2.2 is in error; the following is correct
-// [ Neal Gafter, <3F2577E0.3090008@sun.com> ]
-class_instance_creation_expression ::=
- NEW class_or_interface_type LPAREN argument_list_opt RPAREN class_body_opt
- | NEW type_arguments class_or_interface_type LPAREN argument_list_opt RPAREN class_body_opt
- | primary DOT NEW type_arguments_opt IDENTIFIER type_arguments_opt
- LPAREN argument_list_opt RPAREN class_body_opt
- | name DOT NEW type_arguments_opt IDENTIFIER type_arguments_opt
- LPAREN argument_list_opt RPAREN class_body_opt
- ;
-argument_list_opt ::=
- | argument_list
- ;
-argument_list ::=
- expression
- | argument_list COMMA expression
- ;
-array_creation_uninit ::=
- NEW primitive_type dim_exprs dims_opt
- | NEW class_or_interface_type dim_exprs dims_opt
- ;
-array_creation_init ::=
- NEW primitive_type dims array_initializer
- | NEW class_or_interface_type dims array_initializer
- ;
-dim_exprs ::= dim_expr
- | dim_exprs dim_expr
- ;
-dim_expr ::= LBRACK expression RBRACK
- ;
-dims_opt ::=
- | dims
- ;
-dims ::= LBRACK RBRACK
- | dims LBRACK RBRACK
- ;
-field_access ::=
- primary DOT IDENTIFIER
- | SUPER DOT IDENTIFIER
- | name DOT SUPER DOT IDENTIFIER
- ;
-method_invocation ::=
- name LPAREN argument_list_opt RPAREN
-// the following production appeared in the prototype 2.2 spec, but it
-// introduces ambiguities in the grammar (consider the expression
-// A((B)<C,D>E());
-// which could be either an invocation on E or two boolean comparisons).
-// Neal Gafter has assured me that this production should be removed
-// from the grammar. <3F256C06.7000600@sun.com>
-// | type_arguments name LPAREN argument_list_opt RPAREN
- | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- | primary DOT type_arguments IDENTIFIER LPAREN argument_list_opt RPAREN
- | name DOT type_arguments IDENTIFIER LPAREN argument_list_opt RPAREN
- | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- | SUPER DOT type_arguments IDENTIFIER LPAREN argument_list_opt RPAREN
- | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- | name DOT SUPER DOT type_arguments IDENTIFIER LPAREN argument_list_opt RPAREN
- ;
-array_access ::=
- name LBRACK expression RBRACK
- | primary_no_new_array LBRACK expression RBRACK
- | array_creation_init LBRACK expression RBRACK
- ;
-postfix_expression ::=
- primary
- | name
- | postincrement_expression
- | postdecrement_expression
- ;
-postincrement_expression ::=
- postfix_expression PLUSPLUS
- ;
-postdecrement_expression ::=
- postfix_expression MINUSMINUS
- ;
-unary_expression ::=
- preincrement_expression
- | predecrement_expression
- | PLUS unary_expression
- | MINUS unary_expression
- | unary_expression_not_plus_minus
- ;
-preincrement_expression ::=
- PLUSPLUS unary_expression
- ;
-predecrement_expression ::=
- MINUSMINUS unary_expression
- ;
-unary_expression_not_plus_minus ::=
- postfix_expression
- | COMP unary_expression
- | NOT unary_expression
- | cast_expression
- ;
-// This parsing technique was discovered by Eric Blake <ebb9@email.byu.edu>
-// We solving grammar ambiguities with between parenthesized less-than
-// relational operations and type casts with a slightly-more-complicated
-// cast_expression production.
-// Illustrative example: LPAREN name LT name ...
-// is this going to be a cast_expression or a relational_expression?
-// canonically, this production is:
-// cast_expression ::= LPAREN type RPAREN unary_expression_not_plus_minus
-cast_expression ::=
- LPAREN primitive_type dims_opt RPAREN unary_expression
- | LPAREN name RPAREN unary_expression_not_plus_minus
- | LPAREN name dims RPAREN unary_expression_not_plus_minus
- | LPAREN name LT type_argument_list_1 dims_opt RPAREN
- unary_expression_not_plus_minus
- | LPAREN name LT type_argument_list_1 DOT
- class_or_interface_type dims_opt RPAREN
- unary_expression_not_plus_minus
- ;
-multiplicative_expression ::=
- unary_expression
- | multiplicative_expression MULT unary_expression
- | multiplicative_expression DIV unary_expression
- | multiplicative_expression MOD unary_expression
- ;
-additive_expression ::=
- multiplicative_expression
- | additive_expression PLUS multiplicative_expression
- | additive_expression MINUS multiplicative_expression
- ;
-shift_expression ::=
- additive_expression
- | shift_expression LSHIFT additive_expression
- | shift_expression RSHIFT additive_expression
- | shift_expression URSHIFT additive_expression
- ;
-relational_expression ::=
- shift_expression
- | relational_expression LT shift_expression
- | relational_expression GT shift_expression
- | relational_expression LTEQ shift_expression
- | relational_expression GTEQ shift_expression
- ;
-// we lower the precendence of instanceof to resolve a grammar ambiguity.
-// semantics are unchanged, since relational expressions do not operate
-// on boolean. Eric Blake had a different solution here, where he
-// used the production 'shift_expression LT shift_expression' to solve
-// the same problem.
-instanceof_expression ::=
- relational_expression
- | instanceof_expression INSTANCEOF reference_type
- ;
-equality_expression ::=
- instanceof_expression
- | equality_expression EQEQ instanceof_expression
- | equality_expression NOTEQ instanceof_expression
- ;
-and_expression ::=
- equality_expression
- | and_expression AND equality_expression
- ;
-exclusive_or_expression ::=
- and_expression
- | exclusive_or_expression XOR and_expression
- ;
-inclusive_or_expression ::=
- exclusive_or_expression
- | inclusive_or_expression OR exclusive_or_expression
- ;
-conditional_and_expression ::=
- inclusive_or_expression
- | conditional_and_expression ANDAND inclusive_or_expression
- ;
-conditional_or_expression ::=
- conditional_and_expression
- | conditional_or_expression OROR conditional_and_expression
- ;
-conditional_expression ::=
- conditional_or_expression
- | conditional_or_expression QUESTION expression
- COLON conditional_expression
- ;
-assignment_expression ::=
- conditional_expression
- | assignment
- ;
-// semantic check necessary here to ensure a valid left-hand side.
-// allowing a parenthesized variable here on the lhs was introduced in
-// JLS 2; thanks to Eric Blake for pointing this out.
-assignment ::= postfix_expression assignment_operator assignment_expression
- ;
-assignment_operator ::=
- EQ
- | MULTEQ
- | DIVEQ
- | MODEQ
- | PLUSEQ
- | MINUSEQ
- | LSHIFTEQ
- | RSHIFTEQ
- | URSHIFTEQ
- | ANDEQ
- | XOREQ
- | OREQ
- ;
-expression_opt ::=
- | expression
- ;
-expression ::= assignment_expression
- ;
-// note that this constraint must be enforced during semantic checking
-// 'constant_expression' should include enumerated constants.
-constant_expression ::=
- expression
- ;
-
-// JLS-14 productions.
-type_parameters_opt ::= type_parameters | ;
-type_parameters ::=
- LT type_parameter_list_1
- ;
-type_parameter_list ::=
- type_parameter_list COMMA type_parameter
- | type_parameter
- ;
-type_parameter_list_1 ::=
- type_parameter_1
- | type_parameter_list COMMA type_parameter_1
- ;
-type_parameter ::=
- type_variable type_bound_opt
- ;
-type_parameter_1 ::=
- type_variable GT
- | type_variable type_bound_1
- ;
-type_bound_opt ::= type_bound | ;
-type_bound ::=
- EXTENDS reference_type additional_bound_list_opt
- ;
-type_bound_1 ::=
- EXTENDS reference_type_1
- | EXTENDS reference_type additional_bound_list_1
- ;
-additional_bound_list_opt ::= additional_bound_list | ;
-additional_bound_list ::=
- additional_bound additional_bound_list
- | additional_bound
- ;
-additional_bound_list_1 ::=
- additional_bound additional_bound_list_1
- | additional_bound_1
- ;
-additional_bound ::=
- AND interface_type
- ;
-additional_bound_1 ::=
- AND reference_type_1
- ;
-//////////////////////////////////////////////
-// the following productions are copied from the standard ones, but
-// 'name' all alone is not allowed. The '_nn' stands for 'not name'.
-// we also expand the productions so that they recursively depend on the
-// '_nn' forms of their left hand side, then adding a new production
-// with 'name' explicit on the left-hand side.
-// this allows us to postpone the decision whether '(x)' is an expression
-// or a type-cast until we can see enough right context to make the proper
-// choice.
-postfix_expression_nn ::=
- primary
- // the 'name' production was removed here.
- | postincrement_expression
- | postdecrement_expression
- ;
-unary_expression_nn ::=
- preincrement_expression
- | predecrement_expression
- | PLUS unary_expression
- | MINUS unary_expression
- | unary_expression_not_plus_minus_nn
- ;
-unary_expression_not_plus_minus_nn ::=
- postfix_expression_nn
- | COMP unary_expression
- | NOT unary_expression
- | cast_expression
- ;
-multiplicative_expression_nn ::=
- unary_expression_nn
- | name MULT unary_expression
- | multiplicative_expression_nn MULT unary_expression
- | name DIV unary_expression
- | multiplicative_expression_nn DIV unary_expression
- | name MOD unary_expression
- | multiplicative_expression_nn MOD unary_expression
- ;
-additive_expression_nn ::=
- multiplicative_expression_nn
- | name PLUS multiplicative_expression
- | additive_expression_nn PLUS multiplicative_expression
- | name MINUS multiplicative_expression
- | additive_expression_nn MINUS multiplicative_expression
- ;
-shift_expression_nn ::=
- additive_expression_nn
- | name LSHIFT additive_expression
- | shift_expression_nn LSHIFT additive_expression
- | name RSHIFT additive_expression
- | shift_expression_nn RSHIFT additive_expression
- | name URSHIFT additive_expression
- | shift_expression_nn URSHIFT additive_expression
- ;
-relational_expression_nn ::=
- shift_expression_nn
- // note that we've tweaked the productions for LT/GT to disallow
- // a<b<c as a valid expression. This avoids ambiguity with
- // parameterized types in casts.
- | name LT shift_expression
- | shift_expression_nn LT shift_expression
- | name GT shift_expression
- | shift_expression_nn GT shift_expression
- | name LTEQ shift_expression
- | relational_expression_nn LTEQ shift_expression
- | name GTEQ shift_expression
- | relational_expression_nn GTEQ shift_expression
- ;
-instanceof_expression_nn ::=
- relational_expression_nn
- | name INSTANCEOF reference_type
- | instanceof_expression_nn INSTANCEOF reference_type
- ;
-equality_expression_nn ::=
- instanceof_expression_nn
- | name EQEQ instanceof_expression
- | equality_expression_nn EQEQ instanceof_expression
- | name NOTEQ instanceof_expression
- | equality_expression_nn NOTEQ instanceof_expression
- ;
-and_expression_nn ::=
- equality_expression_nn
- | name AND equality_expression
- | and_expression_nn AND equality_expression
- ;
-exclusive_or_expression_nn ::=
- and_expression_nn
- | name XOR and_expression
- | exclusive_or_expression_nn XOR and_expression
- ;
-inclusive_or_expression_nn ::=
- exclusive_or_expression_nn
- | name OR exclusive_or_expression
- | inclusive_or_expression_nn OR exclusive_or_expression
- ;
-conditional_and_expression_nn ::=
- inclusive_or_expression_nn
- | name ANDAND inclusive_or_expression
- | conditional_and_expression_nn ANDAND inclusive_or_expression
- ;
-conditional_or_expression_nn ::=
- conditional_and_expression_nn
- | name OROR conditional_and_expression
- | conditional_or_expression_nn OROR conditional_and_expression
- ;
-conditional_expression_nn ::=
- conditional_or_expression_nn
- | name QUESTION expression COLON conditional_expression
- | conditional_or_expression_nn QUESTION expression
- COLON conditional_expression
- ;
-assignment_expression_nn ::=
- conditional_expression_nn
- | assignment
- ;
-expression_nn ::= assignment_expression_nn
- ;
+++ /dev/null
-This package contains CUP grammars for the Java programming language.
-
-Copyright (C) 2002 C. Scott Ananian
-This code is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2 of the License, or (at your
-option) any later version. See the file COPYING for more details.
-
-Directory structure:
- Parse/ contains the Java grammars.
- java10.cup contains a Java 1.0 grammar.
- java11.cup contains a Java 1.1 grammar.
- java12.cup contains a Java 1.2 grammar. [added 11-feb-1999]
- java14.cup contains a Java 1.4 grammar. [added 10-apr-2002]
- java15.cup contains a Java 1.5 Java grammar. [added 12-apr-2002]
- [last updated 28-jul-2003; Java 1.5 spec not yet final.]
- Lexer.java interface description for a lexer.
-
- Lex/ contains a simple but complete Java lexer.
- Lex.java main class
- Sym.java a copy of Parse/Sym.java containing symbolic constants.
-
- Main/
- Main.java a simple testing skeleton for the parser/lexer.
-
-The grammar in Parse/ should be processed by CUP into Grm.java.
-There are much better ways to write lexers for java, but the
-implementation in Lex/ seemed to be the easiest at the time. The
-lexer implemented here may not be as efficient as a table-driven lexer,
-but adheres to the java specification exactly.
-
- -- C. Scott Ananian <cananian@alumni.princeton.edu> 3-Apr-1998
- [revised 12-apr-2002]
- [revised 28-jul-2003]
-
-UPDATE: Fixed a lexer bug: '5.2' is a double, not a float. Thanks to
-Ben Walter <bwalter@mit.edu> for spotting this.
-
- -- C. Scott Ananian <cananian@alumni.princeton.edu> 14-Jul-1998
-
-UPDATE: Fixed a couple of minor bugs.
-1) Lex.EscapedUnicodeReader wasn't actually parsing unicode escape sequences
- properly because we didn't implement read(char[], int, int).
-2) Grammar fixes: int[].class, Object[].class and all array class
- literals were not being parsed. Also special void.class literal
- inadvertantly omitted from the grammar.
-Both these problems have been fixed.
-
- -- C. Scott Ananian <cananian@alumni.princeton.edu> 11-Feb-1999
-
-UPDATE: Fixed another lexer bug: Large integer constants such as
-0xFFFF0000 were being incorrectly flagged as 'too large for an int'.
-Also, by the Java Language Specification, "\477" is a valid string
-literal (it is the same as "\0477": the character '\047' followed by
-the character '7'). The lexer handles this case correctly now.
-
-Created java12.cup with grammar updated to Java 1.2. Features
-added include the 'strictfp' keyword and the various new inner class
-features at http://java.sun.com/docs/books/jls/nested-class-clarify.html.
-
-Also added slightly better position/error reporting to all parsers.
-
- -- C. Scott Ananian <cananian@alumni.princeton.edu> 11-Feb-1999
-
-UPDATE: fixed some buglets with symbol/error position reporting.
-
- -- C. Scott Ananian <cananian@alumni.princeton.edu> 13-Sep-1999
-
-UPDATE: multi-line comments were causing incorrect character position
-reporting. If you were using the character-position-to-line-number
-code in Lexer, you would never have noticed this problem. Thanks to
-William Young <youngwr@rose-hulman.edu> for pointing this out.
-
- -- C. Scott Ananian <cananian@alumni.princeton.edu> 27-Oct-1999
-
-UPDATE: extended grammar to handle the 'assert' statement added in
-Java 1.4. Also fixed an oversight: a single SEMICOLON is a valid
-ClassBodyDeclaration; this was added to allow trailing semicolons
-uniformly on class declarations. This wasn't part of the original
-JLS, but was revised in to conform with the actual behavior of the
-javac compiler. I've added this to all the grammars from 1.0-1.4
-to conform to javac behavior; let me know if you've got a good
-reason why this production shouldn't be in early grammars.
-
-Also futzed with the Makefile some to allow building a 'universal'
-driver which will switch between java 1.0/1.1/1.2/1.4 on demand.
-This helps me test the separate grammars; maybe you'll find a
-use for this behavior too.
-
- -- C. Scott Ananian <cananian@alumni.princeton.edu> 10-Apr-2002
-
-NEW: added a grammar for the JSR-14 "Adding Generics to the Java
-Programming Language" Java variant. Calling this java15.cup, since
-this JSR currently seems to be destined for inclusion in Java 1.5.
-This grammar is very very tricky! I need to use a lexer trick to
-handle type casts to parameterized types, which otherwise do not
-seem to be LALR(1).
- -- C. Scott Ananian <cananian@alumni.princeton.edu> 12-Apr-2002
-
-UPDATE: various bug fixes to all grammars, in reponse to bugs reported
-by Eric Blake <ebb9@email.byu.edu> and others.
- a) TWEAK: added 'String' type to IDENTIFIER terminal to match Number types
- given to numeric literals. (all grammars)
- b) BUG FIX: added SEMICOLON production to interface_member_declaration to
- allow optional trailing semicolons, in accordance with the JLS (for
- java 1.2-and-later grammars) and Sun practice (for earlier grammars).
- The 10-Apr-2002 release did not address this problem completely, due
- to an oversight. (all grammars)
- c) BUG FIX: '<primary>.this(...);' is not a legal production;
- '<name>.super(...);' and '<name>.new <identifier>(...' ought to be.
- In particular, plain identifiers ought to be able to qualify instance
- creation and explicit constructor invocation.
- (fix due to Eric Blake; java 1.2 grammar and following)
- d) BUG FIX: parenthesized variables on the left-hand-side of an assignment
- ought to be legal, according to JLS2. For example, this code is
- legal:
- class Foo { void m(int i) { (i) = 1; } }
- (fix due to Eric Blake; java 1.2 grammar and following)
- e) BUG FIX: array access of anonymous arrays ought to be legal, according
- to JLS2. For example, this is legal code:
- class Foo { int i = new int[]{0}[0]; }
- (fix due to Eric Blake; java 1.2 grammar and following)
- f) BUG FIX: nested parameterized types ought to be legal, for example:
- class A<T> { class B<S> { } A<String>.B<String> c; }
- (bug found by Eric Blake; jsr-14 grammar only)
- g) TWEAK: test cases were added for these issues.
-
-In addition, it should be clarified that the 'java15.cup' grammar is
-really only for java 1.4 + jsr-14; recent developments at Sun indicate
-that "Java 1.5" is likely to include several additional language changes
-in addition to JSR-14 parameterized types; see JSR-201 for more details.
-I will endeavor to add these features to 'java15.cup' as soon as their
-syntax is nailed down.
- -- C. Scott Ananian <cananian@alumni.princeton.edu> 13-Apr-2003
-
-UPDATE: Updated the 'java15.cup' grammar to match the latest specifications
-(and their corrections) for Java 1.5. This grammar matches the 2.2
-prototype of JSR-14 + JSR-201 capabilities, with some corrections for
-mistakes in the released specification and expected future features of
-Java 1.5 (in particular, arrays of parameterized types bounded by
-wildcards). Reimplemented java15.cup to use a refactoring originally
-due to Eric Blake which eliminates our previous need for "lexer lookahead"
-(see release notes for 12-April-2002). Added new 'enum' and '...' tokens
-to the lexer to accomodate Java 1.5. New test cases added for the
-additional language features.
- -- C. Scott Ananian <cananian@alumni.princeton.edu> 28-Jul-2003
+++ /dev/null
-/** Some valid java code from Eric Blake. Some of these constructions
- * broke previous versions of the grammars. These should all compile
- * with any JLS2 javac, as well as parse correctly (no syntax errors)
- * using the java12.cup/java14.cup/java15.cup grammars in this package. */
-class Eric {
- // parenthesized variables on the left-hand-size of assignments
- // are legal according to JLS 2. See comments on jikes bug 105
- // http://www-124.ibm.com/developerworks/bugs/?func=detailbug&bug_id=105&group_id=10
- // for more details. According to Eric Blake:
- // The 2nd edition JLS is weak on this point - the grammar
- // in 15.26 prohibits assignments to parenthesized
- // variables, but earlier in 15.8.5 it states that a
- // parenthesized variable is still a variable (in JLS1, a
- // parenthesized variable was a value), and the intent of
- // assignment is that a variable appear on the left hand
- // side. Also, the grammar in chapter 18 (if you can call
- // it such, because of its numerous typos and ambiguities)
- // permits assignment to parenthesized variables.
- void m(int i) {
- (i) = 1;
- }
- // array access of an initialized array creation is legal; see Sun
- // bugs 4091602, 4321177:
- // http://developer.java.sun.com/developer/bugParade/bugs/4091602.html
- // http://developer.java.sun.com/developer/bugParade/bugs/4321177.html
- // Eric Blake says:
- // Again, the body of the JLS prohibits this, but chapter 18 permits it.
- int i = new int[]{0}[0];
- int j = new char[] { 'O', 'K' }.length;
-
- // plain identifiers can qualify instance creation and explicit
- // constructors; see Sun bug 4750181:
- // http://developer.java.sun.com/developer/bugParade/bugs/4750181.html
- // Eric Blake says:
- // Sun admits the grammars between the earlier chapters and
- // chapter 18 are incompatible, so they are not sure whether
- // things like "identifier.new name()" should be legal or
- // not. Chapter 18 treats identifiers as primaries, and javac
- // compiles them.
- class B { };
- B b;
- void foo(Eric e) {
- e.b = e.new B();
- }
-}
+++ /dev/null
-/** Some valid java code from Eric Blake. This should compile
- * with any JSR-14 javac, as well as parse correctly (no syntax errors)
- * using the java15.cup grammar in this package. */
-class Eric15<T> {
- class B<S> { }
- Eric15<Integer>.B<Integer> c;
-}
+++ /dev/null
-class Escape {
- String s = "\477"; // this literal is valid, but..
-// char c = '\477'; // this literal is invalid.
-}
+++ /dev/null
-/** A valid JSR-14 Java program, which illustrates some corner-cases in
- * the 'smart lexer' lookahead implementation of the grammar. It should
- * compile correctly using a JSR-14 javac, as well as parse correctly
- * (no syntax errors) using the java15.cup grammar in this package. */
-public class Test15<X> {
- <T> Test15(T t) { }
- int a = 1, b = 2;
- C c1 = new C<Integer>(), c2 = new C<B>(), c3 = new C<B[]>();
- C<B> cc2 = c2;
- C<B[]> cc3 = c3;
- boolean d = a < b, e = a < b;
- int f[] = new int[5];
- boolean g = a < f[1];
- boolean h = ( a < f[1] );
- Object i0 = (A) cc3;
- Object i = ( A < B[] > ) cc3;
- Object j = ( A < B > ) cc2;
- Object k = ( A < A < B[] > >) null;
- Object kk= ( A < A < B[] >>) null;
- Test15<X>.H hh = null;
- {
- Test15<X>.H hhh = null;
- for (boolean l=a<b, m=a<b; a<b ; l=a<b, f[0]++)
- a=a;
- for (;d;)
- b=b;
- A<Integer> m = c1;
- if (m instanceof C<Integer>)
- a=a;
- for (boolean n = m instanceof C<Integer>,
- o = a<b,
- p = cc3 instanceof C<B[]>;
- cc3 instanceof C<B[]>;
- n = m instanceof C<Integer>,
- o = a<b,
- p = cc3 instanceof C<B[]>)
- b=b;
- for (;m instanceof C<Integer>;)
- a=a;
- if (a < b >> 1)
- ;
- Object o1 = new A<A<B>>(),
- o2 = new A<A<A<B>>>(),
- o3 = new A<A<D<B,A<B>>>>();
-
- // new, "explicit parameter" version of method invocation.
- A<Integer> aa = Test15.<A<Integer>>foo();
- /* although the spec says this should work:
- A<Integer> aa_ = <A<Integer>>foo();
- * Neal Gafter has assured me that this is a bug in the spec.
- * Type arguments are only valid after a dot. */
-
- // "explicit parameters" with constructor invocations.
- new <String> K<Integer>("xh"); // prototype 2.2 chokes on this.
- this.new <String> K<Integer>("xh");
- }
-
- static class A<T> { T t; }
- static class B { }
- static class C<T> extends A<T> { }
- static class D<A,B> { }
- static class E<X,Y extends A<X>> { }
- static interface F { }
- // wildcard bounds.
- static class G { A<? extends F> a; A<? super C<Integer>> b; }
- class H { }
- static class I extends A<Object[]> { }
- static class J extends A<byte[]> { }
- class K<Y> { <T>K(T t) { Test15.<T>foo(); } }
-
- static <T> T foo() { return null; }
-}
+++ /dev/null
-import static java.lang.Math.*; // gratuitous test of static import
-import static java.lang.System.out; // ditto
-import java.util.*;
-class TestJSR201 {
- enum Color { red, green, blue ; };
- public static void main(String... args/* varargs */) {
- /* for each on multi-dimensional array */
- int[][] iaa = new int[10][10];
- for (int ia[] : iaa) {
- for (int i : ia)
- out.print(i); // use static import.
- out.println();
- }
- /** alternate syntax: */
- for each (int ia[] in iaa)
- for each (int i in ia) {
- out.println(i);
- }
- /* */
- for (Color c : Color.VALUES) {
- switch(c) {
- case Color.red: out.print("R"); break;
- case Color.green: out.print("G"); break;
- case Color.blue: out.print("B"); break;
- default: assert false;
- }
- }
- out.println();
- }
- // complex enum declaration, from JSR-201
- public static enum Coin {
- penny(1), nickel(5), dime(10), quarter(25);
- Coin(int value) { this.value = value; }
- private final int value;
- public int value() { return value; }
- }
- public static class Card implements Comparable, java.io.Serializable {
- public enum Rank { deuce, three, four, five, six, seven, eight, nine,
- ten, jack, queen, king, ace }
- public enum Suit { clubs, diamonds, hearts, spades }
-
- private final Rank rank;
- private final Suit suit;
-
- private Card(Rank rank, Suit suit) {
- if (rank == null || suit == null)
- throw new NullPointerException(rank + ", " + suit);
- this.rank = rank;
- this.suit = suit;
- }
-
- public Rank rank() { return rank; }
- public Suit suit() { return suit; }
-
- public String toString() { return rank + " of " + suit; }
-
- public int compareTo(Object o) {
- Card c = (Card)o;
- int rankCompare = rank.compareTo(c.rank);
- return rankCompare != 0 ? rankCompare : suit.compareTo(c.suit);
- }
-
- private static List sortedDeck = new ArrayList(52);
- /* BROKEN IN PROTOTYPE 2.0 */
- static {
- for (Rank rank : Rank.VALUES)
- for (Suit suit : Suit.VALUES)
- sortedDeck.add(new Card(rank, suit));
- }
- /* */
- // Returns a shuffled deck
- public static List newDeck() {
- List result = new ArrayList(sortedDeck);
- Collections.shuffle(result);
- return result;
- }
- }
- // sophisticated example:
- public static abstract enum Operation {
- plus {
- double eval(double x, double y) { return x + y; }
- },
- minus {
- double eval(double x, double y) { return x - y; }
- },
- times {
- double eval(double x, double y) { return x * y; }
- },
- divided_by {
- double eval(double x, double y) { return x / y; }
- };
-
- // Perform arithmetic operation represented by this constant
- abstract double eval(double x, double y);
-
- public static void main(String args[]) {
- double x = Double.parseDouble(args[0]);
- double y = Double.parseDouble(args[1]);
-
- for (Operation op : VALUES)
- out.println(x + " " + op + " " + y + " = " + op.eval(x, y));
- }
- }
-}
+++ /dev/null
-CUP version 0.10k is a maintenance release.
-
-CUP will now accept a filename on the command-line if it is the last
-argument and does not start with "-". This allows better GUI
-integration. Some unix-isms in end-of-line handling have been fixed,
-too; thanks to Jean Vaucher <vaucher@iro.umontreal.ca> for the tip.
-
-The java_cup.runtime.Scanner interface has been refined to allow
-the scanner to return null to signal EOF. JLex and JFlex users will
-like this, as it means they can use the default scanner EOF behavior.
-
-Bruce Hutton <b_hutton@cs.auckland.ac.nz>, Zerksis Umrigar <zdu@acm.org>,
-and Vladimir Antonevich <Vladimir.Antonevich@solcorp.com> all sent bug
-reports touching on erroneous error recovery in the parser runtime.
-Dr. Hutton provided the fixes that I've adopted; Zerksis sent a very
-helpful CUP-vs-bison test case. If you're in a position to notice
-correct/incorrect error recovery and this release works better for you
-than previous ones, thank them --- and send me email so I know whether
-we've quashed this bug for good.
-
-Klaus Georg Barthelmann <barthel@Informatik.Uni-Mainz.DE> caught an
-oversight in the constructors for java_cup.runtime.Symbol. I've also
-taken an obsolete constructor allowing specification of a start state
-for some symbol to package-scope; if this causes anyone backwards
-compatibility problems, email me and I will consider changing it back.
-
-C. Scott Ananian
-Laboratory for Computer Science
-Massachusetts Institute of Technology
-Jul-24-1999 [CSA]
-------------------------------------------------------------------------
-CUP version 0.10j adds new features.
-
-A "-version" command-line option is now accepted, which prints out the
-working version of CUP and halts. This allows automatic version-checking,
-for those applications which require it.
-
-Broadened the CUP input grammar to allow CUP reserved words in package and
-import statements, and in (non)terminal labels. In addition, semicolons
-after 'action code', 'parser code', 'init code', and 'scan with' sections
-have been made optional (if language noise annoys you). Also, these four
-sections may now appear in any order, instead of the strict ordering
-previously required. Finally, you can now spell 'non-terminal' as either
-"non terminal" (old way) *or* "nonterminal" without upsetting CUP.
-[Flexibility requested by Stefan Kahrs <S.M.Kahrs@ukc.ac.uk>]
-[Package and import reserved word issues noted by Frank Rehberger,
- Brandon Schendel, and Bernie Honeisen, among others.]
-
-Clarified the parse table dumps generated by the -dump* options.
-
-I have added code to lr_parser to detect illegal Symbol recycling by the
-scanner and to throw an Error in this case. The scanner must return
-a fresh Symbol object on each invocation, because these objects are
-tagged with parse state and added to the parse stack. Object sharing
-does evil things to the parser; don't do it (you won't get away with it).
-[Symbol recycling problems reported by Ken Arnold <Ken.Arnold@Sun.COM>]
-
-Improved scanner interface, designed by David MacMahon <davidm@smartsc.com>.
-The new java_cup.runtime.Scanner interface is used by the default
-implementation of lr_parser.scan(). See the manual for more details.
-Old parsers will work with the new runtime, but parsers generated with
-0.10j will not work with the runtime from earlier versions unless you
-specify the (new) "-noscanner" option.
-
-C. Scott Ananian
-Laboratory for Computer Science
-Massachusetts Institute of Technology
-Jul-24-1999 [CSA]
-------------------------------------------------------------------------
-CUP version 0.10i is a maintenance release.
-
-A one-off bug in the parser error-recovery code has been caught and corrected
-by Chris Harris <ckharris@ucsd.edu>.
-
-The fields in the emitted symbol class have been made public, rather than
-package scope, since the class already was public.
-
-The issues formerly addressed in Appendix D (accessing parser methods/fields
-from the action class) have been partially addressed by adding a new
-private final field named 'parser' to the action object that points to
-the parser object. THIS INTRODUCES A POTENTIAL INCOMPATIBILITY if you had
-previously defined a field named 'parser' in the 'action code {: ... :}'
-portion of your grammar. The solution is to rename your field.
-
-Finally, incorporated Jako Andras' suggestions to make CUP more friendly
-to makefiles.
-
-A reminder: please submit bug-fixes or feature-additions as *patches*, not
-complete archives. Your patch will have a greater chance of integration
-into the distribution if you package each feature or fix as a separate patch,
-instead of lumping everything together and leaving it to me to figure out
-what you've changed and why.
-
-C. Scott Ananian
-Laboratory for Computer Science
-Massachusetts Institute of Technology
-Feb-18-1999 [CSA]
-------------------------------------------------------------------------
-CUP version 0.10h is a maintenance release.
-
-Starting with this version, CUP encodes the various parser tables as strings
-to get around java's 64k method-size limitation. This allows larger
-parse tables and thus more complicated grammars.
-
-Furthermore, a long-standing buglet that would cause CUP to occasionally
-generate "Attempt to construct a duplicate state" internal errors has been
-fixed.
-
-Another contributed Microsoft-compatible makefile has also been added
-to the distribution.
-
-C. Scott Ananian
-Laboratory for Computer Science
-Massachusetts Institute of Technology
-Feb-10-1999 [CSA]
-------------------------------------------------------------------------
-CUP version 0.10g contains bug fixes, added functionality, and
-performance improvements. Thanks to Matthias Zenger, Peter Selinger,
-Jaroslaw Kachinarz, Ian Davis and others for contributions.
-
-- New command line option '-interface' added. This causes JavaCUP to
- emit an *interface* with the symbol constants, instead of a
- *class*. Without the command-line flag, behavior is identical to
- v0.10f and before: the symbols are emitted as a class.
-- (minor) Added toString() method to java_cup.runtime.Symbol and
- modified the debugging parser to use it. This allows you to
- override toString() to allow a more intelligible debugging parse.
-- The CUP grammar has been extended to allow one to declare array types
- for javaCUP terminals and non-terminals. Matthias Zenger first
- suggested this feature; Peter Selinger was the first to show the
- right way to do it.
-- The symbols prefixed with CUP$ now have the parser class file name
- added to the prefix as well, to allow more than one parser object
- per package. Thanks to Jaroslaw Kachniarz for pointing out this
- problem.
-- Fixed bug that prevented one from invoking the parser multiple times.
- To quote Ian Davis, who found and diagnosed the bug:
- Repeat invocations of the same instantiation of lr_parser.java to parse
- distinct input statements fail for the simple reason that the stack is
- not emptied at start of parsing, but the stack offset is reset to 0.
- This has been fixed.
-- Fixed bug with implicit start productions not receiving a RESULT.
-- Fixed bug with RESULT assignments that are not right-most in the
- production.
-- Updated documentation.
-
-Known issues:
-- All known bugs have been fixed.
-- The java_cup.runtime.SymbolStack / java_cup.runtime.intStack
- performance hack originally suggested by Matthias Zenger has been
- postponed to the next release. By eliminating typecasts and
- synchronized methods, a substantial performance improvement can be
- obtained. Backwards-compatibility issues have forced the postponement
- of the code merge.
-
-C. Scott Ananian
-Laboratory for Computer Science
-Massachusetts Institute of Technology
-3/24/98 [CSA]
-------------------------------------------------------------------------
-CUP version 0.10f is a maintenance release. The code has been cleaned up
-for JDK 1.1 functionality. No major functionality has been added; any bugs
-in 0.10e are still in 0.10f.
-
-- Removed trailing semicolons from class definitions which upset strict
- compilers (not Sun's javac, for some reason).
-- Changed 'PrintStream's to 'PrintWriter's to eliminate deprecation
- warnings.
-
-As of this release, the javaCUP code is being maintained by
-C. Scott Ananian. Suggestions and bug-fixes should be sent to
-cananian@alumni.princeton.edu.
-
-Known issues:
-
-- Precedence bug: rules unmarked by precedence information are treated
- as if they had existing, but very low, precedence. This can mask
- parser conflicts.
-- Efficiency hack: java.util.Stack will be replaced in the next
- release with a special-purpose stack to eliminate
- performance-robbing type-casts.
-- It has been suggested that the symbol *class* should be an
- *interface* instead. This will be a command-line option in the next
- release.
-
-C. Scott Ananian
-Laboratory for Computer Science
-Massachusetts Institute of Technology
-12/21/97 [CSA]
-------------------------------------------------------------------------
-CUP version 0.10e contains a few bug fixes from 0.10a
-
-- %prec directive now works correctly
- fixed by cananian@princeton.edu <C. Scott Ananian>
-- Shift reduce conflicts are now correctly reported
- fixed by danwang@cs.princeton.edu <Daniel . Wang>
-- Error with reporting the positon of the error token also fixed
- fixed by cananian@princeton.edu <C. Scott Ananian>
-- INSTALL script now has a slightly more complex test.
-- foo.java.diff included for changes from previous release
-- Fixed more bugs with reporting of shift reduce conflicts.
- fixed by danwang@cs.princeton.edu <Daniel . Wang>
-- Fixed bug introduced by previous fix patches from <hosking@.cs.purdue.edu>
- Added '\r' as a whitespace character for the lexer suggested by
- (dladd@spyglass.com)
-- Fixed botched relase
-Daniel Wang
-Department of Computer Science
-Princeton University
-
-Last updated: 9/12/97 [DW]
-------------------------------------------------------------------------
-Changes and Additions to CUP v0.9e
-
-CUP version 0.10a is a major overhaul of CUP. The changes are severe,
-meaning no backwards compatibility to older versions.
-
-Here are the changes:
-
-1. CUP now interfaces with the lexer in a completely different
-manner. In the previous releases, a new class was used for every
-distinct type of terminal. This release, however, uses only one class:
-The Symbol class. The Symbol class has three instance variables which
-are significant to the parser when passing information from the lexer.
-The first is the value instance variable. This variable contains the
-value of that terminal. It is of the type declared as the terminal type
-in the parser specification file. The second two are the instance
-variables left and right. They should be filled with the int value of
-where in the input file, character-wise, that terminal was found.
-
-2. Terminal and non-nonterminal declarations now can be declared in two
-different ways to indicate the values of the terminals or non-terminals.
-The previous declarations of the form
-
-terminal {classname} {terminal} [, terminal ...];
-
-still works. The classname, however indicates the type of the value of
-the terminal or non-terminal, and does not indicate the type of object
-placed on the parse stack.
-
-A declaration, such as:
-
-terminal {terminal} [, terminal ...];
-
-indicates the terminals in the list hold no value.
-
-3. CUP doesn't use the Symbol class for just terminals, but for all
-non-terminals as well. When a production reduces to a non-terminal, a
-new Symbol is created, and the value field is filled with the value of
-that non-terminal. The user must know that the terminal and non terminal
-declarations specify a type corresponding to the type of the value field
-for the symbol representing that terminal or non-terminal.
-
-4. Label references do not refer to the object on the parse stack, as in
-the old CUP, but rather to the value of the value instance variable of
-the Symbol that represents that terminal or non-terminal. Hence,
-references to terminal and non-terminal values is direct, as opposed to
-the old CUP, where the labels referred to objects containing the value
-of the terminal or non-terminal.
-
-5. The RESULT variable refers directly to the value of the non-terminal
-to which a rule reduces, rather than to the object on the parse stack.
-Hence, RESULT is of the same type the non-terminal to which it reduces,
-as declared in the non terminal declaration. Again, the reference is
-direct, rather than to something that will contain the data.
-
-6. For every label, two more variables are declared, which are the label
-plus left or the label plus right. These correspond to the left and
-right locations in the input stream to which that terminal or
-non-terminal came from. These values are propagated from the input
-terminals, so that the starting non-terminal should have a left value of
-0 and a right value of the location of the last character read.
-
-7. A call to parse() or debug_parse() return a Symbol. This Symbol is
-of the start non-terminal, so the value field contains the final RESULT
-assignment.
-
-8. CUP now has precedenced terminals. a new declaration section,
-occurring between the terminal and non-terminal declarations and the
-grammar specifies the precedence and associativity of rules. The
-declarations are of the form:
-
-precedence {left| right | nonassoc} terminal[, terminal ...];
-...
-
-The terminals are assigned a precedence, where terminals on the same
-line have equal precedences, and the precedence declarations farther
-down the list of precedence declarations have higher precedence. left,
-right and nonassoc specify the associativity of these terminals. left
-associativity corresponds to a reduce on conflict, right to a shift on
-conflict, and nonassoc to an error on conflict. Hence, ambiguous
-grammars may now be used. For a better explanation, see the manual.
-
-9. Finally the new CUP adds contextual precedence. A production may be
-declare as followed:
-
-lhs ::= {right hand side list of terminals, non-terminals and actions}
- %prec {terminal};
-
-this production would then have a precedence equal to the terminal
-specified after the "%prec". Hence, shift/reduce conflicts can be
-contextually resolved. Note that the "%prec terminal" part comes after
-all actions strings. It does not come before the last action string.
-
-For more information read the manual, found in manual.html
-
-Frank Flannery
-Department of Computer Science
-Princeton University
-
-Last updated: 7/3/96 [FF]
-
-
+++ /dev/null
-#!/bin/csh -f
-#
-# Cup install and test script
-# Scott Hudson 8/31/95
-#
-# Last revision 7/3/96 (for v0.10a)
-# By Frank Flannery
-#
-# Last revision 11/16/96 (for v0.10b)
-# By Daniel Wang
-#
-# Updated version number 7/24/99 for 0.10k
-# By C. Scott Ananian
-echo
-echo "================================"
-echo "Installing and testing Cup v0.10k"
-echo "================================"
-echo
-
-# check for this directory in CLASSPATH
-#
-set cwd = `pwd`
-set c_path = `printenv CLASSPATH`
-if ($c_path !~ "*$cwd*") then
- echo " "
- echo "WARNING:"
- echo "WARNING: The current directory does not appear in your CLASSPATH"
- echo "WARNING: it will be added for this install/test only"
- echo "WARNING:"
- echo " "
- setenv CLASSPATH $cwd':'$c_path
- echo "CLASSPATH now set to "
- printenv CLASSPATH
-endif
-
-# change to the demo directory
-#
-echo " "
-echo "changing to simple_calc subdirectory..."
-echo "cd java_cup/simple_calc"
-cd java_cup/simple_calc
-
-# remove old copies of parser.java and sym.java
-#
-echo " "
-echo "removing any old copies of parser.java and sym.java..."
-echo "rm -f parser.java sym.java"
-rm -f parser.java sym.java
-
-# compile java_cup and run it against the demo program
-# the -cs (for "checksource") option here will force the
-# java_cup and java_cup.runtime source to be compiled prior
-# to running it.
-#
-echo " "
-echo "compiling java_cup then generating demo program..."
-echo "java -cs java_cup.Main < parser.cup"
-java -cs java_cup.Main < parser.cup
-
-# make sure parser.java and sym.java now exist
-#
-if ( ! -e parser.java) then
- echo " "
- echo "ERROR: for some reason parser.java was not created"
- echo "ERROR: install was not successful"
- exit 1
-endif
-if ( ! -e sym.java) then
- echo " "
- echo "ERROR: for some reason sym.java was not created"
- echo "ERROR: install was not successful"
- exit 1
-endif
-
-# run the demo
-# again, the -cs option will cause compilation of all the parts
-# of the demo program (including parser.java and sym.java that
-# should have been generated in the previous step).
-#
-echo "removing old test results..."
-echo "rm -f test_results"
-rm -f test_results
-echo " "
-echo "executing the demo program..."
-echo "echo '1*-2+2;' | java -cs java_cup.simple_calc.Main >& test_results"
-echo '1*-2+2;' | java -cs java_cup.simple_calc.Main >& test_results
-
-# compare with standard results
-#
-set res = `tail -1 test_results`
-if ("$res" !~ "= 0") then
- echo "ERROR: test program produced the wrong results"
- echo "ERROR: output was:"
- cat test_results
- echo "ERROR: install was not successful"
- rm -f test_results
- exit 2
-endif
-
-# all is well
-#
-rm -f test_results
-echo " "
-echo "=============================="
-echo "Install and test was successful"
-echo "=============================="
-exit 0
+++ /dev/null
-This is a quick installation guide for the CUP system.
-For most people, the following steps will suffice:
-
- 1) extract the java_cup files somewhere, and ensure that
- the extraction directory is in your classpath.
-
- This will ensure that java_cup.Main properly refers to the
- Main class in the java_cup subdirectory of this release.
-
- 2) compile java_cup and its runtime system.
- From the installation directory:
- javac java_cup/*.java java_cup/runtime/*.java
-
-That's it! Read the manual now.
- --Scott
-
-24-Mar-1998
+++ /dev/null
-CUP PARSER GENERATOR COPYRIGHT NOTICE, LICENSE AND DISCLAIMER.
-
-Copyright 1996 by Scott Hudson, Frank Flannery, C. Scott Ananian
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both the copyright notice and this permission notice and warranty
-disclaimer appear in supporting documentation, and that the names of
-the authors or their employers not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission.
-
-The authors and their employers disclaim all warranties with regard to
-this software, including all implied warranties of merchantability and
-fitness. In no event shall the authors or their employers be liable
-for any special, indirect or consequential damages or any damages
-whatsoever resulting from loss of use, data or profits, whether in an
-action of contract, negligence or other tortious action, arising out of
-or in connection with the use or performance of this software.
+++ /dev/null
-This directory contains the CUP v0.10k release in source form. You should
-find the following files and subdirectories in this release:
-
- README This file.
- INSTALL.QUICK Quick installation instruction.
- CHANGELOG A brief overview of the changes in v0.10k
- java_cup A subdirectory containing CUP, runtime, and test sources.
- cup_logo.gif A logo image used by the manual.
- manual.html A user's manual in HTML format. (OLD)
- INSTALL A shell script to install and test the system
-
-To get started quickly, read INSTALL.QUICK. If you are on a Windows
-platform, you might want to look in the winnt subdirectory.
-For complete installation information, keep reading.
-
-To install the release, copy the contents of this directory (if you
-haven't done so already) into a "classes" directory accessible to the
-java interpreter (i.e., a directory that is listed in the colon
-separated list of directories in your CLASSPATH environment variable).
-Note: if you have an older version of the system already accessible
-from your CLASSPATH you will want to temporarily remove it to avoid
-conflicts.
-
-Once files have been copied to an appropriate location, you should be able to
-both compile and test the system by executing the INSTALL shell script
-(sorry, but non Unix users are still on their own). Again, be sure that
-you have placed these sources in a directory listed in your CLASSPATH
-environment variable (or changed your CLASSPATH to include this directory).
-
-A manual page that explains the operation and use of the system can be found
-in manual.html and from the CUP home page mentioned below.
-
-Bug reports regarding the installation
-process or the system as a whole should be sent to
-<cananian@alumni.princeton.edu> with "JavaCUP" in the subject.
-
-The CUP home page where the latest information regarding CUP can be found
-(e.g., new releases) is:
-
- http://www.cs.princeton.edu/~appel/modern/java/CUP/
-
-Enjoy,
-
-Scott Hudson
-Graphics, Visualization, and Usability Center
-Georgia Institute of Technology
-
-Last updated: 23-Jul-1999 [CSA]
+++ /dev/null
-Date: Fri, 05 Feb 1999 17:11:08 -0600
-From: jon miner <jon.miner@doit.wisc.edu>
-To: cananian@alumni.princeton.edu
-Subject: Makefile for NT/DOS
-
-I've made (hah) a Makefile for java_cup that will install and test java_cup
-on NT/9x/DOS with GNU Make...
-
-You (should) find it attached.
-
-thanks,
-
-jon
-
--------------------------------------------------------------
-Date: Sun, 07 Feb 1999 17:30:33 -0600
-From: Jon Miner <jon.miner@doit.wisc.edu>
-To: C. Scott Ananian <cananian@lesser-magoo.lcs.mit.edu>
-Subject: Re: Makefile for NT/DOS
-
-The Makefile included is for Microsoft's (I think) Nmake... it doesn't
-jive with just plain old GNU make (At least not on my machine..) Also, the
-Makefile I wrote _should_ (I haven't tested it, though) work (with minor
-changes) on Un*x and WinTel machines...
-
-thanks,
-
-jon
-
-[The makefile has been included in this directory. -- CSA 24-Mar-1998 ]
+++ /dev/null
-SIMPLEDIR=SIMPLE~1
-# SIMPLEDIR=simple_calc
-RM=del
-# RM=rm
-JAVA=java
-JAVAOPTS=
-JAVAC=javac
-JAVACOPTS=-verbose
-
-
-test: java_cup\\Main.class java_cup\\$(SIMPLEDIR)\\Main.class
- echo "1*-2+2;" | $(JAVA) $(JAVAOPTS) java_cup.simple_calc.Main
-
- echo 'If the line above says "= 0" everything is OK.'
-
-
-java_cup\\Main.class:
- $(JAVAC) $(JAVACOPTS) java_cup\\Main.java
-
-java_cup\\$(SIMPLEDIR)\\Main.class:
- cd java_cup
- cd $(SIMPLEDIR)
- echo $(RM) parser.java
- echo $(RM) sym.java
- $(JAVA) $(JAVAOPTS) java_cup.Main < parser.cup
- $(JAVAC) $(JAVACOPTS) Main.java
+++ /dev/null
-
-package java_cup;
-
-import java.util.Enumeration;
-import java.io.*;
-
-/** This class serves as the main driver for the JavaCup system.
- * It accepts user options and coordinates overall control flow.
- * The main flow of control includes the following activities:
- * <ul>
- * <li> Parse user supplied arguments and options.
- * <li> Open output files.
- * <li> Parse the specification from standard input.
- * <li> Check for unused terminals, non-terminals, and productions.
- * <li> Build the state machine, tables, etc.
- * <li> Output the generated code.
- * <li> Close output files.
- * <li> Print a summary if requested.
- * </ul>
- *
- * Options to the main program include: <dl>
- * <dt> -package name
- * <dd> specify package generated classes go in [default none]
- * <dt> -parser name
- * <dd> specify parser class name [default "parser"]
- * <dt> -symbols name
- * <dd> specify name for symbol constant class [default "sym"]
- * <dt> -interface
- * <dd> emit symbol constant <i>interface</i>, rather than class
- * <dt> -nonterms
- * <dd> put non terminals in symbol constant class
- * <dt> -expect #
- * <dd> number of conflicts expected/allowed [default 0]
- * <dt> -compact_red
- * <dd> compact tables by defaulting to most frequent reduce
- * <dt> -nowarn
- * <dd> don't warn about useless productions, etc.
- * <dt> -nosummary
- * <dd> don't print the usual summary of parse states, etc.
- * <dt> -progress
- * <dd> print messages to indicate progress of the system
- * <dt> -time
- * <dd> print time usage summary
- * <dt> -dump_grammar
- * <dd> produce a dump of the symbols and grammar
- * <dt> -dump_states
- * <dd> produce a dump of parse state machine
- * <dt> -dump_tables
- * <dd> produce a dump of the parse tables
- * <dt> -dump
- * <dd> produce a dump of all of the above
- * <dt> -debug
- * <dd> turn on debugging messages within JavaCup
- * <dt> -nopositions
- * <dd> don't generate the positions code
- * <dt> -noscanner
- * <dd> don't refer to java_cup.runtime.Scanner in the parser
- * (for compatibility with old runtimes)
- * <dt> -version
- * <dd> print version information for JavaCUP and halt.
- * </dl>
- *
- * @version last updated: 7/3/96
- * @author Frank Flannery
- */
-
-public class Main {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
- /** Only constructor is private, so we do not allocate any instances of this
- class. */
- private Main() { }
-
- /*-------------------------*/
- /* Options set by the user */
- /*-------------------------*/
- /** User option -- do we print progress messages. */
- protected static boolean print_progress = true;
- /** User option -- do we produce a dump of the state machine */
- protected static boolean opt_dump_states = false;
- /** User option -- do we produce a dump of the parse tables */
- protected static boolean opt_dump_tables = false;
- /** User option -- do we produce a dump of the grammar */
- protected static boolean opt_dump_grammar = false;
- /** User option -- do we show timing information as a part of the summary */
- protected static boolean opt_show_timing = false;
- /** User option -- do we run produce extra debugging messages */
- protected static boolean opt_do_debug = false;
- /** User option -- do we compact tables by making most common reduce the
- default action */
- protected static boolean opt_compact_red = false;
- /** User option -- should we include non terminal symbol numbers in the
- symbol constant class. */
- protected static boolean include_non_terms = false;
- /** User option -- do not print a summary. */
- protected static boolean no_summary = false;
- /** User option -- number of conflicts to expect */
- protected static int expect_conflicts = 0;
-
- /* frankf added this 6/18/96 */
- /** User option -- should generator generate code for left/right values? */
- protected static boolean lr_values = true;
-
- /** User option -- should symbols be put in a class or an interface? [CSA]*/
- protected static boolean sym_interface = false;
-
- /** User option -- should generator suppress references to
- * java_cup.runtime.Scanner for compatibility with old runtimes? */
- protected static boolean suppress_scanner = false;
-
- /*----------------------------------------------------------------------*/
- /* Timing data (not all of these time intervals are mutually exclusive) */
- /*----------------------------------------------------------------------*/
- /** Timing data -- when did we start */
- protected static long start_time = 0;
- /** Timing data -- when did we end preliminaries */
- protected static long prelim_end = 0;
- /** Timing data -- when did we end parsing */
- protected static long parse_end = 0;
- /** Timing data -- when did we end checking */
- protected static long check_end = 0;
- /** Timing data -- when did we end dumping */
- protected static long dump_end = 0;
- /** Timing data -- when did we end state and table building */
- protected static long build_end = 0;
- /** Timing data -- when did we end nullability calculation */
- protected static long nullability_end = 0;
- /** Timing data -- when did we end first set calculation */
- protected static long first_end = 0;
- /** Timing data -- when did we end state machine construction */
- protected static long machine_end = 0;
- /** Timing data -- when did we end table construction */
- protected static long table_end = 0;
- /** Timing data -- when did we end checking for non-reduced productions */
- protected static long reduce_check_end = 0;
- /** Timing data -- when did we finish emitting code */
- protected static long emit_end = 0;
- /** Timing data -- when were we completely done */
- protected static long final_time = 0;
-
- /* Additional timing information is also collected in emit */
-
- /*-----------------------------------------------------------*/
- /*--- Main Program ------------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The main driver for the system.
- * @param argv an array of strings containing command line arguments.
- */
- public static void main(String argv[])
- throws internal_error, java.io.IOException, java.lang.Exception
- {
- boolean did_output = false;
-
- start_time = System.currentTimeMillis();
-
- /* process user options and arguments */
- parse_args(argv);
-
- /* frankf 6/18/96
- hackish, yes, but works */
- emit.set_lr_values(lr_values);
- /* open output files */
- if (print_progress) System.err.println("Opening files...");
- /* use a buffered version of standard input */
- input_file = new BufferedInputStream(System.in);
-
- prelim_end = System.currentTimeMillis();
-
- /* parse spec into internal data structures */
- if (print_progress)
- System.err.println("Parsing specification from standard input...");
- parse_grammar_spec();
-
- parse_end = System.currentTimeMillis();
-
- /* don't proceed unless we are error free */
- if (lexer.error_count == 0)
- {
- /* check for unused bits */
- if (print_progress) System.err.println("Checking specification...");
- check_unused();
-
- check_end = System.currentTimeMillis();
-
- /* build the state machine and parse tables */
- if (print_progress) System.err.println("Building parse tables...");
- build_parser();
-
- build_end = System.currentTimeMillis();
-
- /* output the generated code, if # of conflicts permits */
- if (lexer.error_count != 0) {
- // conflicts! don't emit code, don't dump tables.
- opt_dump_tables = false;
- } else { // everything's okay, emit parser.
- if (print_progress) System.err.println("Writing parser...");
- open_files();
- emit_parser();
- did_output = true;
- }
- }
- /* fix up the times to make the summary easier */
- emit_end = System.currentTimeMillis();
-
- /* do requested dumps */
- if (opt_dump_grammar) dump_grammar();
- if (opt_dump_states) dump_machine();
- if (opt_dump_tables) dump_tables();
-
- dump_end = System.currentTimeMillis();
-
- /* close input/output files */
- if (print_progress) System.err.println("Closing files...");
- close_files();
-
- /* produce a summary if desired */
- if (!no_summary) emit_summary(did_output);
-
- /* If there were errors during the run,
- * exit with non-zero status (makefile-friendliness). --CSA */
- if (lexer.error_count != 0)
- System.exit(100);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Print a "usage message" that described possible command line options,
- * then exit.
- * @param message a specific error message to preface the usage message by.
- */
- protected static void usage(String message)
- {
- System.err.println();
- System.err.println(message);
- System.err.println();
- System.err.println(
-"Usage: " + version.program_name + " [options] [filename]\n" +
-" and expects a specification file on standard input if no filename is given.\n" +
-" Legal options include:\n" +
-" -package name specify package generated classes go in [default none]\n" +
-" -parser name specify parser class name [default \"parser\"]\n" +
-" -symbols name specify name for symbol constant class [default \"sym\"]\n"+
-" -interface put symbols in an interface, rather than a class\n" +
-" -nonterms put non terminals in symbol constant class\n" +
-" -expect # number of conflicts expected/allowed [default 0]\n" +
-" -compact_red compact tables by defaulting to most frequent reduce\n" +
-" -nowarn don't warn about useless productions, etc.\n" +
-" -nosummary don't print the usual summary of parse states, etc.\n" +
-" -nopositions don't propagate the left and right token position values\n" +
-" -noscanner don't refer to java_cup.runtime.Scanner\n" +
-" -progress print messages to indicate progress of the system\n" +
-" -time print time usage summary\n" +
-" -dump_grammar produce a human readable dump of the symbols and grammar\n"+
-" -dump_states produce a dump of parse state machine\n"+
-" -dump_tables produce a dump of the parse tables\n"+
-" -dump produce a dump of all of the above\n"+
-" -version print the version information for CUP and exit\n"
- );
- System.exit(1);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Parse command line options and arguments to set various user-option
- * flags and variables.
- * @param argv the command line arguments to be parsed.
- */
- protected static void parse_args(String argv[])
- {
- int len = argv.length;
- int i;
-
- /* parse the options */
- for (i=0; i<len; i++)
- {
- /* try to get the various options */
- if (argv[i].equals("-package"))
- {
- /* must have an arg */
- if (++i >= len || argv[i].startsWith("-") ||
- argv[i].endsWith(".cup"))
- usage("-package must have a name argument");
-
- /* record the name */
- emit.package_name = argv[i];
- }
- else if (argv[i].equals("-parser"))
- {
- /* must have an arg */
- if (++i >= len || argv[i].startsWith("-") ||
- argv[i].endsWith(".cup"))
- usage("-parser must have a name argument");
-
- /* record the name */
- emit.parser_class_name = argv[i];
- }
- else if (argv[i].equals("-symbols"))
- {
- /* must have an arg */
- if (++i >= len || argv[i].startsWith("-") ||
- argv[i].endsWith(".cup"))
- usage("-symbols must have a name argument");
-
- /* record the name */
- emit.symbol_const_class_name = argv[i];
- }
- else if (argv[i].equals("-nonterms"))
- {
- include_non_terms = true;
- }
- else if (argv[i].equals("-expect"))
- {
- /* must have an arg */
- if (++i >= len || argv[i].startsWith("-") ||
- argv[i].endsWith(".cup"))
- usage("-expect must have a name argument");
-
- /* record the number */
- try {
- expect_conflicts = Integer.parseInt(argv[i]);
- } catch (NumberFormatException e) {
- usage("-expect must be followed by a decimal integer");
- }
- }
- else if (argv[i].equals("-compact_red")) opt_compact_red = true;
- else if (argv[i].equals("-nosummary")) no_summary = true;
- else if (argv[i].equals("-nowarn")) emit.nowarn = true;
- else if (argv[i].equals("-dump_states")) opt_dump_states = true;
- else if (argv[i].equals("-dump_tables")) opt_dump_tables = true;
- else if (argv[i].equals("-progress")) print_progress = true;
- else if (argv[i].equals("-dump_grammar")) opt_dump_grammar = true;
- else if (argv[i].equals("-dump"))
- opt_dump_states = opt_dump_tables = opt_dump_grammar = true;
- else if (argv[i].equals("-time")) opt_show_timing = true;
- else if (argv[i].equals("-debug")) opt_do_debug = true;
- /* frankf 6/18/96 */
- else if (argv[i].equals("-nopositions")) lr_values = false;
- /* CSA 12/21/97 */
- else if (argv[i].equals("-interface")) sym_interface = true;
- /* CSA 23-Jul-1999 */
- else if (argv[i].equals("-noscanner")) suppress_scanner = true;
- /* CSA 23-Jul-1999 */
- else if (argv[i].equals("-version")) {
- System.out.println(version.title_str);
- System.exit(1);
- }
- /* CSA 24-Jul-1999; suggestion by Jean Vaucher */
- else if (!argv[i].startsWith("-") && i==len-1) {
- /* use input from file. */
- try {
- System.setIn(new FileInputStream(argv[i]));
- } catch (java.io.FileNotFoundException e) {
- usage("Unable to open \"" + argv[i] +"\" for input");
- }
- }
- else
- {
- usage("Unrecognized option \"" + argv[i] + "\"");
- }
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /*-------*/
- /* Files */
- /*-------*/
-
- /** Input file. This is a buffered version of System.in. */
- protected static BufferedInputStream input_file;
-
- /** Output file for the parser class. */
- protected static PrintWriter parser_class_file;
-
- /** Output file for the symbol constant class. */
- protected static PrintWriter symbol_class_file;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Open various files used by the system. */
- protected static void open_files()
- {
- File fil;
- String out_name;
-
- /* open each of the output files */
-
- /* parser class */
- out_name = emit.parser_class_name + ".java";
- fil = new File(out_name);
- try {
- parser_class_file = new PrintWriter(
- new BufferedOutputStream(new FileOutputStream(fil), 4096));
- } catch(Exception e) {
- System.err.println("Can't open \"" + out_name + "\" for output");
- System.exit(3);
- }
-
- /* symbol constants class */
- out_name = emit.symbol_const_class_name + ".java";
- fil = new File(out_name);
- try {
- symbol_class_file = new PrintWriter(
- new BufferedOutputStream(new FileOutputStream(fil), 4096));
- } catch(Exception e) {
- System.err.println("Can't open \"" + out_name + "\" for output");
- System.exit(4);
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Close various files used by the system. */
- protected static void close_files() throws java.io.IOException
- {
- if (input_file != null) input_file.close();
- if (parser_class_file != null) parser_class_file.close();
- if (symbol_class_file != null) symbol_class_file.close();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Parse the grammar specification from standard input. This produces
- * sets of terminal, non-terminals, and productions which can be accessed
- * via static variables of the respective classes, as well as the setting
- * of various variables (mostly in the emit class) for small user supplied
- * items such as the code to scan with.
- */
- protected static void parse_grammar_spec() throws java.lang.Exception
- {
- parser parser_obj;
-
- /* create a parser and parse with it */
- parser_obj = new parser();
- try {
- if (opt_do_debug)
- parser_obj.debug_parse();
- else
- parser_obj.parse();
- } catch (Exception e)
- {
- /* something threw an exception. catch it and emit a message so we
- have a line number to work with, then re-throw it */
- lexer.emit_error("Internal error: Unexpected exception");
- throw e;
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Check for unused symbols. Unreduced productions get checked when
- * tables are created.
- */
- protected static void check_unused()
- {
- terminal term;
- non_terminal nt;
-
- /* check for unused terminals */
- for (Enumeration t = terminal.all(); t.hasMoreElements(); )
- {
- term = (terminal)t.nextElement();
-
- /* don't issue a message for EOF */
- if (term == terminal.EOF) continue;
-
- /* or error */
- if (term == terminal.error) continue;
-
- /* is this one unused */
- if (term.use_count() == 0)
- {
- /* count it and warn if we are doing warnings */
- emit.unused_term++;
- if (!emit.nowarn)
- {
- System.err.println("Warning: Terminal \"" + term.name() +
- "\" was declared but never used");
- lexer.warning_count++;
- }
- }
- }
-
- /* check for unused non terminals */
- for (Enumeration n = non_terminal.all(); n.hasMoreElements(); )
- {
- nt = (non_terminal)n.nextElement();
-
- /* is this one unused */
- if (nt.use_count() == 0)
- {
- /* count and warn if we are doing warnings */
- emit.unused_term++;
- if (!emit.nowarn)
- {
- System.err.println("Warning: Non terminal \"" + nt.name() +
- "\" was declared but never used");
- lexer.warning_count++;
- }
- }
- }
-
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . .*/
- /* . . Internal Results of Generating the Parser . .*/
- /* . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Start state in the overall state machine. */
- protected static lalr_state start_state;
-
- /** Resulting parse action table. */
- protected static parse_action_table action_table;
-
- /** Resulting reduce-goto table. */
- protected static parse_reduce_table reduce_table;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Build the (internal) parser from the previously parsed specification.
- * This includes:<ul>
- * <li> Computing nullability of non-terminals.
- * <li> Computing first sets of non-terminals and productions.
- * <li> Building the viable prefix recognizer machine.
- * <li> Filling in the (internal) parse tables.
- * <li> Checking for unreduced productions.
- * </ul>
- */
- protected static void build_parser() throws internal_error
- {
- /* compute nullability of all non terminals */
- if (opt_do_debug || print_progress)
- System.err.println(" Computing non-terminal nullability...");
- non_terminal.compute_nullability();
-
- nullability_end = System.currentTimeMillis();
-
- /* compute first sets of all non terminals */
- if (opt_do_debug || print_progress)
- System.err.println(" Computing first sets...");
- non_terminal.compute_first_sets();
-
- first_end = System.currentTimeMillis();
-
- /* build the LR viable prefix recognition machine */
- if (opt_do_debug || print_progress)
- System.err.println(" Building state machine...");
- start_state = lalr_state.build_machine(emit.start_production);
-
- machine_end = System.currentTimeMillis();
-
- /* build the LR parser action and reduce-goto tables */
- if (opt_do_debug || print_progress)
- System.err.println(" Filling in tables...");
- action_table = new parse_action_table();
- reduce_table = new parse_reduce_table();
- for (Enumeration st = lalr_state.all(); st.hasMoreElements(); )
- {
- lalr_state lst = (lalr_state)st.nextElement();
- lst.build_table_entries(
- action_table, reduce_table);
- }
-
- table_end = System.currentTimeMillis();
-
- /* check and warn for non-reduced productions */
- if (opt_do_debug || print_progress)
- System.err.println(" Checking for non-reduced productions...");
- action_table.check_reductions();
-
- reduce_check_end = System.currentTimeMillis();
-
- /* if we have more conflicts than we expected issue a message and die */
- if (emit.num_conflicts > expect_conflicts)
- {
- System.err.println("*** More conflicts encountered than expected " +
- "-- parser generation aborted");
- lexer.error_count++; // indicate the problem.
- // we'll die on return, after clean up.
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Call the emit routines necessary to write out the generated parser. */
- protected static void emit_parser() throws internal_error
- {
- emit.symbols(symbol_class_file, include_non_terms, sym_interface);
- emit.parser(parser_class_file, action_table, reduce_table,
- start_state.index(), emit.start_production, opt_compact_red,
- suppress_scanner);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Helper routine to optionally return a plural or non-plural ending.
- * @param val the numerical value determining plurality.
- */
- protected static String plural(int val)
- {
- if (val == 1)
- return "";
- else
- return "s";
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Emit a long summary message to standard error (System.err) which
- * summarizes what was found in the specification, how many states were
- * produced, how many conflicts were found, etc. A detailed timing
- * summary is also produced if it was requested by the user.
- * @param output_produced did the system get far enough to generate code.
- */
- protected static void emit_summary(boolean output_produced)
- {
- final_time = System.currentTimeMillis();
-
- if (no_summary) return;
-
- System.err.println("------- " + version.title_str +
- " Parser Generation Summary -------");
-
- /* error and warning count */
- System.err.println(" " + lexer.error_count + " error" +
- plural(lexer.error_count) + " and " + lexer.warning_count +
- " warning" + plural(lexer.warning_count));
-
- /* basic stats */
- System.err.print(" " + terminal.number() + " terminal" +
- plural(terminal.number()) + ", ");
- System.err.print(non_terminal.number() + " non-terminal" +
- plural(non_terminal.number()) + ", and ");
- System.err.println(production.number() + " production" +
- plural(production.number()) + " declared, ");
- System.err.println(" producing " + lalr_state.number() +
- " unique parse states.");
-
- /* unused symbols */
- System.err.println(" " + emit.unused_term + " terminal" +
- plural(emit.unused_term) + " declared but not used.");
- System.err.println(" " + emit.unused_non_term + " non-terminal" +
- plural(emit.unused_term) + " declared but not used.");
-
- /* productions that didn't reduce */
- System.err.println(" " + emit.not_reduced + " production" +
- plural(emit.not_reduced) + " never reduced.");
-
- /* conflicts */
- System.err.println(" " + emit.num_conflicts + " conflict" +
- plural(emit.num_conflicts) + " detected" +
- " (" + expect_conflicts + " expected).");
-
- /* code location */
- if (output_produced)
- System.err.println(" Code written to \"" + emit.parser_class_name +
- ".java\", and \"" + emit.symbol_const_class_name + ".java\".");
- else
- System.err.println(" No code produced.");
-
- if (opt_show_timing) show_times();
-
- System.err.println(
- "---------------------------------------------------- (" +
- version.version_str + ")");
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce the optional timing summary as part of an overall summary. */
- protected static void show_times()
- {
- long total_time = final_time - start_time;
-
- System.err.println(". . . . . . . . . . . . . . . . . . . . . . . . . ");
- System.err.println(" Timing Summary");
- System.err.println(" Total time "
- + timestr(final_time-start_time, total_time));
- System.err.println(" Startup "
- + timestr(prelim_end-start_time, total_time));
- System.err.println(" Parse "
- + timestr(parse_end-prelim_end, total_time) );
- if (check_end != 0)
- System.err.println(" Checking "
- + timestr(check_end-parse_end, total_time));
- if (check_end != 0 && build_end != 0)
- System.err.println(" Parser Build "
- + timestr(build_end-check_end, total_time));
- if (nullability_end != 0 && check_end != 0)
- System.err.println(" Nullability "
- + timestr(nullability_end-check_end, total_time));
- if (first_end != 0 && nullability_end != 0)
- System.err.println(" First sets "
- + timestr(first_end-nullability_end, total_time));
- if (machine_end != 0 && first_end != 0)
- System.err.println(" State build "
- + timestr(machine_end-first_end, total_time));
- if (table_end != 0 && machine_end != 0)
- System.err.println(" Table build "
- + timestr(table_end-machine_end, total_time));
- if (reduce_check_end != 0 && table_end != 0)
- System.err.println(" Checking "
- + timestr(reduce_check_end-table_end, total_time));
- if (emit_end != 0 && build_end != 0)
- System.err.println(" Code Output "
- + timestr(emit_end-build_end, total_time));
- if (emit.symbols_time != 0)
- System.err.println(" Symbols "
- + timestr(emit.symbols_time, total_time));
- if (emit.parser_time != 0)
- System.err.println(" Parser class "
- + timestr(emit.parser_time, total_time));
- if (emit.action_code_time != 0)
- System.err.println(" Actions "
- + timestr(emit.action_code_time, total_time));
- if (emit.production_table_time != 0)
- System.err.println(" Prod table "
- + timestr(emit.production_table_time, total_time));
- if (emit.action_table_time != 0)
- System.err.println(" Action tab "
- + timestr(emit.action_table_time, total_time));
- if (emit.goto_table_time != 0)
- System.err.println(" Reduce tab "
- + timestr(emit.goto_table_time, total_time));
-
- System.err.println(" Dump Output "
- + timestr(dump_end-emit_end, total_time));
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Helper routine to format a decimal based display of seconds and
- * percentage of total time given counts of milliseconds. Note: this
- * is broken for use with some instances of negative time (since we don't
- * use any negative time here, we let if be for now).
- * @param time_val the value being formatted (in ms).
- * @param total_time total time percentages are calculated against (in ms).
- */
- protected static String timestr(long time_val, long total_time)
- {
- boolean neg;
- long ms = 0;
- long sec = 0;
- long percent10;
- String pad;
-
- /* work with positives only */
- neg = time_val < 0;
- if (neg) time_val = -time_val;
-
- /* pull out seconds and ms */
- ms = time_val % 1000;
- sec = time_val / 1000;
-
- /* construct a pad to blank fill seconds out to 4 places */
- if (sec < 10)
- pad = " ";
- else if (sec < 100)
- pad = " ";
- else if (sec < 1000)
- pad = " ";
- else
- pad = "";
-
- /* calculate 10 times the percentage of total */
- percent10 = (time_val*1000)/total_time;
-
- /* build and return the output string */
- return (neg ? "-" : "") + pad + sec + "." +
- ((ms%1000)/100) + ((ms%100)/10) + (ms%10) + "sec" +
- " (" + percent10/10 + "." + percent10%10 + "%)";
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a human readable dump of the grammar. */
- public static void dump_grammar() throws internal_error
- {
- System.err.println("===== Terminals =====");
- for (int tidx=0, cnt=0; tidx < terminal.number(); tidx++, cnt++)
- {
- System.err.print("["+tidx+"]"+terminal.find(tidx).name()+" ");
- if ((cnt+1) % 5 == 0) System.err.println();
- }
- System.err.println();
- System.err.println();
-
- System.err.println("===== Non terminals =====");
- for (int nidx=0, cnt=0; nidx < non_terminal.number(); nidx++, cnt++)
- {
- System.err.print("["+nidx+"]"+non_terminal.find(nidx).name()+" ");
- if ((cnt+1) % 5 == 0) System.err.println();
- }
- System.err.println();
- System.err.println();
-
-
- System.err.println("===== Productions =====");
- for (int pidx=0; pidx < production.number(); pidx++)
- {
- production prod = production.find(pidx);
- System.err.print("["+pidx+"] "+prod.lhs().the_symbol().name() + " ::= ");
- for (int i=0; i<prod.rhs_length(); i++)
- if (prod.rhs(i).is_action())
- System.err.print("{action} ");
- else
- System.err.print(
- ((symbol_part)prod.rhs(i)).the_symbol().name() + " ");
- System.err.println();
- }
- System.err.println();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a (semi-) human readable dump of the complete viable prefix
- * recognition state machine.
- */
- public static void dump_machine()
- {
- lalr_state ordered[] = new lalr_state[lalr_state.number()];
-
- /* put the states in sorted order for a nicer display */
- for (Enumeration s = lalr_state.all(); s.hasMoreElements(); )
- {
- lalr_state st = (lalr_state)s.nextElement();
- ordered[st.index()] = st;
- }
-
- System.err.println("===== Viable Prefix Recognizer =====");
- for (int i = 0; i<lalr_state.number(); i++)
- {
- if (ordered[i] == start_state) System.err.print("START ");
- System.err.println(ordered[i]);
- System.err.println("-------------------");
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a (semi-) human readable dumps of the parse tables */
- public static void dump_tables()
- {
- System.err.println(action_table);
- System.err.println(reduce_table);
- }
-
- /*-----------------------------------------------------------*/
-
-}
-
+++ /dev/null
-
-package java_cup;
-
-/**
- * This class represents a part of a production which contains an
- * action. These are eventually eliminated from productions and converted
- * to trailing actions by factoring out with a production that derives the
- * empty string (and ends with this action).
- *
- * @see java_cup.production
- * @version last update: 11/25/95
- * @author Scott Hudson
- */
-
-public class action_part extends production_part {
-
- /*-----------------------------------------------------------*/
- /*--- Constructors ------------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor.
- * @param code_str string containing the actual user code.
- */
- public action_part(String code_str)
- {
- super(/* never have a label on code */null);
- _code_string = code_str;
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** String containing code for the action in question. */
- protected String _code_string;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** String containing code for the action in question. */
- public String code_string() {return _code_string;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Set the code string. */
- public void set_code_string(String new_str) {_code_string = new_str;}
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Override to report this object as an action. */
- public boolean is_action() { return true; }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison for properly typed object. */
- public boolean equals(action_part other)
- {
- /* compare the strings */
- return other != null && super.equals(other) &&
- other.code_string().equals(code_string());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof action_part))
- return false;
- else
- return equals((action_part)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a hash code. */
- public int hashCode()
- {
- return super.hashCode() ^
- (code_string()==null ? 0 : code_string().hashCode());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string. */
- public String toString()
- {
- return super.toString() + "{" + code_string() + "}";
- }
-
- /*-----------------------------------------------------------*/
-}
+++ /dev/null
-
-package java_cup;
-
-/** A specialized version of a production used when we split an existing
- * production in order to remove an embedded action. Here we keep a bit
- * of extra bookkeeping so that we know where we came from.
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-
-public class action_production extends production {
-
- /** Constructor.
- * @param base the production we are being factored out of.
- * @param lhs_sym the LHS symbol for this production.
- * @param rhs_parts array of production parts for the RHS.
- * @param rhs_len how much of the rhs_parts array is valid.
- * @param action_str the trailing reduce action for this production.
- */
- public action_production(
- production base,
- non_terminal lhs_sym,
- production_part rhs_parts[],
- int rhs_len,
- String action_str)
- throws internal_error
- {
- super(lhs_sym, rhs_parts, rhs_len, action_str);
- _base_production = base;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The production we were taken out of. */
- protected production _base_production;
-
- /** The production we were taken out of. */
- public production base_production() {return _base_production;}
-}
+++ /dev/null
-package java_cup;
-
-/* Defines integers that represent the associativity of terminals
- * @version last updated: 7/3/96
- * @author Frank Flannery
- */
-
-public class assoc {
-
- /* various associativities, no_prec being the default value */
- public final static int left = 0;
- public final static int right = 1;
- public final static int nonassoc = 2;
- public final static int no_prec = -1;
-
-}
\ No newline at end of file
+++ /dev/null
-package java_cup;
-
-import java.io.PrintWriter;
-import java.util.Stack;
-import java.util.Enumeration;
-import java.util.Date;
-
-/**
- * This class handles emitting generated code for the resulting parser.
- * The various parse tables must be constructed, etc. before calling any
- * routines in this class.<p>
- *
- * Three classes are produced by this code:
- * <dl>
- * <dt> symbol constant class
- * <dd> this contains constant declarations for each terminal (and
- * optionally each non-terminal).
- * <dt> action class
- * <dd> this non-public class contains code to invoke all the user actions
- * that were embedded in the parser specification.
- * <dt> parser class
- * <dd> the specialized parser class consisting primarily of some user
- * supplied general and initialization code, and the parse tables.
- * </dl><p>
- *
- * Three parse tables are created as part of the parser class:
- * <dl>
- * <dt> production table
- * <dd> lists the LHS non terminal number, and the length of the RHS of
- * each production.
- * <dt> action table
- * <dd> for each state of the parse machine, gives the action to be taken
- * (shift, reduce, or error) under each lookahead symbol.<br>
- * <dt> reduce-goto table
- * <dd> when a reduce on a given production is taken, the parse stack is
- * popped back a number of elements corresponding to the RHS of the
- * production. This reveals a prior state, which we transition out
- * of under the LHS non terminal symbol for the production (as if we
- * had seen the LHS symbol rather than all the symbols matching the
- * RHS). This table is indexed by non terminal numbers and indicates
- * how to make these transitions.
- * </dl><p>
- *
- * In addition to the method interface, this class maintains a series of
- * public global variables and flags indicating how misc. parts of the code
- * and other output is to be produced, and counting things such as number of
- * conflicts detected (see the source code and public variables below for
- * more details).<p>
- *
- * This class is "static" (contains only static data and methods).<p>
- *
- * @see java_cup.main
- * @version last update: 11/25/95
- * @author Scott Hudson
- */
-
-/* Major externally callable routines here include:
- symbols - emit the symbol constant class
- parser - emit the parser class
-
- In addition the following major internal routines are provided:
- emit_package - emit a package declaration
- emit_action_code - emit the class containing the user's actions
- emit_production_table - emit declaration and init for the production table
- do_action_table - emit declaration and init for the action table
- do_reduce_table - emit declaration and init for the reduce-goto table
-
- Finally, this class uses a number of public instance variables to communicate
- optional parameters and flags used to control how code is generated,
- as well as to report counts of various things (such as number of conflicts
- detected). These include:
-
- prefix - a prefix string used to prefix names that would
- otherwise "pollute" someone else's name space.
- package_name - name of the package emitted code is placed in
- (or null for an unnamed package.
- symbol_const_class_name - name of the class containing symbol constants.
- parser_class_name - name of the class for the resulting parser.
- action_code - user supplied declarations and other code to be
- placed in action class.
- parser_code - user supplied declarations and other code to be
- placed in parser class.
- init_code - user supplied code to be executed as the parser
- is being initialized.
- scan_code - user supplied code to get the next Symbol.
- start_production - the start production for the grammar.
- import_list - list of imports for use with action class.
- num_conflicts - number of conflicts detected.
- nowarn - true if we are not to issue warning messages.
- not_reduced - count of number of productions that never reduce.
- unused_term - count of unused terminal symbols.
- unused_non_term - count of unused non terminal symbols.
- *_time - a series of symbols indicating how long various
- sub-parts of code generation took (used to produce
- optional time reports in main).
-*/
-
-public class emit {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Only constructor is private so no instances can be created. */
- private emit() { }
-
- /*-----------------------------------------------------------*/
- /*--- Static (Class) Variables ------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The prefix placed on names that pollute someone else's name space. */
- public static String prefix = "CUP$";
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Package that the resulting code goes into (null is used for unnamed). */
- public static String package_name = null;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Name of the generated class for symbol constants. */
- public static String symbol_const_class_name = "sym";
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Name of the generated parser class. */
- public static String parser_class_name = "parser";
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** User declarations for direct inclusion in user action class. */
- public static String action_code = null;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** User declarations for direct inclusion in parser class. */
- public static String parser_code = null;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** User code for user_init() which is called during parser initialization. */
- public static String init_code = null;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** User code for scan() which is called to get the next Symbol. */
- public static String scan_code = null;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The start production of the grammar. */
- public static production start_production = null;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** List of imports (Strings containing class names) to go with actions. */
- public static Stack import_list = new Stack();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Number of conflict found while building tables. */
- public static int num_conflicts = 0;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Do we skip warnings? */
- public static boolean nowarn = false;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Count of the number on non-reduced productions found. */
- public static int not_reduced = 0;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Count of unused terminals. */
- public static int unused_term = 0;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Count of unused non terminals. */
- public static int unused_non_term = 0;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /* Timing values used to produce timing report in main.*/
-
- /** Time to produce symbol constant class. */
- public static long symbols_time = 0;
-
- /** Time to produce parser class. */
- public static long parser_time = 0;
-
- /** Time to produce action code class. */
- public static long action_code_time = 0;
-
- /** Time to produce the production table. */
- public static long production_table_time = 0;
-
- /** Time to produce the action table. */
- public static long action_table_time = 0;
-
- /** Time to produce the reduce-goto table. */
- public static long goto_table_time = 0;
-
- /* frankf 6/18/96 */
- protected static boolean _lr_values;
-
- /** whether or not to emit code for left and right values */
- public static boolean lr_values() {return _lr_values;}
- protected static void set_lr_values(boolean b) { _lr_values = b;}
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Build a string with the standard prefix.
- * @param str string to prefix.
- */
- protected static String pre(String str) {
- return prefix + parser_class_name + "$" + str;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Emit a package spec if the user wants one.
- * @param out stream to produce output on.
- */
- protected static void emit_package(PrintWriter out)
- {
- /* generate a package spec if we have a name for one */
- if (package_name != null) {
- out.println("package " + package_name + ";"); out.println();
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Emit code for the symbol constant class, optionally including non terms,
- * if they have been requested.
- * @param out stream to produce output on.
- * @param emit_non_terms do we emit constants for non terminals?
- * @param sym_interface should we emit an interface, rather than a class?
- */
- public static void symbols(PrintWriter out,
- boolean emit_non_terms, boolean sym_interface)
- {
- terminal term;
- non_terminal nt;
- String class_or_interface = (sym_interface)?"interface":"class";
-
- long start_time = System.currentTimeMillis();
-
- /* top of file */
- out.println();
- out.println("//----------------------------------------------------");
- out.println("// The following code was generated by " +
- version.title_str);
- out.println("// " + new Date());
- out.println("//----------------------------------------------------");
- out.println();
- emit_package(out);
-
- /* class header */
- out.println("/** CUP generated " + class_or_interface +
- " containing symbol constants. */");
- out.println("public " + class_or_interface + " " +
- symbol_const_class_name + " {");
-
- out.println(" /* terminals */");
-
- /* walk over the terminals */ /* later might sort these */
- for (Enumeration e = terminal.all(); e.hasMoreElements(); )
- {
- term = (terminal)e.nextElement();
-
- /* output a constant decl for the terminal */
- out.println(" public static final int " + term.name() + " = " +
- term.index() + ";");
- }
-
- /* do the non terminals if they want them (parser doesn't need them) */
- if (emit_non_terms)
- {
- out.println();
- out.println(" /* non terminals */");
-
- /* walk over the non terminals */ /* later might sort these */
- for (Enumeration e = non_terminal.all(); e.hasMoreElements(); )
- {
- nt = (non_terminal)e.nextElement();
-
- /* output a constant decl for the terminal */
- out.println(" static final int " + nt.name() + " = " +
- nt.index() + ";");
- }
- }
-
- /* end of class */
- out.println("}");
- out.println();
-
- symbols_time = System.currentTimeMillis() - start_time;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Emit code for the non-public class holding the actual action code.
- * @param out stream to produce output on.
- * @param start_prod the start production of the grammar.
- */
- protected static void emit_action_code(PrintWriter out, production start_prod)
- throws internal_error
- {
- production prod;
-
- long start_time = System.currentTimeMillis();
-
- /* class header */
- out.println();
- out.println(
- "/** Cup generated class to encapsulate user supplied action code.*/"
- );
- out.println("class " + pre("actions") + " {");
-
- /* user supplied code */
- if (action_code != null)
- {
- out.println();
- out.println(action_code);
- }
-
- /* field for parser object */
- out.println(" private final "+parser_class_name+" parser;");
-
- /* constructor */
- out.println();
- out.println(" /** Constructor */");
- out.println(" " + pre("actions") + "("+parser_class_name+" parser) {");
- out.println(" this.parser = parser;");
- out.println(" }");
-
- /* action method head */
- out.println();
- out.println(" /** Method with the actual generated action code. */");
- out.println(" public final java_cup.runtime.Symbol " +
- pre("do_action") + "(");
- out.println(" int " + pre("act_num,"));
- out.println(" java_cup.runtime.lr_parser " + pre("parser,"));
- out.println(" java.util.Stack " + pre("stack,"));
- out.println(" int " + pre("top)"));
- out.println(" throws java.lang.Exception");
- out.println(" {");
-
- /* declaration of result symbol */
- /* New declaration!! now return Symbol
- 6/13/96 frankf */
- out.println(" /* Symbol object for return from actions */");
- out.println(" java_cup.runtime.Symbol " + pre("result") + ";");
- out.println();
-
- /* switch top */
- out.println(" /* select the action based on the action number */");
- out.println(" switch (" + pre("act_num") + ")");
- out.println(" {");
-
- /* emit action code for each production as a separate case */
- for (Enumeration p = production.all(); p.hasMoreElements(); )
- {
- prod = (production)p.nextElement();
-
- /* case label */
- out.println(" /*. . . . . . . . . . . . . . . . . . . .*/");
- out.println(" case " + prod.index() + ": // " +
- prod.to_simple_string());
-
- /* give them their own block to work in */
- out.println(" {");
-
- /* create the result symbol */
- /*make the variable RESULT which will point to the new Symbol (see below)
- and be changed by action code
- 6/13/96 frankf */
- out.println(" " + prod.lhs().the_symbol().stack_type() +
- " RESULT = null;");
-
- /* Add code to propagate RESULT assignments that occur in
- * action code embedded in a production (ie, non-rightmost
- * action code). 24-Mar-1998 CSA
- */
- for (int i=0; i<prod.rhs_length(); i++) {
- // only interested in non-terminal symbols.
- if (!(prod.rhs(i) instanceof symbol_part)) continue;
- symbol s = ((symbol_part)prod.rhs(i)).the_symbol();
- if (!(s instanceof non_terminal)) continue;
- // skip this non-terminal unless it corresponds to
- // an embedded action production.
- if (((non_terminal)s).is_embedded_action == false) continue;
- // OK, it fits. Make a conditional assignment to RESULT.
- int index = prod.rhs_length() - i - 1; // last rhs is on top.
- out.println(" " + "// propagate RESULT from " +
- s.name());
- out.println(" " + "if ( " +
- "((java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt("
- + emit.pre("top") + "-" + index + ")).value != null )");
- out.println(" " + "RESULT = " +
- "(" + prod.lhs().the_symbol().stack_type() + ") " +
- "((java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt("
- + emit.pre("top") + "-" + index + ")).value;");
- }
-
- /* if there is an action string, emit it */
- if (prod.action() != null && prod.action().code_string() != null &&
- !prod.action().equals(""))
- out.println(prod.action().code_string());
-
- /* here we have the left and right values being propagated.
- must make this a command line option.
- frankf 6/18/96 */
-
- /* Create the code that assigns the left and right values of
- the new Symbol that the production is reducing to */
- if (emit.lr_values()) {
- int loffset;
- String leftstring, rightstring;
- int roffset = 0;
- rightstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" +
- emit.pre("top") + "-" + roffset + ")).right";
- if (prod.rhs_length() == 0)
- leftstring = rightstring;
- else {
- loffset = prod.rhs_length() - 1;
- leftstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" +
- emit.pre("top") + "-" + loffset + ")).left";
- }
- out.println(" " + pre("result") + " = new java_cup.runtime.Symbol(" +
- prod.lhs().the_symbol().index() + "/*" +
- prod.lhs().the_symbol().name() + "*/" +
- ", " + leftstring + ", " + rightstring + ", RESULT);");
- } else {
- out.println(" " + pre("result") + " = new java_cup.runtime.Symbol(" +
- prod.lhs().the_symbol().index() + "/*" +
- prod.lhs().the_symbol().name() + "*/" +
- ", RESULT);");
- }
-
- /* end of their block */
- out.println(" }");
-
- /* if this was the start production, do action for accept */
- if (prod == start_prod)
- {
- out.println(" /* ACCEPT */");
- out.println(" " + pre("parser") + ".done_parsing();");
- }
-
- /* code to return lhs symbol */
- out.println(" return " + pre("result") + ";");
- out.println();
- }
-
- /* end of switch */
- out.println(" /* . . . . . .*/");
- out.println(" default:");
- out.println(" throw new Exception(");
- out.println(" \"Invalid action number found in " +
- "internal parse table\");");
- out.println();
- out.println(" }");
-
- /* end of method */
- out.println(" }");
-
- /* end of class */
- out.println("}");
- out.println();
-
- action_code_time = System.currentTimeMillis() - start_time;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Emit the production table.
- * @param out stream to produce output on.
- */
- protected static void emit_production_table(PrintWriter out)
- {
- production all_prods[];
- production prod;
-
- long start_time = System.currentTimeMillis();
-
- /* collect up the productions in order */
- all_prods = new production[production.number()];
- for (Enumeration p = production.all(); p.hasMoreElements(); )
- {
- prod = (production)p.nextElement();
- all_prods[prod.index()] = prod;
- }
-
- // make short[][]
- short[][] prod_table = new short[production.number()][2];
- for (int i = 0; i<production.number(); i++)
- {
- prod = all_prods[i];
- // { lhs symbol , rhs size }
- prod_table[i][0] = (short) prod.lhs().the_symbol().index();
- prod_table[i][1] = (short) prod.rhs_length();
- }
- /* do the top of the table */
- out.println();
- out.println(" /** Production table. */");
- out.println(" protected static final short _production_table[][] = ");
- out.print (" unpackFromStrings(");
- do_table_as_string(out, prod_table);
- out.println(");");
-
- /* do the public accessor method */
- out.println();
- out.println(" /** Access to production table. */");
- out.println(" public short[][] production_table() " +
- "{return _production_table;}");
-
- production_table_time = System.currentTimeMillis() - start_time;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Emit the action table.
- * @param out stream to produce output on.
- * @param act_tab the internal representation of the action table.
- * @param compact_reduces do we use the most frequent reduce as default?
- */
- protected static void do_action_table(
- PrintWriter out,
- parse_action_table act_tab,
- boolean compact_reduces)
- throws internal_error
- {
- parse_action_row row;
- parse_action act;
- int red;
-
- long start_time = System.currentTimeMillis();
-
- /* collect values for the action table */
- short[][] action_table = new short[act_tab.num_states()][];
- /* do each state (row) of the action table */
- for (int i = 0; i < act_tab.num_states(); i++)
- {
- /* get the row */
- row = act_tab.under_state[i];
-
- /* determine the default for the row */
- if (compact_reduces)
- row.compute_default();
- else
- row.default_reduce = -1;
-
- /* make temporary table for the row. */
- short[] temp_table = new short[2*row.size()];
- int nentries = 0;
-
- /* do each column */
- for (int j = 0; j < row.size(); j++)
- {
- /* extract the action from the table */
- act = row.under_term[j];
-
- /* skip error entries these are all defaulted out */
- if (act.kind() != parse_action.ERROR)
- {
- /* first put in the symbol index, then the actual entry */
-
- /* shifts get positive entries of state number + 1 */
- if (act.kind() == parse_action.SHIFT)
- {
- /* make entry */
- temp_table[nentries++] = (short) j;
- temp_table[nentries++] = (short)
- (((shift_action)act).shift_to().index() + 1);
- }
-
- /* reduce actions get negated entries of production# + 1 */
- else if (act.kind() == parse_action.REDUCE)
- {
- /* if its the default entry let it get defaulted out */
- red = ((reduce_action)act).reduce_with().index();
- if (red != row.default_reduce) {
- /* make entry */
- temp_table[nentries++] = (short) j;
- temp_table[nentries++] = (short) (-(red+1));
- }
- } else if (act.kind() == parse_action.NONASSOC)
- {
- /* do nothing, since we just want a syntax error */
- }
- /* shouldn't be anything else */
- else
- throw new internal_error("Unrecognized action code " +
- act.kind() + " found in parse table");
- }
- }
-
- /* now we know how big to make the row */
- action_table[i] = new short[nentries + 2];
- System.arraycopy(temp_table, 0, action_table[i], 0, nentries);
-
- /* finish off the row with a default entry */
- action_table[i][nentries++] = -1;
- if (row.default_reduce != -1)
- action_table[i][nentries++] = (short) (-(row.default_reduce+1));
- else
- action_table[i][nentries++] = 0;
- }
-
- /* finish off the init of the table */
- out.println();
- out.println(" /** Parse-action table. */");
- out.println(" protected static final short[][] _action_table = ");
- out.print (" unpackFromStrings(");
- do_table_as_string(out, action_table);
- out.println(");");
-
- /* do the public accessor method */
- out.println();
- out.println(" /** Access to parse-action table. */");
- out.println(" public short[][] action_table() {return _action_table;}");
-
- action_table_time = System.currentTimeMillis() - start_time;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Emit the reduce-goto table.
- * @param out stream to produce output on.
- * @param red_tab the internal representation of the reduce-goto table.
- */
- protected static void do_reduce_table(
- PrintWriter out,
- parse_reduce_table red_tab)
- {
- lalr_state goto_st;
- parse_action act;
-
- long start_time = System.currentTimeMillis();
-
- /* collect values for reduce-goto table */
- short[][] reduce_goto_table = new short[red_tab.num_states()][];
- /* do each row of the reduce-goto table */
- for (int i=0; i<red_tab.num_states(); i++)
- {
- /* make temporary table for the row. */
- short[] temp_table = new short[2*red_tab.under_state[i].size()];
- int nentries = 0;
- /* do each entry in the row */
- for (int j=0; j<red_tab.under_state[i].size(); j++)
- {
- /* get the entry */
- goto_st = red_tab.under_state[i].under_non_term[j];
-
- /* if we have none, skip it */
- if (goto_st != null)
- {
- /* make entries for the index and the value */
- temp_table[nentries++] = (short) j;
- temp_table[nentries++] = (short) goto_st.index();
- }
- }
- /* now we know how big to make the row. */
- reduce_goto_table[i] = new short[nentries+2];
- System.arraycopy(temp_table, 0, reduce_goto_table[i], 0, nentries);
-
- /* end row with default value */
- reduce_goto_table[i][nentries++] = -1;
- reduce_goto_table[i][nentries++] = -1;
- }
-
- /* emit the table. */
- out.println();
- out.println(" /** <code>reduce_goto</code> table. */");
- out.println(" protected static final short[][] _reduce_table = ");
- out.print (" unpackFromStrings(");
- do_table_as_string(out, reduce_goto_table);
- out.println(");");
-
- /* do the public accessor method */
- out.println();
- out.println(" /** Access to <code>reduce_goto</code> table. */");
- out.println(" public short[][] reduce_table() {return _reduce_table;}");
- out.println();
-
- goto_table_time = System.currentTimeMillis() - start_time;
- }
-
- // print a string array encoding the given short[][] array.
- protected static void do_table_as_string(PrintWriter out, short[][] sa) {
- out.println("new String[] {");
- out.print(" \"");
- int nchar=0, nbytes=0;
- nbytes+=do_escaped(out, (char)(sa.length>>16));
- nchar =do_newline(out, nchar, nbytes);
- nbytes+=do_escaped(out, (char)(sa.length&0xFFFF));
- nchar =do_newline(out, nchar, nbytes);
- for (int i=0; i<sa.length; i++) {
- nbytes+=do_escaped(out, (char)(sa[i].length>>16));
- nchar =do_newline(out, nchar, nbytes);
- nbytes+=do_escaped(out, (char)(sa[i].length&0xFFFF));
- nchar =do_newline(out, nchar, nbytes);
- for (int j=0; j<sa[i].length; j++) {
- // contents of string are (value+2) to allow for common -1, 0 cases
- // (UTF-8 encoding is most efficient for 0<c<0x80)
- nbytes+=do_escaped(out, (char)(2+sa[i][j]));
- nchar =do_newline(out, nchar, nbytes);
- }
- }
- out.print("\" }");
- }
- // split string if it is very long; start new line occasionally for neatness
- protected static int do_newline(PrintWriter out, int nchar, int nbytes) {
- if (nbytes > 65500) { out.println("\", "); out.print(" \""); }
- else if (nchar > 11) { out.println("\" +"); out.print(" \""); }
- else return nchar+1;
- return 0;
- }
- // output an escape sequence for the given character code.
- protected static int do_escaped(PrintWriter out, char c) {
- StringBuffer escape = new StringBuffer();
- if (c <= 0xFF) {
- escape.append(Integer.toOctalString(c));
- while(escape.length() < 3) escape.insert(0, '0');
- } else {
- escape.append(Integer.toHexString(c));
- while(escape.length() < 4) escape.insert(0, '0');
- escape.insert(0, 'u');
- }
- escape.insert(0, '\\');
- out.print(escape.toString());
-
- // return number of bytes this takes up in UTF-8 encoding.
- if (c == 0) return 2;
- if (c >= 0x01 && c <= 0x7F) return 1;
- if (c >= 0x80 && c <= 0x7FF) return 2;
- return 3;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Emit the parser subclass with embedded tables.
- * @param out stream to produce output on.
- * @param action_table internal representation of the action table.
- * @param reduce_table internal representation of the reduce-goto table.
- * @param start_st start state of the parse machine.
- * @param start_prod start production of the grammar.
- * @param compact_reduces do we use most frequent reduce as default?
- * @param suppress_scanner should scanner be suppressed for compatibility?
- */
- public static void parser(
- PrintWriter out,
- parse_action_table action_table,
- parse_reduce_table reduce_table,
- int start_st,
- production start_prod,
- boolean compact_reduces,
- boolean suppress_scanner)
- throws internal_error
- {
- long start_time = System.currentTimeMillis();
-
- /* top of file */
- out.println();
- out.println("//----------------------------------------------------");
- out.println("// The following code was generated by " +
- version.title_str);
- out.println("// " + new Date());
- out.println("//----------------------------------------------------");
- out.println();
- emit_package(out);
-
- /* user supplied imports */
- for (int i = 0; i < import_list.size(); i++)
- out.println("import " + import_list.elementAt(i) + ";");
-
- /* class header */
- out.println();
- out.println("/** "+version.title_str+" generated parser.");
- out.println(" * @version " + new Date());
- out.println(" */");
- out.println("public class " + parser_class_name +
- " extends java_cup.runtime.lr_parser {");
-
- /* constructors [CSA/davidm, 24-jul-99] */
- out.println();
- out.println(" /** Default constructor. */");
- out.println(" public " + parser_class_name + "() {super();}");
- if (!suppress_scanner) {
- out.println();
- out.println(" /** Constructor which sets the default scanner. */");
- out.println(" public " + parser_class_name +
- "(java_cup.runtime.Scanner s) {super(s);}");
- }
-
- /* emit the various tables */
- emit_production_table(out);
- do_action_table(out, action_table, compact_reduces);
- do_reduce_table(out, reduce_table);
-
- /* instance of the action encapsulation class */
- out.println(" /** Instance of action encapsulation class. */");
- out.println(" protected " + pre("actions") + " action_obj;");
- out.println();
-
- /* action object initializer */
- out.println(" /** Action encapsulation object initializer. */");
- out.println(" protected void init_actions()");
- out.println(" {");
- out.println(" action_obj = new " + pre("actions") + "(this);");
- out.println(" }");
- out.println();
-
- /* access to action code */
- out.println(" /** Invoke a user supplied parse action. */");
- out.println(" public java_cup.runtime.Symbol do_action(");
- out.println(" int act_num,");
- out.println(" java_cup.runtime.lr_parser parser,");
- out.println(" java.util.Stack stack,");
- out.println(" int top)");
- out.println(" throws java.lang.Exception");
- out.println(" {");
- out.println(" /* call code in generated class */");
- out.println(" return action_obj." + pre("do_action(") +
- "act_num, parser, stack, top);");
- out.println(" }");
- out.println("");
-
-
- /* method to tell the parser about the start state */
- out.println(" /** Indicates start state. */");
- out.println(" public int start_state() {return " + start_st + ";}");
-
- /* method to indicate start production */
- out.println(" /** Indicates start production. */");
- out.println(" public int start_production() {return " +
- start_production.index() + ";}");
- out.println();
-
- /* methods to indicate EOF and error symbol indexes */
- out.println(" /** <code>EOF</code> Symbol index. */");
- out.println(" public int EOF_sym() {return " + terminal.EOF.index() +
- ";}");
- out.println();
- out.println(" /** <code>error</code> Symbol index. */");
- out.println(" public int error_sym() {return " + terminal.error.index() +
- ";}");
- out.println();
-
- /* user supplied code for user_init() */
- if (init_code != null)
- {
- out.println();
- out.println(" /** User initialization code. */");
- out.println(" public void user_init() throws java.lang.Exception");
- out.println(" {");
- out.println(init_code);
- out.println(" }");
- }
-
- /* user supplied code for scan */
- if (scan_code != null)
- {
- out.println();
- out.println(" /** Scan to get the next Symbol. */");
- out.println(" public java_cup.runtime.Symbol scan()");
- out.println(" throws java.lang.Exception");
- out.println(" {");
- out.println(scan_code);
- out.println(" }");
- }
-
- /* user supplied code */
- if (parser_code != null)
- {
- out.println();
- out.println(parser_code);
- }
-
- /* end of class */
- out.println("}");
-
- /* put out the action code class */
- emit_action_code(out, start_prod);
-
- parser_time = System.currentTimeMillis() - start_time;
- }
-
- /*-----------------------------------------------------------*/
-}
+++ /dev/null
-
-package java_cup;
-
-/** Exception subclass for reporting internal errors in JavaCup. */
-public class internal_error extends Exception
- {
- /** Constructor with a message */
- public internal_error(String msg)
- {
- super(msg);
- }
-
- /** Method called to do a forced error exit on an internal error
- for cases when we can't actually throw the exception. */
- public void crash()
- {
- System.err.println("JavaCUP Fatal Internal Error Detected");
- System.err.println(getMessage());
- printStackTrace();
- System.exit(-1);
- }
- }
+++ /dev/null
-package java_cup;
-
-import java.util.Stack;
-import java.util.Enumeration;
-
-/** This class represents an LALR item. Each LALR item consists of
- * a production, a "dot" at a position within that production, and
- * a set of lookahead symbols (terminal). (The first two of these parts
- * are provide by the super class). An item is designed to represent a
- * configuration that the parser may be in. For example, an item of the
- * form: <pre>
- * [A ::= B * C d E , {a,b,c}]
- * </pre>
- * indicates that the parser is in the middle of parsing the production <pre>
- * A ::= B C d E
- * </pre>
- * that B has already been parsed, and that we will expect to see a lookahead
- * of either a, b, or c once the complete RHS of this production has been
- * found.<p>
- *
- * Items may initially be missing some items from their lookahead sets.
- * Links are maintained from each item to the set of items that would need
- * to be updated if symbols are added to its lookahead set. During
- * "lookahead propagation", we add symbols to various lookahead sets and
- * propagate these changes across these dependency links as needed.
- *
- * @see java_cup.lalr_item_set
- * @see java_cup.lalr_state
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-public class lalr_item extends lr_item_core {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Full constructor.
- * @param prod the production for the item.
- * @param pos the position of the "dot" within the production.
- * @param look the set of lookahead symbols.
- */
- public lalr_item(production prod, int pos, terminal_set look)
- throws internal_error
- {
- super(prod, pos);
- _lookahead = look;
- _propagate_items = new Stack();
- needs_propagation = true;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor with default position (dot at start).
- * @param prod the production for the item.
- * @param look the set of lookahead symbols.
- */
- public lalr_item(production prod, terminal_set look) throws internal_error
- {
- this(prod,0,look);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor with default position and empty lookahead set.
- * @param prod the production for the item.
- */
- public lalr_item(production prod) throws internal_error
- {
- this(prod,0,new terminal_set());
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The lookahead symbols of the item. */
- protected terminal_set _lookahead;
-
- /** The lookahead symbols of the item. */
- public terminal_set lookahead() {return _lookahead;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Links to items that the lookahead needs to be propagated to. */
- protected Stack _propagate_items;
-
- /** Links to items that the lookahead needs to be propagated to */
- public Stack propagate_items() {return _propagate_items;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Flag to indicate that this item needs to propagate its lookahead
- * (whether it has changed or not).
- */
- protected boolean needs_propagation;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Add a new item to the set of items we propagate to. */
- public void add_propagate(lalr_item prop_to)
- {
- _propagate_items.push(prop_to);
- needs_propagation = true;
- }
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Propagate incoming lookaheads through this item to others need to
- * be changed.
- * @params incoming symbols to potentially be added to lookahead of this item.
- */
- public void propagate_lookaheads(terminal_set incoming) throws internal_error
- {
- boolean change = false;
-
- /* if we don't need to propagate, then bail out now */
- if (!needs_propagation && (incoming == null || incoming.empty()))
- return;
-
- /* if we have null incoming, treat as an empty set */
- if (incoming != null)
- {
- /* add the incoming to the lookahead of this item */
- change = lookahead().add(incoming);
- }
-
- /* if we changed or need it anyway, propagate across our links */
- if (change || needs_propagation)
- {
- /* don't need to propagate again */
- needs_propagation = false;
-
- /* propagate our lookahead into each item we are linked to */
- for (int i = 0; i < propagate_items().size(); i++)
- ((lalr_item)propagate_items().elementAt(i))
- .propagate_lookaheads(lookahead());
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce the new lalr_item that results from shifting the dot one position
- * to the right.
- */
- public lalr_item shift() throws internal_error
- {
- lalr_item result;
-
- /* can't shift if we have dot already at the end */
- if (dot_at_end())
- throw new internal_error("Attempt to shift past end of an lalr_item");
-
- /* create the new item w/ the dot shifted by one */
- result = new lalr_item(the_production(), dot_pos()+1,
- new terminal_set(lookahead()));
-
- /* change in our lookahead needs to be propagated to this item */
- add_propagate(result);
-
- return result;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Calculate lookahead representing symbols that could appear after the
- * symbol that the dot is currently in front of. Note: this routine must
- * not be invoked before first sets and nullability has been calculated
- * for all non terminals.
- */
- public terminal_set calc_lookahead(terminal_set lookahead_after)
- throws internal_error
- {
- terminal_set result;
- int pos;
- production_part part;
- symbol sym;
-
- /* sanity check */
- if (dot_at_end())
- throw new internal_error(
- "Attempt to calculate a lookahead set with a completed item");
-
- /* start with an empty result */
- result = new terminal_set();
-
- /* consider all nullable symbols after the one to the right of the dot */
- for (pos = dot_pos()+1; pos < the_production().rhs_length(); pos++)
- {
- part = the_production().rhs(pos);
-
- /* consider what kind of production part it is -- skip actions */
- if (!part.is_action())
- {
- sym = ((symbol_part)part).the_symbol();
-
- /* if its a terminal add it in and we are done */
- if (!sym.is_non_term())
- {
- result.add((terminal)sym);
- return result;
- }
- else
- {
- /* otherwise add in first set of the non terminal */
- result.add(((non_terminal)sym).first_set());
-
- /* if its nullable we continue adding, if not, we are done */
- if (!((non_terminal)sym).nullable())
- return result;
- }
- }
- }
-
- /* if we get here everything past the dot was nullable
- we add in the lookahead for after the production and we are done */
- result.add(lookahead_after);
- return result;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if everything from the symbol one beyond the dot all the
- * way to the end of the right hand side is nullable. This would indicate
- * that the lookahead of this item must be included in the lookaheads of
- * all items produced as a closure of this item. Note: this routine should
- * not be invoked until after first sets and nullability have been
- * calculated for all non terminals.
- */
- public boolean lookahead_visible() throws internal_error
- {
- production_part part;
- symbol sym;
-
- /* if the dot is at the end, we have a problem, but the cleanest thing
- to do is just return true. */
- if (dot_at_end()) return true;
-
- /* walk down the rhs and bail if we get a non-nullable symbol */
- for (int pos = dot_pos() + 1; pos < the_production().rhs_length(); pos++)
- {
- part = the_production().rhs(pos);
-
- /* skip actions */
- if (!part.is_action())
- {
- sym = ((symbol_part)part).the_symbol();
-
- /* if its a terminal we fail */
- if (!sym.is_non_term()) return false;
-
- /* if its not nullable we fail */
- if (!((non_terminal)sym).nullable()) return false;
- }
- }
-
- /* if we get here its all nullable */
- return true;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison -- here we only require the cores to be equal since
- * we need to do sets of items based only on core equality (ignoring
- * lookahead sets).
- */
- public boolean equals(lalr_item other)
- {
- if (other == null) return false;
- return super.equals(other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof lalr_item))
- return false;
- else
- return equals((lalr_item)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Return a hash code -- here we only hash the core since we only test core
- * matching in LALR items.
- */
- public int hashCode()
- {
- return super.hashCode();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to string. */
- public String toString()
- {
- String result = "";
-
- // additional output for debugging:
- // result += "(" + obj_hash() + ")";
- result += "[";
- result += super.toString();
- result += ", ";
- if (lookahead() != null)
- {
- result += "{";
- for (int t = 0; t < terminal.number(); t++)
- if (lookahead().contains(t))
- result += terminal.find(t).name() + " ";
- result += "}";
- }
- else
- result += "NULL LOOKAHEAD!!";
- result += "]";
-
- // additional output for debugging:
- // result += " -> ";
- // for (int i = 0; i<propagate_items().size(); i++)
- // result+=((lalr_item)(propagate_items().elementAt(i))).obj_hash()+" ";
- //
- // if (needs_propagation) result += " NP";
-
- return result;
- }
- /*-----------------------------------------------------------*/
-}
+++ /dev/null
-
-package java_cup;
-
-import java.util.Hashtable;
-import java.util.Enumeration;
-
-/** This class represents a set of LALR items. For purposes of building
- * these sets, items are considered unique only if they have unique cores
- * (i.e., ignoring differences in their lookahead sets).<p>
- *
- * This class provides fairly conventional set oriented operations (union,
- * sub/super-set tests, etc.), as well as an LALR "closure" operation (see
- * compute_closure()).
- *
- * @see java_cup.lalr_item
- * @see java_cup.lalr_state
- * @version last updated: 3/6/96
- * @author Scott Hudson
- */
-
-public class lalr_item_set {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Constructor for an empty set. */
- public lalr_item_set() { }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor for cloning from another set.
- * @param other indicates set we should copy from.
- */
- public lalr_item_set(lalr_item_set other)
- throws internal_error
- {
- not_null(other);
- _all = (Hashtable)other._all.clone();
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** A hash table to implement the set. We store the items using themselves
- * as keys.
- */
- protected Hashtable _all = new Hashtable(11);
-
- /** Access to all elements of the set. */
- public Enumeration all() {return _all.elements();}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Cached hashcode for this set. */
- protected Integer hashcode_cache = null;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Size of the set */
- public int size() {return _all.size();}
-
- /*-----------------------------------------------------------*/
- /*--- Set Operation Methods ---------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Does the set contain a particular item?
- * @param itm the item in question.
- */
- public boolean contains(lalr_item itm) {return _all.containsKey(itm);}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Return the item in the set matching a particular item (or null if not
- * found)
- * @param itm the item we are looking for.
- */
- public lalr_item find(lalr_item itm) {return (lalr_item)_all.get(itm);}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Is this set an (improper) subset of another?
- * @param other the other set in question.
- */
- public boolean is_subset_of(lalr_item_set other) throws internal_error
- {
- not_null(other);
-
- /* walk down our set and make sure every element is in the other */
- for (Enumeration e = all(); e.hasMoreElements(); )
- if (!other.contains((lalr_item)e.nextElement()))
- return false;
-
- /* they were all there */
- return true;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Is this set an (improper) superset of another?
- * @param other the other set in question.
- */
- public boolean is_superset_of(lalr_item_set other) throws internal_error
- {
- not_null(other);
- return other.is_subset_of(this);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Add a singleton item, merging lookahead sets if the item is already
- * part of the set. returns the element of the set that was added or
- * merged into.
- * @param itm the item being added.
- */
- public lalr_item add(lalr_item itm) throws internal_error
- {
- lalr_item other;
-
- not_null(itm);
-
- /* see if an item with a matching core is already there */
- other = (lalr_item)_all.get(itm);
-
- /* if so, merge this lookahead into the original and leave it */
- if (other != null)
- {
- other.lookahead().add(itm.lookahead());
- return other;
- }
- /* otherwise we just go in the set */
- else
- {
- /* invalidate cached hashcode */
- hashcode_cache = null;
-
- _all.put(itm,itm);
- return itm;
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Remove a single item if it is in the set.
- * @param itm the item to remove.
- */
- public void remove(lalr_item itm) throws internal_error
- {
- not_null(itm);
-
- /* invalidate cached hashcode */
- hashcode_cache = null;
-
- /* remove it from hash table implementing set */
- _all.remove(itm);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Add a complete set, merging lookaheads where items are already in
- * the set
- * @param other the set to be added.
- */
- public void add(lalr_item_set other) throws internal_error
- {
- not_null(other);
-
- /* walk down the other set and do the adds individually */
- for (Enumeration e = other.all(); e.hasMoreElements(); )
- add((lalr_item)e.nextElement());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Remove (set subtract) a complete set.
- * @param other the set to remove.
- */
- public void remove(lalr_item_set other) throws internal_error
- {
- not_null(other);
-
- /* walk down the other set and do the removes individually */
- for (Enumeration e = other.all(); e.hasMoreElements(); )
- remove((lalr_item)e.nextElement());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Remove and return one item from the set (done in hash order). */
- public lalr_item get_one() throws internal_error
- {
- Enumeration the_set;
- lalr_item result;
-
- the_set = all();
- if (the_set.hasMoreElements())
- {
- result = (lalr_item)the_set.nextElement();
- remove(result);
- return result;
- }
- else
- return null;
- }
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Helper function for null test. Throws an interal_error exception if its
- * parameter is null.
- * @param obj the object we are testing.
- */
- protected void not_null(Object obj) throws internal_error
- {
- if (obj == null)
- throw new internal_error("Null object used in set operation");
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Compute the closure of the set using the LALR closure rules. Basically
- * for every item of the form: <pre>
- * [L ::= a *N alpha, l]
- * </pre>
- * (where N is a a non terminal and alpha is a string of symbols) make
- * sure there are also items of the form: <pre>
- * [N ::= *beta, first(alpha l)]
- * </pre>
- * corresponding to each production of N. Items with identical cores but
- * differing lookahead sets are merged by creating a new item with the same
- * core and the union of the lookahead sets (the LA in LALR stands for
- * "lookahead merged" and this is where the merger is). This routine
- * assumes that nullability and first sets have been computed for all
- * productions before it is called.
- */
- public void compute_closure()
- throws internal_error
- {
- lalr_item_set consider;
- lalr_item itm, new_itm, add_itm;
- non_terminal nt;
- terminal_set new_lookaheads;
- Enumeration p;
- production prod;
- boolean need_prop;
-
-
-
- /* invalidate cached hashcode */
- hashcode_cache = null;
-
- /* each current element needs to be considered */
- consider = new lalr_item_set(this);
-
- /* repeat this until there is nothing else to consider */
- while (consider.size() > 0)
- {
- /* get one item to consider */
- itm = consider.get_one();
-
- /* do we have a dot before a non terminal */
- nt = itm.dot_before_nt();
- if (nt != null)
- {
- /* create the lookahead set based on first after dot */
- new_lookaheads = itm.calc_lookahead(itm.lookahead());
-
- /* are we going to need to propagate our lookahead to new item */
- need_prop = itm.lookahead_visible();
-
- /* create items for each production of that non term */
- for (p = nt.productions(); p.hasMoreElements(); )
- {
- prod = (production)p.nextElement();
-
- /* create new item with dot at start and that lookahead */
- new_itm = new lalr_item(prod,
- new terminal_set(new_lookaheads));
-
- /* add/merge item into the set */
- add_itm = add(new_itm);
- /* if propagation is needed link to that item */
- if (need_prop)
- itm.add_propagate(add_itm);
-
- /* was this was a new item*/
- if (add_itm == new_itm)
- {
- /* that may need further closure, consider it also */
- consider.add(new_itm);
- }
- }
- }
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison. */
- public boolean equals(lalr_item_set other)
- {
- if (other == null || other.size() != size()) return false;
-
- /* once we know they are the same size, then improper subset does test */
- try {
- return is_subset_of(other);
- } catch (internal_error e) {
- /* can't throw error from here (because superclass doesn't) so crash */
- e.crash();
- return false;
- }
-
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof lalr_item_set))
- return false;
- else
- return equals((lalr_item_set)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Return hash code. */
- public int hashCode()
- {
- int result = 0;
- Enumeration e;
- int cnt;
-
- /* only compute a new one if we don't have it cached */
- if (hashcode_cache == null)
- {
- /* hash together codes from at most first 5 elements */
- // CSA fix! we'd *like* to hash just a few elements, but
- // that means equal sets will have inequal hashcodes, which
- // we're not allowed (by contract) to do. So hash them all.
- for (e = all(), cnt=0 ; e.hasMoreElements() /*&& cnt<5*/; cnt++)
- result ^= ((lalr_item)e.nextElement()).hashCode();
-
- hashcode_cache = new Integer(result);
- }
-
- return hashcode_cache.intValue();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to string. */
- public String toString()
- {
- StringBuffer result = new StringBuffer();
-
- result.append("{\n");
- for (Enumeration e=all(); e.hasMoreElements(); )
- {
- result.append(" " + (lalr_item)e.nextElement() + "\n");
- }
- result.append("}");
-
- return result.toString();
- }
- /*-----------------------------------------------------------*/
-}
-
+++ /dev/null
-
-package java_cup;
-
-import java.util.Hashtable;
-import java.util.Enumeration;
-import java.util.Stack;
-
-/** This class represents a state in the LALR viable prefix recognition machine.
- * A state consists of an LALR item set and a set of transitions to other
- * states under terminal and non-terminal symbols. Each state represents
- * a potential configuration of the parser. If the item set of a state
- * includes an item such as: <pre>
- * [A ::= B * C d E , {a,b,c}]
- * </pre>
- * this indicates that when the parser is in this state it is currently
- * looking for an A of the given form, has already seen the B, and would
- * expect to see an a, b, or c after this sequence is complete. Note that
- * the parser is normally looking for several things at once (represented
- * by several items). In our example above, the state would also include
- * items such as: <pre>
- * [C ::= * X e Z, {d}]
- * [X ::= * f, {e}]
- * </pre>
- * to indicate that it was currently looking for a C followed by a d (which
- * would be reduced into a C, matching the first symbol in our production
- * above), and the terminal f followed by e.<p>
- *
- * At runtime, the parser uses a viable prefix recognition machine made up
- * of these states to parse. The parser has two operations, shift and reduce.
- * In a shift, it consumes one Symbol and makes a transition to a new state.
- * This corresponds to "moving the dot past" a terminal in one or more items
- * in the state (these new shifted items will then be found in the state at
- * the end of the transition). For a reduce operation, the parser is
- * signifying that it is recognizing the RHS of some production. To do this
- * it first "backs up" by popping a stack of previously saved states. It
- * pops off the same number of states as are found in the RHS of the
- * production. This leaves the machine in the same state is was in when the
- * parser first attempted to find the RHS. From this state it makes a
- * transition based on the non-terminal on the LHS of the production. This
- * corresponds to placing the parse in a configuration equivalent to having
- * replaced all the symbols from the the input corresponding to the RHS with
- * the symbol on the LHS.
- *
- * @see java_cup.lalr_item
- * @see java_cup.lalr_item_set
- * @see java_cup.lalr_transition
- * @version last updated: 7/3/96
- * @author Frank Flannery
- *
- */
-
-public class lalr_state {
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Constructor for building a state from a set of items.
- * @param itms the set of items that makes up this state.
- */
- public lalr_state(lalr_item_set itms) throws internal_error
- {
- /* don't allow null or duplicate item sets */
- if (itms == null)
- throw new internal_error(
- "Attempt to construct an LALR state from a null item set");
-
- if (find_state(itms) != null)
- throw new internal_error(
- "Attempt to construct a duplicate LALR state");
-
- /* assign a unique index */
- _index = next_index++;
-
- /* store the items */
- _items = itms;
-
- /* add to the global collection, keyed with its item set */
- _all.put(_items,this);
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Static (Class) Variables ------------------*/
- /*-----------------------------------------------------------*/
-
- /** Collection of all states. */
- protected static Hashtable _all = new Hashtable();
-
- /** Collection of all states. */
- public static Enumeration all() {return _all.elements();}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Indicate total number of states there are. */
- public static int number() {return _all.size();}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Hash table to find states by their kernels (i.e, the original,
- * unclosed, set of items -- which uniquely define the state). This table
- * stores state objects using (a copy of) their kernel item sets as keys.
- */
- protected static Hashtable _all_kernels = new Hashtable();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Find and return state with a given a kernel item set (or null if not
- * found). The kernel item set is the subset of items that were used to
- * originally create the state. These items are formed by "shifting the
- * dot" within items of other states that have a transition to this one.
- * The remaining elements of this state's item set are added during closure.
- * @param itms the kernel set of the state we are looking for.
- */
- public static lalr_state find_state(lalr_item_set itms)
- {
- if (itms == null)
- return null;
- else
- return (lalr_state)_all.get(itms);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Static counter for assigning unique state indexes. */
- protected static int next_index = 0;
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The item set for this state. */
- protected lalr_item_set _items;
-
- /** The item set for this state. */
- public lalr_item_set items() {return _items;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** List of transitions out of this state. */
- protected lalr_transition _transitions = null;
-
- /** List of transitions out of this state. */
- public lalr_transition transitions() {return _transitions;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Index of this state in the parse tables */
- protected int _index;
-
- /** Index of this state in the parse tables */
- public int index() {return _index;}
-
- /*-----------------------------------------------------------*/
- /*--- Static Methods ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Helper routine for debugging -- produces a dump of the given state
- * onto System.out.
- */
- protected static void dump_state(lalr_state st) throws internal_error
- {
- lalr_item_set itms;
- lalr_item itm;
- production_part part;
-
- if (st == null)
- {
- System.out.println("NULL lalr_state");
- return;
- }
-
- System.out.println("lalr_state [" + st.index() + "] {");
- itms = st.items();
- for (Enumeration e = itms.all(); e.hasMoreElements(); )
- {
- itm = (lalr_item)e.nextElement();
- System.out.print(" [");
- System.out.print(itm.the_production().lhs().the_symbol().name());
- System.out.print(" ::= ");
- for (int i = 0; i<itm.the_production().rhs_length(); i++)
- {
- if (i == itm.dot_pos()) System.out.print("(*) ");
- part = itm.the_production().rhs(i);
- if (part.is_action())
- System.out.print("{action} ");
- else
- System.out.print(((symbol_part)part).the_symbol().name() + " ");
- }
- if (itm.dot_at_end()) System.out.print("(*) ");
- System.out.println("]");
- }
- System.out.println("}");
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Propagate lookahead sets through the constructed viable prefix
- * recognizer. When the machine is constructed, each item that results
- in the creation of another such that its lookahead is included in the
- other's will have a propagate link set up for it. This allows additions
- to the lookahead of one item to be included in other items that it
- was used to directly or indirectly create.
- */
- protected static void propagate_all_lookaheads() throws internal_error
- {
- /* iterate across all states */
- for (Enumeration st = all(); st.hasMoreElements(); )
- {
- /* propagate lookaheads out of that state */
- ((lalr_state)st.nextElement()).propagate_lookaheads();
- }
- }
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Add a transition out of this state to another.
- * @param on_sym the symbol the transition is under.
- * @param to_st the state the transition goes to.
- */
- public void add_transition(symbol on_sym, lalr_state to_st)
- throws internal_error
- {
- lalr_transition trans;
-
- /* create a new transition object and put it in our list */
- trans = new lalr_transition(on_sym, to_st, _transitions);
- _transitions = trans;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Build an LALR viable prefix recognition machine given a start
- * production. This method operates by first building a start state
- * from the start production (based on a single item with the dot at
- * the beginning and EOF as expected lookahead). Then for each state
- * it attempts to extend the machine by creating transitions out of
- * the state to new or existing states. When considering extension
- * from a state we make a transition on each symbol that appears before
- * the dot in some item. For example, if we have the items: <pre>
- * [A ::= a b * X c, {d,e}]
- * [B ::= a b * X d, {a,b}]
- * </pre>
- * in some state, then we would be making a transition under X to a new
- * state. This new state would be formed by a "kernel" of items
- * corresponding to moving the dot past the X. In this case: <pre>
- * [A ::= a b X * c, {d,e}]
- * [B ::= a b X * Y, {a,b}]
- * </pre>
- * The full state would then be formed by "closing" this kernel set of
- * items so that it included items that represented productions of things
- * the parser was now looking for. In this case we would items
- * corresponding to productions of Y, since various forms of Y are expected
- * next when in this state (see lalr_item_set.compute_closure() for details
- * on closure). <p>
- *
- * The process of building the viable prefix recognizer terminates when no
- * new states can be added. However, in order to build a smaller number of
- * states (i.e., corresponding to LALR rather than canonical LR) the state
- * building process does not maintain full loookaheads in all items.
- * Consequently, after the machine is built, we go back and propagate
- * lookaheads through the constructed machine using a call to
- * propagate_all_lookaheads(). This makes use of propagation links
- * constructed during the closure and transition process.
- *
- * @param start_prod the start production of the grammar
- * @see java_cup.lalr_item_set#compute_closure
- * @see java_cup.lalr_state#propagate_all_lookaheads
- */
-
- public static lalr_state build_machine(production start_prod)
- throws internal_error
- {
- lalr_state start_state;
- lalr_item_set start_items;
- lalr_item_set new_items;
- lalr_item_set linked_items;
- lalr_item_set kernel;
- Stack work_stack = new Stack();
- lalr_state st, new_st;
- symbol_set outgoing;
- lalr_item itm, new_itm, existing, fix_itm;
- symbol sym, sym2;
- Enumeration i, s, fix;
-
- /* sanity check */
- if (start_prod == null)
- throw new internal_error(
- "Attempt to build viable prefix recognizer using a null production");
-
- /* build item with dot at front of start production and EOF lookahead */
- start_items = new lalr_item_set();
-
- itm = new lalr_item(start_prod);
- itm.lookahead().add(terminal.EOF);
-
- start_items.add(itm);
-
- /* create copy the item set to form the kernel */
- kernel = new lalr_item_set(start_items);
-
- /* create the closure from that item set */
- start_items.compute_closure();
-
- /* build a state out of that item set and put it in our work set */
- start_state = new lalr_state(start_items);
- work_stack.push(start_state);
-
- /* enter the state using the kernel as the key */
- _all_kernels.put(kernel, start_state);
-
- /* continue looking at new states until we have no more work to do */
- while (!work_stack.empty())
- {
- /* remove a state from the work set */
- st = (lalr_state)work_stack.pop();
-
- /* gather up all the symbols that appear before dots */
- outgoing = new symbol_set();
- for (i = st.items().all(); i.hasMoreElements(); )
- {
- itm = (lalr_item)i.nextElement();
-
- /* add the symbol before the dot (if any) to our collection */
- sym = itm.symbol_after_dot();
- if (sym != null) outgoing.add(sym);
- }
-
- /* now create a transition out for each individual symbol */
- for (s = outgoing.all(); s.hasMoreElements(); )
- {
- sym = (symbol)s.nextElement();
-
- /* will be keeping the set of items with propagate links */
- linked_items = new lalr_item_set();
-
- /* gather up shifted versions of all the items that have this
- symbol before the dot */
- new_items = new lalr_item_set();
- for (i = st.items().all(); i.hasMoreElements();)
- {
- itm = (lalr_item)i.nextElement();
-
- /* if this is the symbol we are working on now, add to set */
- sym2 = itm.symbol_after_dot();
- if (sym.equals(sym2))
- {
- /* add to the kernel of the new state */
- new_items.add(itm.shift());
-
- /* remember that itm has propagate link to it */
- linked_items.add(itm);
- }
- }
-
- /* use new items as state kernel */
- kernel = new lalr_item_set(new_items);
-
- /* have we seen this one already? */
- new_st = (lalr_state)_all_kernels.get(kernel);
-
- /* if we haven't, build a new state out of the item set */
- if (new_st == null)
- {
- /* compute closure of the kernel for the full item set */
- new_items.compute_closure();
-
- /* build the new state */
- new_st = new lalr_state(new_items);
-
- /* add the new state to our work set */
- work_stack.push(new_st);
-
- /* put it in our kernel table */
- _all_kernels.put(kernel, new_st);
- }
- /* otherwise relink propagation to items in existing state */
- else
- {
- /* walk through the items that have links to the new state */
- for (fix = linked_items.all(); fix.hasMoreElements(); )
- {
- fix_itm = (lalr_item)fix.nextElement();
-
- /* look at each propagate link out of that item */
- for (int l =0; l < fix_itm.propagate_items().size(); l++)
- {
- /* pull out item linked to in the new state */
- new_itm =
- (lalr_item)fix_itm.propagate_items().elementAt(l);
-
- /* find corresponding item in the existing state */
- existing = new_st.items().find(new_itm);
-
- /* fix up the item so it points to the existing set */
- if (existing != null)
- fix_itm.propagate_items().setElementAt(existing ,l);
- }
- }
- }
-
- /* add a transition from current state to that state */
- st.add_transition(sym, new_st);
- }
- }
-
- /* all done building states */
-
- /* propagate complete lookahead sets throughout the states */
- propagate_all_lookaheads();
-
- return start_state;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Propagate lookahead sets out of this state. This recursively
- * propagates to all items that have propagation links from some item
- * in this state.
- */
- protected void propagate_lookaheads() throws internal_error
- {
- /* recursively propagate out from each item in the state */
- for (Enumeration itm = items().all(); itm.hasMoreElements(); )
- ((lalr_item)itm.nextElement()).propagate_lookaheads(null);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Fill in the parse table entries for this state. There are two
- * parse tables that encode the viable prefix recognition machine, an
- * action table and a reduce-goto table. The rows in each table
- * correspond to states of the machine. The columns of the action table
- * are indexed by terminal symbols and correspond to either transitions
- * out of the state (shift entries) or reductions from the state to some
- * previous state saved on the stack (reduce entries). All entries in the
- * action table that are not shifts or reduces, represent errors. The
- * reduce-goto table is indexed by non terminals and represents transitions
- * out of a state on that non-terminal.<p>
- * Conflicts occur if more than one action needs to go in one entry of the
- * action table (this cannot happen with the reduce-goto table). Conflicts
- * are resolved by always shifting for shift/reduce conflicts and choosing
- * the lowest numbered production (hence the one that appeared first in
- * the specification) in reduce/reduce conflicts. All conflicts are
- * reported and if more conflicts are detected than were declared by the
- * user, code generation is aborted.
- *
- * @param act_table the action table to put entries in.
- * @param reduce_table the reduce-goto table to put entries in.
- */
- public void build_table_entries(
- parse_action_table act_table,
- parse_reduce_table reduce_table)
- throws internal_error
- {
- parse_action_row our_act_row;
- parse_reduce_row our_red_row;
- lalr_item itm;
- parse_action act, other_act;
- symbol sym;
- terminal_set conflict_set = new terminal_set();
-
- /* pull out our rows from the tables */
- our_act_row = act_table.under_state[index()];
- our_red_row = reduce_table.under_state[index()];
-
- /* consider each item in our state */
- for (Enumeration i = items().all(); i.hasMoreElements(); )
- {
- itm = (lalr_item)i.nextElement();
-
-
- /* if its completed (dot at end) then reduce under the lookahead */
- if (itm.dot_at_end())
- {
- act = new reduce_action(itm.the_production());
-
- /* consider each lookahead symbol */
- for (int t = 0; t < terminal.number(); t++)
- {
- /* skip over the ones not in the lookahead */
- if (!itm.lookahead().contains(t)) continue;
-
- /* if we don't already have an action put this one in */
- if (our_act_row.under_term[t].kind() ==
- parse_action.ERROR)
- {
- our_act_row.under_term[t] = act;
- }
- else
- {
- /* we now have at least one conflict */
- terminal term = terminal.find(t);
- other_act = our_act_row.under_term[t];
-
- /* if the other act was not a shift */
- if ((other_act.kind() != parse_action.SHIFT) &&
- (other_act.kind() != parse_action.NONASSOC))
- {
- /* if we have lower index hence priority, replace it*/
- if (itm.the_production().index() <
- ((reduce_action)other_act).reduce_with().index())
- {
- /* replace the action */
- our_act_row.under_term[t] = act;
- }
- } else {
- /* Check precedences,see if problem is correctable */
- if(fix_with_precedence(itm.the_production(),
- t, our_act_row, act)) {
- term = null;
- }
- }
- if(term!=null) {
-
- conflict_set.add(term);
- }
- }
- }
- }
- }
-
- /* consider each outgoing transition */
- for (lalr_transition trans=transitions(); trans!=null; trans=trans.next())
- {
- /* if its on an terminal add a shift entry */
- sym = trans.on_symbol();
- if (!sym.is_non_term())
- {
- act = new shift_action(trans.to_state());
-
- /* if we don't already have an action put this one in */
- if ( our_act_row.under_term[sym.index()].kind() ==
- parse_action.ERROR)
- {
- our_act_row.under_term[sym.index()] = act;
- }
- else
- {
- /* we now have at least one conflict */
- production p = ((reduce_action)our_act_row.under_term[sym.index()]).reduce_with();
-
- /* shift always wins */
- if (!fix_with_precedence(p, sym.index(), our_act_row, act)) {
- our_act_row.under_term[sym.index()] = act;
- conflict_set.add(terminal.find(sym.index()));
- }
- }
- }
- else
- {
- /* for non terminals add an entry to the reduce-goto table */
- our_red_row.under_non_term[sym.index()] = trans.to_state();
- }
- }
-
- /* if we end up with conflict(s), report them */
- if (!conflict_set.empty())
- report_conflicts(conflict_set);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
-
- /** Procedure that attempts to fix a shift/reduce error by using
- * precedences. --frankf 6/26/96
- *
- * if a production (also called rule) or the lookahead terminal
- * has a precedence, then the table can be fixed. if the rule
- * has greater precedence than the terminal, a reduce by that rule
- * in inserted in the table. If the terminal has a higher precedence,
- * it is shifted. if they have equal precedence, then the associativity
- * of the precedence is used to determine what to put in the table:
- * if the precedence is left associative, the action is to reduce.
- * if the precedence is right associative, the action is to shift.
- * if the precedence is non associative, then it is a syntax error.
- *
- * @param p the production
- * @param term_index the index of the lokahead terminal
- * @param parse_action_row a row of the action table
- * @param act the rule in conflict with the table entry
- */
-
- protected boolean fix_with_precedence(
- production p,
- int term_index,
- parse_action_row table_row,
- parse_action act)
-
- throws internal_error {
-
- terminal term = terminal.find(term_index);
-
- /* if the production has a precedence number, it can be fixed */
- if (p.precedence_num() > assoc.no_prec) {
-
- /* if production precedes terminal, put reduce in table */
- if (p.precedence_num() > term.precedence_num()) {
- table_row.under_term[term_index] =
- insert_reduce(table_row.under_term[term_index],act);
- return true;
- }
-
- /* if terminal precedes rule, put shift in table */
- else if (p.precedence_num() < term.precedence_num()) {
- table_row.under_term[term_index] =
- insert_shift(table_row.under_term[term_index],act);
- return true;
- }
- else { /* they are == precedence */
-
- /* equal precedences have equal sides, so only need to
- look at one: if it is right, put shift in table */
- if (term.precedence_side() == assoc.right) {
- table_row.under_term[term_index] =
- insert_shift(table_row.under_term[term_index],act);
- return true;
- }
-
- /* if it is left, put reduce in table */
- else if (term.precedence_side() == assoc.left) {
- table_row.under_term[term_index] =
- insert_reduce(table_row.under_term[term_index],act);
- return true;
- }
-
- /* if it is nonassoc, we're not allowed to have two nonassocs
- of equal precedence in a row, so put in NONASSOC */
- else if (term.precedence_side() == assoc.nonassoc) {
- table_row.under_term[term_index] = new nonassoc_action();
- return true;
- } else {
- /* something really went wrong */
- throw new internal_error("Unable to resolve conflict correctly");
- }
- }
- }
- /* check if terminal has precedence, if so, shift, since
- rule does not have precedence */
- else if (term.precedence_num() > assoc.no_prec) {
- table_row.under_term[term_index] =
- insert_shift(table_row.under_term[term_index],act);
- return true;
- }
-
- /* otherwise, neither the rule nor the terminal has a precedence,
- so it can't be fixed. */
- return false;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
-
- /* given two actions, and an action type, return the
- action of that action type. give an error if they are of
- the same action, because that should never have tried
- to be fixed
-
- */
- protected parse_action insert_action(
- parse_action a1,
- parse_action a2,
- int act_type)
- throws internal_error
- {
- if ((a1.kind() == act_type) && (a2.kind() == act_type)) {
- throw new internal_error("Conflict resolution of bogus actions");
- } else if (a1.kind() == act_type) {
- return a1;
- } else if (a2.kind() == act_type) {
- return a2;
- } else {
- throw new internal_error("Conflict resolution of bogus actions");
- }
- }
-
- /* find the shift in the two actions */
- protected parse_action insert_shift(
- parse_action a1,
- parse_action a2)
- throws internal_error
- {
- return insert_action(a1, a2, parse_action.SHIFT);
- }
-
- /* find the reduce in the two actions */
- protected parse_action insert_reduce(
- parse_action a1,
- parse_action a2)
- throws internal_error
- {
- return insert_action(a1, a2, parse_action.REDUCE);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce warning messages for all conflicts found in this state. */
- protected void report_conflicts(terminal_set conflict_set)
- throws internal_error
- {
- lalr_item itm, compare;
- symbol shift_sym;
-
- boolean after_itm;
-
- /* consider each element */
- for (Enumeration itms = items().all(); itms.hasMoreElements(); )
- {
- itm = (lalr_item)itms.nextElement();
-
- /* clear the S/R conflict set for this item */
-
- /* if it results in a reduce, it could be a conflict */
- if (itm.dot_at_end())
- {
- /* not yet after itm */
- after_itm = false;
-
- /* compare this item against all others looking for conflicts */
- for (Enumeration comps = items().all(); comps.hasMoreElements(); )
- {
- compare = (lalr_item)comps.nextElement();
-
- /* if this is the item, next one is after it */
- if (itm == compare) after_itm = true;
-
- /* only look at it if its not the same item */
- if (itm != compare)
- {
- /* is it a reduce */
- if (compare.dot_at_end())
- {
- /* only look at reduces after itm */
- if (after_itm)
- /* does the comparison item conflict? */
- if (compare.lookahead().intersects(itm.lookahead()))
- /* report a reduce/reduce conflict */
- report_reduce_reduce(itm, compare);
- }
- }
- }
- /* report S/R conflicts under all the symbols we conflict under */
- for (int t = 0; t < terminal.number(); t++)
- if (conflict_set.contains(t))
- report_shift_reduce(itm,t);
- }
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a warning message for one reduce/reduce conflict.
- *
- * @param itm1 first item in conflict.
- * @param itm2 second item in conflict.
- */
- protected void report_reduce_reduce(lalr_item itm1, lalr_item itm2)
- throws internal_error
- {
- boolean comma_flag = false;
-
- System.err.println("*** Reduce/Reduce conflict found in state #"+index());
- System.err.print (" between ");
- System.err.println(itm1.to_simple_string());
- System.err.print (" and ");
- System.err.println(itm2.to_simple_string());
- System.err.print(" under symbols: {" );
- for (int t = 0; t < terminal.number(); t++)
- {
- if (itm1.lookahead().contains(t) && itm2.lookahead().contains(t))
- {
- if (comma_flag) System.err.print(", "); else comma_flag = true;
- System.err.print(terminal.find(t).name());
- }
- }
- System.err.println("}");
- System.err.print(" Resolved in favor of ");
- if (itm1.the_production().index() < itm2.the_production().index())
- System.err.println("the first production.\n");
- else
- System.err.println("the second production.\n");
-
- /* count the conflict */
- emit.num_conflicts++;
- lexer.warning_count++;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a warning message for one shift/reduce conflict.
- *
- * @param red_itm the item with the reduce.
- * @param conflict_sym the index of the symbol conflict occurs under.
- */
- protected void report_shift_reduce(
- lalr_item red_itm,
- int conflict_sym)
- throws internal_error
- {
- lalr_item itm;
- symbol shift_sym;
-
- /* emit top part of message including the reduce item */
- System.err.println("*** Shift/Reduce conflict found in state #"+index());
- System.err.print (" between ");
- System.err.println(red_itm.to_simple_string());
-
- /* find and report on all items that shift under our conflict symbol */
- for (Enumeration itms = items().all(); itms.hasMoreElements(); )
- {
- itm = (lalr_item)itms.nextElement();
-
- /* only look if its not the same item and not a reduce */
- if (itm != red_itm && !itm.dot_at_end())
- {
- /* is it a shift on our conflicting terminal */
- shift_sym = itm.symbol_after_dot();
- if (!shift_sym.is_non_term() && shift_sym.index() == conflict_sym)
- {
- /* yes, report on it */
- System.err.println(" and " + itm.to_simple_string());
- }
- }
- }
- System.err.println(" under symbol "+ terminal.find(conflict_sym).name());
- System.err.println(" Resolved in favor of shifting.\n");
-
- /* count the conflict */
- emit.num_conflicts++;
- lexer.warning_count++;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison. */
- public boolean equals(lalr_state other)
- {
- /* we are equal if our item sets are equal */
- return other != null && items().equals(other.items());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof lalr_state))
- return false;
- else
- return equals((lalr_state)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a hash code. */
- public int hashCode()
- {
- /* just use the item set hash code */
- return items().hashCode();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string. */
- public String toString()
- {
- String result;
- lalr_transition tr;
-
- /* dump the item set */
- result = "lalr_state [" + index() + "]: " + _items + "\n";
-
- /* do the transitions */
- for (tr = transitions(); tr != null; tr = tr.next())
- {
- result += tr;
- result += "\n";
- }
-
- return result;
- }
-
- /*-----------------------------------------------------------*/
-}
+++ /dev/null
-package java_cup;
-
-/** This class represents a transition in an LALR viable prefix recognition
- * machine. Transitions can be under terminals for non-terminals. They are
- * internally linked together into singly linked lists containing all the
- * transitions out of a single state via the _next field.
- *
- * @see java_cup.lalr_state
- * @version last updated: 11/25/95
- * @author Scott Hudson
- *
- */
-public class lalr_transition {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Full constructor.
- * @param on_sym symbol we are transitioning on.
- * @param to_st state we transition to.
- * @param nxt next transition in linked list.
- */
- public lalr_transition(symbol on_sym, lalr_state to_st, lalr_transition nxt)
- throws internal_error
- {
- /* sanity checks */
- if (on_sym == null)
- throw new internal_error("Attempt to create transition on null symbol");
- if (to_st == null)
- throw new internal_error("Attempt to create transition to null state");
-
- /* initialize */
- _on_symbol = on_sym;
- _to_state = to_st;
- _next = nxt;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor with null next.
- * @param on_sym symbol we are transitioning on.
- * @param to_st state we transition to.
- */
- public lalr_transition(symbol on_sym, lalr_state to_st) throws internal_error
- {
- this(on_sym, to_st, null);
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The symbol we make the transition on. */
- protected symbol _on_symbol;
-
- /** The symbol we make the transition on. */
- public symbol on_symbol() {return _on_symbol;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The state we transition to. */
- protected lalr_state _to_state;
-
- /** The state we transition to. */
- public lalr_state to_state() {return _to_state;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Next transition in linked list of transitions out of a state */
- protected lalr_transition _next;
-
- /** Next transition in linked list of transitions out of a state */
- public lalr_transition next() {return _next;}
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Convert to a string. */
- public String toString()
- {
- String result;
-
- result = "transition on " + on_symbol().name() + " to state [";
- result += _to_state.index();
- result += "]";
-
- return result;
- }
-
- /*-----------------------------------------------------------*/
-}
+++ /dev/null
-package java_cup;
-
-import java_cup.runtime.Symbol;
-import java.util.Hashtable;
-
-/** This class implements a small scanner (aka lexical analyzer or lexer) for
- * the JavaCup specification. This scanner reads characters from standard
- * input (System.in) and returns integers corresponding to the terminal
- * number of the next Symbol. Once end of input is reached the EOF Symbol is
- * returned on every subsequent call.<p>
- * Symbols currently returned include: <pre>
- * Symbol Constant Returned Symbol Constant Returned
- * ------ ----------------- ------ -----------------
- * "package" PACKAGE "import" IMPORT
- * "code" CODE "action" ACTION
- * "parser" PARSER "terminal" TERMINAL
- * "non" NON "init" INIT
- * "scan" SCAN "with" WITH
- * "start" START "precedence" PRECEDENCE
- * "left" LEFT "right" RIGHT
- * "nonassoc" NONASSOC "%prec PRECENT_PREC
- * [ LBRACK ] RBRACK
- * ; SEMI
- * , COMMA * STAR
- * . DOT : COLON
- * ::= COLON_COLON_EQUALS | BAR
- * identifier ID {:...:} CODE_STRING
- * "nonterminal" NONTERMINAL
- * </pre>
- * All symbol constants are defined in sym.java which is generated by
- * JavaCup from parser.cup.<p>
- *
- * In addition to the scanner proper (called first via init() then with
- * next_token() to get each Symbol) this class provides simple error and
- * warning routines and keeps a count of errors and warnings that is
- * publicly accessible.<p>
- *
- * This class is "static" (i.e., it has only static members and methods).
- *
- * @version last updated: 7/3/96
- * @author Frank Flannery
- */
-public class lexer {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The only constructor is private, so no instances can be created. */
- private lexer() { }
-
- /*-----------------------------------------------------------*/
- /*--- Static (Class) Variables ------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** First character of lookahead. */
- protected static int next_char;
-
- /** Second character of lookahead. */
- protected static int next_char2;
-
- /** Second character of lookahead. */
- protected static int next_char3;
-
- /** Second character of lookahead. */
- protected static int next_char4;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** EOF constant. */
- protected static final int EOF_CHAR = -1;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Table of keywords. Keywords are initially treated as identifiers.
- * Just before they are returned we look them up in this table to see if
- * they match one of the keywords. The string of the name is the key here,
- * which indexes Integer objects holding the symbol number.
- */
- protected static Hashtable keywords = new Hashtable(23);
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Table of single character symbols. For ease of implementation, we
- * store all unambiguous single character Symbols in this table of Integer
- * objects keyed by Integer objects with the numerical value of the
- * appropriate char (currently Character objects have a bug which precludes
- * their use in tables).
- */
- protected static Hashtable char_symbols = new Hashtable(11);
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Current line number for use in error messages. */
- protected static int current_line = 1;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Character position in current line. */
- protected static int current_position = 1;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Character position in current line. */
- protected static int absolute_position = 1;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Count of total errors detected so far. */
- public static int error_count = 0;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Count of warnings issued so far */
- public static int warning_count = 0;
-
- /*-----------------------------------------------------------*/
- /*--- Static Methods ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Initialize the scanner. This sets up the keywords and char_symbols
- * tables and reads the first two characters of lookahead.
- */
- public static void init() throws java.io.IOException
- {
- /* set up the keyword table */
- keywords.put("package", new Integer(sym.PACKAGE));
- keywords.put("import", new Integer(sym.IMPORT));
- keywords.put("code", new Integer(sym.CODE));
- keywords.put("action", new Integer(sym.ACTION));
- keywords.put("parser", new Integer(sym.PARSER));
- keywords.put("terminal", new Integer(sym.TERMINAL));
- keywords.put("non", new Integer(sym.NON));
- keywords.put("nonterminal",new Integer(sym.NONTERMINAL));// [CSA]
- keywords.put("init", new Integer(sym.INIT));
- keywords.put("scan", new Integer(sym.SCAN));
- keywords.put("with", new Integer(sym.WITH));
- keywords.put("start", new Integer(sym.START));
- keywords.put("precedence", new Integer(sym.PRECEDENCE));
- keywords.put("left", new Integer(sym.LEFT));
- keywords.put("right", new Integer(sym.RIGHT));
- keywords.put("nonassoc", new Integer(sym.NONASSOC));
-
- /* set up the table of single character symbols */
- char_symbols.put(new Integer(';'), new Integer(sym.SEMI));
- char_symbols.put(new Integer(','), new Integer(sym.COMMA));
- char_symbols.put(new Integer('*'), new Integer(sym.STAR));
- char_symbols.put(new Integer('.'), new Integer(sym.DOT));
- char_symbols.put(new Integer('|'), new Integer(sym.BAR));
- char_symbols.put(new Integer('['), new Integer(sym.LBRACK));
- char_symbols.put(new Integer(']'), new Integer(sym.RBRACK));
-
- /* read two characters of lookahead */
- next_char = System.in.read();
- if (next_char == EOF_CHAR) {
- next_char2 = EOF_CHAR;
- next_char3 = EOF_CHAR;
- next_char4 = EOF_CHAR;
- } else {
- next_char2 = System.in.read();
- if (next_char2 == EOF_CHAR) {
- next_char3 = EOF_CHAR;
- next_char4 = EOF_CHAR;
- } else {
- next_char3 = System.in.read();
- if (next_char3 == EOF_CHAR) {
- next_char4 = EOF_CHAR;
- } else {
- next_char4 = System.in.read();
- }
- }
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Advance the scanner one character in the input stream. This moves
- * next_char2 to next_char and then reads a new next_char2.
- */
- protected static void advance() throws java.io.IOException
- {
- int old_char;
-
- old_char = next_char;
- next_char = next_char2;
- if (next_char == EOF_CHAR) {
- next_char2 = EOF_CHAR;
- next_char3 = EOF_CHAR;
- next_char4 = EOF_CHAR;
- } else {
- next_char2 = next_char3;
- if (next_char2 == EOF_CHAR) {
- next_char3 = EOF_CHAR;
- next_char4 = EOF_CHAR;
- } else {
- next_char3 = next_char4;
- if (next_char3 == EOF_CHAR) {
- next_char4 = EOF_CHAR;
- } else {
- next_char4 = System.in.read();
- }
- }
- }
-
- /* count this */
- absolute_position++;
- current_position++;
- if (old_char == '\n' || (old_char == '\r' && next_char!='\n'))
- {
- current_line++;
- current_position = 1;
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Emit an error message. The message will be marked with both the
- * current line number and the position in the line. Error messages
- * are printed on standard error (System.err).
- * @param message the message to print.
- */
- public static void emit_error(String message)
- {
- System.err.println("Error at " + current_line + "(" + current_position +
- "): " + message);
- error_count++;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Emit a warning message. The message will be marked with both the
- * current line number and the position in the line. Messages are
- * printed on standard error (System.err).
- * @param message the message to print.
- */
- public static void emit_warn(String message)
- {
- System.err.println("Warning at " + current_line + "(" + current_position +
- "): " + message);
- warning_count++;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if a character is ok to start an id.
- * @param ch the character in question.
- */
- protected static boolean id_start_char(int ch)
- {
- /* allow for % in identifiers. a hack to allow my
- %prec in. Should eventually make lex spec for this
- frankf */
- return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
- (ch == '_');
-
- // later need to deal with non-8-bit chars here
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if a character is ok for the middle of an id.
- * @param ch the character in question.
- */
- protected static boolean id_char(int ch)
- {
- return id_start_char(ch) || (ch >= '0' && ch <= '9');
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Try to look up a single character symbol, returns -1 for not found.
- * @param ch the character in question.
- */
- protected static int find_single_char(int ch)
- {
- Integer result;
-
- result = (Integer)char_symbols.get(new Integer((char)ch));
- if (result == null)
- return -1;
- else
- return result.intValue();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Handle swallowing up a comment. Both old style C and new style C++
- * comments are handled.
- */
- protected static void swallow_comment() throws java.io.IOException
- {
- /* next_char == '/' at this point */
-
- /* is it a traditional comment */
- if (next_char2 == '*')
- {
- /* swallow the opener */
- advance(); advance();
-
- /* swallow the comment until end of comment or EOF */
- for (;;)
- {
- /* if its EOF we have an error */
- if (next_char == EOF_CHAR)
- {
- emit_error("Specification file ends inside a comment");
- return;
- }
-
- /* if we can see the closer we are done */
- if (next_char == '*' && next_char2 == '/')
- {
- advance();
- advance();
- return;
- }
-
- /* otherwise swallow char and move on */
- advance();
- }
- }
-
- /* is its a new style comment */
- if (next_char2 == '/')
- {
- /* swallow the opener */
- advance(); advance();
-
- /* swallow to '\n', '\r', '\f', or EOF */
- while (next_char != '\n' && next_char != '\r' &&
- next_char != '\f' && next_char!=EOF_CHAR)
- advance();
-
- return;
-
- }
-
- /* shouldn't get here, but... if we get here we have an error */
- emit_error("Malformed comment in specification -- ignored");
- advance();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Swallow up a code string. Code strings begin with "{:" and include
- all characters up to the first occurrence of ":}" (there is no way to
- include ":}" inside a code string). The routine returns a String
- object suitable for return by the scanner.
- */
- protected static Symbol do_code_string() throws java.io.IOException
- {
- StringBuffer result = new StringBuffer();
-
- /* at this point we have lookahead of "{:" -- swallow that */
- advance(); advance();
-
- /* save chars until we see ":}" */
- while (!(next_char == ':' && next_char2 == '}'))
- {
- /* if we have run off the end issue a message and break out of loop */
- if (next_char == EOF_CHAR)
- {
- emit_error("Specification file ends inside a code string");
- break;
- }
-
- /* otherwise record the char and move on */
- result.append(new Character((char)next_char));
- advance();
- }
-
- /* advance past the closer and build a return Symbol */
- advance(); advance();
- return new Symbol(sym.CODE_STRING, result.toString());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Process an identifier. Identifiers begin with a letter, underscore,
- * or dollar sign, which is followed by zero or more letters, numbers,
- * underscores or dollar signs. This routine returns a String suitable
- * for return by the scanner.
- */
- protected static Symbol do_id() throws java.io.IOException
- {
- StringBuffer result = new StringBuffer();
- String result_str;
- Integer keyword_num;
- char buffer[] = new char[1];
-
- /* next_char holds first character of id */
- buffer[0] = (char)next_char;
- result.append(buffer,0,1);
- advance();
-
- /* collect up characters while they fit in id */
- while(id_char(next_char))
- {
- buffer[0] = (char)next_char;
- result.append(buffer,0,1);
- advance();
- }
-
- /* extract a string and try to look it up as a keyword */
- result_str = result.toString();
- keyword_num = (Integer)keywords.get(result_str);
-
- /* if we found something, return that keyword */
- if (keyword_num != null)
- return new Symbol(keyword_num.intValue());
-
- /* otherwise build and return an id Symbol with an attached string */
- return new Symbol(sym.ID, result_str);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Return one Symbol. This is the main external interface to the scanner.
- * It consumes sufficient characters to determine the next input Symbol
- * and returns it. To help with debugging, this routine actually calls
- * real_next_token() which does the work. If you need to debug the
- * parser, this can be changed to call debug_next_token() which prints
- * a debugging message before returning the Symbol.
- */
- public static Symbol next_token() throws java.io.IOException
- {
- return real_next_token();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Debugging version of next_token(). This routine calls the real scanning
- * routine, prints a message on System.out indicating what the Symbol is,
- * then returns it.
- */
- public static Symbol debug_next_token() throws java.io.IOException
- {
- Symbol result = real_next_token();
- System.out.println("# next_Symbol() => " + result.sym);
- return result;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The actual routine to return one Symbol. This is normally called from
- * next_token(), but for debugging purposes can be called indirectly from
- * debug_next_token().
- */
- protected static Symbol real_next_token() throws java.io.IOException
- {
- int sym_num;
-
- for (;;)
- {
- /* look for white space */
- if (next_char == ' ' || next_char == '\t' || next_char == '\n' ||
- next_char == '\f' || next_char == '\r')
- {
- /* advance past it and try the next character */
- advance();
- continue;
- }
-
- /* look for a single character symbol */
- sym_num = find_single_char(next_char);
- if (sym_num != -1)
- {
- /* found one -- advance past it and return a Symbol for it */
- advance();
- return new Symbol(sym_num);
- }
-
- /* look for : or ::= */
- if (next_char == ':')
- {
- /* if we don't have a second ':' return COLON */
- if (next_char2 != ':')
- {
- advance();
- return new Symbol(sym.COLON);
- }
-
- /* move forward and look for the '=' */
- advance();
- if (next_char2 == '=')
- {
- advance(); advance();
- return new Symbol(sym.COLON_COLON_EQUALS);
- }
- else
- {
- /* return just the colon (already consumed) */
- return new Symbol(sym.COLON);
- }
- }
-
- /* find a "%prec" string and return it. otherwise, a '%' was found,
- which has no right being in the specification otherwise */
- if (next_char == '%') {
- advance();
- if ((next_char == 'p') && (next_char2 == 'r') && (next_char3 == 'e') &&
- (next_char4 == 'c')) {
- advance();
- advance();
- advance();
- advance();
- return new Symbol(sym.PERCENT_PREC);
- } else {
- emit_error("Found extraneous percent sign");
- }
- }
-
- /* look for a comment */
- if (next_char == '/' && (next_char2 == '*' || next_char2 == '/'))
- {
- /* swallow then continue the scan */
- swallow_comment();
- continue;
- }
-
- /* look for start of code string */
- if (next_char == '{' && next_char2 == ':')
- return do_code_string();
-
- /* look for an id or keyword */
- if (id_start_char(next_char)) return do_id();
-
- /* look for EOF */
- if (next_char == EOF_CHAR) return new Symbol(sym.EOF);
-
- /* if we get here, we have an unrecognized character */
- emit_warn("Unrecognized character '" +
- new Character((char)next_char) + "'(" + next_char +
- ") -- ignored");
-
- /* advance past it */
- advance();
- }
- }
-
- /*-----------------------------------------------------------*/
-}
-
+++ /dev/null
-
-package java_cup;
-
-/** The "core" of an LR item. This includes a production and the position
- * of a marker (the "dot") within the production. Typically item cores
- * are written using a production with an embedded "dot" to indicate their
- * position. For example: <pre>
- * A ::= B * C d E
- * </pre>
- * This represents a point in a parse where the parser is trying to match
- * the given production, and has succeeded in matching everything before the
- * "dot" (and hence is expecting to see the symbols after the dot next). See
- * lalr_item, lalr_item_set, and lalr_start for full details on the meaning
- * and use of items.
- *
- * @see java_cup.lalr_item
- * @see java_cup.lalr_item_set
- * @see java_cup.lalr_state
- * @version last updated: 11/25/95
- * @author Scott Hudson
-*/
-
-public class lr_item_core {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Full constructor.
- * @param prod production this item uses.
- * @param pos position of the "dot" within the item.
- */
- public lr_item_core(production prod, int pos) throws internal_error
- {
- symbol after_dot = null;
- production_part part;
-
- if (prod == null)
- throw new internal_error(
- "Attempt to create an lr_item_core with a null production");
-
- _the_production = prod;
-
- if (pos < 0 || pos > _the_production.rhs_length())
- throw new internal_error(
- "Attempt to create an lr_item_core with a bad dot position");
-
- _dot_pos = pos;
-
- /* compute and cache hash code now */
- _core_hash_cache = 13*_the_production.hashCode() + pos;
-
- /* cache the symbol after the dot */
- if (_dot_pos < _the_production.rhs_length())
- {
- part = _the_production.rhs(_dot_pos);
- if (!part.is_action())
- _symbol_after_dot = ((symbol_part)part).the_symbol();
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor for dot at start of right hand side.
- * @param prod production this item uses.
- */
- public lr_item_core(production prod) throws internal_error
- {
- this(prod,0);
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The production for the item. */
- protected production _the_production;
-
- /** The production for the item. */
- public production the_production() {return _the_production;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The position of the "dot" -- this indicates the part of the production
- * that the marker is before, so 0 indicates a dot at the beginning of
- * the RHS.
- */
- protected int _dot_pos;
-
- /** The position of the "dot" -- this indicates the part of the production
- * that the marker is before, so 0 indicates a dot at the beginning of
- * the RHS.
- */
- public int dot_pos() {return _dot_pos;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Cache of the hash code. */
- protected int _core_hash_cache;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Cache of symbol after the dot. */
- protected symbol _symbol_after_dot = null;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Is the dot at the end of the production? */
- public boolean dot_at_end()
- {
- return _dot_pos >= _the_production.rhs_length();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Return the symbol after the dot. If there is no symbol after the dot
- * we return null. */
- public symbol symbol_after_dot()
- {
- /* use the cached symbol */
- return _symbol_after_dot;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if we have a dot before a non terminal, and if so which one
- * (return null or the non terminal).
- */
- public non_terminal dot_before_nt()
- {
- symbol sym;
-
- /* get the symbol after the dot */
- sym = symbol_after_dot();
-
- /* if it exists and is a non terminal, return it */
- if (sym != null && sym.is_non_term())
- return (non_terminal)sym;
- else
- return null;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a new lr_item_core that results from shifting the dot one
- * position to the right.
- */
- public lr_item_core shift_core() throws internal_error
- {
- if (dot_at_end())
- throw new internal_error(
- "Attempt to shift past end of an lr_item_core");
-
- return new lr_item_core(_the_production, _dot_pos+1);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison for the core only. This is separate out because we
- * need separate access in a super class.
- */
- public boolean core_equals(lr_item_core other)
- {
- return other != null &&
- _the_production.equals(other._the_production) &&
- _dot_pos == other._dot_pos;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison. */
- public boolean equals(lr_item_core other) {return core_equals(other);}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof lr_item_core))
- return false;
- else
- return equals((lr_item_core)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Hash code for the core (separated so we keep non overridden version). */
- public int core_hashCode()
- {
- return _core_hash_cache;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Hash code for the item. */
- public int hashCode()
- {
- return _core_hash_cache;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Return the hash code that object would have provided for us so we have
- * a (nearly) unique id for debugging.
- */
- protected int obj_hash()
- {
- return super.hashCode();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string (separated out from toString() so we can call it
- * from subclass that overrides toString()).
- */
- public String to_simple_string() throws internal_error
- {
- String result;
- production_part part;
-
- if (_the_production.lhs() != null &&
- _the_production.lhs().the_symbol() != null &&
- _the_production.lhs().the_symbol().name() != null)
- result = _the_production.lhs().the_symbol().name();
- else
- result = "$$NULL$$";
-
- result += " ::= ";
-
- for (int i = 0; i<_the_production.rhs_length(); i++)
- {
- /* do we need the dot before this one? */
- if (i == _dot_pos)
- result += "(*) ";
-
- /* print the name of the part */
- if (_the_production.rhs(i) == null)
- {
- result += "$$NULL$$ ";
- }
- else
- {
- part = _the_production.rhs(i);
- if (part == null)
- result += "$$NULL$$ ";
- else if (part.is_action())
- result += "{ACTION} ";
- else if (((symbol_part)part).the_symbol() != null &&
- ((symbol_part)part).the_symbol().name() != null)
- result += ((symbol_part)part).the_symbol().name() + " ";
- else
- result += "$$NULL$$ ";
- }
- }
-
- /* put the dot after if needed */
- if (_dot_pos == _the_production.rhs_length())
- result += "(*) ";
-
- return result;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string */
- public String toString()
- {
- /* can't throw here since super class doesn't, so we crash instead */
- try {
- return to_simple_string();
- } catch(internal_error e) {
- e.crash();
- return null;
- }
- }
-
- /*-----------------------------------------------------------*/
-
-}
-
+++ /dev/null
-package java_cup;
-
-import java.util.Hashtable;
-import java.util.Enumeration;
-
-/** This class represents a non-terminal symbol in the grammar. Each
- * non terminal has a textual name, an index, and a string which indicates
- * the type of object it will be implemented with at runtime (i.e. the class
- * of object that will be pushed on the parse stack to represent it).
- *
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-
-public class non_terminal extends symbol {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Full constructor.
- * @param nm the name of the non terminal.
- * @param tp the type string for the non terminal.
- */
- public non_terminal(String nm, String tp)
- {
- /* super class does most of the work */
- super(nm, tp);
-
- /* add to set of all non terminals and check for duplicates */
- Object conflict = _all.put(nm,this);
- if (conflict != null)
- // can't throw an exception here because these are used in static
- // initializers, so we crash instead
- // was:
- // throw new internal_error("Duplicate non-terminal ("+nm+") created");
- (new internal_error("Duplicate non-terminal ("+nm+") created")).crash();
-
- /* assign a unique index */
- _index = next_index++;
-
- /* add to by_index set */
- _all_by_index.put(new Integer(_index), this);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor with default type.
- * @param nm the name of the non terminal.
- */
- public non_terminal(String nm)
- {
- this(nm, null);
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Static (Class) Variables ------------------*/
- /*-----------------------------------------------------------*/
-
- /** Table of all non-terminals -- elements are stored using name strings
- * as the key
- */
- protected static Hashtable _all = new Hashtable();
-
- /** Access to all non-terminals. */
- public static Enumeration all() {return _all.elements();}
-
- /** lookup a non terminal by name string */
- public static non_terminal find(String with_name)
- {
- if (with_name == null)
- return null;
- else
- return (non_terminal)_all.get(with_name);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Table of all non terminals indexed by their index number. */
- protected static Hashtable _all_by_index = new Hashtable();
-
- /** Lookup a non terminal by index. */
- public static non_terminal find(int indx)
- {
- Integer the_indx = new Integer(indx);
-
- return (non_terminal)_all_by_index.get(the_indx);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Total number of non-terminals. */
- public static int number() {return _all.size();}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Static counter to assign unique indexes. */
- protected static int next_index = 0;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Static counter for creating unique non-terminal names */
- static protected int next_nt = 0;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** special non-terminal for start symbol */
- public static final non_terminal START_nt = new non_terminal("$START");
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** flag non-terminals created to embed action productions */
- public boolean is_embedded_action = false; /* added 24-Mar-1998, CSA */
-
- /*-----------------------------------------------------------*/
- /*--- Static Methods ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Method for creating a new uniquely named hidden non-terminal using
- * the given string as a base for the name (or "NT$" if null is passed).
- * @param prefix base name to construct unique name from.
- */
- static non_terminal create_new(String prefix) throws internal_error
- {
- if (prefix == null) prefix = "NT$";
- return new non_terminal(prefix + next_nt++);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** static routine for creating a new uniquely named hidden non-terminal */
- static non_terminal create_new() throws internal_error
- {
- return create_new(null);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Compute nullability of all non-terminals. */
- public static void compute_nullability() throws internal_error
- {
- boolean change = true;
- non_terminal nt;
- Enumeration e;
- production prod;
-
- /* repeat this process until there is no change */
- while (change)
- {
- /* look for a new change */
- change = false;
-
- /* consider each non-terminal */
- for (e=all(); e.hasMoreElements(); )
- {
- nt = (non_terminal)e.nextElement();
-
- /* only look at things that aren't already marked nullable */
- if (!nt.nullable())
- {
- if (nt.looks_nullable())
- {
- nt._nullable = true;
- change = true;
- }
- }
- }
- }
-
- /* do one last pass over the productions to finalize all of them */
- for (e=production.all(); e.hasMoreElements(); )
- {
- prod = (production)e.nextElement();
- prod.set_nullable(prod.check_nullable());
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Compute first sets for all non-terminals. This assumes nullability has
- * already computed.
- */
- public static void compute_first_sets() throws internal_error
- {
- boolean change = true;
- Enumeration n;
- Enumeration p;
- non_terminal nt;
- production prod;
- terminal_set prod_first;
-
- /* repeat this process until we have no change */
- while (change)
- {
- /* look for a new change */
- change = false;
-
- /* consider each non-terminal */
- for (n = all(); n.hasMoreElements(); )
- {
- nt = (non_terminal)n.nextElement();
-
- /* consider every production of that non terminal */
- for (p = nt.productions(); p.hasMoreElements(); )
- {
- prod = (production)p.nextElement();
-
- /* get the updated first of that production */
- prod_first = prod.check_first_set();
-
- /* if this going to add anything, add it */
- if (!prod_first.is_subset_of(nt._first_set))
- {
- change = true;
- nt._first_set.add(prod_first);
- }
- }
- }
- }
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Table of all productions with this non terminal on the LHS. */
- protected Hashtable _productions = new Hashtable(11);
-
- /** Access to productions with this non terminal on the LHS. */
- public Enumeration productions() {return _productions.elements();}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Total number of productions with this non terminal on the LHS. */
- public int num_productions() {return _productions.size();}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Add a production to our set of productions. */
- public void add_production(production prod) throws internal_error
- {
- /* catch improper productions */
- if (prod == null || prod.lhs() == null || prod.lhs().the_symbol() != this)
- throw new internal_error(
- "Attempt to add invalid production to non terminal production table");
-
- /* add it to the table, keyed with itself */
- _productions.put(prod,prod);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Nullability of this non terminal. */
- protected boolean _nullable;
-
- /** Nullability of this non terminal. */
- public boolean nullable() {return _nullable;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** First set for this non-terminal. */
- protected terminal_set _first_set = new terminal_set();
-
- /** First set for this non-terminal. */
- public terminal_set first_set() {return _first_set;}
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Indicate that this symbol is a non-terminal. */
- public boolean is_non_term()
- {
- return true;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Test to see if this non terminal currently looks nullable. */
- protected boolean looks_nullable() throws internal_error
- {
- /* look and see if any of the productions now look nullable */
- for (Enumeration e = productions(); e.hasMoreElements(); )
- /* if the production can go to empty, we are nullable */
- if (((production)e.nextElement()).check_nullable())
- return true;
-
- /* none of the productions can go to empty, so we are not nullable */
- return false;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** convert to string */
- public String toString()
- {
- return super.toString() + "[" + index() + "]" + (nullable() ? "*" : "");
- }
-
- /*-----------------------------------------------------------*/
-}
+++ /dev/null
-
-package java_cup;
-
-/** This class represents a shift/reduce nonassociative error within the
- * parse table. If action_table element is assign to type
- * nonassoc_action, it cannot be changed, and signifies that there
- * is a conflict between shifting and reducing a production and a
- * terminal that shouldn't be next to each other.
- *
- * @version last updated: 7/2/96
- * @author Frank Flannery
- */
-public class nonassoc_action extends parse_action {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor.
- */
- public nonassoc_action() throws internal_error
- {
- /* don't need to set anything, since it signifies error */
- }
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Quick access to type of action. */
- public int kind() {return NONASSOC;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality test. */
- public boolean equals(parse_action other)
- {
- return other != null && other.kind() == NONASSOC;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality test. */
- public boolean equals(Object other)
- {
- if (other instanceof parse_action)
- return equals((parse_action)other);
- else
- return false;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Compute a hash code. */
- public int hashCode()
- {
- /* all objects of this class hash together */
- return 0xCafe321;
- }
-
-
-
- /** Convert to string. */
- public String toString()
- {
- return "NONASSOC";
- }
-
- /*-----------------------------------------------------------*/
-
-}
+++ /dev/null
-
-package java_cup;
-
-/** This class serves as the base class for entries in a parse action table.
- * Full entries will either be SHIFT(state_num), REDUCE(production), NONASSOC,
- * or ERROR. Objects of this base class will default to ERROR, while
- * the other three types will be represented by subclasses.
- *
- * @see java_cup.reduce_action
- * @see java_cup.shift_action
- * @version last updated: 7/2/96
- * @author Frank Flannery
- */
-
-public class parse_action {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor. */
- public parse_action()
- {
- /* nothing to do in the base class */
- }
-
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Static (Class) Variables ------------------*/
- /*-----------------------------------------------------------*/
-
- /** Constant for action type -- error action. */
- public static final int ERROR = 0;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constant for action type -- shift action. */
- public static final int SHIFT = 1;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constants for action type -- reduce action. */
- public static final int REDUCE = 2;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constants for action type -- reduce action. */
- public static final int NONASSOC = 3;
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Quick access to the type -- base class defaults to error. */
- public int kind() {return ERROR;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality test. */
- public boolean equals(parse_action other)
- {
- /* we match all error actions */
- return other != null && other.kind() == ERROR;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality test. */
- public boolean equals(Object other)
- {
- if (other instanceof parse_action)
- return equals((parse_action)other);
- else
- return false;
- }
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Compute a hash code. */
- public int hashCode()
- {
- /* all objects of this class hash together */
- return 0xCafe123;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to string. */
- public String toString() {return "ERROR";}
-
- /*-----------------------------------------------------------*/
-}
-
+++ /dev/null
-
-package java_cup;
-
-/** This class represents one row (corresponding to one machine state) of the
- * parse action table.
- */
-public class parse_action_row {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor. Note: this should not be used until the number of
- * terminals in the grammar has been established.
- */
- public parse_action_row()
- {
- /* make sure the size is set */
- if (_size <= 0 ) _size = terminal.number();
-
- /* allocate the array */
- under_term = new parse_action[size()];
-
- /* set each element to an error action */
- for (int i=0; i<_size; i++)
- under_term[i] = new parse_action();
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Static (Class) Variables ------------------*/
- /*-----------------------------------------------------------*/
-
- /** Number of columns (terminals) in every row. */
- protected static int _size = 0;
-
- /** Number of columns (terminals) in every row. */
- public static int size() {return _size;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Table of reduction counts (reused by compute_default()). */
- protected static int reduction_count[] = null;
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Actual action entries for the row. */
- public parse_action under_term[];
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Default (reduce) action for this row. -1 will represent default
- * of error.
- */
- public int default_reduce;
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Compute the default (reduce) action for this row and store it in
- * default_reduce. In the case of non-zero default we will have the
- * effect of replacing all errors by that reduction. This may cause
- * us to do erroneous reduces, but will never cause us to shift past
- * the point of the error and never cause an incorrect parse. -1 will
- * be used to encode the fact that no reduction can be used as a
- * default (in which case error will be used).
- */
- public void compute_default()
- {
- int i, prod, max_prod, max_red;
-
- /* if we haven't allocated the count table, do so now */
- if (reduction_count == null)
- reduction_count = new int[production.number()];
-
- /* clear the reduction count table and maximums */
- for (i = 0; i < production.number(); i++)
- reduction_count[i] = 0;
- max_prod = -1;
- max_red = 0;
-
- /* walk down the row and look at the reduces */
- for (i = 0; i < size(); i++)
- if (under_term[i].kind() == parse_action.REDUCE)
- {
- /* count the reduce in the proper production slot and keep the
- max up to date */
- prod = ((reduce_action)under_term[i]).reduce_with().index();
- reduction_count[prod]++;
- if (reduction_count[prod] > max_red)
- {
- max_red = reduction_count[prod];
- max_prod = prod;
- }
- }
-
- /* record the max as the default (or -1 for not found) */
- default_reduce = max_prod;
- }
-
- /*-----------------------------------------------------------*/
-
-}
-
+++ /dev/null
-
-package java_cup;
-
-import java.util.Enumeration;
-
-/** This class represents the complete "action" table of the parser.
- * It has one row for each state in the parse machine, and a column for
- * each terminal symbol. Each entry in the table represents a shift,
- * reduce, or an error.
- *
- * @see java_cup.parse_action
- * @see java_cup.parse_action_row
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-public class parse_action_table {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor. All terminals, non-terminals, and productions must
- * already have been entered, and the viable prefix recognizer should
- * have been constructed before this is called.
- */
- public parse_action_table()
- {
- /* determine how many states we are working with */
- _num_states = lalr_state.number();
-
- /* allocate the array and fill it in with empty rows */
- under_state = new parse_action_row[_num_states];
- for (int i=0; i<_num_states; i++)
- under_state[i] = new parse_action_row();
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** How many rows/states are in the machine/table. */
- protected int _num_states;
-
- /** How many rows/states are in the machine/table. */
- public int num_states() {return _num_states;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Actual array of rows, one per state. */
- public parse_action_row[] under_state;
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Check the table to ensure that all productions have been reduced.
- * Issue a warning message (to System.err) for each production that
- * is never reduced.
- */
- public void check_reductions()
- throws internal_error
- {
- parse_action act;
- production prod;
-
- /* tabulate reductions -- look at every table entry */
- for (int row = 0; row < num_states(); row++)
- {
- for (int col = 0; col < under_state[row].size(); col++)
- {
- /* look at the action entry to see if its a reduce */
- act = under_state[row].under_term[col];
- if (act != null && act.kind() == parse_action.REDUCE)
- {
- /* tell production that we used it */
- ((reduce_action)act).reduce_with().note_reduction_use();
- }
- }
- }
-
- /* now go across every production and make sure we hit it */
- for (Enumeration p = production.all(); p.hasMoreElements(); )
- {
- prod = (production)p.nextElement();
-
- /* if we didn't hit it give a warning */
- if (prod.num_reductions() == 0)
- {
- /* count it *
- emit.not_reduced++;
-
- /* give a warning if they haven't been turned off */
- if (!emit.nowarn)
- {
- System.err.println("*** Production \"" +
- prod.to_simple_string() + "\" never reduced");
- lexer.warning_count++;
- }
- }
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*
-
- /** Convert to a string. */
- public String toString()
- {
- String result;
- int cnt;
-
- result = "-------- ACTION_TABLE --------\n";
- for (int row = 0; row < num_states(); row++)
- {
- result += "From state #" + row + "\n";
- cnt = 0;
- for (int col = 0; col < under_state[row].size(); col++)
- {
- /* if the action is not an error print it */
- if (under_state[row].under_term[col].kind() != parse_action.ERROR)
- {
- result += " [term " + col + ":" + under_state[row].under_term[col] + "]";
-
- /* end the line after the 2nd one */
- cnt++;
- if (cnt == 2)
- {
- result += "\n";
- cnt = 0;
- }
- }
- }
- /* finish the line if we haven't just done that */
- if (cnt != 0) result += "\n";
- }
- result += "------------------------------";
-
- return result;
- }
-
- /*-----------------------------------------------------------*/
-
-}
-
+++ /dev/null
-
-package java_cup;
-
-/** This class represents one row (corresponding to one machine state) of the
- * reduce-goto parse table.
- */
-public class parse_reduce_row {
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor. Note: this should not be used until the number
- * of terminals in the grammar has been established.
- */
- public parse_reduce_row()
- {
- /* make sure the size is set */
- if (_size <= 0 ) _size = non_terminal.number();
-
- /* allocate the array */
- under_non_term = new lalr_state[size()];
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Static (Class) Variables ------------------*/
- /*-----------------------------------------------------------*/
-
- /** Number of columns (non terminals) in every row. */
- protected static int _size = 0;
-
- /** Number of columns (non terminals) in every row. */
- public static int size() {return _size;}
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Actual entries for the row. */
- public lalr_state under_non_term[];
-}
-
+++ /dev/null
-
-package java_cup;
-
-import java.util.Enumeration;
-
-/** This class represents the complete "reduce-goto" table of the parser.
- * It has one row for each state in the parse machines, and a column for
- * each terminal symbol. Each entry contains a state number to shift to
- * as the last step of a reduce.
- *
- * @see java_cup.parse_reduce_row
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-public class parse_reduce_table {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor. Note: all terminals, non-terminals, and productions
- * must already have been entered, and the viable prefix recognizer should
- * have been constructed before this is called.
- */
- public parse_reduce_table()
- {
- /* determine how many states we are working with */
- _num_states = lalr_state.number();
-
- /* allocate the array and fill it in with empty rows */
- under_state = new parse_reduce_row[_num_states];
- for (int i=0; i<_num_states; i++)
- under_state[i] = new parse_reduce_row();
- }
-
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** How many rows/states in the machine/table. */
- protected int _num_states;
-
- /** How many rows/states in the machine/table. */
- public int num_states() {return _num_states;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Actual array of rows, one per state */
- public parse_reduce_row[] under_state;
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Convert to a string. */
- public String toString()
- {
- String result;
- lalr_state goto_st;
- int cnt;
-
- result = "-------- REDUCE_TABLE --------\n";
- for (int row = 0; row < num_states(); row++)
- {
- result += "From state #" + row + "\n";
- cnt = 0;
- for (int col = 0; col < under_state[row].size(); col++)
- {
- /* pull out the table entry */
- goto_st = under_state[row].under_non_term[col];
-
- /* if it has action in it, print it */
- if (goto_st != null)
- {
- result += " [non term " + col + "->";
- result += "state " + goto_st.index() + "]";
-
- /* end the line after the 3rd one */
- cnt++;
- if (cnt == 3)
- {
- result += "\n";
- cnt = 0;
- }
- }
- }
- /* finish the line if we haven't just done that */
- if (cnt != 0) result += "\n";
- }
- result += "-----------------------------";
-
- return result;
- }
-
- /*-----------------------------------------------------------*/
-
-}
-
+++ /dev/null
-
-/*================================================================*/
-/*
- JavaCup Specification for the JavaCup Specification Language
- by Scott Hudson, GVU Center, Georgia Tech, August 1995
- and Frank Flannery, Department of Computer Science, Princeton Univ,
- July 1996
- Bug Fixes: C. Scott Ananian, Dept of Electrical Engineering, Princeton
- University, October 1996. [later Massachusetts Institute of Technology]
-
-
- This JavaCup specification is used to implement JavaCup itself.
- It specifies the parser for the JavaCup specification language.
- (It also serves as a reasonable example of what a typical JavaCup
- spec looks like).
-
- The specification has the following parts:
- Package and import declarations
- These serve the same purpose as in a normal Java source file
- (and will appear in the generated code for the parser). In this
- case we are part of the java_cup package and we import both the
- java_cup runtime system and Hashtable from the standard Java
- utilities package.
-
- Action code
- This section provides code that is included with the class encapsulating
- the various pieces of user code embedded in the grammar (i.e., the
- semantic actions). This provides a series of helper routines and
- data structures that the semantic actions use.
-
- Parser code
- This section provides code included in the parser class itself. In
- this case we override the default error reporting routines.
-
- Init with and scan with
- These sections provide small bits of code that initialize, then
- indicate how to invoke the scanner.
-
- Symbols and grammar
- These sections declare all the terminal and non terminal symbols
- and the types of objects that they will be represented by at runtime,
- then indicate the start symbol of the grammar (), and finally provide
- the grammar itself (with embedded actions).
-
- Operation of the parser
- The parser acts primarily by accumulating data structures representing
- various parts of the specification. Various small parts (e.g., single
- code strings) are stored as static variables of the emit class and
- in a few cases as variables declared in the action code section.
- Terminals, non terminals, and productions, are maintained as collection
- accessible via static methods of those classes. In addition, two
- symbol tables are kept:
- symbols maintains the name to object mapping for all symbols
- non_terms maintains a separate mapping containing only the non terms
-
- Several intermediate working structures are also declared in the action
- code section. These include: rhs_parts, rhs_pos, and lhs_nt which
- build up parts of the current production while it is being parsed.
-
- Author(s)
- Scott Hudson, GVU Center, Georgia Tech.
- Frank Flannery, Department of Computer Science, Princeton Univ.
- C. Scott Ananian, Department of Electrical Engineering, Princeton Univ.
-
- Revisions
- v0.9a First released version [SEH] 8/29/95
- v0.9b Updated for beta language (throws clauses) [SEH] 11/25/95
- v0.10a Made many improvements/changes. now offers:
- return value
- left/right positions and propagations
- cleaner label references
- precedence and associativity for terminals
- contextual precedence for productions
- [FF] 7/3/96
- v0.10b Fixed %prec directive so it works like it's supposed to.
- [CSA] 10/10/96
- v0.10g Added support for array types on symbols.
- [CSA] 03/23/98
- v0.10i Broaden set of IDs allowed in multipart_id and label_id so
- that only java reserved words (and not CUP reserved words like
- 'parser' and 'start') are prohibited. Allow reordering of
- action code, parser code, init code, and scan with sections,
- and made closing semicolon optional for these sections.
- Added 'nonterminal' as a terminal symbol, finally fixing a
- spelling mistake that's been around since the beginning.
- For backwards compatibility, you can still misspell the
- word if you like.
-*/
-/*================================================================*/
-
-package java_cup;
-import java_cup.runtime.*;
-import java.util.Hashtable;
-
-/*----------------------------------------------------------------*/
-
-action code {:
- /** helper routine to clone a new production part adding a given label */
- protected production_part add_lab(production_part part, String lab)
- throws internal_error
- {
- /* if there is no label, or this is an action, just return the original */
- if (lab == null || part.is_action()) return part;
-
- /* otherwise build a new one with the given label attached */
- return new symbol_part(((symbol_part)part).the_symbol(),lab);
- }
-
- /** max size of right hand side we will support */
- protected final int MAX_RHS = 200;
-
- /** array for accumulating right hand side parts */
- protected production_part[] rhs_parts = new production_part[MAX_RHS];
-
- /** where we are currently in building a right hand side */
- protected int rhs_pos = 0;
-
- /** start a new right hand side */
- protected void new_rhs() {rhs_pos = 0; }
-
- /** add a new right hand side part */
- protected void add_rhs_part(production_part part) throws java.lang.Exception
- {
- if (rhs_pos >= MAX_RHS)
- throw new Exception("Internal Error: Productions limited to " +
- MAX_RHS + " symbols and actions");
-
- rhs_parts[rhs_pos] = part;
- rhs_pos++;
- }
-
- /** string to build up multiple part names */
- protected String multipart_name = new String();
-
- /** append a new name segment to the accumulated multipart name */
- protected void append_multipart(String name)
- {
- String dot = "";
-
- /* if we aren't just starting out, put on a dot */
- if (multipart_name.length() != 0) dot = ".";
-
- multipart_name = multipart_name.concat(dot + name);
- }
-
- /** table of declared symbols -- contains production parts indexed by name */
- protected Hashtable symbols = new Hashtable();
-
- /** table of just non terminals -- contains non_terminals indexed by name */
- protected Hashtable non_terms = new Hashtable();
-
- /** declared start non_terminal */
- protected non_terminal start_nt = null;
-
- /** left hand side non terminal of the current production */
- protected non_terminal lhs_nt;
-
- /** Current precedence number */
- int _cur_prec = 0;
-
- /** Current precedence side */
- int _cur_side = assoc.no_prec;
-
- /** update the precedences we are declaring */
- protected void update_precedence(int p) {
- _cur_side = p;
- _cur_prec++;
- }
- /** add relevant data to terminals */
- protected void add_precedence(String term) {
- if (term == null) {
- System.err.println("Unable to add precedence to nonexistent terminal");
- } else {
- symbol_part sp = (symbol_part)symbols.get(term);
- if (sp == null) {
- System.err.println("Could find terminal " + term + " while declaring precedence");
- } else {
- java_cup.symbol sym = sp.the_symbol();
- if (sym instanceof terminal)
- ((terminal)sym).set_precedence(_cur_side, _cur_prec);
- else System.err.println("Precedence declaration: Can't find terminal " + term);
- }
- }
- }
-:};
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-parser code {:
-
- /* override error routines */
-
- public void report_fatal_error(
- String message,
- Object info)
- {
- done_parsing();
- lexer.emit_error(message);
- System.err.println("Can't recover from previous error(s), giving up.");
- System.exit(1);
- }
-
- public void report_error(String message, Object info)
- {
- lexer.emit_error(message);
- }
-:};
-
-/*----------------------------------------------------------------*/
-
-init with {: lexer.init(); :};
-scan with {: return lexer.next_token(); :};
-
-/*----------------------------------------------------------------*/
-
-terminal
- PACKAGE, IMPORT, CODE, ACTION, PARSER, TERMINAL, NON, INIT, SCAN, WITH,
- START, SEMI, COMMA, STAR, DOT, COLON, COLON_COLON_EQUALS, BAR, PRECEDENCE,
- LEFT, RIGHT, NONASSOC, PERCENT_PREC, LBRACK, RBRACK, NONTERMINAL;
-
-terminal String ID, CODE_STRING;
-
-non terminal
- spec, package_spec, import_list, action_code_part,
- code_parts, code_part, opt_semi, non_terminal,
- parser_code_part, symbol_list, start_spec, production_list,
- multipart_id, import_spec, import_id, init_code, scan_code, symbol,
- type_id, term_name_list, non_term_name_list, production, prod_part_list,
- prod_part, new_term_id, new_non_term_id, rhs_list, rhs, empty,
- precedence_list, preced, terminal_list, precedence_l, declares_term,
- declares_non_term;
-
-non terminal String nt_id, symbol_id, label_id, opt_label, terminal_id,
- term_id, robust_id;
-
-/*----------------------------------------------------------------*/
-
-start with spec;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-spec ::=
- {:
- /* declare "error" as a terminal */
- symbols.put("error", new symbol_part(terminal.error));
-
- /* declare start non terminal */
- non_terms.put("$START", non_terminal.START_nt);
- :}
- package_spec
- import_list
- code_parts
- symbol_list
- precedence_list
- start_spec
- production_list
- |
- /* error recovery assuming something went wrong before symbols
- and we have TERMINAL or NON TERMINAL to sync on. if we get
- an error after that, we recover inside symbol_list or
- production_list
- */
- error
- symbol_list
- precedence_list
- start_spec
- production_list
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-package_spec ::=
- PACKAGE
- multipart_id
- {:
- /* save the package name */
- emit.package_name = multipart_name;
-
- /* reset the accumulated multipart name */
- multipart_name = new String();
- :}
- SEMI
- |
- empty
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-import_list ::=
- import_list
- import_spec
- |
- empty
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-import_spec ::=
- IMPORT
- import_id
- {:
- /* save this import on the imports list */
- emit.import_list.push(multipart_name);
-
- /* reset the accumulated multipart name */
- multipart_name = new String();
- :}
- SEMI
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-// allow any order; all parts are optional. [CSA, 23-Jul-1999]
-// (we check in the part action to make sure we don't have 2 of any part)
-code_part ::=
- action_code_part | parser_code_part | init_code | scan_code ;
-code_parts ::=
- | code_parts code_part;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-action_code_part ::=
- ACTION CODE CODE_STRING:user_code opt_semi
- {:
- if (emit.action_code!=null)
- lexer.emit_error("Redundant action code (skipping)");
- else /* save the user included code string */
- emit.action_code = user_code;
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-parser_code_part ::=
- PARSER CODE CODE_STRING:user_code opt_semi
- {:
- if (emit.parser_code!=null)
- lexer.emit_error("Redundant parser code (skipping)");
- else /* save the user included code string */
- emit.parser_code = user_code;
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-init_code ::=
- INIT WITH CODE_STRING:user_code opt_semi
- {:
- if (emit.init_code!=null)
- lexer.emit_error("Redundant init code (skipping)");
- else /* save the user code */
- emit.init_code = user_code;
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-scan_code ::=
- SCAN WITH CODE_STRING:user_code opt_semi
- {:
- if (emit.scan_code!=null)
- lexer.emit_error("Redundant scan code (skipping)");
- else /* save the user code */
- emit.scan_code = user_code;
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-symbol_list ::= symbol_list symbol | symbol;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-symbol ::=
- TERMINAL
- type_id
- declares_term
- |
- TERMINAL
- declares_term
- |
- non_terminal
- type_id
- declares_non_term
- |
- non_terminal
- declares_non_term
- |
- /* error recovery productions -- sync on semicolon */
-
- TERMINAL
- error
- {:
- /* reset the accumulated multipart name */
- multipart_name = new String();
- :}
- SEMI
- |
- non_terminal
- error
- {:
- /* reset the accumulated multipart name */
- multipart_name = new String();
- :}
- SEMI
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-declares_term ::=
- term_name_list
- {:
- /* reset the accumulated multipart name */
- multipart_name = new String();
- :}
- SEMI
- ;
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-declares_non_term ::=
- non_term_name_list
- {:
- /* reset the accumulated multipart name */
- multipart_name = new String();
- :}
- SEMI
- ;
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-term_name_list ::= term_name_list COMMA new_term_id | new_term_id;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-non_term_name_list ::=
- non_term_name_list
- COMMA
- new_non_term_id
- |
- new_non_term_id
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-
-precedence_list ::= precedence_l | empty;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-precedence_l ::= precedence_l preced | preced;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-preced ::=
- PRECEDENCE LEFT
- {:
- update_precedence(assoc.left);
- :}
- terminal_list SEMI
- |
- PRECEDENCE RIGHT
- {:
- update_precedence(assoc.right);
- :}
- terminal_list SEMI
- |
- PRECEDENCE NONASSOC
- {:
- update_precedence(assoc.nonassoc);
- :}
- terminal_list SEMI
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-terminal_list ::= terminal_list COMMA terminal_id
- |
- terminal_id
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-terminal_id ::= term_id:sym
- {:
- add_precedence(sym);
- RESULT = sym;
- :};
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-term_id ::= symbol_id:sym
- {:
- /* check that the symbol_id is a terminal */
- if (symbols.get(sym) == null)
- {
- /* issue a message */
- lexer.emit_error("Terminal \"" + sym +
- "\" has not been declared");
- }
- RESULT = sym;
- :};
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-start_spec ::=
- START WITH nt_id:start_name
- {:
- /* verify that the name has been declared as a non terminal */
- non_terminal nt = (non_terminal)non_terms.get(start_name);
- if (nt == null)
- {
- lexer.emit_error( "Start non terminal \"" + start_name +
- "\" has not been declared");
- }
- else
- {
- /* remember the non-terminal for later */
- start_nt = nt;
-
- /* build a special start production */
- new_rhs();
- add_rhs_part(add_lab(new symbol_part(start_nt), "start_val"));
- add_rhs_part(new symbol_part(terminal.EOF));
- add_rhs_part(new action_part("RESULT = start_val;"));
- emit.start_production =
- new production(non_terminal.START_nt, rhs_parts, rhs_pos);
- new_rhs();
- }
- :}
- SEMI
- |
- empty
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-production_list ::= production_list production | production;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-production ::=
- nt_id:lhs_id
- {:
- /* lookup the lhs nt */
- lhs_nt = (non_terminal)non_terms.get(lhs_id);
-
- /* if it wasn't declared, emit a message */
- if (lhs_nt == null)
- {
- if (lexer.error_count == 0)
- lexer.emit_error("LHS non terminal \"" + lhs_id +
- "\" has not been declared");
- }
-
- /* reset the rhs accumulation */
- new_rhs();
- :}
- COLON_COLON_EQUALS
- {: :}
- rhs_list
- SEMI
- |
- error
- {: lexer.emit_error("Syntax Error"); :}
- SEMI
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-rhs_list ::= rhs_list BAR rhs | rhs;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-rhs ::=
- prod_part_list PERCENT_PREC term_id:term_name
- {:
- java_cup.symbol sym = null;
- if (lhs_nt != null)
- {
- /* Find the precedence symbol */
- if (term_name == null) {
- System.err.println("No terminal for contextual precedence");
- sym = null;
- } else {
- sym = ((symbol_part)symbols.get(term_name)).the_symbol();
- }
- /* build the production */
- production p;
- if ((sym!=null) && (sym instanceof terminal)) {
- p = new production(lhs_nt, rhs_parts, rhs_pos,
- ((terminal)sym).precedence_num(),
- ((terminal)sym).precedence_side());
- ((symbol_part)symbols.get(term_name)).the_symbol().note_use();
- } else {
- System.err.println("Invalid terminal " + term_name +
- " for contextual precedence assignment");
- p = new production(lhs_nt, rhs_parts, rhs_pos);
- }
-
- /* if we have no start non-terminal declared and this is
- the first production, make its lhs nt the start_nt
- and build a special start production for it. */
- if (start_nt == null)
- {
- start_nt = lhs_nt;
-
- /* build a special start production */
- new_rhs();
- add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
- add_rhs_part(new symbol_part(terminal.EOF));
- add_rhs_part(new action_part("RESULT = start_val;"));
- if ((sym!=null) && (sym instanceof terminal)) {
- emit.start_production =
- new production(non_terminal.START_nt, rhs_parts,
- rhs_pos, ((terminal)sym).precedence_num(),
- ((terminal)sym).precedence_side());
- } else {
- emit.start_production =
- new production(non_terminal.START_nt, rhs_parts, rhs_pos);
- }
- new_rhs();
- }
- }
-
- /* reset the rhs accumulation in any case */
- new_rhs();
- :}
- |
- prod_part_list
- {:
- if (lhs_nt != null)
- {
- /* build the production */
- production p = new production(lhs_nt, rhs_parts, rhs_pos);
-
- /* if we have no start non-terminal declared and this is
- the first production, make its lhs nt the start_nt
- and build a special start production for it. */
- if (start_nt == null)
- {
- start_nt = lhs_nt;
-
- /* build a special start production */
- new_rhs();
- add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
- add_rhs_part(new symbol_part(terminal.EOF));
- add_rhs_part(new action_part("RESULT = start_val;"));
- emit.start_production =
- new production(non_terminal.START_nt, rhs_parts, rhs_pos);
-
- new_rhs();
- }
- }
-
- /* reset the rhs accumulation in any case */
- new_rhs();
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-prod_part_list ::= prod_part_list prod_part | empty;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-prod_part ::=
- symbol_id:symid opt_label:labid
- {:
- /* try to look up the id */
- production_part symb = (production_part)symbols.get(symid);
-
- /* if that fails, symbol is undeclared */
- if (symb == null)
- {
- if (lexer.error_count == 0)
- lexer.emit_error("java_cup.runtime.Symbol \"" + symid +
- "\" has not been declared");
- }
- else
- {
- /* add a labeled production part */
- add_rhs_part(add_lab(symb, labid));
- }
- :}
- |
- CODE_STRING:code_str
- {:
- /* add a new production part */
- add_rhs_part(new action_part(code_str));
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-opt_label ::=
- COLON label_id:labid
- {: RESULT = labid; :}
- |
- empty
- {: RESULT = null; :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-multipart_id ::=
- multipart_id DOT robust_id:another_id
- {: append_multipart(another_id); :}
- |
- robust_id:an_id
- {: append_multipart(an_id); :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-import_id ::=
- multipart_id DOT STAR
- {: append_multipart("*"); :}
- |
- multipart_id
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-type_id ::= multipart_id
- | type_id LBRACK RBRACK
- {: multipart_name = multipart_name.concat("[]"); :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-new_term_id ::=
- ID:term_id
- {:
- /* see if this terminal has been declared before */
- if (symbols.get(term_id) != null)
- {
- /* issue a message */
- lexer.emit_error("java_cup.runtime.Symbol \"" + term_id +
- "\" has already been declared");
- }
- else
- {
- /* if no type declared, declare one */
- if (multipart_name.equals("")) {
- append_multipart("Object");
- }
- /* build a production_part and put it in the table */
- symbols.put(term_id,
- new symbol_part(new terminal(term_id, multipart_name)));
- }
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-new_non_term_id ::=
- ID:non_term_id
- {:
- /* see if this non terminal has been declared before */
- if (symbols.get(non_term_id) != null)
- {
- /* issue a message */
- lexer.emit_error( "java_cup.runtime.Symbol \"" + non_term_id +
- "\" has already been declared");
- }
- else
- {
- if (multipart_name.equals("")) {
- append_multipart("Object");
- }
- /* build the non terminal object */
- non_terminal this_nt =
- new non_terminal(non_term_id, multipart_name);
-
- /* put it in the non_terms table */
- non_terms.put(non_term_id, this_nt);
-
- /* build a production_part and put it in the symbols table */
- symbols.put(non_term_id, new symbol_part(this_nt));
- }
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-nt_id ::=
- ID:the_id
- {: RESULT = the_id; :}
- | error
- {:
- lexer.emit_error("Illegal use of reserved word");
- RESULT="ILLEGAL";
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-symbol_id ::=
- ID:the_id
- {: RESULT = the_id; :}
- | error
- {:
- lexer.emit_error("Illegal use of reserved word");
- RESULT="ILLEGAL";
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-label_id ::=
- robust_id:the_id
- {: RESULT = the_id; :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-robust_id ::= /* all ids that aren't reserved words in Java */
- ID:the_id {: RESULT = the_id; :}
- /* package is reserved. */
- /* import is reserved. */
- | CODE {: RESULT = "code"; :}
- | ACTION {: RESULT = "action"; :}
- | PARSER {: RESULT = "parser"; :}
- | TERMINAL {: RESULT = "terminal"; :}
- | NON {: RESULT = "non"; :}
- | NONTERMINAL {: RESULT = "nonterminal"; :}
- | INIT {: RESULT = "init"; :}
- | SCAN {: RESULT = "scan"; :}
- | WITH {: RESULT = "with"; :}
- | START {: RESULT = "start"; :}
- | PRECEDENCE {: RESULT = "precedence"; :}
- | LEFT {: RESULT = "left"; :}
- | RIGHT {: RESULT = "right"; :}
- | NONASSOC {: RESULT = "nonassoc"; :}
- | error
- {:
- lexer.emit_error("Illegal use of reserved word");
- RESULT="ILLEGAL";
- :}
- ;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-non_terminal ::= NON TERMINAL | NONTERMINAL;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-opt_semi ::= /* nothing */
- | SEMI;
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
-empty ::= /* nothing */;
-
-/*----------------------------------------------------------------*/
-
-
-
-
-
-
-
-
-
+++ /dev/null
-
-//----------------------------------------------------
-// The following code was generated by CUP v0.10k
-// Sun Jul 25 13:35:26 EDT 1999
-//----------------------------------------------------
-
-package java_cup;
-
-import java_cup.runtime.*;
-import java.util.Hashtable;
-
-/** CUP v0.10k generated parser.
- * @version Sun Jul 25 13:35:26 EDT 1999
- */
-public class parser extends java_cup.runtime.lr_parser {
-
- /** Default constructor. */
- public parser() {super();}
-
- /** Constructor which sets the default scanner. */
- public parser(java_cup.runtime.Scanner s) {super(s);}
-
- /** Production table. */
- protected static final short _production_table[][] =
- unpackFromStrings(new String[] {
- "\000\153\000\002\002\004\000\002\055\002\000\002\003" +
- "\012\000\002\003\007\000\002\056\002\000\002\004\006" +
- "\000\002\004\003\000\002\005\004\000\002\005\003\000" +
- "\002\057\002\000\002\020\006\000\002\010\003\000\002" +
- "\010\003\000\002\010\003\000\002\010\003\000\002\007" +
- "\002\000\002\007\004\000\002\006\006\000\002\013\006" +
- "\000\002\022\006\000\002\023\006\000\002\014\004\000" +
- "\002\014\003\000\002\024\005\000\002\024\004\000\002" +
- "\024\005\000\002\024\004\000\002\060\002\000\002\024" +
- "\006\000\002\061\002\000\002\024\006\000\002\062\002" +
- "\000\002\044\005\000\002\063\002\000\002\045\005\000" +
- "\002\026\005\000\002\026\003\000\002\027\005\000\002" +
- "\027\003\000\002\040\003\000\002\040\003\000\002\043" +
- "\004\000\002\043\003\000\002\064\002\000\002\041\007" +
- "\000\002\065\002\000\002\041\007\000\002\066\002\000" +
- "\002\041\007\000\002\042\005\000\002\042\003\000\002" +
- "\052\003\000\002\053\003\000\002\067\002\000\002\015" +
- "\007\000\002\015\003\000\002\016\004\000\002\016\003" +
- "\000\002\070\002\000\002\071\002\000\002\030\010\000" +
- "\002\072\002\000\002\030\005\000\002\035\005\000\002" +
- "\035\003\000\002\036\005\000\002\036\003\000\002\031" +
- "\004\000\002\031\003\000\002\032\004\000\002\032\003" +
- "\000\002\051\004\000\002\051\003\000\002\017\005\000" +
- "\002\017\003\000\002\021\005\000\002\021\003\000\002" +
- "\025\003\000\002\025\005\000\002\033\003\000\002\034" +
- "\003\000\002\046\003\000\002\046\003\000\002\047\003" +
- "\000\002\047\003\000\002\050\003\000\002\054\003\000" +
- "\002\054\003\000\002\054\003\000\002\054\003\000\002" +
- "\054\003\000\002\054\003\000\002\054\003\000\002\054" +
- "\003\000\002\054\003\000\002\054\003\000\002\054\003" +
- "\000\002\054\003\000\002\054\003\000\002\054\003\000" +
- "\002\054\003\000\002\054\003\000\002\012\004\000\002" +
- "\012\003\000\002\011\002\000\002\011\003\000\002\037" +
- "\002" });
-
- /** Access to production table. */
- public short[][] production_table() {return _production_table;}
-
- /** Parse-action table. */
- protected static final short[][] _action_table =
- unpackFromStrings(new String[] {
- "\000\247\000\026\003\006\004\000\005\000\007\000\010" +
- "\000\011\000\012\000\013\000\014\000\035\000\001\002" +
- "\000\004\002\251\001\002\000\024\004\200\005\uff97\007" +
- "\uff97\010\uff97\011\uff97\012\uff97\013\uff97\014\uff97\035\uff97" +
- "\001\002\000\010\011\007\012\012\035\014\001\002\000" +
- "\042\003\163\006\026\007\027\010\040\011\036\012\022" +
- "\013\042\014\030\015\017\016\015\026\033\027\023\030" +
- "\035\031\041\035\025\036\160\001\002\000\020\003\uffeb" +
- "\011\uffeb\012\uffeb\016\uffeb\026\uffeb\035\uffeb\036\uffeb\001" +
- "\002\000\020\003\uff97\011\007\012\012\016\uff97\026\065" +
- "\035\014\036\uff97\001\002\000\004\011\061\001\002\000" +
- "\042\003\034\006\026\007\027\010\040\011\036\012\022" +
- "\013\042\014\030\015\017\016\015\026\033\027\023\030" +
- "\035\031\041\035\025\036\016\001\002\000\042\003\uff9a" +
- "\006\uff9a\007\uff9a\010\uff9a\011\uff9a\012\uff9a\013\uff9a\014" +
- "\uff9a\015\uff9a\016\uff9a\026\uff9a\027\uff9a\030\uff9a\031\uff9a" +
- "\035\uff9a\036\uff9a\001\002\000\022\003\uffa1\017\uffa1\022" +
- "\uffa1\025\uffa1\032\uffa1\033\uffa1\036\uffa1\037\uffa1\001\002" +
- "\000\014\017\uffb1\020\uffb1\022\uffab\033\uffab\036\uffab\001" +
- "\002\000\022\003\uffa2\017\uffa2\022\uffa2\025\uffa2\032\uffa2" +
- "\033\uffa2\036\uffa2\037\uffa2\001\002\000\006\017\uffe0\020" +
- "\055\001\002\000\010\022\051\033\uffb4\036\uffb4\001\002" +
- "\000\022\003\uffa6\017\uffa6\022\uffa6\025\uffa6\032\uffa6\033" +
- "\uffa6\036\uffa6\037\uffa6\001\002\000\022\003\uff9f\017\uff9f" +
- "\022\uff9f\025\uff9f\032\uff9f\033\uff9f\036\uff9f\037\uff9f\001" +
- "\002\000\006\033\047\036\045\001\002\000\022\003\uffa5" +
- "\017\uffa5\022\uffa5\025\uffa5\032\uffa5\033\uffa5\036\uffa5\037" +
- "\uffa5\001\002\000\022\003\uffaa\017\uffaa\022\uffaa\025\uffaa" +
- "\032\uffaa\033\uffaa\036\uffaa\037\uffaa\001\002\000\022\003" +
- "\uffa9\017\uffa9\022\uffa9\025\uffa9\032\uffa9\033\uffa9\036\uffa9" +
- "\037\uffa9\001\002\000\022\003\uffa3\017\uffa3\022\uffa3\025" +
- "\uffa3\032\uffa3\033\uffa3\036\uffa3\037\uffa3\001\002\000\012" +
- "\017\uffb7\022\uffb7\033\uffb7\036\uffb7\001\002\000\020\003" +
- "\uffe7\011\uffe7\012\uffe7\016\uffe7\026\uffe7\035\uffe7\036\uffe7" +
- "\001\002\000\022\003\uffa0\017\uffa0\022\uffa0\025\uffa0\032" +
- "\uffa0\033\uffa0\036\uffa0\037\uffa0\001\002\000\012\017\uffe4" +
- "\022\uff9c\033\uff9c\036\uff9c\001\002\000\022\003\uff9e\017" +
- "\uff9e\022\uff9e\025\uff9e\032\uff9e\033\uff9e\036\uff9e\037\uff9e" +
- "\001\002\000\022\003\uffa7\017\uffa7\022\uffa7\025\uffa7\032" +
- "\uffa7\033\uffa7\036\uffa7\037\uffa7\001\002\000\006\017\uffdb" +
- "\020\uffdb\001\002\000\022\003\uffa8\017\uffa8\022\uffa8\025" +
- "\uffa8\032\uffa8\033\uffa8\036\uffa8\037\uffa8\001\002\000\022" +
- "\003\uff9d\017\uff9d\022\uff9d\025\uff9d\032\uff9d\033\uff9d\036" +
- "\uff9d\037\uff9d\001\002\000\022\003\uffa4\017\uffa4\022\uffa4" +
- "\025\uffa4\032\uffa4\033\uffa4\036\uffa4\037\uffa4\001\002\000" +
- "\004\017\044\001\002\000\020\003\uffe3\011\uffe3\012\uffe3" +
- "\016\uffe3\026\uffe3\035\uffe3\036\uffe3\001\002\000\006\017" +
- "\uffb1\020\uffb1\001\002\000\020\003\uffe8\011\uffe8\012\uffe8" +
- "\016\uffe8\026\uffe8\035\uffe8\036\uffe8\001\002\000\004\034" +
- "\050\001\002\000\006\033\uffb3\036\uffb3\001\002\000\042" +
- "\003\054\006\026\007\027\010\040\011\036\012\022\013" +
- "\042\014\030\015\017\016\015\026\033\027\023\030\035" +
- "\031\041\035\025\036\053\001\002\000\012\017\uffb8\022" +
- "\uffb8\033\uffb8\036\uffb8\001\002\000\022\003\uffab\017\uffab" +
- "\022\uffab\025\uffab\032\uffab\033\uffab\036\uffab\037\uffab\001" +
- "\002\000\022\003\uff9c\017\uff9c\022\uff9c\025\uff9c\032\uff9c" +
- "\033\uff9c\036\uff9c\037\uff9c\001\002\000\004\036\045\001" +
- "\002\000\004\017\057\001\002\000\020\003\uffdf\011\uffdf" +
- "\012\uffdf\016\uffdf\026\uffdf\035\uffdf\036\uffdf\001\002\000" +
- "\006\017\uffdc\020\uffdc\001\002\000\042\003\uff9b\006\uff9b" +
- "\007\uff9b\010\uff9b\011\uff9b\012\uff9b\013\uff9b\014\uff9b\015" +
- "\uff9b\016\uff9b\026\uff9b\027\uff9b\030\uff9b\031\uff9b\035\uff9b" +
- "\036\uff9b\001\002\000\010\003\uff97\016\116\036\uff97\001" +
- "\002\000\012\003\uffda\016\uffda\026\065\036\uffda\001\002" +
- "\000\010\003\uffd9\016\uffd9\036\uffd9\001\002\000\010\027" +
- "\071\030\072\031\070\001\002\000\020\003\uffec\011\uffec" +
- "\012\uffec\016\uffec\026\uffec\035\uffec\036\uffec\001\002\000" +
- "\012\003\uffd7\016\uffd7\026\uffd7\036\uffd7\001\002\000\006" +
- "\003\uffd2\036\uffd2\001\002\000\006\003\uffd6\036\uffd6\001" +
- "\002\000\006\003\uffd4\036\uffd4\001\002\000\006\003\077" +
- "\036\074\001\002\000\022\003\uffae\017\uffae\020\uffae\023" +
- "\uffae\025\uffae\032\uffae\036\uffae\037\uffae\001\002\000\010" +
- "\017\uffcd\020\uffcd\025\uffcd\001\002\000\006\017\uffce\020" +
- "\uffce\001\002\000\022\003\uffad\017\uffad\020\uffad\023\uffad" +
- "\025\uffad\032\uffad\036\uffad\037\uffad\001\002\000\006\017" +
- "\102\020\103\001\002\000\006\017\uffcf\020\uffcf\001\002" +
- "\000\012\003\uffd3\016\uffd3\026\uffd3\036\uffd3\001\002\000" +
- "\006\003\077\036\074\001\002\000\006\017\uffd0\020\uffd0" +
- "\001\002\000\006\003\077\036\074\001\002\000\006\017" +
- "\107\020\103\001\002\000\012\003\uffd5\016\uffd5\026\uffd5" +
- "\036\uffd5\001\002\000\006\003\077\036\074\001\002\000" +
- "\006\017\112\020\103\001\002\000\012\003\uffd1\016\uffd1" +
- "\026\uffd1\036\uffd1\001\002\000\012\003\uffd8\016\uffd8\026" +
- "\uffd8\036\uffd8\001\002\000\006\003\uffca\036\uffca\001\002" +
- "\000\006\003\126\036\120\001\002\000\004\015\117\001" +
- "\002\000\006\003\122\036\120\001\002\000\006\017\uffb0" +
- "\024\uffb0\001\002\000\004\017\uffcc\001\002\000\004\017" +
- "\uffaf\001\002\000\004\017\124\001\002\000\006\003\uffcb" +
- "\036\uffcb\001\002\000\004\024\uffc7\001\002\000\006\017" +
- "\uffc4\024\uffaf\001\002\000\010\002\ufffe\003\126\036\120" +
- "\001\002\000\010\002\uffc8\003\uffc8\036\uffc8\001\002\000" +
- "\010\002\uffc9\003\uffc9\036\uffc9\001\002\000\004\017\133" +
- "\001\002\000\010\002\uffc3\003\uffc3\036\uffc3\001\002\000" +
- "\004\024\135\001\002\000\016\003\uffc6\017\uffc6\025\uffc6" +
- "\032\uffc6\036\uffc6\037\uffc6\001\002\000\016\003\uff97\017" +
- "\uff97\025\uff97\032\uff97\036\uff97\037\uff97\001\002\000\016" +
- "\003\uffbd\017\uffbd\025\uffbd\032\uffbd\036\uffbd\037\uffbd\001" +
- "\002\000\016\003\077\017\uffbf\025\uffbf\032\147\036\074" +
- "\037\146\001\002\000\006\017\uffc1\025\uffc1\001\002\000" +
- "\006\017\143\025\144\001\002\000\010\002\uffc5\003\uffc5" +
- "\036\uffc5\001\002\000\016\003\uff97\017\uff97\025\uff97\032" +
- "\uff97\036\uff97\037\uff97\001\002\000\006\017\uffc2\025\uffc2" +
- "\001\002\000\016\003\uffbb\017\uffbb\025\uffbb\032\uffbb\036" +
- "\uffbb\037\uffbb\001\002\000\006\003\077\036\074\001\002" +
- "\000\020\003\uff97\017\uff97\023\154\025\uff97\032\uff97\036" +
- "\uff97\037\uff97\001\002\000\016\003\uffbe\017\uffbe\025\uffbe" +
- "\032\uffbe\036\uffbe\037\uffbe\001\002\000\016\003\uffb9\017" +
- "\uffb9\025\uffb9\032\uffb9\036\uffb9\037\uffb9\001\002\000\016" +
- "\003\uffbc\017\uffbc\025\uffbc\032\uffbc\036\uffbc\037\uffbc\001" +
- "\002\000\042\003\054\006\026\007\027\010\040\011\036" +
- "\012\022\013\042\014\030\015\017\016\015\026\033\027" +
- "\023\030\035\031\041\035\025\036\053\001\002\000\016" +
- "\003\uffba\017\uffba\025\uffba\032\uffba\036\uffba\037\uffba\001" +
- "\002\000\016\003\uffac\017\uffac\025\uffac\032\uffac\036\uffac" +
- "\037\uffac\001\002\000\006\017\uffc0\025\uffc0\001\002\000" +
- "\014\017\uffb2\020\uffb2\022\uffab\033\uffab\036\uffab\001\002" +
- "\000\006\033\047\036\170\001\002\000\006\017\uffdd\020" +
- "\uffdd\001\002\000\012\017\uffe6\022\uff9c\033\uff9c\036\uff9c" +
- "\001\002\000\020\003\uffe9\011\uffe9\012\uffe9\016\uffe9\026" +
- "\uffe9\035\uffe9\036\uffe9\001\002\000\006\017\uffe2\020\167" +
- "\001\002\000\004\017\172\001\002\000\004\036\170\001" +
- "\002\000\006\017\uffb2\020\uffb2\001\002\000\006\017\uffde" +
- "\020\uffde\001\002\000\020\003\uffe1\011\uffe1\012\uffe1\016" +
- "\uffe1\026\uffe1\035\uffe1\036\uffe1\001\002\000\004\017\174" +
- "\001\002\000\020\003\uffe5\011\uffe5\012\uffe5\016\uffe5\026" +
- "\uffe5\035\uffe5\036\uffe5\001\002\000\020\003\uffea\011\uffea" +
- "\012\uffea\016\uffea\026\uffea\035\uffea\036\uffea\001\002\000" +
- "\022\005\ufffb\007\ufffb\010\ufffb\011\ufffb\012\ufffb\013\ufffb" +
- "\014\ufffb\035\ufffb\001\002\000\022\005\uff97\007\uff97\010" +
- "\uff97\011\uff97\012\uff97\013\uff97\014\uff97\035\uff97\001\002" +
- "\000\042\003\054\006\026\007\027\010\040\011\036\012" +
- "\022\013\042\014\030\015\017\016\015\026\033\027\023" +
- "\030\035\031\041\035\025\036\053\001\002\000\006\017" +
- "\ufffd\022\051\001\002\000\004\017\203\001\002\000\022" +
- "\005\ufffc\007\ufffc\010\ufffc\011\ufffc\012\ufffc\013\ufffc\014" +
- "\ufffc\035\ufffc\001\002\000\022\005\210\007\ufff2\010\ufff2" +
- "\011\ufff2\012\ufff2\013\ufff2\014\ufff2\035\ufff2\001\002\000" +
- "\022\005\ufff9\007\ufff9\010\ufff9\011\ufff9\012\ufff9\013\ufff9" +
- "\014\ufff9\035\ufff9\001\002\000\020\007\223\010\224\011" +
- "\007\012\012\013\227\014\225\035\014\001\002\000\022" +
- "\005\ufffa\007\ufffa\010\ufffa\011\ufffa\012\ufffa\013\ufffa\014" +
- "\ufffa\035\ufffa\001\002\000\042\003\054\006\026\007\027" +
- "\010\040\011\036\012\022\013\042\014\030\015\017\016" +
- "\015\026\033\027\023\030\035\031\041\035\025\036\053" +
- "\001\002\000\006\017\uffb5\022\215\001\002\000\004\017" +
- "\ufff8\001\002\000\004\017\214\001\002\000\022\005\ufff7" +
- "\007\ufff7\010\ufff7\011\ufff7\012\ufff7\013\ufff7\014\ufff7\035" +
- "\ufff7\001\002\000\044\003\054\006\026\007\027\010\040" +
- "\011\036\012\022\013\042\014\030\015\017\016\015\021" +
- "\216\026\033\027\023\030\035\031\041\035\025\036\053" +
- "\001\002\000\004\017\uffb6\001\002\000\020\007\ufff3\010" +
- "\ufff3\011\ufff3\012\ufff3\013\ufff3\014\ufff3\035\ufff3\001\002" +
- "\000\020\007\ufff5\010\ufff5\011\ufff5\012\ufff5\013\ufff5\014" +
- "\ufff5\035\ufff5\001\002\000\020\007\ufff1\010\ufff1\011\ufff1" +
- "\012\ufff1\013\ufff1\014\ufff1\035\ufff1\001\002\000\020\007" +
- "\ufff4\010\ufff4\011\ufff4\012\ufff4\013\ufff4\014\ufff4\035\ufff4" +
- "\001\002\000\004\006\246\001\002\000\004\006\243\001" +
- "\002\000\004\015\240\001\002\000\020\007\ufff6\010\ufff6" +
- "\011\ufff6\012\ufff6\013\ufff6\014\ufff6\035\ufff6\001\002\000" +
- "\004\015\234\001\002\000\020\003\uff97\011\007\012\012" +
- "\016\uff97\026\065\035\014\036\uff97\001\002\000\010\003" +
- "\uff97\016\116\036\uff97\001\002\000\006\003\126\036\120" +
- "\001\002\000\010\002\uffff\003\126\036\120\001\002\000" +
- "\004\037\235\001\002\000\022\007\uff99\010\uff99\011\uff99" +
- "\012\uff99\013\uff99\014\uff99\017\236\035\uff99\001\002\000" +
- "\020\007\uff98\010\uff98\011\uff98\012\uff98\013\uff98\014\uff98" +
- "\035\uff98\001\002\000\020\007\uffee\010\uffee\011\uffee\012" +
- "\uffee\013\uffee\014\uffee\035\uffee\001\002\000\004\037\241" +
- "\001\002\000\022\007\uff99\010\uff99\011\uff99\012\uff99\013" +
- "\uff99\014\uff99\017\236\035\uff99\001\002\000\020\007\uffed" +
- "\010\uffed\011\uffed\012\uffed\013\uffed\014\uffed\035\uffed\001" +
- "\002\000\004\037\244\001\002\000\022\007\uff99\010\uff99" +
- "\011\uff99\012\uff99\013\uff99\014\uff99\017\236\035\uff99\001" +
- "\002\000\020\007\uffef\010\uffef\011\uffef\012\uffef\013\uffef" +
- "\014\uffef\035\uffef\001\002\000\004\037\247\001\002\000" +
- "\022\007\uff99\010\uff99\011\uff99\012\uff99\013\uff99\014\uff99" +
- "\017\236\035\uff99\001\002\000\020\007\ufff0\010\ufff0\011" +
- "\ufff0\012\ufff0\013\ufff0\014\ufff0\035\ufff0\001\002\000\004" +
- "\002\001\001\002" });
-
- /** Access to parse-action table. */
- public short[][] action_table() {return _action_table;}
-
- /** <code>reduce_goto</code> table. */
- protected static final short[][] _reduce_table =
- unpackFromStrings(new String[] {
- "\000\247\000\006\003\003\055\004\001\001\000\002\001" +
- "\001\000\006\004\176\037\175\001\001\000\010\012\012" +
- "\014\010\024\007\001\001\000\016\017\020\025\160\026" +
- "\164\033\161\044\163\054\030\001\001\000\002\001\001" +
- "\000\016\012\012\024\065\037\063\040\061\041\066\043" +
- "\062\001\001\000\002\001\001\000\016\017\020\025\023" +
- "\027\017\034\036\045\031\054\030\001\001\000\002\001" +
- "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
- "\000\004\063\055\001\001\000\002\001\001\000\002\001" +
- "\001\000\002\001\001\000\010\027\017\034\036\045\045" +
- "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
- "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
- "\000\002\001\001\000\004\061\042\001\001\000\002\001" +
- "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
- "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
- "\002\001\001\000\002\001\001\000\002\001\001\000\002" +
- "\001\001\000\002\001\001\000\004\054\051\001\001\000" +
- "\002\001\001\000\002\001\001\000\002\001\001\000\004" +
- "\034\057\001\001\000\002\001\001\000\002\001\001\000" +
- "\002\001\001\000\002\001\001\000\006\015\114\037\113" +
- "\001\001\000\004\041\112\001\001\000\002\001\001\000" +
- "\002\001\001\000\002\001\001\000\002\001\001\000\004" +
- "\066\107\001\001\000\004\064\104\001\001\000\004\065" +
- "\072\001\001\000\012\042\077\047\074\052\100\053\075" +
- "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
- "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
- "\000\002\001\001\000\010\047\074\052\103\053\075\001" +
- "\001\000\002\001\001\000\012\042\105\047\074\052\100" +
- "\053\075\001\001\000\002\001\001\000\002\001\001\000" +
- "\012\042\110\047\074\052\100\053\075\001\001\000\002" +
- "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
- "\001\000\010\016\126\030\127\046\124\001\001\000\002" +
- "\001\001\000\004\046\120\001\001\000\002\001\001\000" +
- "\004\067\122\001\001\000\002\001\001\000\002\001\001" +
- "\000\002\001\001\000\004\070\133\001\001\000\004\072" +
- "\131\001\001\000\006\030\130\046\124\001\001\000\002" +
- "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
- "\001\000\002\001\001\000\004\071\135\001\001\000\012" +
- "\031\137\035\141\036\140\037\136\001\001\000\002\001" +
- "\001\000\006\032\150\047\147\001\001\000\002\001\001" +
- "\000\002\001\001\000\002\001\001\000\010\031\137\036" +
- "\144\037\136\001\001\000\002\001\001\000\002\001\001" +
- "\000\006\047\074\053\156\001\001\000\006\037\151\051" +
- "\152\001\001\000\002\001\001\000\002\001\001\000\002" +
- "\001\001\000\006\050\154\054\155\001\001\000\002\001" +
- "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
- "\000\010\026\164\033\161\044\174\001\001\000\002\001" +
- "\001\000\004\060\172\001\001\000\002\001\001\000\004" +
- "\062\165\001\001\000\002\001\001\000\004\033\170\001" +
- "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
- "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
- "\002\001\001\000\006\005\203\037\204\001\001\000\006" +
- "\017\200\054\030\001\001\000\004\056\201\001\001\000" +
- "\002\001\001\000\002\001\001\000\006\007\205\020\206" +
- "\001\001\000\002\001\001\000\022\006\225\010\220\012" +
- "\012\013\217\014\227\022\221\023\216\024\007\001\001" +
- "\000\002\001\001\000\010\017\210\021\211\054\030\001" +
- "\001\000\002\001\001\000\004\057\212\001\001\000\002" +
- "\001\001\000\002\001\001\000\004\054\051\001\001\000" +
- "\002\001\001\000\002\001\001\000\002\001\001\000\002" +
- "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
- "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
- "\000\016\012\012\024\065\037\063\040\230\041\066\043" +
- "\062\001\001\000\006\015\231\037\113\001\001\000\010" +
- "\016\232\030\127\046\124\001\001\000\006\030\130\046" +
- "\124\001\001\000\002\001\001\000\004\011\236\001\001" +
- "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
- "\004\011\241\001\001\000\002\001\001\000\002\001\001" +
- "\000\004\011\244\001\001\000\002\001\001\000\002\001" +
- "\001\000\004\011\247\001\001\000\002\001\001\000\002" +
- "\001\001" });
-
- /** Access to <code>reduce_goto</code> table. */
- public short[][] reduce_table() {return _reduce_table;}
-
- /** Instance of action encapsulation class. */
- protected CUP$parser$actions action_obj;
-
- /** Action encapsulation object initializer. */
- protected void init_actions()
- {
- action_obj = new CUP$parser$actions(this);
- }
-
- /** Invoke a user supplied parse action. */
- public java_cup.runtime.Symbol do_action(
- int act_num,
- java_cup.runtime.lr_parser parser,
- java.util.Stack stack,
- int top)
- throws java.lang.Exception
- {
- /* call code in generated class */
- return action_obj.CUP$parser$do_action(act_num, parser, stack, top);
- }
-
- /** Indicates start state. */
- public int start_state() {return 0;}
- /** Indicates start production. */
- public int start_production() {return 0;}
-
- /** <code>EOF</code> Symbol index. */
- public int EOF_sym() {return 0;}
-
- /** <code>error</code> Symbol index. */
- public int error_sym() {return 1;}
-
-
- /** User initialization code. */
- public void user_init() throws java.lang.Exception
- {
- lexer.init();
- }
-
- /** Scan to get the next Symbol. */
- public java_cup.runtime.Symbol scan()
- throws java.lang.Exception
- {
- return lexer.next_token();
- }
-
-
-
- /* override error routines */
-
- public void report_fatal_error(
- String message,
- Object info)
- {
- done_parsing();
- lexer.emit_error(message);
- System.err.println("Can't recover from previous error(s), giving up.");
- System.exit(1);
- }
-
- public void report_error(String message, Object info)
- {
- lexer.emit_error(message);
- }
-
-}
-
-/** Cup generated class to encapsulate user supplied action code.*/
-class CUP$parser$actions {
-
-
- /** helper routine to clone a new production part adding a given label */
- protected production_part add_lab(production_part part, String lab)
- throws internal_error
- {
- /* if there is no label, or this is an action, just return the original */
- if (lab == null || part.is_action()) return part;
-
- /* otherwise build a new one with the given label attached */
- return new symbol_part(((symbol_part)part).the_symbol(),lab);
- }
-
- /** max size of right hand side we will support */
- protected final int MAX_RHS = 200;
-
- /** array for accumulating right hand side parts */
- protected production_part[] rhs_parts = new production_part[MAX_RHS];
-
- /** where we are currently in building a right hand side */
- protected int rhs_pos = 0;
-
- /** start a new right hand side */
- protected void new_rhs() {rhs_pos = 0; }
-
- /** add a new right hand side part */
- protected void add_rhs_part(production_part part) throws java.lang.Exception
- {
- if (rhs_pos >= MAX_RHS)
- throw new Exception("Internal Error: Productions limited to " +
- MAX_RHS + " symbols and actions");
-
- rhs_parts[rhs_pos] = part;
- rhs_pos++;
- }
-
- /** string to build up multiple part names */
- protected String multipart_name = new String();
-
- /** append a new name segment to the accumulated multipart name */
- protected void append_multipart(String name)
- {
- String dot = "";
-
- /* if we aren't just starting out, put on a dot */
- if (multipart_name.length() != 0) dot = ".";
-
- multipart_name = multipart_name.concat(dot + name);
- }
-
- /** table of declared symbols -- contains production parts indexed by name */
- protected Hashtable symbols = new Hashtable();
-
- /** table of just non terminals -- contains non_terminals indexed by name */
- protected Hashtable non_terms = new Hashtable();
-
- /** declared start non_terminal */
- protected non_terminal start_nt = null;
-
- /** left hand side non terminal of the current production */
- protected non_terminal lhs_nt;
-
- /** Current precedence number */
- int _cur_prec = 0;
-
- /** Current precedence side */
- int _cur_side = assoc.no_prec;
-
- /** update the precedences we are declaring */
- protected void update_precedence(int p) {
- _cur_side = p;
- _cur_prec++;
- }
- /** add relevant data to terminals */
- protected void add_precedence(String term) {
- if (term == null) {
- System.err.println("Unable to add precedence to nonexistent terminal");
- } else {
- symbol_part sp = (symbol_part)symbols.get(term);
- if (sp == null) {
- System.err.println("Could find terminal " + term + " while declaring precedence");
- } else {
- java_cup.symbol sym = sp.the_symbol();
- if (sym instanceof terminal)
- ((terminal)sym).set_precedence(_cur_side, _cur_prec);
- else System.err.println("Precedence declaration: Can't find terminal " + term);
- }
- }
- }
-
- private final parser parser;
-
- /** Constructor */
- CUP$parser$actions(parser parser) {
- this.parser = parser;
- }
-
- /** Method with the actual generated action code. */
- public final java_cup.runtime.Symbol CUP$parser$do_action(
- int CUP$parser$act_num,
- java_cup.runtime.lr_parser CUP$parser$parser,
- java.util.Stack CUP$parser$stack,
- int CUP$parser$top)
- throws java.lang.Exception
- {
- /* Symbol object for return from actions */
- java_cup.runtime.Symbol CUP$parser$result;
-
- /* select the action based on the action number */
- switch (CUP$parser$act_num)
- {
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 106: // empty ::=
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(29/*empty*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 105: // opt_semi ::= SEMI
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(7/*opt_semi*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 104: // opt_semi ::=
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(7/*opt_semi*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 103: // non_terminal ::= NONTERMINAL
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(8/*non_terminal*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 102: // non_terminal ::= NON TERMINAL
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(8/*non_terminal*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 101: // robust_id ::= error
- {
- String RESULT = null;
-
- lexer.emit_error("Illegal use of reserved word");
- RESULT="ILLEGAL";
-
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 100: // robust_id ::= NONASSOC
- {
- String RESULT = null;
- RESULT = "nonassoc";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 99: // robust_id ::= RIGHT
- {
- String RESULT = null;
- RESULT = "right";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 98: // robust_id ::= LEFT
- {
- String RESULT = null;
- RESULT = "left";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 97: // robust_id ::= PRECEDENCE
- {
- String RESULT = null;
- RESULT = "precedence";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 96: // robust_id ::= START
- {
- String RESULT = null;
- RESULT = "start";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 95: // robust_id ::= WITH
- {
- String RESULT = null;
- RESULT = "with";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 94: // robust_id ::= SCAN
- {
- String RESULT = null;
- RESULT = "scan";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 93: // robust_id ::= INIT
- {
- String RESULT = null;
- RESULT = "init";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 92: // robust_id ::= NONTERMINAL
- {
- String RESULT = null;
- RESULT = "nonterminal";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 91: // robust_id ::= NON
- {
- String RESULT = null;
- RESULT = "non";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 90: // robust_id ::= TERMINAL
- {
- String RESULT = null;
- RESULT = "terminal";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 89: // robust_id ::= PARSER
- {
- String RESULT = null;
- RESULT = "parser";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 88: // robust_id ::= ACTION
- {
- String RESULT = null;
- RESULT = "action";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 87: // robust_id ::= CODE
- {
- String RESULT = null;
- RESULT = "code";
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 86: // robust_id ::= ID
- {
- String RESULT = null;
- int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = the_id;
- CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 85: // label_id ::= robust_id
- {
- String RESULT = null;
- int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = the_id;
- CUP$parser$result = new java_cup.runtime.Symbol(38/*label_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 84: // symbol_id ::= error
- {
- String RESULT = null;
-
- lexer.emit_error("Illegal use of reserved word");
- RESULT="ILLEGAL";
-
- CUP$parser$result = new java_cup.runtime.Symbol(37/*symbol_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 83: // symbol_id ::= ID
- {
- String RESULT = null;
- int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = the_id;
- CUP$parser$result = new java_cup.runtime.Symbol(37/*symbol_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 82: // nt_id ::= error
- {
- String RESULT = null;
-
- lexer.emit_error("Illegal use of reserved word");
- RESULT="ILLEGAL";
-
- CUP$parser$result = new java_cup.runtime.Symbol(36/*nt_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 81: // nt_id ::= ID
- {
- String RESULT = null;
- int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = the_id;
- CUP$parser$result = new java_cup.runtime.Symbol(36/*nt_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 80: // new_non_term_id ::= ID
- {
- Object RESULT = null;
- int non_term_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int non_term_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String non_term_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
-
- /* see if this non terminal has been declared before */
- if (symbols.get(non_term_id) != null)
- {
- /* issue a message */
- lexer.emit_error( "java_cup.runtime.Symbol \"" + non_term_id +
- "\" has already been declared");
- }
- else
- {
- if (multipart_name.equals("")) {
- append_multipart("Object");
- }
- /* build the non terminal object */
- non_terminal this_nt =
- new non_terminal(non_term_id, multipart_name);
-
- /* put it in the non_terms table */
- non_terms.put(non_term_id, this_nt);
-
- /* build a production_part and put it in the symbols table */
- symbols.put(non_term_id, new symbol_part(this_nt));
- }
-
- CUP$parser$result = new java_cup.runtime.Symbol(26/*new_non_term_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 79: // new_term_id ::= ID
- {
- Object RESULT = null;
- int term_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int term_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String term_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
-
- /* see if this terminal has been declared before */
- if (symbols.get(term_id) != null)
- {
- /* issue a message */
- lexer.emit_error("java_cup.runtime.Symbol \"" + term_id +
- "\" has already been declared");
- }
- else
- {
- /* if no type declared, declare one */
- if (multipart_name.equals("")) {
- append_multipart("Object");
- }
- /* build a production_part and put it in the table */
- symbols.put(term_id,
- new symbol_part(new terminal(term_id, multipart_name)));
- }
-
- CUP$parser$result = new java_cup.runtime.Symbol(25/*new_term_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 78: // type_id ::= type_id LBRACK RBRACK
- {
- Object RESULT = null;
- multipart_name = multipart_name.concat("[]");
- CUP$parser$result = new java_cup.runtime.Symbol(19/*type_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 77: // type_id ::= multipart_id
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(19/*type_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 76: // import_id ::= multipart_id
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(15/*import_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 75: // import_id ::= multipart_id DOT STAR
- {
- Object RESULT = null;
- append_multipart("*");
- CUP$parser$result = new java_cup.runtime.Symbol(15/*import_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 74: // multipart_id ::= robust_id
- {
- Object RESULT = null;
- int an_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int an_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String an_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- append_multipart(an_id);
- CUP$parser$result = new java_cup.runtime.Symbol(13/*multipart_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 73: // multipart_id ::= multipart_id DOT robust_id
- {
- Object RESULT = null;
- int another_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int another_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String another_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- append_multipart(another_id);
- CUP$parser$result = new java_cup.runtime.Symbol(13/*multipart_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 72: // opt_label ::= empty
- {
- String RESULT = null;
- RESULT = null;
- CUP$parser$result = new java_cup.runtime.Symbol(39/*opt_label*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 71: // opt_label ::= COLON label_id
- {
- String RESULT = null;
- int labidleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int labidright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String labid = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = labid;
- CUP$parser$result = new java_cup.runtime.Symbol(39/*opt_label*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 70: // prod_part ::= CODE_STRING
- {
- Object RESULT = null;
- int code_strleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int code_strright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String code_str = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
-
- /* add a new production part */
- add_rhs_part(new action_part(code_str));
-
- CUP$parser$result = new java_cup.runtime.Symbol(24/*prod_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 69: // prod_part ::= symbol_id opt_label
- {
- Object RESULT = null;
- int symidleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
- int symidright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
- String symid = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
- int labidleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int labidright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String labid = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
-
- /* try to look up the id */
- production_part symb = (production_part)symbols.get(symid);
-
- /* if that fails, symbol is undeclared */
- if (symb == null)
- {
- if (lexer.error_count == 0)
- lexer.emit_error("java_cup.runtime.Symbol \"" + symid +
- "\" has not been declared");
- }
- else
- {
- /* add a labeled production part */
- add_rhs_part(add_lab(symb, labid));
- }
-
- CUP$parser$result = new java_cup.runtime.Symbol(24/*prod_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 68: // prod_part_list ::= empty
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(23/*prod_part_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 67: // prod_part_list ::= prod_part_list prod_part
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(23/*prod_part_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 66: // rhs ::= prod_part_list
- {
- Object RESULT = null;
-
- if (lhs_nt != null)
- {
- /* build the production */
- production p = new production(lhs_nt, rhs_parts, rhs_pos);
-
- /* if we have no start non-terminal declared and this is
- the first production, make its lhs nt the start_nt
- and build a special start production for it. */
- if (start_nt == null)
- {
- start_nt = lhs_nt;
-
- /* build a special start production */
- new_rhs();
- add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
- add_rhs_part(new symbol_part(terminal.EOF));
- add_rhs_part(new action_part("RESULT = start_val;"));
- emit.start_production =
- new production(non_terminal.START_nt, rhs_parts, rhs_pos);
-
- new_rhs();
- }
- }
-
- /* reset the rhs accumulation in any case */
- new_rhs();
-
- CUP$parser$result = new java_cup.runtime.Symbol(28/*rhs*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 65: // rhs ::= prod_part_list PERCENT_PREC term_id
- {
- Object RESULT = null;
- int term_nameleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int term_nameright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String term_name = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
-
- java_cup.symbol sym = null;
- if (lhs_nt != null)
- {
- /* Find the precedence symbol */
- if (term_name == null) {
- System.err.println("No terminal for contextual precedence");
- sym = null;
- } else {
- sym = ((symbol_part)symbols.get(term_name)).the_symbol();
- }
- /* build the production */
- production p;
- if ((sym!=null) && (sym instanceof terminal)) {
- p = new production(lhs_nt, rhs_parts, rhs_pos,
- ((terminal)sym).precedence_num(),
- ((terminal)sym).precedence_side());
- ((symbol_part)symbols.get(term_name)).the_symbol().note_use();
- } else {
- System.err.println("Invalid terminal " + term_name +
- " for contextual precedence assignment");
- p = new production(lhs_nt, rhs_parts, rhs_pos);
- }
-
- /* if we have no start non-terminal declared and this is
- the first production, make its lhs nt the start_nt
- and build a special start production for it. */
- if (start_nt == null)
- {
- start_nt = lhs_nt;
-
- /* build a special start production */
- new_rhs();
- add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
- add_rhs_part(new symbol_part(terminal.EOF));
- add_rhs_part(new action_part("RESULT = start_val;"));
- if ((sym!=null) && (sym instanceof terminal)) {
- emit.start_production =
- new production(non_terminal.START_nt, rhs_parts,
- rhs_pos, ((terminal)sym).precedence_num(),
- ((terminal)sym).precedence_side());
- } else {
- emit.start_production =
- new production(non_terminal.START_nt, rhs_parts, rhs_pos);
- }
- new_rhs();
- }
- }
-
- /* reset the rhs accumulation in any case */
- new_rhs();
-
- CUP$parser$result = new java_cup.runtime.Symbol(28/*rhs*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 64: // rhs_list ::= rhs
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(27/*rhs_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 63: // rhs_list ::= rhs_list BAR rhs
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(27/*rhs_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 62: // production ::= error NT$13 SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$13
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(22/*production*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 61: // NT$13 ::=
- {
- Object RESULT = null;
- lexer.emit_error("Syntax Error");
- CUP$parser$result = new java_cup.runtime.Symbol(56/*NT$13*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 60: // production ::= nt_id NT$11 COLON_COLON_EQUALS NT$12 rhs_list SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$11
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-4)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-4)).value;
- // propagate RESULT from NT$12
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
- int lhs_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-5)).left;
- int lhs_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-5)).right;
- String lhs_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-5)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(22/*production*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-5)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 59: // NT$12 ::=
- {
- Object RESULT = null;
- int lhs_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
- int lhs_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
- String lhs_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(55/*NT$12*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 58: // NT$11 ::=
- {
- Object RESULT = null;
- int lhs_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int lhs_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String lhs_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
-
- /* lookup the lhs nt */
- lhs_nt = (non_terminal)non_terms.get(lhs_id);
-
- /* if it wasn't declared, emit a message */
- if (lhs_nt == null)
- {
- if (lexer.error_count == 0)
- lexer.emit_error("LHS non terminal \"" + lhs_id +
- "\" has not been declared");
- }
-
- /* reset the rhs accumulation */
- new_rhs();
-
- CUP$parser$result = new java_cup.runtime.Symbol(54/*NT$11*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 57: // production_list ::= production
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(12/*production_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 56: // production_list ::= production_list production
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(12/*production_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 55: // start_spec ::= empty
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(11/*start_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 54: // start_spec ::= START WITH nt_id NT$10 SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$10
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
- int start_nameleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
- int start_nameright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
- String start_name = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(11/*start_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 53: // NT$10 ::=
- {
- Object RESULT = null;
- int start_nameleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int start_nameright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String start_name = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
-
- /* verify that the name has been declared as a non terminal */
- non_terminal nt = (non_terminal)non_terms.get(start_name);
- if (nt == null)
- {
- lexer.emit_error( "Start non terminal \"" + start_name +
- "\" has not been declared");
- }
- else
- {
- /* remember the non-terminal for later */
- start_nt = nt;
-
- /* build a special start production */
- new_rhs();
- add_rhs_part(add_lab(new symbol_part(start_nt), "start_val"));
- add_rhs_part(new symbol_part(terminal.EOF));
- add_rhs_part(new action_part("RESULT = start_val;"));
- emit.start_production =
- new production(non_terminal.START_nt, rhs_parts, rhs_pos);
- new_rhs();
- }
-
- CUP$parser$result = new java_cup.runtime.Symbol(53/*NT$10*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 52: // term_id ::= symbol_id
- {
- String RESULT = null;
- int symleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int symright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String sym = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
-
- /* check that the symbol_id is a terminal */
- if (symbols.get(sym) == null)
- {
- /* issue a message */
- lexer.emit_error("Terminal \"" + sym +
- "\" has not been declared");
- }
- RESULT = sym;
-
- CUP$parser$result = new java_cup.runtime.Symbol(41/*term_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 51: // terminal_id ::= term_id
- {
- String RESULT = null;
- int symleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int symright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- String sym = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
-
- add_precedence(sym);
- RESULT = sym;
-
- CUP$parser$result = new java_cup.runtime.Symbol(40/*terminal_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 50: // terminal_list ::= terminal_id
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(32/*terminal_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 49: // terminal_list ::= terminal_list COMMA terminal_id
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(32/*terminal_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 48: // preced ::= PRECEDENCE NONASSOC NT$9 terminal_list SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$9
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(31/*preced*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 47: // NT$9 ::=
- {
- Object RESULT = null;
-
- update_precedence(assoc.nonassoc);
-
- CUP$parser$result = new java_cup.runtime.Symbol(52/*NT$9*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 46: // preced ::= PRECEDENCE RIGHT NT$8 terminal_list SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$8
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(31/*preced*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 45: // NT$8 ::=
- {
- Object RESULT = null;
-
- update_precedence(assoc.right);
-
- CUP$parser$result = new java_cup.runtime.Symbol(51/*NT$8*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 44: // preced ::= PRECEDENCE LEFT NT$7 terminal_list SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$7
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(31/*preced*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 43: // NT$7 ::=
- {
- Object RESULT = null;
-
- update_precedence(assoc.left);
-
- CUP$parser$result = new java_cup.runtime.Symbol(50/*NT$7*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 42: // precedence_l ::= preced
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(33/*precedence_l*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 41: // precedence_l ::= precedence_l preced
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(33/*precedence_l*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 40: // precedence_list ::= empty
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(30/*precedence_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 39: // precedence_list ::= precedence_l
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(30/*precedence_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 38: // non_term_name_list ::= new_non_term_id
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(21/*non_term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 37: // non_term_name_list ::= non_term_name_list COMMA new_non_term_id
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(21/*non_term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 36: // term_name_list ::= new_term_id
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(20/*term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 35: // term_name_list ::= term_name_list COMMA new_term_id
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(20/*term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 34: // declares_non_term ::= non_term_name_list NT$6 SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$6
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(35/*declares_non_term*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 33: // NT$6 ::=
- {
- Object RESULT = null;
-
- /* reset the accumulated multipart name */
- multipart_name = new String();
-
- CUP$parser$result = new java_cup.runtime.Symbol(49/*NT$6*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 32: // declares_term ::= term_name_list NT$5 SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$5
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(34/*declares_term*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 31: // NT$5 ::=
- {
- Object RESULT = null;
-
- /* reset the accumulated multipart name */
- multipart_name = new String();
-
- CUP$parser$result = new java_cup.runtime.Symbol(48/*NT$5*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 30: // symbol ::= non_terminal error NT$4 SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$4
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 29: // NT$4 ::=
- {
- Object RESULT = null;
-
- /* reset the accumulated multipart name */
- multipart_name = new String();
-
- CUP$parser$result = new java_cup.runtime.Symbol(47/*NT$4*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 28: // symbol ::= TERMINAL error NT$3 SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$3
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 27: // NT$3 ::=
- {
- Object RESULT = null;
-
- /* reset the accumulated multipart name */
- multipart_name = new String();
-
- CUP$parser$result = new java_cup.runtime.Symbol(46/*NT$3*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 26: // symbol ::= non_terminal declares_non_term
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 25: // symbol ::= non_terminal type_id declares_non_term
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 24: // symbol ::= TERMINAL declares_term
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 23: // symbol ::= TERMINAL type_id declares_term
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 22: // symbol_list ::= symbol
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(10/*symbol_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 21: // symbol_list ::= symbol_list symbol
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(10/*symbol_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 20: // scan_code ::= SCAN WITH CODE_STRING opt_semi
- {
- Object RESULT = null;
- int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
- int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
- String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- if (emit.scan_code!=null)
- lexer.emit_error("Redundant scan code (skipping)");
- else /* save the user code */
- emit.scan_code = user_code;
-
- CUP$parser$result = new java_cup.runtime.Symbol(17/*scan_code*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 19: // init_code ::= INIT WITH CODE_STRING opt_semi
- {
- Object RESULT = null;
- int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
- int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
- String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- if (emit.init_code!=null)
- lexer.emit_error("Redundant init code (skipping)");
- else /* save the user code */
- emit.init_code = user_code;
-
- CUP$parser$result = new java_cup.runtime.Symbol(16/*init_code*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 18: // parser_code_part ::= PARSER CODE CODE_STRING opt_semi
- {
- Object RESULT = null;
- int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
- int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
- String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- if (emit.parser_code!=null)
- lexer.emit_error("Redundant parser code (skipping)");
- else /* save the user included code string */
- emit.parser_code = user_code;
-
- CUP$parser$result = new java_cup.runtime.Symbol(9/*parser_code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 17: // action_code_part ::= ACTION CODE CODE_STRING opt_semi
- {
- Object RESULT = null;
- int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
- int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
- String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- if (emit.action_code!=null)
- lexer.emit_error("Redundant action code (skipping)");
- else /* save the user included code string */
- emit.action_code = user_code;
-
- CUP$parser$result = new java_cup.runtime.Symbol(4/*action_code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 16: // code_parts ::= code_parts code_part
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(5/*code_parts*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 15: // code_parts ::=
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(5/*code_parts*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 14: // code_part ::= scan_code
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 13: // code_part ::= init_code
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 12: // code_part ::= parser_code_part
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 11: // code_part ::= action_code_part
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 10: // import_spec ::= IMPORT import_id NT$2 SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$2
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(14/*import_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 9: // NT$2 ::=
- {
- Object RESULT = null;
-
- /* save this import on the imports list */
- emit.import_list.push(multipart_name);
-
- /* reset the accumulated multipart name */
- multipart_name = new String();
-
- CUP$parser$result = new java_cup.runtime.Symbol(45/*NT$2*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 8: // import_list ::= empty
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(3/*import_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 7: // import_list ::= import_list import_spec
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(3/*import_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 6: // package_spec ::= empty
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(2/*package_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 5: // package_spec ::= PACKAGE multipart_id NT$1 SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$1
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(2/*package_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 4: // NT$1 ::=
- {
- Object RESULT = null;
-
- /* save the package name */
- emit.package_name = multipart_name;
-
- /* reset the accumulated multipart name */
- multipart_name = new String();
-
- CUP$parser$result = new java_cup.runtime.Symbol(44/*NT$1*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 3: // spec ::= error symbol_list precedence_list start_spec production_list
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(1/*spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 2: // spec ::= NT$0 package_spec import_list code_parts symbol_list precedence_list start_spec production_list
- {
- Object RESULT = null;
- // propagate RESULT from NT$0
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-7)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-7)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(1/*spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-7)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 1: // NT$0 ::=
- {
- Object RESULT = null;
-
- /* declare "error" as a terminal */
- symbols.put("error", new symbol_part(terminal.error));
-
- /* declare start non terminal */
- non_terms.put("$START", non_terminal.START_nt);
-
- CUP$parser$result = new java_cup.runtime.Symbol(43/*NT$0*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 0: // $START ::= spec EOF
- {
- Object RESULT = null;
- int start_valleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
- int start_valright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
- Object start_val = (Object)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
- RESULT = start_val;
- CUP$parser$result = new java_cup.runtime.Symbol(0/*$START*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- /* ACCEPT */
- CUP$parser$parser.done_parsing();
- return CUP$parser$result;
-
- /* . . . . . .*/
- default:
- throw new Exception(
- "Invalid action number found in internal parse table");
-
- }
- }
-}
-
+++ /dev/null
-
-package java_cup;
-
-import java.util.Hashtable;
-import java.util.Enumeration;
-
-/** This class represents a production in the grammar. It contains
- * a LHS non terminal, and an array of RHS symbols. As various
- * transformations are done on the RHS of the production, it may shrink.
- * As a result a separate length is always maintained to indicate how much
- * of the RHS array is still valid.<p>
- *
- * I addition to construction and manipulation operations, productions provide
- * methods for factoring out actions (see remove_embedded_actions()), for
- * computing the nullability of the production (i.e., can it derive the empty
- * string, see check_nullable()), and operations for computing its first
- * set (i.e., the set of terminals that could appear at the beginning of some
- * string derived from the production, see check_first_set()).
- *
- * @see java_cup.production_part
- * @see java_cup.symbol_part
- * @see java_cup.action_part
- * @version last updated: 7/3/96
- * @author Frank Flannery
- */
-
-public class production {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Full constructor. This constructor accepts a LHS non terminal,
- * an array of RHS parts (including terminals, non terminals, and
- * actions), and a string for a final reduce action. It does several
- * manipulations in the process of creating a production object.
- * After some validity checking it translates labels that appear in
- * actions into code for accessing objects on the runtime parse stack.
- * It them merges adjacent actions if they appear and moves any trailing
- * action into the final reduce actions string. Next it removes any
- * embedded actions by factoring them out with new action productions.
- * Finally it assigns a unique index to the production.<p>
- *
- * Factoring out of actions is accomplished by creating new "hidden"
- * non terminals. For example if the production was originally: <pre>
- * A ::= B {action} C D
- * </pre>
- * then it is factored into two productions:<pre>
- * A ::= B X C D
- * X ::= {action}
- * </pre>
- * (where X is a unique new non terminal). This has the effect of placing
- * all actions at the end where they can be handled as part of a reduce by
- * the parser.
- */
- public production(
- non_terminal lhs_sym,
- production_part rhs_parts[],
- int rhs_l,
- String action_str)
- throws internal_error
- {
- int i;
- action_part tail_action;
- String declare_str;
- int rightlen = rhs_l;
-
- /* remember the length */
- if (rhs_l >= 0)
- _rhs_length = rhs_l;
- else if (rhs_parts != null)
- _rhs_length = rhs_parts.length;
- else
- _rhs_length = 0;
-
- /* make sure we have a valid left-hand-side */
- if (lhs_sym == null)
- throw new internal_error(
- "Attempt to construct a production with a null LHS");
-
- /* I'm not translating labels anymore, I'm adding code to declare
- labels as valid variables. This way, the users code string is
- untouched
- 6/96 frankf */
-
- /* check if the last part of the right hand side is an action. If
- it is, it won't be on the stack, so we don't want to count it
- in the rightlen. Then when we search down the stack for a
- Symbol, we don't try to search past action */
-
- if (rhs_l > 0) {
- if (rhs_parts[rhs_l - 1].is_action()) {
- rightlen = rhs_l - 1;
- } else {
- rightlen = rhs_l;
- }
- }
-
- /* get the generated declaration code for the necessary labels. */
- declare_str = declare_labels(
- rhs_parts, rightlen, action_str);
-
- if (action_str == null)
- action_str = declare_str;
- else
- action_str = declare_str + action_str;
-
- /* count use of lhs */
- lhs_sym.note_use();
-
- /* create the part for left-hand-side */
- _lhs = new symbol_part(lhs_sym);
-
- /* merge adjacent actions (if any) */
- _rhs_length = merge_adjacent_actions(rhs_parts, _rhs_length);
-
- /* strip off any trailing action */
- tail_action = strip_trailing_action(rhs_parts, _rhs_length);
- if (tail_action != null) _rhs_length--;
-
- /* Why does this run through the right hand side happen
- over and over? here a quick combination of two
- prior runs plus one I wanted of my own
- frankf 6/25/96 */
- /* allocate and copy over the right-hand-side */
- /* count use of each rhs symbol */
- _rhs = new production_part[_rhs_length];
- for (i=0; i<_rhs_length; i++) {
- _rhs[i] = rhs_parts[i];
- if (!_rhs[i].is_action()) {
- ((symbol_part)_rhs[i]).the_symbol().note_use();
- if (((symbol_part)_rhs[i]).the_symbol() instanceof terminal) {
- _rhs_prec =
- ((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_num();
- _rhs_assoc =
- ((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_side();
- }
- }
- }
-
- /*now action string is really declaration string, so put it in front!
- 6/14/96 frankf */
- if (action_str == null) action_str = "";
- if (tail_action != null && tail_action.code_string() != null)
- action_str = action_str + "\t\t" + tail_action.code_string();
-
- /* stash the action */
- _action = new action_part(action_str);
-
- /* rewrite production to remove any embedded actions */
- remove_embedded_actions();
-
- /* assign an index */
- _index = next_index++;
-
- /* put us in the global collection of productions */
- _all.put(new Integer(_index),this);
-
- /* put us in the production list of the lhs non terminal */
- lhs_sym.add_production(this);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor with no action string. */
- public production(
- non_terminal lhs_sym,
- production_part rhs_parts[],
- int rhs_l)
- throws internal_error
- {
- this(lhs_sym,rhs_parts,rhs_l,null);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /* Constructor with precedence and associativity of production
- contextually define */
- public production(
- non_terminal lhs_sym,
- production_part rhs_parts[],
- int rhs_l,
- String action_str,
- int prec_num,
- int prec_side)
- throws internal_error
- {
- this(lhs_sym,rhs_parts,rhs_l,action_str);
-
- /* set the precedence */
- set_precedence_num(prec_num);
- set_precedence_side(prec_side);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /* Constructor w/ no action string and contextual precedence
- defined */
- public production(
- non_terminal lhs_sym,
- production_part rhs_parts[],
- int rhs_l,
- int prec_num,
- int prec_side)
- throws internal_error
- {
- this(lhs_sym,rhs_parts,rhs_l,null);
- /* set the precedence */
- set_precedence_num(prec_num);
- set_precedence_side(prec_side);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Static (Class) Variables ------------------*/
- /*-----------------------------------------------------------*/
-
-
- /** Table of all productions. Elements are stored using their index as
- * the key.
- */
- protected static Hashtable _all = new Hashtable();
-
- /** Access to all productions. */
- public static Enumeration all() {return _all.elements();}
-
- /** Lookup a production by index. */
- public static production find(int indx) {
- return (production) _all.get(new Integer(indx));
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Total number of productions. */
- public static int number() {return _all.size();}
-
- /** Static counter for assigning unique index numbers. */
- protected static int next_index;
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The left hand side non-terminal. */
- protected symbol_part _lhs;
-
- /** The left hand side non-terminal. */
- public symbol_part lhs() {return _lhs;}
-
-
- /** The precedence of the rule */
- protected int _rhs_prec = -1;
- protected int _rhs_assoc = -1;
-
- /** Access to the precedence of the rule */
- public int precedence_num() { return _rhs_prec; }
- public int precedence_side() { return _rhs_assoc; }
-
- /** Setting the precedence of a rule */
- public void set_precedence_num(int prec_num) {
- _rhs_prec = prec_num;
- }
- public void set_precedence_side(int prec_side) {
- _rhs_assoc = prec_side;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** A collection of parts for the right hand side. */
- protected production_part _rhs[];
-
- /** Access to the collection of parts for the right hand side. */
- public production_part rhs(int indx) throws internal_error
- {
- if (indx >= 0 && indx < _rhs_length)
- return _rhs[indx];
- else
- throw new internal_error(
- "Index out of range for right hand side of production");
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** How much of the right hand side array we are presently using. */
- protected int _rhs_length;
-
- /** How much of the right hand side array we are presently using. */
- public int rhs_length() {return _rhs_length;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** An action_part containing code for the action to be performed when we
- * reduce with this production.
- */
- protected action_part _action;
-
- /** An action_part containing code for the action to be performed when we
- * reduce with this production.
- */
- public action_part action() {return _action;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Index number of the production. */
- protected int _index;
-
- /** Index number of the production. */
- public int index() {return _index;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Count of number of reductions using this production. */
- protected int _num_reductions = 0;
-
- /** Count of number of reductions using this production. */
- public int num_reductions() {return _num_reductions;}
-
- /** Increment the count of reductions with this non-terminal */
- public void note_reduction_use() {_num_reductions++;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Is the nullability of the production known or unknown? */
- protected boolean _nullable_known = false;
-
- /** Is the nullability of the production known or unknown? */
- public boolean nullable_known() {return _nullable_known;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Nullability of the production (can it derive the empty string). */
- protected boolean _nullable = false;
-
- /** Nullability of the production (can it derive the empty string). */
- public boolean nullable() {return _nullable;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** First set of the production. This is the set of terminals that
- * could appear at the front of some string derived from this production.
- */
- protected terminal_set _first_set = new terminal_set();
-
- /** First set of the production. This is the set of terminals that
- * could appear at the front of some string derived from this production.
- */
- public terminal_set first_set() {return _first_set;}
-
- /*-----------------------------------------------------------*/
- /*--- Static Methods ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Determine if a given character can be a label id starter.
- * @param c the character in question.
- */
- protected static boolean is_id_start(char c)
- {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_');
-
- //later need to handle non-8-bit chars here
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if a character can be in a label id.
- * @param c the character in question.
- */
- protected static boolean is_id_char(char c)
- {
- return is_id_start(c) || (c >= '0' && c <= '9');
- }
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
-
- /** Return label declaration code
- * @param labelname the label name
- * @param stack_type the stack type of label?
- * @author frankf
- */
- protected String make_declaration(
- String labelname,
- String stack_type,
- int offset)
- {
- String ret;
-
- /* Put in the left/right value labels */
- if (emit.lr_values())
- ret = "\t\tint " + labelname + "left = ((java_cup.runtime.Symbol)" +
- emit.pre("stack") + ".elementAt(" + emit.pre("top") +
- "-" + offset + ")).left;\n" +
- "\t\tint " + labelname + "right = ((java_cup.runtime.Symbol)" +
- emit.pre("stack") + ".elementAt(" + emit.pre("top") +
- "-" + offset + ")).right;\n";
- else ret = "";
-
- /* otherwise, just declare label. */
- return ret + "\t\t" + stack_type + " " + labelname + " = (" + stack_type +
- ")((" + "java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt(" + emit.pre("top")
- + "-" + offset + ")).value;\n";
-
- }
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Declare label names as valid variables within the action string
- * @param rhs array of RHS parts.
- * @param rhs_len how much of rhs to consider valid.
- * @param final_action the final action string of the production.
- * @param lhs_type the object type associated with the LHS symbol.
- */
- protected String declare_labels(
- production_part rhs[],
- int rhs_len,
- String final_action)
- {
- String declaration = "";
-
- symbol_part part;
- action_part act_part;
- int pos;
-
- /* walk down the parts and extract the labels */
- for (pos = 0; pos < rhs_len; pos++)
- {
- if (!rhs[pos].is_action())
- {
- part = (symbol_part)rhs[pos];
-
- /* if it has a label, make declaration! */
- if (part.label() != null)
- {
- declaration = declaration +
- make_declaration(part.label(), part.the_symbol().stack_type(),
- rhs_len-pos-1);
- }
- }
- }
- return declaration;
- }
-
-
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Helper routine to merge adjacent actions in a set of RHS parts
- * @param rhs_parts array of RHS parts.
- * @param len amount of that array that is valid.
- * @return remaining valid length.
- */
- protected int merge_adjacent_actions(production_part rhs_parts[], int len)
- {
- int from_loc, to_loc, merge_cnt;
-
- /* bail out early if we have no work to do */
- if (rhs_parts == null || len == 0) return 0;
-
- merge_cnt = 0;
- to_loc = -1;
- for (from_loc=0; from_loc<len; from_loc++)
- {
- /* do we go in the current position or one further */
- if (to_loc < 0 || !rhs_parts[to_loc].is_action()
- || !rhs_parts[from_loc].is_action())
- {
- /* next one */
- to_loc++;
-
- /* clear the way for it */
- if (to_loc != from_loc) rhs_parts[to_loc] = null;
- }
-
- /* if this is not trivial? */
- if (to_loc != from_loc)
- {
- /* do we merge or copy? */
- if (rhs_parts[to_loc] != null && rhs_parts[to_loc].is_action() &&
- rhs_parts[from_loc].is_action())
- {
- /* merge */
- rhs_parts[to_loc] = new action_part(
- ((action_part)rhs_parts[to_loc]).code_string() +
- ((action_part)rhs_parts[from_loc]).code_string());
- merge_cnt++;
- }
- else
- {
- /* copy */
- rhs_parts[to_loc] = rhs_parts[from_loc];
- }
- }
- }
-
- /* return the used length */
- return len - merge_cnt;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Helper routine to strip a trailing action off rhs and return it
- * @param rhs_parts array of RHS parts.
- * @param len how many of those are valid.
- * @return the removed action part.
- */
- protected action_part strip_trailing_action(
- production_part rhs_parts[],
- int len)
- {
- action_part result;
-
- /* bail out early if we have nothing to do */
- if (rhs_parts == null || len == 0) return null;
-
- /* see if we have a trailing action */
- if (rhs_parts[len-1].is_action())
- {
- /* snip it out and return it */
- result = (action_part)rhs_parts[len-1];
- rhs_parts[len-1] = null;
- return result;
- }
- else
- return null;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Remove all embedded actions from a production by factoring them
- * out into individual action production using new non terminals.
- * if the original production was: <pre>
- * A ::= B {action1} C {action2} D
- * </pre>
- * then it will be factored into: <pre>
- * A ::= B NT$1 C NT$2 D
- * NT$1 ::= {action1}
- * NT$2 ::= {action2}
- * </pre>
- * where NT$1 and NT$2 are new system created non terminals.
- */
-
- /* the declarations added to the parent production are also passed along,
- as they should be perfectly valid in this code string, since it
- was originally a code string in the parent, not on its own.
- frank 6/20/96 */
- protected void remove_embedded_actions(
-
- ) throws internal_error
- {
- non_terminal new_nt;
- production new_prod;
- String declare_str;
-
- /* walk over the production and process each action */
- for (int act_loc = 0; act_loc < rhs_length(); act_loc++)
- if (rhs(act_loc).is_action())
- {
-
-
- declare_str = declare_labels(
- _rhs, act_loc, "");
- /* create a new non terminal for the action production */
- new_nt = non_terminal.create_new();
- new_nt.is_embedded_action = true; /* 24-Mar-1998, CSA */
-
- /* create a new production with just the action */
- new_prod = new action_production(this, new_nt, null, 0,
- declare_str + ((action_part)rhs(act_loc)).code_string());
-
- /* replace the action with the generated non terminal */
- _rhs[act_loc] = new symbol_part(new_nt);
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Check to see if the production (now) appears to be nullable.
- * A production is nullable if its RHS could derive the empty string.
- * This results when the RHS is empty or contains only non terminals
- * which themselves are nullable.
- */
- public boolean check_nullable() throws internal_error
- {
- production_part part;
- symbol sym;
- int pos;
-
- /* if we already know bail out early */
- if (nullable_known()) return nullable();
-
- /* if we have a zero size RHS we are directly nullable */
- if (rhs_length() == 0)
- {
- /* stash and return the result */
- return set_nullable(true);
- }
-
- /* otherwise we need to test all of our parts */
- for (pos=0; pos<rhs_length(); pos++)
- {
- part = rhs(pos);
-
- /* only look at non-actions */
- if (!part.is_action())
- {
- sym = ((symbol_part)part).the_symbol();
-
- /* if its a terminal we are definitely not nullable */
- if (!sym.is_non_term())
- return set_nullable(false);
- /* its a non-term, is it marked nullable */
- else if (!((non_terminal)sym).nullable())
- /* this one not (yet) nullable, so we aren't */
- return false;
- }
- }
-
- /* if we make it here all parts are nullable */
- return set_nullable(true);
- }
-
- /** set (and return) nullability */
- boolean set_nullable(boolean v)
- {
- _nullable_known = true;
- _nullable = v;
- return v;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Update (and return) the first set based on current NT firsts.
- * This assumes that nullability has already been computed for all non
- * terminals and productions.
- */
- public terminal_set check_first_set() throws internal_error
- {
- int part;
- symbol sym;
-
- /* walk down the right hand side till we get past all nullables */
- for (part=0; part<rhs_length(); part++)
- {
- /* only look at non-actions */
- if (!rhs(part).is_action())
- {
- sym = ((symbol_part)rhs(part)).the_symbol();
-
- /* is it a non-terminal?*/
- if (sym.is_non_term())
- {
- /* add in current firsts from that NT */
- _first_set.add(((non_terminal)sym).first_set());
-
- /* if its not nullable, we are done */
- if (!((non_terminal)sym).nullable())
- break;
- }
- else
- {
- /* its a terminal -- add that to the set */
- _first_set.add((terminal)sym);
-
- /* we are done */
- break;
- }
- }
- }
-
- /* return our updated first set */
- return first_set();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison. */
- public boolean equals(production other)
- {
- if (other == null) return false;
- return other._index == _index;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof production))
- return false;
- else
- return equals((production)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a hash code. */
- public int hashCode()
- {
- /* just use a simple function of the index */
- return _index*13;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string. */
- public String toString()
- {
- String result;
-
- /* catch any internal errors */
- try {
- result = "production [" + index() + "]: ";
- result += ((lhs() != null) ? lhs().toString() : "$$NULL-LHS$$");
- result += " :: = ";
- for (int i = 0; i<rhs_length(); i++)
- result += rhs(i) + " ";
- result += ";";
- if (action() != null && action().code_string() != null)
- result += " {" + action().code_string() + "}";
-
- if (nullable_known())
- if (nullable())
- result += "[NULLABLE]";
- else
- result += "[NOT NULLABLE]";
- } catch (internal_error e) {
- /* crash on internal error since we can't throw it from here (because
- superclass does not throw anything. */
- e.crash();
- result = null;
- }
-
- return result;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a simpler string. */
- public String to_simple_string() throws internal_error
- {
- String result;
-
- result = ((lhs() != null) ? lhs().the_symbol().name() : "NULL_LHS");
- result += " ::= ";
- for (int i = 0; i < rhs_length(); i++)
- if (!rhs(i).is_action())
- result += ((symbol_part)rhs(i)).the_symbol().name() + " ";
-
- return result;
- }
-
- /*-----------------------------------------------------------*/
-
-}
+++ /dev/null
-package java_cup;
-
-/** This class represents one part (either a symbol or an action) of a
- * production. In this base class it contains only an optional label
- * string that the user can use to refer to the part within actions.<p>
- *
- * This is an abstract class.
- *
- * @see java_cup.production
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-public abstract class production_part {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor. */
- public production_part(String lab)
- {
- _label = lab;
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Optional label for referring to the part within an action (null for
- * no label).
- */
- protected String _label;
-
- /** Optional label for referring to the part within an action (null for
- * no label).
- */
- public String label() {return _label;}
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Indicate if this is an action (rather than a symbol). Here in the
- * base class, we don't this know yet, so its an abstract method.
- */
- public abstract boolean is_action();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison. */
- public boolean equals(production_part other)
- {
- if (other == null) return false;
-
- /* compare the labels */
- if (label() != null)
- return label().equals(other.label());
- else
- return other.label() == null;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof production_part))
- return false;
- else
- return equals((production_part)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a hash code. */
- public int hashCode()
- {
- return label()==null ? 0 : label().hashCode();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string. */
- public String toString()
- {
- if (label() != null)
- return label() + ":";
- else
- return " ";
- }
-
- /*-----------------------------------------------------------*/
-
-}
+++ /dev/null
-
-package java_cup;
-
-/** This class represents a reduce action within the parse table.
- * The action simply stores the production that it reduces with and
- * responds to queries about its type.
- *
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-public class reduce_action extends parse_action {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor.
- * @param prod the production this action reduces with.
- */
- public reduce_action(production prod ) throws internal_error
- {
- /* sanity check */
- if (prod == null)
- throw new internal_error(
- "Attempt to create a reduce_action with a null production");
-
- _reduce_with = prod;
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The production we reduce with. */
- protected production _reduce_with;
-
- /** The production we reduce with. */
- public production reduce_with() {return _reduce_with;}
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Quick access to type of action. */
- public int kind() {return REDUCE;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality test. */
- public boolean equals(reduce_action other)
- {
- return other != null && other.reduce_with() == reduce_with();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality test. */
- public boolean equals(Object other)
- {
- if (other instanceof reduce_action)
- return equals((reduce_action)other);
- else
- return false;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Compute a hash code. */
- public int hashCode()
- {
- /* use the hash code of the production we are reducing with */
- return reduce_with().hashCode();
- }
-
-
- /** Convert to string. */
- public String toString()
- {
- return "REDUCE(with prod " + reduce_with().index() + ")";
- }
-
- /*-----------------------------------------------------------*/
-
-}
+++ /dev/null
-package java_cup.runtime;
-
-/**
- * Defines the Scanner interface, which CUP uses in the default
- * implementation of <code>lr_parser.scan()</code>. Integration
- * of scanners implementing <code>Scanner</code> is facilitated.
- *
- * @version last updated 23-Jul-1999
- * @author David MacMahon <davidm@smartsc.com>
- */
-
-/* *************************************************
- Interface Scanner
-
- Declares the next_token() method that should be
- implemented by scanners. This method is typically
- called by lr_parser.scan(). End-of-file can be
- indicated either by returning
- <code>new Symbol(lr_parser.EOF_sym())</code> or
- <code>null</code>.
- ***************************************************/
-public interface Scanner {
- /** Return the next token, or <code>null</code> on end-of-file. */
- public Symbol next_token() throws java.lang.Exception;
-}
+++ /dev/null
-package java_cup.runtime;
-
-/**
- * Defines the Symbol class, which is used to represent all terminals
- * and nonterminals while parsing. The lexer should pass CUP Symbols
- * and CUP returns a Symbol.
- *
- * @version last updated: 7/3/96
- * @author Frank Flannery
- */
-
-/* ****************************************************************
- Class Symbol
- what the parser expects to receive from the lexer.
- the token is identified as follows:
- sym: the symbol type
- parse_state: the parse state.
- value: is the lexical value of type Object
- left : is the left position in the original input file
- right: is the right position in the original input file
-******************************************************************/
-
-public class Symbol {
-
-/*******************************
- Constructor for l,r values
- *******************************/
-
- public Symbol(int id, int l, int r, Object o) {
- this(id);
- left = l;
- right = r;
- value = o;
- }
-
-/*******************************
- Constructor for no l,r values
-********************************/
-
- public Symbol(int id, Object o) {
- this(id, -1, -1, o);
- }
-
-/*****************************
- Constructor for no value
- ***************************/
-
- public Symbol(int id, int l, int r) {
- this(id, l, r, null);
- }
-
-/***********************************
- Constructor for no value or l,r
-***********************************/
-
- public Symbol(int sym_num) {
- this(sym_num, -1);
- left = -1;
- right = -1;
- value = null;
- }
-
-/***********************************
- Constructor to give a start state
-***********************************/
- Symbol(int sym_num, int state)
- {
- sym = sym_num;
- parse_state = state;
- }
-
-/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The symbol number of the terminal or non terminal being represented */
- public int sym;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The parse state to be recorded on the parse stack with this symbol.
- * This field is for the convenience of the parser and shouldn't be
- * modified except by the parser.
- */
- public int parse_state;
- /** This allows us to catch some errors caused by scanners recycling
- * symbols. For the use of the parser only. [CSA, 23-Jul-1999] */
- boolean used_by_parser = false;
-
-/*******************************
- The data passed to parser
- *******************************/
-
- public int left, right;
- public Object value;
-
- /*****************************
- Printing this token out. (Override for pretty-print).
- ****************************/
- public String toString() { return "#"+sym; }
-}
-
-
-
-
-
-
+++ /dev/null
-
-package java_cup.runtime;
-
-import java.util.Stack;
-
-/** This class implements a skeleton table driven LR parser. In general,
- * LR parsers are a form of bottom up shift-reduce parsers. Shift-reduce
- * parsers act by shifting input onto a parse stack until the Symbols
- * matching the right hand side of a production appear on the top of the
- * stack. Once this occurs, a reduce is performed. This involves removing
- * the Symbols corresponding to the right hand side of the production
- * (the so called "handle") and replacing them with the non-terminal from
- * the left hand side of the production. <p>
- *
- * To control the decision of whether to shift or reduce at any given point,
- * the parser uses a state machine (the "viable prefix recognition machine"
- * built by the parser generator). The current state of the machine is placed
- * on top of the parse stack (stored as part of a Symbol object representing
- * a terminal or non terminal). The parse action table is consulted
- * (using the current state and the current lookahead Symbol as indexes) to
- * determine whether to shift or to reduce. When the parser shifts, it
- * changes to a new state by pushing a new Symbol (containing a new state)
- * onto the stack. When the parser reduces, it pops the handle (right hand
- * side of a production) off the stack. This leaves the parser in the state
- * it was in before any of those Symbols were matched. Next the reduce-goto
- * table is consulted (using the new state and current lookahead Symbol as
- * indexes) to determine a new state to go to. The parser then shifts to
- * this goto state by pushing the left hand side Symbol of the production
- * (also containing the new state) onto the stack.<p>
- *
- * This class actually provides four LR parsers. The methods parse() and
- * debug_parse() provide two versions of the main parser (the only difference
- * being that debug_parse() emits debugging trace messages as it parses).
- * In addition to these main parsers, the error recovery mechanism uses two
- * more. One of these is used to simulate "parsing ahead" in the input
- * without carrying out actions (to verify that a potential error recovery
- * has worked), and the other is used to parse through buffered "parse ahead"
- * input in order to execute all actions and re-synchronize the actual parser
- * configuration.<p>
- *
- * This is an abstract class which is normally filled out by a subclass
- * generated by the JavaCup parser generator. In addition to supplying
- * the actual parse tables, generated code also supplies methods which
- * invoke various pieces of user supplied code, provide access to certain
- * special Symbols (e.g., EOF and error), etc. Specifically, the following
- * abstract methods are normally supplied by generated code:
- * <dl compact>
- * <dt> short[][] production_table()
- * <dd> Provides a reference to the production table (indicating the index of
- * the left hand side non terminal and the length of the right hand side
- * for each production in the grammar).
- * <dt> short[][] action_table()
- * <dd> Provides a reference to the parse action table.
- * <dt> short[][] reduce_table()
- * <dd> Provides a reference to the reduce-goto table.
- * <dt> int start_state()
- * <dd> Indicates the index of the start state.
- * <dt> int start_production()
- * <dd> Indicates the index of the starting production.
- * <dt> int EOF_sym()
- * <dd> Indicates the index of the EOF Symbol.
- * <dt> int error_sym()
- * <dd> Indicates the index of the error Symbol.
- * <dt> Symbol do_action()
- * <dd> Executes a piece of user supplied action code. This always comes at
- * the point of a reduce in the parse, so this code also allocates and
- * fills in the left hand side non terminal Symbol object that is to be
- * pushed onto the stack for the reduce.
- * <dt> void init_actions()
- * <dd> Code to initialize a special object that encapsulates user supplied
- * actions (this object is used by do_action() to actually carry out the
- * actions).
- * </dl>
- *
- * In addition to these routines that <i>must</i> be supplied by the
- * generated subclass there are also a series of routines that <i>may</i>
- * be supplied. These include:
- * <dl>
- * <dt> Symbol scan()
- * <dd> Used to get the next input Symbol from the scanner.
- * <dt> Scanner getScanner()
- * <dd> Used to provide a scanner for the default implementation of
- * scan().
- * <dt> int error_sync_size()
- * <dd> This determines how many Symbols past the point of an error
- * must be parsed without error in order to consider a recovery to
- * be valid. This defaults to 3. Values less than 2 are not
- * recommended.
- * <dt> void report_error(String message, Object info)
- * <dd> This method is called to report an error. The default implementation
- * simply prints a message to System.err and where the error occurred.
- * This method is often replaced in order to provide a more sophisticated
- * error reporting mechanism.
- * <dt> void report_fatal_error(String message, Object info)
- * <dd> This method is called when a fatal error that cannot be recovered from
- * is encountered. In the default implementation, it calls
- * report_error() to emit a message, then throws an exception.
- * <dt> void syntax_error(Symbol cur_token)
- * <dd> This method is called as soon as syntax error is detected (but
- * before recovery is attempted). In the default implementation it
- * invokes: report_error("Syntax error", null);
- * <dt> void unrecovered_syntax_error(Symbol cur_token)
- * <dd> This method is called if syntax error recovery fails. In the default
- * implementation it invokes:<br>
- * report_fatal_error("Couldn't repair and continue parse", null);
- * </dl>
- *
- * @see java_cup.runtime.Symbol
- * @see java_cup.runtime.Symbol
- * @see java_cup.runtime.virtual_parse_stack
- * @version last updated: 7/3/96
- * @author Frank Flannery
- */
-
-public abstract class lr_parser {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor. */
- public lr_parser()
- {
- /* nothing to do here */
- }
-
- /** Constructor that sets the default scanner. [CSA/davidm] */
- public lr_parser(Scanner s) {
- this(); /* in case default constructor someday does something */
- setScanner(s);
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Static (Class) Variables ------------------*/
- /*-----------------------------------------------------------*/
-
- /** The default number of Symbols after an error we much match to consider
- * it recovered from.
- */
- protected final static int _error_sync_size = 3;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The number of Symbols after an error we much match to consider it
- * recovered from.
- */
- protected int error_sync_size() {return _error_sync_size; }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Table of production information (supplied by generated subclass).
- * This table contains one entry per production and is indexed by
- * the negative-encoded values (reduce actions) in the action_table.
- * Each entry has two parts, the index of the non-terminal on the
- * left hand side of the production, and the number of Symbols
- * on the right hand side.
- */
- public abstract short[][] production_table();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The action table (supplied by generated subclass). This table is
- * indexed by state and terminal number indicating what action is to
- * be taken when the parser is in the given state (i.e., the given state
- * is on top of the stack) and the given terminal is next on the input.
- * States are indexed using the first dimension, however, the entries for
- * a given state are compacted and stored in adjacent index, value pairs
- * which are searched for rather than accessed directly (see get_action()).
- * The actions stored in the table will be either shifts, reduces, or
- * errors. Shifts are encoded as positive values (one greater than the
- * state shifted to). Reduces are encoded as negative values (one less
- * than the production reduced by). Error entries are denoted by zero.
- *
- * @see java_cup.runtime.lr_parser#get_action
- */
- public abstract short[][] action_table();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The reduce-goto table (supplied by generated subclass). This
- * table is indexed by state and non-terminal number and contains
- * state numbers. States are indexed using the first dimension, however,
- * the entries for a given state are compacted and stored in adjacent
- * index, value pairs which are searched for rather than accessed
- * directly (see get_reduce()). When a reduce occurs, the handle
- * (corresponding to the RHS of the matched production) is popped off
- * the stack. The new top of stack indicates a state. This table is
- * then indexed by that state and the LHS of the reducing production to
- * indicate where to "shift" to.
- *
- * @see java_cup.runtime.lr_parser#get_reduce
- */
- public abstract short[][] reduce_table();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The index of the start state (supplied by generated subclass). */
- public abstract int start_state();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The index of the start production (supplied by generated subclass). */
- public abstract int start_production();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The index of the end of file terminal Symbol (supplied by generated
- * subclass).
- */
- public abstract int EOF_sym();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The index of the special error Symbol (supplied by generated subclass). */
- public abstract int error_sym();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Internal flag to indicate when parser should quit. */
- protected boolean _done_parsing = false;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** This method is called to indicate that the parser should quit. This is
- * normally called by an accept action, but can be used to cancel parsing
- * early in other circumstances if desired.
- */
- public void done_parsing()
- {
- _done_parsing = true;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
- /* Global parse state shared by parse(), error recovery, and
- * debugging routines */
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Indication of the index for top of stack (for use by actions). */
- protected int tos;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The current lookahead Symbol. */
- protected Symbol cur_token;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The parse stack itself. */
- protected Stack stack = new Stack();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Direct reference to the production table. */
- protected short[][] production_tab;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Direct reference to the action table. */
- protected short[][] action_tab;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Direct reference to the reduce-goto table. */
- protected short[][] reduce_tab;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** This is the scanner object used by the default implementation
- * of scan() to get Symbols. To avoid name conflicts with existing
- * code, this field is private. [CSA/davidm] */
- private Scanner _scanner;
-
- /**
- * Simple accessor method to set the default scanner.
- */
- public void setScanner(Scanner s) { _scanner = s; }
-
- /**
- * Simple accessor method to get the default scanner.
- */
- public Scanner getScanner() { return _scanner; }
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Perform a bit of user supplied action code (supplied by generated
- * subclass). Actions are indexed by an internal action number assigned
- * at parser generation time.
- *
- * @param act_num the internal index of the action to be performed.
- * @param parser the parser object we are acting for.
- * @param stack the parse stack of that object.
- * @param top the index of the top element of the parse stack.
- */
- public abstract Symbol do_action(
- int act_num,
- lr_parser parser,
- Stack stack,
- int top)
- throws java.lang.Exception;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** User code for initialization inside the parser. Typically this
- * initializes the scanner. This is called before the parser requests
- * the first Symbol. Here this is just a placeholder for subclasses that
- * might need this and we perform no action. This method is normally
- * overridden by the generated code using this contents of the "init with"
- * clause as its body.
- */
- public void user_init() throws java.lang.Exception { }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Initialize the action object. This is called before the parser does
- * any parse actions. This is filled in by generated code to create
- * an object that encapsulates all action code.
- */
- protected abstract void init_actions() throws java.lang.Exception;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Get the next Symbol from the input (supplied by generated subclass).
- * Once end of file has been reached, all subsequent calls to scan
- * should return an EOF Symbol (which is Symbol number 0). By default
- * this method returns getScanner().next_token(); this implementation
- * can be overriden by the generated parser using the code declared in
- * the "scan with" clause. Do not recycle objects; every call to
- * scan() should return a fresh object.
- */
- public Symbol scan() throws java.lang.Exception {
- Symbol sym = getScanner().next_token();
- return (sym!=null) ? sym : new Symbol(EOF_sym());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Report a fatal error. This method takes a message string and an
- * additional object (to be used by specializations implemented in
- * subclasses). Here in the base class a very simple implementation
- * is provided which reports the error then throws an exception.
- *
- * @param message an error message.
- * @param info an extra object reserved for use by specialized subclasses.
- */
- public void report_fatal_error(
- String message,
- Object info)
- throws java.lang.Exception
- {
- /* stop parsing (not really necessary since we throw an exception, but) */
- done_parsing();
-
- /* use the normal error message reporting to put out the message */
- report_error(message, info);
-
- /* throw an exception */
- throw new Exception("Can't recover from previous error(s)");
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Report a non fatal error (or warning). This method takes a message
- * string and an additional object (to be used by specializations
- * implemented in subclasses). Here in the base class a very simple
- * implementation is provided which simply prints the message to
- * System.err.
- *
- * @param message an error message.
- * @param info an extra object reserved for use by specialized subclasses.
- */
- public void report_error(String message, Object info)
- {
- System.err.print(message);
- if (info instanceof Symbol)
- if (((Symbol)info).left != -1)
- System.err.println(" at character " + ((Symbol)info).left +
- " of input");
- else System.err.println("");
- else System.err.println("");
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** This method is called when a syntax error has been detected and recovery
- * is about to be invoked. Here in the base class we just emit a
- * "Syntax error" error message.
- *
- * @param cur_token the current lookahead Symbol.
- */
- public void syntax_error(Symbol cur_token)
- {
- report_error("Syntax error", cur_token);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** This method is called if it is determined that syntax error recovery
- * has been unsuccessful. Here in the base class we report a fatal error.
- *
- * @param cur_token the current lookahead Symbol.
- */
- public void unrecovered_syntax_error(Symbol cur_token)
- throws java.lang.Exception
- {
- report_fatal_error("Couldn't repair and continue parse", cur_token);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Fetch an action from the action table. The table is broken up into
- * rows, one per state (rows are indexed directly by state number).
- * Within each row, a list of index, value pairs are given (as sequential
- * entries in the table), and the list is terminated by a default entry
- * (denoted with a Symbol index of -1). To find the proper entry in a row
- * we do a linear or binary search (depending on the size of the row).
- *
- * @param state the state index of the action being accessed.
- * @param sym the Symbol index of the action being accessed.
- */
- protected final short get_action(int state, int sym)
- {
- short tag;
- int first, last, probe;
- short[] row = action_tab[state];
-
- /* linear search if we are < 10 entries */
- if (row.length < 20)
- for (probe = 0; probe < row.length; probe++)
- {
- /* is this entry labeled with our Symbol or the default? */
- tag = row[probe++];
- if (tag == sym || tag == -1)
- {
- /* return the next entry */
- return row[probe];
- }
- }
- /* otherwise binary search */
- else
- {
- first = 0;
- last = (row.length-1)/2 - 1; /* leave out trailing default entry */
- while (first <= last)
- {
- probe = (first+last)/2;
- if (sym == row[probe*2])
- return row[probe*2+1];
- else if (sym > row[probe*2])
- first = probe+1;
- else
- last = probe-1;
- }
-
- /* not found, use the default at the end */
- return row[row.length-1];
- }
-
- /* shouldn't happened, but if we run off the end we return the
- default (error == 0) */
- return 0;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Fetch a state from the reduce-goto table. The table is broken up into
- * rows, one per state (rows are indexed directly by state number).
- * Within each row, a list of index, value pairs are given (as sequential
- * entries in the table), and the list is terminated by a default entry
- * (denoted with a Symbol index of -1). To find the proper entry in a row
- * we do a linear search.
- *
- * @param state the state index of the entry being accessed.
- * @param sym the Symbol index of the entry being accessed.
- */
- protected final short get_reduce(int state, int sym)
- {
- short tag;
- short[] row = reduce_tab[state];
-
- /* if we have a null row we go with the default */
- if (row == null)
- return -1;
-
- for (int probe = 0; probe < row.length; probe++)
- {
- /* is this entry labeled with our Symbol or the default? */
- tag = row[probe++];
- if (tag == sym || tag == -1)
- {
- /* return the next entry */
- return row[probe];
- }
- }
- /* if we run off the end we return the default (error == -1) */
- return -1;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** This method provides the main parsing routine. It returns only when
- * done_parsing() has been called (typically because the parser has
- * accepted, or a fatal error has been reported). See the header
- * documentation for the class regarding how shift/reduce parsers operate
- * and how the various tables are used.
- */
- public Symbol parse() throws java.lang.Exception
- {
- /* the current action code */
- int act;
-
- /* the Symbol/stack element returned by a reduce */
- Symbol lhs_sym = null;
-
- /* information about production being reduced with */
- short handle_size, lhs_sym_num;
-
- /* set up direct reference to tables to drive the parser */
-
- production_tab = production_table();
- action_tab = action_table();
- reduce_tab = reduce_table();
-
- /* initialize the action encapsulation object */
- init_actions();
-
- /* do user initialization */
- user_init();
-
- /* get the first token */
- cur_token = scan();
-
- /* push dummy Symbol with start state to get us underway */
- stack.removeAllElements();
- stack.push(new Symbol(0, start_state()));
- tos = 0;
-
- /* continue until we are told to stop */
- for (_done_parsing = false; !_done_parsing; )
- {
- /* Check current token for freshness. */
- if (cur_token.used_by_parser)
- throw new Error("Symbol recycling detected (fix your scanner).");
-
- /* current state is always on the top of the stack */
-
- /* look up action out of the current state with the current input */
- act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym);
-
- /* decode the action -- > 0 encodes shift */
- if (act > 0)
- {
- /* shift to the encoded state by pushing it on the stack */
- cur_token.parse_state = act-1;
- cur_token.used_by_parser = true;
- stack.push(cur_token);
- tos++;
-
- /* advance to the next Symbol */
- cur_token = scan();
- }
- /* if its less than zero, then it encodes a reduce action */
- else if (act < 0)
- {
- /* perform the action for the reduce */
- lhs_sym = do_action((-act)-1, this, stack, tos);
-
- /* look up information about the production */
- lhs_sym_num = production_tab[(-act)-1][0];
- handle_size = production_tab[(-act)-1][1];
-
- /* pop the handle off the stack */
- for (int i = 0; i < handle_size; i++)
- {
- stack.pop();
- tos--;
- }
-
- /* look up the state to go to from the one popped back to */
- act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num);
-
- /* shift to that state */
- lhs_sym.parse_state = act;
- lhs_sym.used_by_parser = true;
- stack.push(lhs_sym);
- tos++;
- }
- /* finally if the entry is zero, we have an error */
- else if (act == 0)
- {
- /* call user syntax error reporting routine */
- syntax_error(cur_token);
-
- /* try to error recover */
- if (!error_recovery(false))
- {
- /* if that fails give up with a fatal syntax error */
- unrecovered_syntax_error(cur_token);
-
- /* just in case that wasn't fatal enough, end parse */
- done_parsing();
- } else {
- lhs_sym = (Symbol)stack.peek();
- }
- }
- }
- return lhs_sym;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Write a debugging message to System.err for the debugging version
- * of the parser.
- *
- * @param mess the text of the debugging message.
- */
- public void debug_message(String mess)
- {
- System.err.println(mess);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Dump the parse stack for debugging purposes. */
- public void dump_stack()
- {
- if (stack == null)
- {
- debug_message("# Stack dump requested, but stack is null");
- return;
- }
-
- debug_message("============ Parse Stack Dump ============");
-
- /* dump the stack */
- for (int i=0; i<stack.size(); i++)
- {
- debug_message("Symbol: " + ((Symbol)stack.elementAt(i)).sym +
- " State: " + ((Symbol)stack.elementAt(i)).parse_state);
- }
- debug_message("==========================================");
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Do debug output for a reduce.
- *
- * @param prod_num the production we are reducing with.
- * @param nt_num the index of the LHS non terminal.
- * @param rhs_size the size of the RHS.
- */
- public void debug_reduce(int prod_num, int nt_num, int rhs_size)
- {
- debug_message("# Reduce with prod #" + prod_num + " [NT=" + nt_num +
- ", " + "SZ=" + rhs_size + "]");
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Do debug output for shift.
- *
- * @param shift_tkn the Symbol being shifted onto the stack.
- */
- public void debug_shift(Symbol shift_tkn)
- {
- debug_message("# Shift under term #" + shift_tkn.sym +
- " to state #" + shift_tkn.parse_state);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Do debug output for stack state. [CSA]
- */
- public void debug_stack() {
- StringBuffer sb=new StringBuffer("## STACK:");
- for (int i=0; i<stack.size(); i++) {
- Symbol s = (Symbol) stack.elementAt(i);
- sb.append(" <state "+s.parse_state+", sym "+s.sym+">");
- if ((i%3)==2 || (i==(stack.size()-1))) {
- debug_message(sb.toString());
- sb = new StringBuffer(" ");
- }
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Perform a parse with debugging output. This does exactly the
- * same things as parse(), except that it calls debug_shift() and
- * debug_reduce() when shift and reduce moves are taken by the parser
- * and produces various other debugging messages.
- */
- public Symbol debug_parse()
- throws java.lang.Exception
- {
- /* the current action code */
- int act;
-
- /* the Symbol/stack element returned by a reduce */
- Symbol lhs_sym = null;
-
- /* information about production being reduced with */
- short handle_size, lhs_sym_num;
-
- /* set up direct reference to tables to drive the parser */
- production_tab = production_table();
- action_tab = action_table();
- reduce_tab = reduce_table();
-
- debug_message("# Initializing parser");
-
- /* initialize the action encapsulation object */
- init_actions();
-
- /* do user initialization */
- user_init();
-
- /* the current Symbol */
- cur_token = scan();
-
- debug_message("# Current Symbol is #" + cur_token.sym);
-
- /* push dummy Symbol with start state to get us underway */
- stack.removeAllElements();
- stack.push(new Symbol(0, start_state()));
- tos = 0;
-
- /* continue until we are told to stop */
- for (_done_parsing = false; !_done_parsing; )
- {
- /* Check current token for freshness. */
- if (cur_token.used_by_parser)
- throw new Error("Symbol recycling detected (fix your scanner).");
-
- /* current state is always on the top of the stack */
- //debug_stack();
-
- /* look up action out of the current state with the current input */
- act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym);
-
- /* decode the action -- > 0 encodes shift */
- if (act > 0)
- {
- /* shift to the encoded state by pushing it on the stack */
- cur_token.parse_state = act-1;
- cur_token.used_by_parser = true;
- debug_shift(cur_token);
- stack.push(cur_token);
- tos++;
-
- /* advance to the next Symbol */
- cur_token = scan();
- debug_message("# Current token is " + cur_token);
- }
- /* if its less than zero, then it encodes a reduce action */
- else if (act < 0)
- {
- /* perform the action for the reduce */
- lhs_sym = do_action((-act)-1, this, stack, tos);
-
- /* look up information about the production */
- lhs_sym_num = production_tab[(-act)-1][0];
- handle_size = production_tab[(-act)-1][1];
-
- debug_reduce((-act)-1, lhs_sym_num, handle_size);
-
- /* pop the handle off the stack */
- for (int i = 0; i < handle_size; i++)
- {
- stack.pop();
- tos--;
- }
-
- /* look up the state to go to from the one popped back to */
- act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num);
- debug_message("# Reduce rule: top state " +
- ((Symbol)stack.peek()).parse_state +
- ", lhs sym " + lhs_sym_num + " -> state " + act);
-
- /* shift to that state */
- lhs_sym.parse_state = act;
- lhs_sym.used_by_parser = true;
- stack.push(lhs_sym);
- tos++;
-
- debug_message("# Goto state #" + act);
- }
- /* finally if the entry is zero, we have an error */
- else if (act == 0)
- {
- /* call user syntax error reporting routine */
- syntax_error(cur_token);
-
- /* try to error recover */
- if (!error_recovery(true))
- {
- /* if that fails give up with a fatal syntax error */
- unrecovered_syntax_error(cur_token);
-
- /* just in case that wasn't fatal enough, end parse */
- done_parsing();
- } else {
- lhs_sym = (Symbol)stack.peek();
- }
- }
- }
- return lhs_sym;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
- /* Error recovery code */
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Attempt to recover from a syntax error. This returns false if recovery
- * fails, true if it succeeds. Recovery happens in 4 steps. First we
- * pop the parse stack down to a point at which we have a shift out
- * of the top-most state on the error Symbol. This represents the
- * initial error recovery configuration. If no such configuration is
- * found, then we fail. Next a small number of "lookahead" or "parse
- * ahead" Symbols are read into a buffer. The size of this buffer is
- * determined by error_sync_size() and determines how many Symbols beyond
- * the error must be matched to consider the recovery a success. Next,
- * we begin to discard Symbols in attempt to get past the point of error
- * to a point where we can continue parsing. After each Symbol, we attempt
- * to "parse ahead" though the buffered lookahead Symbols. The "parse ahead"
- * process simulates that actual parse, but does not modify the real
- * parser's configuration, nor execute any actions. If we can parse all
- * the stored Symbols without error, then the recovery is considered a
- * success. Once a successful recovery point is determined, we do an
- * actual parse over the stored input -- modifying the real parse
- * configuration and executing all actions. Finally, we return the the
- * normal parser to continue with the overall parse.
- *
- * @param debug should we produce debugging messages as we parse.
- */
- protected boolean error_recovery(boolean debug)
- throws java.lang.Exception
- {
- if (debug) debug_message("# Attempting error recovery");
-
- /* first pop the stack back into a state that can shift on error and
- do that shift (if that fails, we fail) */
- if (!find_recovery_config(debug))
- {
- if (debug) debug_message("# Error recovery fails");
- return false;
- }
-
- /* read ahead to create lookahead we can parse multiple times */
- read_lookahead();
-
- /* repeatedly try to parse forward until we make it the required dist */
- for (;;)
- {
- /* try to parse forward, if it makes it, bail out of loop */
- if (debug) debug_message("# Trying to parse ahead");
- if (try_parse_ahead(debug))
- {
- break;
- }
-
- /* if we are now at EOF, we have failed */
- if (lookahead[0].sym == EOF_sym())
- {
- if (debug) debug_message("# Error recovery fails at EOF");
- return false;
- }
-
- /* otherwise, we consume another Symbol and try again */
- // BUG FIX by Bruce Hutton
- // Computer Science Department, University of Auckland,
- // Auckland, New Zealand.
- // It is the first token that is being consumed, not the one
- // we were up to parsing
- if (debug)
- debug_message("# Consuming Symbol #" + lookahead[ 0 ].sym);
- restart_lookahead();
- }
-
- /* we have consumed to a point where we can parse forward */
- if (debug) debug_message("# Parse-ahead ok, going back to normal parse");
-
- /* do the real parse (including actions) across the lookahead */
- parse_lookahead(debug);
-
- /* we have success */
- return true;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if we can shift under the special error Symbol out of the
- * state currently on the top of the (real) parse stack.
- */
- protected boolean shift_under_error()
- {
- /* is there a shift under error Symbol */
- return get_action(((Symbol)stack.peek()).parse_state, error_sym()) > 0;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Put the (real) parse stack into error recovery configuration by
- * popping the stack down to a state that can shift on the special
- * error Symbol, then doing the shift. If no suitable state exists on
- * the stack we return false
- *
- * @param debug should we produce debugging messages as we parse.
- */
- protected boolean find_recovery_config(boolean debug)
- {
- Symbol error_token;
- int act;
-
- if (debug) debug_message("# Finding recovery state on stack");
-
- /* Remember the right-position of the top symbol on the stack */
- int right_pos = ((Symbol)stack.peek()).right;
- int left_pos = ((Symbol)stack.peek()).left;
-
- /* pop down until we can shift under error Symbol */
- while (!shift_under_error())
- {
- /* pop the stack */
- if (debug)
- debug_message("# Pop stack by one, state was # " +
- ((Symbol)stack.peek()).parse_state);
- left_pos = ((Symbol)stack.pop()).left;
- tos--;
-
- /* if we have hit bottom, we fail */
- if (stack.empty())
- {
- if (debug) debug_message("# No recovery state found on stack");
- return false;
- }
- }
-
- /* state on top of the stack can shift under error, find the shift */
- act = get_action(((Symbol)stack.peek()).parse_state, error_sym());
- if (debug)
- {
- debug_message("# Recover state found (#" +
- ((Symbol)stack.peek()).parse_state + ")");
- debug_message("# Shifting on error to state #" + (act-1));
- }
-
- /* build and shift a special error Symbol */
- error_token = new Symbol(error_sym(), left_pos, right_pos);
- error_token.parse_state = act-1;
- error_token.used_by_parser = true;
- stack.push(error_token);
- tos++;
-
- return true;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Lookahead Symbols used for attempting error recovery "parse aheads". */
- protected Symbol lookahead[];
-
- /** Position in lookahead input buffer used for "parse ahead". */
- protected int lookahead_pos;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Read from input to establish our buffer of "parse ahead" lookahead
- * Symbols.
- */
- protected void read_lookahead() throws java.lang.Exception
- {
- /* create the lookahead array */
- lookahead = new Symbol[error_sync_size()];
-
- /* fill in the array */
- for (int i = 0; i < error_sync_size(); i++)
- {
- lookahead[i] = cur_token;
- cur_token = scan();
- }
-
- /* start at the beginning */
- lookahead_pos = 0;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Return the current lookahead in our error "parse ahead" buffer. */
- protected Symbol cur_err_token() { return lookahead[lookahead_pos]; }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Advance to next "parse ahead" input Symbol. Return true if we have
- * input to advance to, false otherwise.
- */
- protected boolean advance_lookahead()
- {
- /* advance the input location */
- lookahead_pos++;
-
- /* return true if we didn't go off the end */
- return lookahead_pos < error_sync_size();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Reset the parse ahead input to one Symbol past where we started error
- * recovery (this consumes one new Symbol from the real input).
- */
- protected void restart_lookahead() throws java.lang.Exception
- {
- /* move all the existing input over */
- for (int i = 1; i < error_sync_size(); i++)
- lookahead[i-1] = lookahead[i];
-
- /* read a new Symbol into the last spot */
- // BUG Fix by Bruce Hutton
- // Computer Science Department, University of Auckland,
- // Auckland, New Zealand. [applied 5-sep-1999 by csa]
- // The following two lines were out of order!!
- lookahead[error_sync_size()-1] = cur_token;
- cur_token = scan();
-
- /* reset our internal position marker */
- lookahead_pos = 0;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Do a simulated parse forward (a "parse ahead") from the current
- * stack configuration using stored lookahead input and a virtual parse
- * stack. Return true if we make it all the way through the stored
- * lookahead input without error. This basically simulates the action of
- * parse() using only our saved "parse ahead" input, and not executing any
- * actions.
- *
- * @param debug should we produce debugging messages as we parse.
- */
- protected boolean try_parse_ahead(boolean debug)
- throws java.lang.Exception
- {
- int act;
- short lhs, rhs_size;
-
- /* create a virtual stack from the real parse stack */
- virtual_parse_stack vstack = new virtual_parse_stack(stack);
-
- /* parse until we fail or get past the lookahead input */
- for (;;)
- {
- /* look up the action from the current state (on top of stack) */
- act = get_action(vstack.top(), cur_err_token().sym);
-
- /* if its an error, we fail */
- if (act == 0) return false;
-
- /* > 0 encodes a shift */
- if (act > 0)
- {
- /* push the new state on the stack */
- vstack.push(act-1);
-
- if (debug) debug_message("# Parse-ahead shifts Symbol #" +
- cur_err_token().sym + " into state #" + (act-1));
-
- /* advance simulated input, if we run off the end, we are done */
- if (!advance_lookahead()) return true;
- }
- /* < 0 encodes a reduce */
- else
- {
- /* if this is a reduce with the start production we are done */
- if ((-act)-1 == start_production())
- {
- if (debug) debug_message("# Parse-ahead accepts");
- return true;
- }
-
- /* get the lhs Symbol and the rhs size */
- lhs = production_tab[(-act)-1][0];
- rhs_size = production_tab[(-act)-1][1];
-
- /* pop handle off the stack */
- for (int i = 0; i < rhs_size; i++)
- vstack.pop();
-
- if (debug)
- debug_message("# Parse-ahead reduces: handle size = " +
- rhs_size + " lhs = #" + lhs + " from state #" + vstack.top());
-
- /* look up goto and push it onto the stack */
- vstack.push(get_reduce(vstack.top(), lhs));
- if (debug)
- debug_message("# Goto state #" + vstack.top());
- }
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Parse forward using stored lookahead Symbols. In this case we have
- * already verified that parsing will make it through the stored lookahead
- * Symbols and we are now getting back to the point at which we can hand
- * control back to the normal parser. Consequently, this version of the
- * parser performs all actions and modifies the real parse configuration.
- * This returns once we have consumed all the stored input or we accept.
- *
- * @param debug should we produce debugging messages as we parse.
- */
- protected void parse_lookahead(boolean debug)
- throws java.lang.Exception
- {
- /* the current action code */
- int act;
-
- /* the Symbol/stack element returned by a reduce */
- Symbol lhs_sym = null;
-
- /* information about production being reduced with */
- short handle_size, lhs_sym_num;
-
- /* restart the saved input at the beginning */
- lookahead_pos = 0;
-
- if (debug)
- {
- debug_message("# Reparsing saved input with actions");
- debug_message("# Current Symbol is #" + cur_err_token().sym);
- debug_message("# Current state is #" +
- ((Symbol)stack.peek()).parse_state);
- }
-
- /* continue until we accept or have read all lookahead input */
- while(!_done_parsing)
- {
- /* current state is always on the top of the stack */
-
- /* look up action out of the current state with the current input */
- act =
- get_action(((Symbol)stack.peek()).parse_state, cur_err_token().sym);
-
- /* decode the action -- > 0 encodes shift */
- if (act > 0)
- {
- /* shift to the encoded state by pushing it on the stack */
- cur_err_token().parse_state = act-1;
- cur_err_token().used_by_parser = true;
- if (debug) debug_shift(cur_err_token());
- stack.push(cur_err_token());
- tos++;
-
- /* advance to the next Symbol, if there is none, we are done */
- if (!advance_lookahead())
- {
- if (debug) debug_message("# Completed reparse");
-
- /* scan next Symbol so we can continue parse */
- // BUGFIX by Chris Harris <ckharris@ucsd.edu>:
- // correct a one-off error by commenting out
- // this next line.
- /*cur_token = scan();*/
-
- /* go back to normal parser */
- return;
- }
-
- if (debug)
- debug_message("# Current Symbol is #" + cur_err_token().sym);
- }
- /* if its less than zero, then it encodes a reduce action */
- else if (act < 0)
- {
- /* perform the action for the reduce */
- lhs_sym = do_action((-act)-1, this, stack, tos);
-
- /* look up information about the production */
- lhs_sym_num = production_tab[(-act)-1][0];
- handle_size = production_tab[(-act)-1][1];
-
- if (debug) debug_reduce((-act)-1, lhs_sym_num, handle_size);
-
- /* pop the handle off the stack */
- for (int i = 0; i < handle_size; i++)
- {
- stack.pop();
- tos--;
- }
-
- /* look up the state to go to from the one popped back to */
- act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num);
-
- /* shift to that state */
- lhs_sym.parse_state = act;
- lhs_sym.used_by_parser = true;
- stack.push(lhs_sym);
- tos++;
-
- if (debug) debug_message("# Goto state #" + act);
-
- }
- /* finally if the entry is zero, we have an error
- (shouldn't happen here, but...)*/
- else if (act == 0)
- {
- report_fatal_error("Syntax error", lhs_sym);
- return;
- }
- }
-
-
- }
-
- /*-----------------------------------------------------------*/
-
- /** Utility function: unpacks parse tables from strings */
- protected static short[][] unpackFromStrings(String[] sa)
- {
- // Concatanate initialization strings.
- StringBuffer sb = new StringBuffer(sa[0]);
- for (int i=1; i<sa.length; i++)
- sb.append(sa[i]);
- int n=0; // location in initialization string
- int size1 = (((int)sb.charAt(n))<<16) | ((int)sb.charAt(n+1)); n+=2;
- short[][] result = new short[size1][];
- for (int i=0; i<size1; i++) {
- int size2 = (((int)sb.charAt(n))<<16) | ((int)sb.charAt(n+1)); n+=2;
- result[i] = new short[size2];
- for (int j=0; j<size2; j++)
- result[i][j] = (short) (sb.charAt(n++)-2);
- }
- return result;
- }
-}
-
+++ /dev/null
-
-package java_cup.runtime;
-
-import java.util.Stack;
-
-/** This class implements a temporary or "virtual" parse stack that
- * replaces the top portion of the actual parse stack (the part that
- * has been changed by some set of operations) while maintaining its
- * original contents. This data structure is used when the parse needs
- * to "parse ahead" to determine if a given error recovery attempt will
- * allow the parse to continue far enough to consider it successful. Once
- * success or failure of parse ahead is determined the system then
- * reverts to the original parse stack (which has not actually been
- * modified). Since parse ahead does not execute actions, only parse
- * state is maintained on the virtual stack, not full Symbol objects.
- *
- * @see java_cup.runtime.lr_parser
- * @version last updated: 7/3/96
- * @author Frank Flannery
- */
-
-public class virtual_parse_stack {
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Constructor to build a virtual stack out of a real stack. */
- public virtual_parse_stack(Stack shadowing_stack) throws java.lang.Exception
- {
- /* sanity check */
- if (shadowing_stack == null)
- throw new Exception(
- "Internal parser error: attempt to create null virtual stack");
-
- /* set up our internals */
- real_stack = shadowing_stack;
- vstack = new Stack();
- real_next = 0;
-
- /* get one element onto the virtual portion of the stack */
- get_from_real();
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The real stack that we shadow. This is accessed when we move off
- * the bottom of the virtual portion of the stack, but is always left
- * unmodified.
- */
- protected Stack real_stack;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Top of stack indicator for where we leave off in the real stack.
- * This is measured from top of stack, so 0 would indicate that no
- * elements have been "moved" from the real to virtual stack.
- */
- protected int real_next;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The virtual top portion of the stack. This stack contains Integer
- * objects with state numbers. This stack shadows the top portion
- * of the real stack within the area that has been modified (via operations
- * on the virtual stack). When this portion of the stack becomes empty we
- * transfer elements from the underlying stack onto this stack.
- */
- protected Stack vstack;
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Transfer an element from the real to the virtual stack. This assumes
- * that the virtual stack is currently empty.
- */
- protected void get_from_real()
- {
- Symbol stack_sym;
-
- /* don't transfer if the real stack is empty */
- if (real_next >= real_stack.size()) return;
-
- /* get a copy of the first Symbol we have not transfered */
- stack_sym = (Symbol)real_stack.elementAt(real_stack.size()-1-real_next);
-
- /* record the transfer */
- real_next++;
-
- /* put the state number from the Symbol onto the virtual stack */
- vstack.push(new Integer(stack_sym.parse_state));
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Indicate whether the stack is empty. */
- public boolean empty()
- {
- /* if vstack is empty then we were unable to transfer onto it and
- the whole thing is empty. */
- return vstack.empty();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Return value on the top of the stack (without popping it). */
- public int top() throws java.lang.Exception
- {
- if (vstack.empty())
- throw new Exception(
- "Internal parser error: top() called on empty virtual stack");
-
- return ((Integer)vstack.peek()).intValue();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Pop the stack. */
- public void pop() throws java.lang.Exception
- {
- if (vstack.empty())
- throw new Exception(
- "Internal parser error: pop from empty virtual stack");
-
- /* pop it */
- vstack.pop();
-
- /* if we are now empty transfer an element (if there is one) */
- if (vstack.empty())
- get_from_real();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Push a state number onto the stack. */
- public void push(int state_num)
- {
- vstack.push(new Integer(state_num));
- }
-
- /*-----------------------------------------------------------*/
-
-}
+++ /dev/null
-
-package java_cup;
-
-/** This class represents a shift action within the parse table.
- * The action simply stores the state that it shifts to and responds
- * to queries about its type.
- *
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-public class shift_action extends parse_action {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Simple constructor.
- * @param shft_to the state that this action shifts to.
- */
- public shift_action(lalr_state shft_to) throws internal_error
- {
- /* sanity check */
- if (shft_to == null)
- throw new internal_error(
- "Attempt to create a shift_action to a null state");
-
- _shift_to = shft_to;
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The state we shift to. */
- protected lalr_state _shift_to;
-
- /** The state we shift to. */
- public lalr_state shift_to() {return _shift_to;}
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Quick access to type of action. */
- public int kind() {return SHIFT;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality test. */
- public boolean equals(shift_action other)
- {
- return other != null && other.shift_to() == shift_to();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality test. */
- public boolean equals(Object other)
- {
- if (other instanceof shift_action)
- return equals((shift_action)other);
- else
- return false;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Compute a hash code. */
- public int hashCode()
- {
- /* use the hash code of the state we are shifting to */
- return shift_to().hashCode();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string. */
- public String toString() {return "SHIFT(to state " + shift_to().index() + ")";}
-
- /*-----------------------------------------------------------*/
-
-}
+++ /dev/null
-// Driver for parser
-
-package java_cup.simple_calc;
-
-import java_cup.simple_calc.parser;
-import java_cup.runtime.Symbol;
-
-class Main {
-
- static boolean do_debug_parse = false;
-
- static public void main(String[] args) throws java.io.IOException {
-
- /* create a parsing object */
- parser parser_obj = new parser(new scanner());
-
- /* open input files, etc. here */
- Symbol parse_tree = null;
-
- try {
- if (do_debug_parse)
- parse_tree = parser_obj.debug_parse();
- else
- parse_tree = parser_obj.parse();
- } catch (Exception e) {
- /* do cleanup here -- possibly rethrow e */
- } finally {
- /* do close out here */
- }
- }
-}
-
+++ /dev/null
-// JavaCup specification for a simple expression evaluator (w/ actions)
-
-package java_cup.simple_calc;
-
-import java_cup.runtime.*;
-
-/* Terminals (tokens returned by the scanner). */
-terminal SEMI, PLUS, MINUS, TIMES, DIVIDE, MOD;
-terminal UMINUS, LPAREN, RPAREN;
-terminal Integer NUMBER;
-
-/* Non terminals */
-non terminal Object expr_list, expr_part;
-non terminal Integer expr;
-
-/* Precedences */
-precedence left PLUS, MINUS;
-precedence left TIMES, DIVIDE, MOD;
-precedence left UMINUS, LPAREN;
-
-/* The grammar */
-expr_list ::= expr_list expr_part
- |
- expr_part;
-
-expr_part ::= expr:e
- {: System.out.println("= " + e); :}
- SEMI
- ;
-
-expr ::= expr:e1 PLUS expr:e2
- {: RESULT = new Integer(e1.intValue() + e2.intValue()); :}
- |
- expr:e1 MINUS expr:e2
- {: RESULT = new Integer(e1.intValue() - e2.intValue()); :}
- |
- expr:e1 TIMES expr:e2
- {: RESULT = new Integer(e1.intValue() * e2.intValue()); :}
- |
- expr:e1 DIVIDE expr:e2
- {: RESULT = new Integer(e1.intValue() / e2.intValue()); :}
- |
- expr:e1 MOD expr:e2
- {: RESULT = new Integer(e1.intValue() % e2.intValue()); :}
- |
- NUMBER:n
- {: RESULT = n; :}
- |
- MINUS expr:e
- {: RESULT = new Integer(0 - e.intValue()); :}
- %prec UMINUS
- |
- LPAREN expr:e RPAREN
- {: RESULT = e; :}
- ;
+++ /dev/null
-
-//----------------------------------------------------
-// The following code was generated by CUP v0.10k
-// Sun Jul 25 13:36:02 EDT 1999
-//----------------------------------------------------
-
-package java_cup.simple_calc;
-
-import java_cup.runtime.*;
-
-/** CUP v0.10k generated parser.
- * @version Sun Jul 25 13:36:02 EDT 1999
- */
-public class parser extends java_cup.runtime.lr_parser {
-
- /** Default constructor. */
- public parser() {super();}
-
- /** Constructor which sets the default scanner. */
- public parser(java_cup.runtime.Scanner s) {super(s);}
-
- /** Production table. */
- protected static final short _production_table[][] =
- unpackFromStrings(new String[] {
- "\000\015\000\002\003\004\000\002\002\004\000\002\003" +
- "\003\000\002\006\002\000\002\004\005\000\002\005\005" +
- "\000\002\005\005\000\002\005\005\000\002\005\005\000" +
- "\002\005\005\000\002\005\003\000\002\005\004\000\002" +
- "\005\005" });
-
- /** Access to production table. */
- public short[][] production_table() {return _production_table;}
-
- /** Parse-action table. */
- protected static final short[][] _action_table =
- unpackFromStrings(new String[] {
- "\000\030\000\010\006\004\013\011\015\005\001\002\000" +
- "\010\006\004\013\011\015\005\001\002\000\020\004\ufff7" +
- "\005\ufff7\006\ufff7\007\ufff7\010\ufff7\011\ufff7\014\ufff7\001" +
- "\002\000\012\002\uffff\006\uffff\013\uffff\015\uffff\001\002" +
- "\000\016\004\ufffe\005\016\006\014\007\020\010\017\011" +
- "\013\001\002\000\012\002\027\006\004\013\011\015\005" +
- "\001\002\000\010\006\004\013\011\015\005\001\002\000" +
- "\016\005\016\006\014\007\020\010\017\011\013\014\015" +
- "\001\002\000\010\006\004\013\011\015\005\001\002\000" +
- "\010\006\004\013\011\015\005\001\002\000\020\004\ufff5" +
- "\005\ufff5\006\ufff5\007\ufff5\010\ufff5\011\ufff5\014\ufff5\001" +
- "\002\000\010\006\004\013\011\015\005\001\002\000\010" +
- "\006\004\013\011\015\005\001\002\000\010\006\004\013" +
- "\011\015\005\001\002\000\020\004\ufffa\005\ufffa\006\ufffa" +
- "\007\ufffa\010\ufffa\011\ufffa\014\ufffa\001\002\000\020\004" +
- "\ufff9\005\ufff9\006\ufff9\007\ufff9\010\ufff9\011\ufff9\014\ufff9" +
- "\001\002\000\020\004\ufffc\005\ufffc\006\ufffc\007\020\010" +
- "\017\011\013\014\ufffc\001\002\000\020\004\ufffb\005\ufffb" +
- "\006\ufffb\007\020\010\017\011\013\014\ufffb\001\002\000" +
- "\020\004\ufff8\005\ufff8\006\ufff8\007\ufff8\010\ufff8\011\ufff8" +
- "\014\ufff8\001\002\000\012\002\001\006\001\013\001\015" +
- "\001\001\002\000\004\002\000\001\002\000\004\004\031" +
- "\001\002\000\012\002\ufffd\006\ufffd\013\ufffd\015\ufffd\001" +
- "\002\000\020\004\ufff6\005\ufff6\006\ufff6\007\ufff6\010\ufff6" +
- "\011\ufff6\014\ufff6\001\002" });
-
- /** Access to parse-action table. */
- public short[][] action_table() {return _action_table;}
-
- /** <code>reduce_goto</code> table. */
- protected static final short[][] _reduce_table =
- unpackFromStrings(new String[] {
- "\000\030\000\010\003\007\004\005\005\006\001\001\000" +
- "\004\005\031\001\001\000\002\001\001\000\002\001\001" +
- "\000\004\006\027\001\001\000\006\004\025\005\006\001" +
- "\001\000\004\005\011\001\001\000\002\001\001\000\004" +
- "\005\024\001\001\000\004\005\023\001\001\000\002\001" +
- "\001\000\004\005\022\001\001\000\004\005\021\001\001" +
- "\000\004\005\020\001\001\000\002\001\001\000\002\001" +
- "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
- "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
- "\002\001\001\000\002\001\001" });
-
- /** Access to <code>reduce_goto</code> table. */
- public short[][] reduce_table() {return _reduce_table;}
-
- /** Instance of action encapsulation class. */
- protected CUP$parser$actions action_obj;
-
- /** Action encapsulation object initializer. */
- protected void init_actions()
- {
- action_obj = new CUP$parser$actions(this);
- }
-
- /** Invoke a user supplied parse action. */
- public java_cup.runtime.Symbol do_action(
- int act_num,
- java_cup.runtime.lr_parser parser,
- java.util.Stack stack,
- int top)
- throws java.lang.Exception
- {
- /* call code in generated class */
- return action_obj.CUP$parser$do_action(act_num, parser, stack, top);
- }
-
- /** Indicates start state. */
- public int start_state() {return 0;}
- /** Indicates start production. */
- public int start_production() {return 1;}
-
- /** <code>EOF</code> Symbol index. */
- public int EOF_sym() {return 0;}
-
- /** <code>error</code> Symbol index. */
- public int error_sym() {return 1;}
-
-}
-
-/** Cup generated class to encapsulate user supplied action code.*/
-class CUP$parser$actions {
- private final parser parser;
-
- /** Constructor */
- CUP$parser$actions(parser parser) {
- this.parser = parser;
- }
-
- /** Method with the actual generated action code. */
- public final java_cup.runtime.Symbol CUP$parser$do_action(
- int CUP$parser$act_num,
- java_cup.runtime.lr_parser CUP$parser$parser,
- java.util.Stack CUP$parser$stack,
- int CUP$parser$top)
- throws java.lang.Exception
- {
- /* Symbol object for return from actions */
- java_cup.runtime.Symbol CUP$parser$result;
-
- /* select the action based on the action number */
- switch (CUP$parser$act_num)
- {
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 12: // expr ::= LPAREN expr RPAREN
- {
- Integer RESULT = null;
- int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
- int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
- Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
- RESULT = e;
- CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 11: // expr ::= MINUS expr
- {
- Integer RESULT = null;
- int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = new Integer(0 - e.intValue());
- CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 10: // expr ::= NUMBER
- {
- Integer RESULT = null;
- int nleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int nright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- Integer n = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = n;
- CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 9: // expr ::= expr MOD expr
- {
- Integer RESULT = null;
- int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
- int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
- Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
- int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = new Integer(e1.intValue() % e2.intValue());
- CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 8: // expr ::= expr DIVIDE expr
- {
- Integer RESULT = null;
- int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
- int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
- Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
- int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = new Integer(e1.intValue() / e2.intValue());
- CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 7: // expr ::= expr TIMES expr
- {
- Integer RESULT = null;
- int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
- int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
- Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
- int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = new Integer(e1.intValue() * e2.intValue());
- CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 6: // expr ::= expr MINUS expr
- {
- Integer RESULT = null;
- int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
- int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
- Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
- int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = new Integer(e1.intValue() - e2.intValue());
- CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 5: // expr ::= expr PLUS expr
- {
- Integer RESULT = null;
- int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
- int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
- Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
- int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- RESULT = new Integer(e1.intValue() + e2.intValue());
- CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 4: // expr_part ::= expr NT$0 SEMI
- {
- Object RESULT = null;
- // propagate RESULT from NT$0
- if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
- RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
- int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
- int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
- Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
-
- CUP$parser$result = new java_cup.runtime.Symbol(2/*expr_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 3: // NT$0 ::=
- {
- Object RESULT = null;
- int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
- int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
- Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
- System.out.println("= " + e);
- CUP$parser$result = new java_cup.runtime.Symbol(4/*NT$0*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 2: // expr_list ::= expr_part
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(1/*expr_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 1: // $START ::= expr_list EOF
- {
- Object RESULT = null;
- int start_valleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
- int start_valright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
- Object start_val = (Object)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
- RESULT = start_val;
- CUP$parser$result = new java_cup.runtime.Symbol(0/*$START*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- /* ACCEPT */
- CUP$parser$parser.done_parsing();
- return CUP$parser$result;
-
- /*. . . . . . . . . . . . . . . . . . . .*/
- case 0: // expr_list ::= expr_list expr_part
- {
- Object RESULT = null;
-
- CUP$parser$result = new java_cup.runtime.Symbol(1/*expr_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
- }
- return CUP$parser$result;
-
- /* . . . . . .*/
- default:
- throw new Exception(
- "Invalid action number found in internal parse table");
-
- }
- }
-}
-
+++ /dev/null
-// Simple Example Scanner Class
-
-package java_cup.simple_calc;
-
-import java_cup.runtime.Symbol;
-
-public class scanner implements java_cup.runtime.Scanner {
- final java.io.InputStream instream;
-
- public scanner(java.io.InputStream is) throws java.io.IOException {
- instream = is;
- }
- public scanner() throws java.io.IOException { this(System.in); }
-
- /* single lookahead character */
- protected int next_char = -2;
-
- /* advance input by one character */
- protected void advance()
- throws java.io.IOException
- { next_char = instream.read(); }
-
- /* initialize the scanner */
- private void init()
- throws java.io.IOException
- { advance(); }
-
- /* recognize and return the next complete token */
- public Symbol next_token()
- throws java.io.IOException
- {
- if (next_char==-2) init(); // set stuff up first time we are called.
- for (;;)
- switch (next_char)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- /* parse a decimal integer */
- int i_val = 0;
- do {
- i_val = i_val * 10 + (next_char - '0');
- advance();
- } while (next_char >= '0' && next_char <= '9');
- return new Symbol(sym.NUMBER, new Integer(i_val));
-
- case ';': advance(); return new Symbol(sym.SEMI);
- case '+': advance(); return new Symbol(sym.PLUS);
- case '-': advance(); return new Symbol(sym.MINUS);
- case '*': advance(); return new Symbol(sym.TIMES);
- case '/': advance(); return new Symbol(sym.DIVIDE);
- case '%': advance(); return new Symbol(sym.MOD);
- case '(': advance(); return new Symbol(sym.LPAREN);
- case ')': advance(); return new Symbol(sym.RPAREN);
-
- case -1: return new Symbol(sym.EOF);
-
- default:
- /* in this simple scanner we just ignore everything else */
- advance();
- break;
- }
- }
-};
+++ /dev/null
-
-//----------------------------------------------------
-// The following code was generated by CUP v0.10k
-// Sun Jul 25 13:36:02 EDT 1999
-//----------------------------------------------------
-
-package java_cup.simple_calc;
-
-/** CUP generated class containing symbol constants. */
-public class sym {
- /* terminals */
- public static final int SEMI = 2;
- public static final int EOF = 0;
- public static final int DIVIDE = 6;
- public static final int NUMBER = 11;
- public static final int error = 1;
- public static final int UMINUS = 8;
- public static final int MINUS = 4;
- public static final int TIMES = 5;
- public static final int LPAREN = 9;
- public static final int RPAREN = 10;
- public static final int MOD = 7;
- public static final int PLUS = 3;
-}
-
+++ /dev/null
-
-//----------------------------------------------------
-// The following code was generated by CUP v0.10k
-// Sun Jul 25 13:35:26 EDT 1999
-//----------------------------------------------------
-
-package java_cup;
-
-/** CUP generated class containing symbol constants. */
-public class sym {
- /* terminals */
- public static final int NON = 8;
- public static final int NONTERMINAL = 27;
- public static final int STAR = 15;
- public static final int SEMI = 13;
- public static final int CODE = 4;
- public static final int EOF = 0;
- public static final int NONASSOC = 23;
- public static final int LEFT = 21;
- public static final int PACKAGE = 2;
- public static final int COLON = 17;
- public static final int WITH = 11;
- public static final int IMPORT = 3;
- public static final int error = 1;
- public static final int COLON_COLON_EQUALS = 18;
- public static final int COMMA = 14;
- public static final int DOT = 16;
- public static final int SCAN = 10;
- public static final int ID = 28;
- public static final int INIT = 9;
- public static final int PARSER = 6;
- public static final int TERMINAL = 7;
- public static final int PRECEDENCE = 20;
- public static final int LBRACK = 25;
- public static final int RBRACK = 26;
- public static final int PERCENT_PREC = 24;
- public static final int START = 12;
- public static final int RIGHT = 22;
- public static final int BAR = 19;
- public static final int ACTION = 5;
- public static final int CODE_STRING = 29;
-}
-
+++ /dev/null
-package java_cup;
-
-/** This abstract class serves as the base class for grammar symbols (i.e.,
- * both terminals and non-terminals). Each symbol has a name string, and
- * a string giving the type of object that the symbol will be represented by
- * on the runtime parse stack. In addition, each symbol maintains a use count
- * in order to detect symbols that are declared but never used, and an index
- * number that indicates where it appears in parse tables (index numbers are
- * unique within terminals or non terminals, but not across both).
- *
- * @see java_cup.terminal
- * @see java_cup.non_terminal
- * @version last updated: 7/3/96
- * @author Frank Flannery
- */
-public abstract class symbol {
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Full constructor.
- * @param nm the name of the symbol.
- * @param tp a string with the type name.
- */
- public symbol(String nm, String tp)
- {
- /* sanity check */
- if (nm == null) nm = "";
-
- /* apply default if no type given */
- if (tp == null) tp = "Object";
-
- _name = nm;
- _stack_type = tp;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor with default type.
- * @param nm the name of the symbol.
- */
- public symbol(String nm)
- {
- this(nm, null);
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** String for the human readable name of the symbol. */
- protected String _name;
-
- /** String for the human readable name of the symbol. */
- public String name() {return _name;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** String for the type of object used for the symbol on the parse stack. */
- protected String _stack_type;
-
- /** String for the type of object used for the symbol on the parse stack. */
- public String stack_type() {return _stack_type;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Count of how many times the symbol appears in productions. */
- protected int _use_count = 0;
-
- /** Count of how many times the symbol appears in productions. */
- public int use_count() {return _use_count;}
-
- /** Increment the use count. */
- public void note_use() {_use_count++;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Index of this symbol (terminal or non terminal) in the parse tables.
- * Note: indexes are unique among terminals and unique among non terminals,
- * however, a terminal may have the same index as a non-terminal, etc.
- */
- protected int _index;
-
- /** Index of this symbol (terminal or non terminal) in the parse tables.
- * Note: indexes are unique among terminals and unique among non terminals,
- * however, a terminal may have the same index as a non-terminal, etc.
- */
- public int index() {return _index;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Indicate if this is a non-terminal. Here in the base class we
- * don't know, so this is abstract.
- */
- public abstract boolean is_non_term();
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string. */
- public String toString()
- {
- return name();
- }
-
- /*-----------------------------------------------------------*/
-
-}
+++ /dev/null
-package java_cup;
-
-/** This class represents a part of a production which is a symbol (terminal
- * or non terminal). This simply maintains a reference to the symbol in
- * question.
- *
- * @see java_cup.production
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-public class symbol_part extends production_part {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Full constructor.
- * @param sym the symbol that this part is made up of.
- * @param lab an optional label string for the part.
- */
- public symbol_part(symbol sym, String lab) throws internal_error
- {
- super(lab);
-
- if (sym == null)
- throw new internal_error(
- "Attempt to construct a symbol_part with a null symbol");
- _the_symbol = sym;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor with no label.
- * @param sym the symbol that this part is made up of.
- */
- public symbol_part(symbol sym) throws internal_error
- {
- this(sym,null);
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The symbol that this part is made up of. */
- protected symbol _the_symbol;
-
- /** The symbol that this part is made up of. */
- public symbol the_symbol() {return _the_symbol;}
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Respond that we are not an action part. */
- public boolean is_action() { return false; }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison. */
- public boolean equals(symbol_part other)
- {
- return other != null && super.equals(other) &&
- the_symbol().equals(other.the_symbol());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof symbol_part))
- return false;
- else
- return equals((symbol_part)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a hash code. */
- public int hashCode()
- {
- return super.hashCode() ^
- (the_symbol()==null ? 0 : the_symbol().hashCode());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string. */
- public String toString()
- {
- if (the_symbol() != null)
- return super.toString() + the_symbol();
- else
- return super.toString() + "$$MISSING-SYMBOL$$";
- }
-
- /*-----------------------------------------------------------*/
-
-}
+++ /dev/null
-
-package java_cup;
-
-import java.util.Hashtable;
-import java.util.Enumeration;
-
-/** This class represents a set of symbols and provides a series of
- * set operations to manipulate them.
- *
- * @see java_cup.symbol
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-public class symbol_set {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Constructor for an empty set. */
- public symbol_set() { }
-
- /** Constructor for cloning from another set.
- * @param other the set we are cloning from.
- */
- public symbol_set(symbol_set other) throws internal_error
- {
- not_null(other);
- _all = (Hashtable)other._all.clone();
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** A hash table to hold the set. Symbols are keyed using their name string.
- */
- protected Hashtable _all = new Hashtable(11);
-
- /** Access to all elements of the set. */
- public Enumeration all() {return _all.elements();}
-
- /** size of the set */
- public int size() {return _all.size();}
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Helper function to test for a null object and throw an exception
- * if one is found.
- * @param obj the object we are testing.
- */
- protected void not_null(Object obj) throws internal_error
- {
- if (obj == null)
- throw new internal_error("Null object used in set operation");
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if the set contains a particular symbol.
- * @param sym the symbol we are looking for.
- */
- public boolean contains(symbol sym) {return _all.containsKey(sym.name());}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if this set is an (improper) subset of another.
- * @param other the set we are testing against.
- */
- public boolean is_subset_of(symbol_set other) throws internal_error
- {
- not_null(other);
-
- /* walk down our set and make sure every element is in the other */
- for (Enumeration e = all(); e.hasMoreElements(); )
- if (!other.contains((symbol)e.nextElement()))
- return false;
-
- /* they were all there */
- return true;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if this set is an (improper) superset of another.
- * @param other the set we are are testing against.
- */
- public boolean is_superset_of(symbol_set other) throws internal_error
- {
- not_null(other);
- return other.is_subset_of(this);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Add a single symbol to the set.
- * @param sym the symbol we are adding.
- * @return true if this changes the set.
- */
- public boolean add(symbol sym) throws internal_error
- {
- Object previous;
-
- not_null(sym);
-
- /* put the object in */
- previous = _all.put(sym.name(),sym);
-
- /* if we had a previous, this is no change */
- return previous == null;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Remove a single symbol if it is in the set.
- * @param sym the symbol we are removing.
- */
- public void remove(symbol sym) throws internal_error
- {
- not_null(sym);
- _all.remove(sym.name());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Add (union) in a complete set.
- * @param other the set we are adding in.
- * @return true if this changes the set.
- */
- public boolean add(symbol_set other) throws internal_error
- {
- boolean result = false;
-
- not_null(other);
-
- /* walk down the other set and do the adds individually */
- for (Enumeration e = other.all(); e.hasMoreElements(); )
- result = add((symbol)e.nextElement()) || result;
-
- return result;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Remove (set subtract) a complete set.
- * @param other the set we are removing.
- */
- public void remove(symbol_set other) throws internal_error
- {
- not_null(other);
-
- /* walk down the other set and do the removes individually */
- for (Enumeration e = other.all(); e.hasMoreElements(); )
- remove((symbol)e.nextElement());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison. */
- public boolean equals(symbol_set other)
- {
- if (other == null || other.size() != size()) return false;
-
- /* once we know they are the same size, then improper subset does test */
- try {
- return is_subset_of(other);
- } catch (internal_error e) {
- /* can't throw the error (because super class doesn't), so we crash */
- e.crash();
- return false;
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof symbol_set))
- return false;
- else
- return equals((symbol_set)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Compute a hash code. */
- public int hashCode()
- {
- int result = 0;
- int cnt;
- Enumeration e;
-
- /* hash together codes from at most first 5 elements */
- for (e = all(), cnt=0 ; e.hasMoreElements() && cnt<5; cnt++)
- result ^= ((symbol)e.nextElement()).hashCode();
-
- return result;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string. */
- public String toString()
- {
- String result;
- boolean comma_flag;
-
- result = "{";
- comma_flag = false;
- for (Enumeration e = all(); e.hasMoreElements(); )
- {
- if (comma_flag)
- result += ", ";
- else
- comma_flag = true;
-
- result += ((symbol)e.nextElement()).name();
- }
- result += "}";
-
- return result;
- }
-
- /*-----------------------------------------------------------*/
-
-}
-
-
+++ /dev/null
-package java_cup;
-
-import java_cup.assoc;
-import java.util.Hashtable;
-import java.util.Enumeration;
-
-/** This class represents a terminal symbol in the grammar. Each terminal
- * has a textual name, an index, and a string which indicates the type of
- * object it will be implemented with at runtime (i.e. the class of object
- * that will be returned by the scanner and pushed on the parse stack to
- * represent it).
- *
- * @version last updated: 7/3/96
- * @author Frank Flannery
- */
-public class terminal extends symbol {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Full constructor.
- * @param nm the name of the terminal.
- * @param tp the type of the terminal.
- */
- public terminal(String nm, String tp, int precedence_side, int precedence_num)
- {
- /* superclass does most of the work */
- super(nm, tp);
-
- /* add to set of all terminals and check for duplicates */
- Object conflict = _all.put(nm,this);
- if (conflict != null)
- // can't throw an execption here because this is used in static
- // initializers, so we do a crash instead
- // was:
- // throw new internal_error("Duplicate terminal (" + nm + ") created");
- (new internal_error("Duplicate terminal (" + nm + ") created")).crash();
-
- /* assign a unique index */
- _index = next_index++;
-
- /* set the precedence */
- _precedence_num = precedence_num;
- _precedence_side = precedence_side;
-
- /* add to by_index set */
- _all_by_index.put(new Integer(_index), this);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor for non-precedented terminal
- */
-
- public terminal(String nm, String tp)
- {
- this(nm, tp, assoc.no_prec, -1);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor with default type.
- * @param nm the name of the terminal.
- */
- public terminal(String nm)
- {
- this(nm, null);
- }
-
- /*-----------------------------------------------------------*/
- /*------------------- Class Variables ---------------------*/
- /*-----------------------------------------------------------*/
-
- private int _precedence_num;
- private int _precedence_side;
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Static (Class) Variables ------------------*/
- /*-----------------------------------------------------------*/
-
- /** Table of all terminals. Elements are stored using name strings as
- * the key
- */
- protected static Hashtable _all = new Hashtable();
-
- /** Access to all terminals. */
- public static Enumeration all() {return _all.elements();}
-
- /** Lookup a terminal by name string. */
- public static terminal find(String with_name)
- {
- if (with_name == null)
- return null;
- else
- return (terminal)_all.get(with_name);
- }
-
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Table of all terminals indexed by their index number. */
- protected static Hashtable _all_by_index = new Hashtable();
-
- /** Lookup a terminal by index. */
- public static terminal find(int indx)
- {
- Integer the_indx = new Integer(indx);
-
- return (terminal)_all_by_index.get(the_indx);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Total number of terminals. */
- public static int number() {return _all.size();}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Static counter to assign unique index. */
- protected static int next_index = 0;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Special terminal for end of input. */
- public static final terminal EOF = new terminal("EOF");
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** special terminal used for error recovery */
- public static final terminal error = new terminal("error");
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ---------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Report this symbol as not being a non-terminal. */
- public boolean is_non_term()
- {
- return false;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string. */
- public String toString()
- {
- return super.toString() + "[" + index() + "]";
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** get the precedence of a terminal */
- public int precedence_num() {
- return _precedence_num;
- }
- public int precedence_side() {
- return _precedence_side;
- }
-
- /** set the precedence of a terminal */
- public void set_precedence(int p, int new_prec) {
- _precedence_side = p;
- _precedence_num = new_prec;
- }
-
- /*-----------------------------------------------------------*/
-
-}
+++ /dev/null
-
-package java_cup;
-
-import java.util.BitSet;
-
-/** A set of terminals implemented as a bitset.
- * @version last updated: 11/25/95
- * @author Scott Hudson
- */
-public class terminal_set {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Constructor for an empty set. */
- public terminal_set()
- {
- /* allocate the bitset at what is probably the right size */
- _elements = new BitSet(terminal.number());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor for cloning from another set.
- * @param other the set we are cloning from.
- */
- public terminal_set(terminal_set other)
- throws internal_error
- {
- not_null(other);
- _elements = (BitSet)other._elements.clone();
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Static (Class) Variables ------------------*/
- /*-----------------------------------------------------------*/
-
- /** Constant for the empty set. */
- public static final terminal_set EMPTY = new terminal_set();
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Bitset to implement the actual set. */
- protected BitSet _elements;
-
- /*-----------------------------------------------------------*/
- /*--- General Methods ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Helper function to test for a null object and throw an exception if
- * one is found.
- * @param obj the object we are testing.
- */
- protected void not_null(Object obj) throws internal_error
- {
- if (obj == null)
- throw new internal_error("Null object used in set operation");
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if the set is empty. */
- public boolean empty()
- {
- return equals(EMPTY);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if the set contains a particular terminal.
- * @param sym the terminal symbol we are looking for.
- */
- public boolean contains(terminal sym)
- throws internal_error
- {
- not_null(sym);
- return _elements.get(sym.index());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Given its index determine if the set contains a particular terminal.
- * @param indx the index of the terminal in question.
- */
- public boolean contains(int indx)
- {
- return _elements.get(indx);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if this set is an (improper) subset of another.
- * @param other the set we are testing against.
- */
- public boolean is_subset_of(terminal_set other)
- throws internal_error
- {
- not_null(other);
-
- /* make a copy of the other set */
- BitSet copy_other = (BitSet)other._elements.clone();
-
- /* and or in */
- copy_other.or(_elements);
-
- /* if it hasn't changed, we were a subset */
- return copy_other.equals(other._elements);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if this set is an (improper) superset of another.
- * @param other the set we are testing against.
- */
- public boolean is_superset_of(terminal_set other)
- throws internal_error
- {
- not_null(other);
- return other.is_subset_of(this);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Add a single terminal to the set.
- * @param sym the terminal being added.
- * @return true if this changes the set.
- */
- public boolean add(terminal sym)
- throws internal_error
- {
- boolean result;
-
- not_null(sym);
-
- /* see if we already have this */
- result = _elements.get(sym.index());
-
- /* if not we add it */
- if (!result)
- _elements.set(sym.index());
-
- return result;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Remove a terminal if it is in the set.
- * @param sym the terminal being removed.
- */
- public void remove(terminal sym)
- throws internal_error
- {
- not_null(sym);
- _elements.clear(sym.index());
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Add (union) in a complete set.
- * @param other the set being added.
- * @return true if this changes the set.
- */
- public boolean add(terminal_set other)
- throws internal_error
- {
- not_null(other);
-
- /* make a copy */
- BitSet copy = (BitSet)_elements.clone();
-
- /* or in the other set */
- _elements.or(other._elements);
-
- /* changed if we are not the same as the copy */
- return !_elements.equals(copy);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if this set intersects another.
- * @param other the other set in question.
- */
- public boolean intersects(terminal_set other)
- throws internal_error
- {
- not_null(other);
-
- /* make a copy of the other set */
- BitSet copy = (BitSet)other._elements.clone();
-
- /* xor out our values */
- copy.xor(this._elements);
-
- /* see if its different */
- return !copy.equals(other._elements);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison. */
- public boolean equals(terminal_set other)
- {
- if (other == null)
- return false;
- else
- return _elements.equals(other._elements);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof terminal_set))
- return false;
- else
- return equals((terminal_set)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to string. */
- public String toString()
- {
- String result;
- boolean comma_flag;
-
- result = "{";
- comma_flag = false;
- for (int t = 0; t < terminal.number(); t++)
- {
- if (_elements.get(t))
- {
- if (comma_flag)
- result += ", ";
- else
- comma_flag = true;
-
- result += terminal.find(t).name();
- }
- }
- result += "}";
-
- return result;
- }
-
- /*-----------------------------------------------------------*/
-
-}
-
+++ /dev/null
-
-package java_cup;
-
-/** This class contains version and authorship information.
- * It contains only static data elements and basically just a central
- * place to put this kind of information so it can be updated easily
- * for each release.
- *
- * Version numbers used here are broken into 3 parts: major, minor, and
- * update, and are written as v<major>.<minor>.<update> (e.g. v0.10a).
- * Major numbers will change at the time of major reworking of some
- * part of the system. Minor numbers for each public release or
- * change big enough to cause incompatibilities. Finally update
- * letter will be incremented for small bug fixes and changes that
- * probably wouldn't be noticed by a user.
- *
- * @version last updated: 12/22/97 [CSA]
- * @author Frank Flannery
- */
-
-public class version {
- /** The major version number. */
- public static final int major = 0;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The minor version number. */
- public static final int minor = 10;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The update letter. */
- public static final char update = 'k';
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** String for the current version. */
- public static final String version_str = "v" + major + "." + minor + update;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Full title of the system */
- public static final String title_str = "CUP " + version_str;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Name of the author */
- public static final String author_str =
- "Scott E. Hudson, Frank Flannery, and C. Scott Ananian";
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The command name normally used to invoke this program */
- public static final String program_name = "java_cup";
-}
+++ /dev/null
-<html><head>
-<title>CUP User's Manual</title>
-</head>
-<body>
-
-<hr>
-<img src="cup_logo.gif" alt="[CUP Logo Image]">
-<hr>
-<h1>CUP User's Manual</h1>
-<h3><a href="http://www.cc.gatech.edu/gvu/people/Faculty/Scott.E.Hudson.html">
-Scott E. Hudson</a><br>
-<a href="http://www.cc.gatech.edu/gvu/gvutop.html">
-Graphics Visualization and Usability Center</a><br>
-<a href="http://www.gatech.edu/TechHome.html">
-Georgia Institute of Technology</a></h3>
-Modified by <a href="http://www.princeton.edu/~frankf">Frank
-Flannery</a>, <a href="http://www.pdos.lcs.mit.edu/~cananian/">C. Scott Ananian</a>,
-<a href="http://www.cs.princeton.edu/~danwang">Dan Wang</a> with advice from
-<a href="http://www.cs.princeton.edu/~appel">Andrew W. Appel</a><br>
-Last updated July 1999 (v0.10j)
-<hr>
-
-<h3>Table of Contents</h3>
-<dl compact>
- <dt> i. <dd> <a href="#about">About CUP Version 0.10</a>
- <dt> 1. <dd> <a href="#intro">Introduction and Example</a>
- <dt> 2. <dd> <a href="#spec">Specification Syntax</a>
- <dt> 3. <dd> <a href="#running">Running CUP</a>
- <dt> 4. <dd> <a href="#parser">Customizing the Parser</a>
- <dt> 5. <dd> <a href="#scanner">Scanner interface</a>
- <dt> 6. <dd> <a href="#errors">Error Recovery</a>
- <dt> 7. <dd> <a href="#conclusion">Conclusion</a>
- <dt> <dd> <a href="#refs">References</a>
- <dt> A. <dd> <a href="#appendixa">Grammar for CUP Specification Files</a>
- <dt> B. <dd> <a href="#appendixb">A Very Simple Example Scanner</a>
- <dt> C. <dd> <a href="#changes">Incompatibilites between CUP 0.9 and CUP 0.10</a>
- <dt> D. <dd> <a href="#bugs">Bugs</a>
- <dt> E. <dd> <a href="#version">Change log</a>
-</dl>
-
-<a name=about>
-<h3>i. About CUP Version 0.10</h3>
-</a> Version
-0.10 of CUP adds many new changes and features over the previous releases
-of version 0.9. These changes attempt to make CUP more like its
-predecessor, YACC. As a result, the old 0.9 parser specifications for CUP are
-not compatible and a reading of <a href="#changes">appendix C</a> of the new
-manual will be necessary to write new specifications. The new version,
-however, gives the user more power and options, making parser specifications
-easier to write.
-
-<a name=intro>
-<h3>1. Introduction and Example</h3></a>
-
-This manual describes the basic operation and use of the
-Java<a href="#trademark">(tm)</a>
-Based Constructor of Useful Parsers (CUP for short).
-CUP is a system for generating LALR parsers from simple specifications.
-It serves the same role as the widely used program YACC
-<a href="#YACCref">[1]</a> and in fact offers most of the features of YACC.
-However, CUP is written in Java, uses specifications including embedded
-Java code, and produces parsers which are implemented in Java.<p>
-
-Although this manual covers all aspects of the CUP system, it is relatively
-brief, and assumes you have at least a little bit of knowledge of LR
-parsing. A working knowledge of YACC is also very helpful in
-understanding how CUP specifications work.
-A number of compiler construction textbooks (such as
-<a href="#dragonbook">[2</a>,<a href="#crafting">3]</a>) cover this material,
-and discuss the YACC system (which is quite similar to this one) as a
-specific example. In addition, Andrew Appel's <a
-href="http://www.cs.princeton.edu/~appel/modern/java/">Modern Compiler
-Implementation in Java</a> textbook <a href="#modernjava">[4]</a> uses
-and describes CUP in the context of compiler construction.
-<p>
-
-Using CUP involves creating a simple specification based on the
-grammar for which a parser is needed, along with construction of a
-scanner capable of breaking characters up into meaningful tokens (such
-as keywords, numbers, and special symbols).<p>
-
-As a simple example, consider a
-system for evaluating simple arithmetic expressions over integers.
-This system would read expressions from standard input (each terminated
-with a semicolon), evaluate them, and print the result on standard output.
-A grammar for the input to such a system might look like: <pre>
- expr_list ::= expr_list expr_part | expr_part
- expr_part ::= expr ';'
- expr ::= expr '+' expr | expr '-' expr | expr '*' expr
- | expr '/' expr | expr '%' expr | '(' expr ')'
- | '-' expr | number
-</pre>
-To specify a parser based on this grammar, our first step is to identify and
-name the set of terminal symbols that will appear on input, and the set of
-non-terminal symbols. In this case, the non-terminals are:
-
-<pre><tt> expr_list, expr_part </tt> and <tt> expr </tt>.</pre>
-
-For terminal names we might choose:
-
-<pre><tt> SEMI, PLUS, MINUS, TIMES, DIVIDE, MOD, NUMBER, LPAREN,</tt>
-and <tt>RPAREN</tt></pre>
-
-The experienced user will note a problem with the above grammar. It is
-ambiguous. An ambiguous grammar is a grammar which, given a certain
-input, can reduce the parts of the input in two different ways such as
-to give two different answers. Take the above grammar, for
-example. given the following input: <br>
-<tt>3 + 4 * 6</tt><br>
-The grammar can either evaluate the <tt>3 + 4</tt> and then multiply
-seven by six, or it can evaluate <tt>4 * 6</tt> and then add three.
-Older versions of CUP forced the user to write unambiguous grammars, but
-now there is a construct allowing the user to specify precedences and
-associativities for terminals. This means that the above ambiguous
-grammar can be used, after specifying precedences and associativities.
-There is more explanation later.
-
-Based on these namings we can construct a small CUP specification
-as follows:<br>
-<hr>
-<pre><tt>// CUP specification for a simple expression evaluator (no actions)
-
-import java_cup.runtime.*;
-
-/* Preliminaries to set up and use the scanner. */
-init with {: scanner.init(); :};
-scan with {: return scanner.next_token(); :};
-
-/* Terminals (tokens returned by the scanner). */
-terminal SEMI, PLUS, MINUS, TIMES, DIVIDE, MOD;
-terminal UMINUS, LPAREN, RPAREN;
-terminal Integer NUMBER;
-
-/* Non terminals */
-non terminal expr_list, expr_part;
-non terminal Integer expr, term, factor;
-
-/* Precedences */
-precedence left PLUS, MINUS;
-precedence left TIMES, DIVIDE, MOD;
-precedence left UMINUS;
-
-/* The grammar */
-expr_list ::= expr_list expr_part |
- expr_part;
-expr_part ::= expr SEMI;
-expr ::= expr PLUS expr
- | expr MINUS expr
- | expr TIMES expr
- | expr DIVIDE expr
- | expr MOD expr
- | MINUS expr %prec UMINUS
- | LPAREN expr RPAREN
- | NUMBER
- ;
-</tt></pre>
-<hr><br>
-We will consider each part of the specification syntax in detail later.
-However, here we can quickly see that the specification contains four
-main parts. The first part provides preliminary and miscellaneous declarations
-to specify how the parser is to be generated, and supply parts of the
-runtime code. In this case we indicate that the <tt>java_cup.runtime</tt>
-classes should be imported, then supply a small bit of initialization code,
-and some code for invoking the scanner to retrieve the next input token.
-The second part of the specification declares terminals and non-terminals,
-and associates object classes with each. In this case, the terminals
-are declared as either with no type, or of type
-<tt>Integer</tt>. The specified type of the
-terminal or non-terminal is the type of the value of those terminals or
-non-terminals. If no type is specified, the terminal or non-terminal
-carries no value. Here, no type indicates that these
-terminals and non-terminals hold no value.
-The third part specifies the precedence and
-associativity of terminals. The last precedence declaration give its
-terminals the highest precedence. The final
-part of the specification contains the grammar.<p>
-
-
-To produce a parser from this specification we use the CUP generator.
-If this specification were stored in a file <tt>parser.cup</tt>, then
-(on a Unix system at least) we might invoke CUP using a command like:
-<pre><tt> java java_cup.Main < parser.cup</tt> </pre>
-or (starting with CUP 0.10k):
-<pre><tt> java java_cup.Main parser.cup</tt> </pre>
-The system will produce two Java source files containing
-parts of the generated parser: <tt>sym.java</tt> and <tt>parser.java</tt>
-(these names can be changed with command-line options; see
-<A HREF="#running">below</a>).
-As you might expect, these two files contain declarations for the classes
-<tt>sym</tt> and <tt>parser</tt>. The <tt>sym</tt> class contains a series of
-constant declarations, one for each terminal symbol. This is typically used
-by the scanner to refer to symbols (e.g. with code such as
-"<tt>return new Symbol(sym.SEMI);</tt>" ). The <tt>parser</tt> class
-implements the parser itself.<p>
-
-The specification above, while constructing a full parser, does not perform
-any semantic actions &emdash; it will only indicate success or failure of a parse.
-To calculate and print values of each expression, we must embed Java
-code within the parser to carry out actions at various points. In CUP,
-actions are contained in <i>code strings</i> which are surrounded by delimiters
-of the form <tt>{:</tt> and <tt>:}</tt> (we can see examples of this in the
-<tt>init with</tt> and <tt>scan with</tt> clauses above). In general, the
-system records all characters within the delimiters, but does not try to check
-that it contains valid Java code.<p>
-
-A more complete CUP specification for our example system (with actions
-embedded at various points in the grammar) is shown below:<br>
-<hr>
-<pre><tt>// CUP specification for a simple expression evaluator (w/ actions)
-
-import java_cup.runtime.*;
-
-/* Preliminaries to set up and use the scanner. */
-init with {: scanner.init(); :};
-scan with {: return scanner.next_token(); :};
-
-/* Terminals (tokens returned by the scanner). */
-terminal SEMI, PLUS, MINUS, TIMES, DIVIDE, MOD;
-terminal UMINUS, LPAREN, RPAREN;
-terminal Integer NUMBER;
-
-/* Non-terminals */
-non terminal expr_list, expr_part;
-non terminal Integer expr;
-
-/* Precedences */
-precedence left PLUS, MINUS;
-precedence left TIMES, DIVIDE, MOD;
-precedence left UMINUS;
-
-/* The grammar */
-expr_list ::= expr_list expr_part
- |
- expr_part;
-
-expr_part ::= expr:e
- {: System.out.println("= " + e); :}
- SEMI
- ;
-
-expr ::= expr:e1 PLUS expr:e2
- {: RESULT = new Integer(e1.intValue() + e2.intValue()); :}
- |
- expr:e1 MINUS expr:e2
- {: RESULT = new Integer(e1.intValue() - e2.intValue()); :}
- |
- expr:e1 TIMES expr:e2
- {: RESULT = new Integer(e1.intValue() * e2.intValue()); :}
- |
- expr:e1 DIVIDE expr:e2
- {: RESULT = new Integer(e1.intValue() / e2.intValue()); :}
- |
- expr:e1 MOD expr:e2
- {: RESULT = new Integer(e1.intValue() % e2.intValue()); :}
- |
- NUMBER:n
- {: RESULT = n; :}
- |
- MINUS expr:e
- {: RESULT = new Integer(0 - e.intValue()); :}
- %prec UMINUS
- |
- LPAREN expr:e RPAREN
- {: RESULT = e; :}
- ;
-</tt></pre>
-<hr><br>
-Here we can see several changes. Most importantly, code to be executed at
-various points in the parse is included inside code strings delimited by
-<tt>{:</tt> and <tt>:}</tt>. In addition, labels have been placed on various
-symbols in the right hand side of productions. For example in:<br>
-<pre> expr:e1 PLUS expr:e2
- {: RESULT = new Integer(e1.intValue() + e2.intValue()); :}
-</pre>
-<a name="RES_part">
-the first non-terminal <tt>expr</tt> has been labeled with <tt>e1</tt>, and
-the second with <tt>e2</tt>. The left hand side value
-of each production is always implicitly labeled as <tt>RESULT</tt>.<p>
-
-Each symbol appearing in a production is represented at runtime by an
-object of type <tt>Symbol</tt> on the parse stack. The labels refer to
-the instance variable <tt>value</tt> in those objects. In the
-expression <tt>expr:e1 PLUS expr:e2</tt>, <tt>e1</tt> and <tt>e2</tt>
-refer to objects of type Integer. These objects are in the value fields
-of the objects of type <tt>Symbol</tt> representing those non-terminals
-on the parse stack. <tt>RESULT</tt> is of type <tt>Integer</tt> as
-well, since the resulting non-terminal <tt>expr</tt> was declared as of
-type <tt>Integer</tt>. This object becomes the <tt>value</tt> instance
-variable of a new <tt>Symbol</tt> object.<p>
-
-For each label, two more variables accessible to the user are declared.
-A left and right value labels are passed to the code string, so that the
-user can find out where the left and right side of each terminal or
-non-terminal is in the input stream. The name of these variables is the
-label name, plus <tt>left</tt> or <tt>right</tt>. for example, given
-the right hand side of a production <tt>expr:e1 PLUS expr:e2</tt> the
-user could not only access variables <tt>e1</tt> and <tt>e2</tt>, but
-also <tt>e1left, e1right, e2left</tt> and <tt>e2right</tt>. these
-variables are of type <tt>int</tt>.<p>
-
-<a name="lex_part">
-
-The final step in creating a working parser is to create a <i>scanner</i> (also
-known as a <i>lexical analyzer</i> or simply a <i>lexer</i>). This routine is
-responsible for reading individual characters, removing things things like
-white space and comments, recognizing which terminal symbols from the
-grammar each group of characters represents, then returning Symbol objects
-representing these symbols to the parser.
-The terminals will be retrieved with a call to the
-scanner function. In the example, the parser will call
-<tt>scanner.next_token()</tt>. The scanner should return objects of
-type <tt>java_cup.runtime.Symbol</tt>. This type is very different than
-older versions of CUP's <tt>java_cup.runtime.symbol</tt>. These Symbol
-objects contains the instance variable <tt>value</tt> of type Object,
-which should be
-set by the lexer. This variable refers to the value of that symbol, and
-the type of object in value should be of the same type as declared in
-the <tt>terminal</tt> and <tt>non terminal</tt> declarations. In the
-above example, if the lexer wished to pass a NUMBER token, it should
-create a <tt>Symbol</tt> with the <tt>value</tt> instance variable
-filled with an object of type <tt>Integer</tt>. <code>Symbol</code>
-objects corresponding to terminals and non-terminals with no value
-have a null value field.<p>
-
-The code contained in the <tt>init with</tt> clause of the specification
-will be executed before any tokens are requested. Each token will be
-requested using whatever code is found in the <tt>scan with</tt> clause.
-Beyond this, the exact form the scanner takes is up to you; however
-note that each call to the scanner function should return a new
-instance of <code>java_cup.runtime.Symbol</code> (or a subclass).
-These symbol objects are annotated with parser information and pushed
-onto a stack; reusing objects will result in the parser annotations
-being scrambled. As of CUP 0.10j, <code>Symbol</code> reuse should be
-detected if it occurs; the parser will throw an <code>Error</code>
-telling you to fix your scanner.<p>
-
-In the <a href="#spec">next section</a> a more detailed and formal
-explanation of all parts of a CUP specification will be given.
-<a href="#running">Section 3</a> describes options for running the
-CUP system. <a href="#parser">Section 4</a> discusses the details
-of how to customize a CUP parser, while <a href="#scanner">section 5</a>
-discusses the scanner interface added in CUP 0.10j. <a href="#errors">Section
- 6</a> considers error recovery. Finally, <a href="#conclusion">Section 7</a>
-provides a conclusion.
-
-<a name="spec">
-<h3>2. Specification Syntax</h3></a>
-Now that we have seen a small example, we present a complete description of all
-parts of a CUP specification. A specification has four sections with
-a total of eight specific parts (however, most of these are optional).
-A specification consists of:
-<ul>
-<li> <a href="#package_spec">package and import specifications</a>,
-<li> <a href="#code_part">user code components</a>,
-<li> <a href="#symbol_list">symbol (terminal and non-terminal) lists</a>,
-<li> <a href="#precedence">precedence declarations</a>, and
-<li> <a href="#production_list">the grammar</a>.
-</ul>
-Each of these parts must appear in the order presented here. (A complete
-grammar for the specification language is given in
-<a href="#appendixa">Appendix A</a>.) The particulars of each part of
-the specification are described in the subsections below.<p>
-
-<h5><a name="package_spec">Package and Import Specifications</a></h5>
-
-A specification begins with optional <tt>package</tt> and <tt>import</tt>
-declarations. These have the same syntax, and play the same
-role, as the package and import declarations found in a normal Java program.
-A package declaration is of the form:
-
-<pre><tt> package <i>name</i>;</tt></pre>
-
-where name <tt><i>name</i></tt> is a Java package identifier, possibly in
-several parts separated by ".". In general, CUP employs Java lexical
-conventions. So for example, both styles of Java comments are supported,
-and identifiers are constructed beginning with a letter, dollar
-sign ($), or underscore (_), which can then be followed by zero or more
-letters, numbers, dollar signs, and underscores.<p>
-
-After an optional <tt>package</tt> declaration, there can be zero or more
-<tt>import</tt> declarations. As in a Java program these have the form:
-
-<pre><tt> import <i>package_name.class_name</i>;</tt>
-</pre>
-or
-<pre><tt> import <i>package_name</i>.*;</tt>
-</pre>
-
-The package declaration indicates what package the <tt>sym</tt> and
-<tt>parser</tt> classes that are generated by the system will be in.
-Any import declarations that appear in the specification will also appear
-in the source file for the <tt>parser</tt> class allowing various names from
-that package to be used directly in user supplied action code.
-
-<h5><a name="code_part">User Code Components</a></h5>
-
-Following the optional <tt>package</tt> and <tt>import</tt> declarations
-are a series of optional declarations that allow user code to be included
-as part of the generated parser (see <a href="#parser">Section 4</a> for a
-full description of how the parser uses this code). As a part of the parser
-file, a separate non-public class to contain all embedded user actions is
-produced. The first <tt>action code</tt> declaration section allows code to
-be included in this class. Routines and variables for use by the code
-embedded in the grammar would normally be placed in this section (a typical
-example might be symbol table manipulation routines). This declaration takes
-the form:
-
-<pre><tt> action code {: ... :};</tt>
-</pre>
-
-where <tt>{: ... :}</tt> is a code string whose contents will be placed
-directly within the <tt>action class</tt> class declaration.<p>
-
-After the <tt>action code</tt> declaration is an optional
-<tt>parser code</tt> declaration. This declaration allows methods and
-variable to be placed directly within the generated parser class.
-Although this is less common, it can be helpful when customizing the
-parser &emdash; it is possible for example, to include scanning methods inside
-the parser and/or override the default error reporting routines. This
-declaration is very similar to the <tt>action code</tt> declaration and
-takes the form:
-
-<pre><tt> parser code {: ... :};</tt>
-</pre>
-
-Again, code from the code string is placed directly into the generated parser
-class definition.<p>
-
-Next in the specification is the optional <tt>init</tt> declaration
-which has the form:
-
-<pre><tt> init with {: ... :};</tt></pre>
-
-This declaration provides code that will be executed by the parser
-before it asks for the first token. Typically, this is used to initialize
-the scanner as well as various tables and other data structures that might
-be needed by semantic actions. In this case, the code given in the code
-string forms the body of a <tt>void</tt> method inside the <tt>parser</tt>
-class.<p>
-
-The final (optional) user code section of the specification indicates how
-the parser should ask for the next token from the scanner. This has the
-form:
-
-<pre><tt> scan with {: ... :};</tt></pre>
-
-As with the <tt>init</tt> clause, the contents of the code string forms
-the body of a method in the generated parser. However, in this case
-the method returns an object of type <tt>java_cup.runtime.Symbol</tt>.
-Consequently the code found in the <tt>scan with</tt> clause should
-return such a value. See <a href="#scanner">section 5</a> for
-information on the default behavior if the <code>scan with</code>
-section is omitted.<p>
-
-As of CUP 0.10j the action code, parser code, init code, and scan with
-sections may appear in any order. They must, however, precede the
-symbol lists.<p>
-
-<h5><a name="symbol_list">Symbol Lists</a></h5>
-
-Following user supplied code comes the first required part of the
-specification: the symbol lists. These declarations are responsible
-for naming and supplying a type for each terminal and non-terminal
-symbol that appears in the grammar. As indicated above, each terminal
-and non-terminal symbol is represented at runtime with a <tt>Symbol</tt>
-object. In
-the case of terminals, these are returned by the scanner and placed on
-the parse stack. The lexer should put the value of the terminal in the
-<tt>value</tt> instance variable.
-In the case of non-terminals these replace a series
-of <tt>Symbol</tt> objects on the parse stack whenever the right hand side of
-some production is recognized. In order to tell the parser which object
-types should be used for which symbol, <tt>terminal</tt> and
-<tt>non terminal</tt> declarations are used. These take the forms:
-
-<pre><tt> terminal <i>classname</i> <i>name1, name2,</i> ...;</tt>
-<tt> non terminal <i>classname</i> <i>name1, name2,</i> ...;</tt>
-<tt> terminal <i>name1, name2,</i> ...;</tt>
-</pre>
-
-and
-
-<pre><tt> non terminal <i>name1, name2,</i> ...;</tt>
-</pre>
-
-where <tt><i>classname</i></tt> can be a multiple part name separated with
-"."s. The
-<tt><i>classname</i></tt> specified represents the type of the value of
-that terminal or non-terminal. When accessing these values through
-labels, the users uses the type declared. the <tt><i>classname</i></tt>
-can be of any type. If no <tt><i>classname</i></tt> is given, then the
-terminal or non-terminal holds no value. a label referring to such a
-symbol with have a null value. As of CUP 0.10j, you may specify
-non-terminals the declaration "<code>nonterminal</code>" (note, no
-space) as well as the original "<code>non terminal</code>" spelling.<p>
-
-Names of terminals and non-terminals cannot be CUP reserved words;
-these include "code", "action", "parser", "terminal", "non",
-"nonterminal", "init", "scan", "with", "start", "precedence", "left",
-"right", "nonassoc", "import", and "package".<p>
-
-<h5><a name="precedence">Precedence and Associativity declarations</a></h5>
-
-The third section, which is optional, specifies the precedences and
-associativity of terminals. This is useful for parsing with ambiguous
-grammars, as done in the example above. There are three type of
-precedence/associativity declarations:
-<pre><tt>
- precedence left <i>terminal</i>[, <i>terminal</i>...];
- precedence right <i>terminal</i>[, <i>terminal</i>...];
- precedence nonassoc <i>terminal</i>[, <i>terminal</i>...];
-</tt></pre>
-
-The comma separated list indicates that those terminals should have the
-associativity specified at that precedence level and the precedence of
-that declaration. The order of precedence, from highest to lowest, is
-bottom to top. Hence, this declares that multiplication and division have
-higher precedence than addition and subtraction:
-<pre><tt>
- precedence left ADD, SUBTRACT;
- precedence left TIMES, DIVIDE;
-</tt></pre>
-Precedence resolves shift reduce problems. For example, given the input
-to the above example parser <tt>3 + 4 * 8</tt>, the parser doesn't know
-whether to reduce <tt>3 + 4</tt> or shift the '*' onto the stack.
-However, since '*' has a higher precedence than '+', it will be shifted
-and the multiplication will be performed before the addition.<p>
-
-CUP assigns each one of its terminals a precedence according to these
-declarations. Any terminals not in this declaration have lowest
-precedence. CUP also assigns each of its productions a precedence.
-That precedence is equal to the precedence of the last terminal in that
-production. If the production has no terminals, then it has lowest
-precedence. For example, <tt>expr ::= expr TIMES expr</tt> would have
-the same precedence as <tt>TIMES</tt>. When there is a shift/reduce
-conflict, the parser determines whether the terminal to be shifted has a
-higher precedence, or if the production to reduce by does. If the
-terminal has higher precedence, it it shifted, if the production has
-higher precedence, a reduce is performed. If they have equal
-precedence, associativity of the terminal determine what happens.<p>
-
-An associativity is assigned to each terminal used in the
-precedence/associativity declarations. The three associativities are
-<tt>left, right</tt> and <tt>nonassoc</tt> Associativities are also
-used to resolve shift/reduce conflicts, but only in the case of equal
-precedences. If the associativity of the terminal that can be shifted
-is <tt>left</tt>, then a reduce is performed. This means, if the input
-is a string of additions, like <tt>3 + 4 + 5 + 6 + 7</tt>, the parser
-will <i>always</i> reduce them from left to right, in this case,
-starting with <tt>3 + 4</tt>. If the associativity of the terminal is
-<tt>right</tt>, it is shifted onto the stack. hence, the reductions
-will take place from right to left. So, if PLUS were declared with
-associativity of <tt>right</tt>, the <tt>6 + 7</tt> would be reduced
-first in the above string. If a terminal is declared as
-<tt>nonassoc</tt>, then two consecutive occurrences of equal precedence
-non-associative terminals generates an error. This is useful for
-comparison operations. For example, if the input string is
-<tt>6 == 7 == 8 == 9</tt>, the parser should generate an error. If '=='
-is declared as <tt>nonassoc</tt> then an error will be generated. <p>
-
-All terminals not used in the precedence/associativity declarations are
-treated as lowest precedence. If a shift/reduce error results,
-involving two such terminals, it cannot be resolved, as the above
-conflicts are, so it will be reported.<p>
-
-<h5><a name="production_list">The Grammar</a></h5>
-
-The final section of a CUP declaration provides the grammar. This
-section optionally starts with a declaration of the form:
-
-<pre><tt> start with <i>non-terminal</i>;</tt>
-</pre>
-
-This indicates which non-terminal is the <i>start</i> or <i>goal</i>
-non-terminal for parsing. If a start non-terminal is not explicitly
-declared, then the non-terminal on the left hand side of the first
-production will be used. At the end of a successful parse, CUP returns
-an object of type <tt>java_cup.runtime.Symbol</tt>. This
-<tt>Symbol</tt>'s value instance variable contains the final reduction
-result.<p>
-
-The grammar itself follows the optional <tt>start</tt> declaration. Each
-production in the grammar has a left hand side non-terminal followed by
-the symbol "<tt>::=</tt>", which is then followed by a series of zero or more
-actions, terminal, or non-terminal
-symbols, followed by an optional contextual precedence assignment,
-and terminated with a semicolon (;).<p>
-
-<a name="label_part">
-
-Each symbol on the right hand side can optionally be labeled with a name.
-Label names appear after the symbol name separated by a colon (:). Label
-names must be unique within the production, and can be used within action
-code to refer to the value of the symbol. Along with the label, two
-more variables are created, which are the label plus <tt>left</tt> and
-the label plus <tt>right</tt>. These are <tt>int</tt> values that
-contain the right and left locations of what the terminal or
-non-terminal covers in the input file. These values must be properly
-initialized in the terminals by the lexer. The left and right values
-then propagate to non-terminals to which productions reduce.<p>
-
-If there are several productions for the same non-terminal they may be
-declared together. In this case the productions start with the non-terminal
-and "<tt>::=</tt>". This is followed by multiple right hand sides each
-separated by a bar (|). The full set of productions is then terminated by a
-semicolon.<p>
-
-Actions appear in the right hand side as code strings (e.g., Java code inside
-<tt>{:</tt> ... <tt>:}</tt> delimiters). These are executed by the parser
-at the point when the portion of the production to the left of the
-action has been recognized. (Note that the scanner will have returned the
-token one past the point of the action since the parser needs this extra
-<i>lookahead</i> token for recognition.)<p>
-
-<a name="cpp">
-
-Contextual precedence assignments follow all the symbols and actions of
-the right hand side of the production whose precedence it is assigning.
-Contextual precedence assignment allows a production to be assigned a
-precedence not based on the last terminal in it. A good example is
-shown in the above sample parser specification:
-
-<pre><tt>
- precedence left PLUS, MINUS;
- precedence left TIMES, DIVIDE, MOD;
- precedence left UMINUS;
-
- expr ::= MINUS expr:e
- {: RESULT = new Integer(0 - e.intValue()); :}
- %prec UMINUS
-</tt></pre>
-
-Here, there production is declared as having the precedence of UMINUS.
-Hence, the parser can give the MINUS sign two different precedences,
-depending on whether it is a unary minus or a subtraction operation.
-
-<a name="running">
-<h3>3. Running CUP</h3></a>
-
-As mentioned above, CUP is written in Java. To invoke it, one needs
-to use the Java interpreter to invoke the static method
-<tt>java_cup.Main()</tt>, passing an array of strings containing options.
-Assuming a Unix machine, the simplest way to do this is typically to invoke it
-directly from the command line with a command such as:
-
-<pre><tt> java java_cup.Main <i>options</i> < <i>inputfile</i></tt></pre>
-
-Once running, CUP expects to find a specification file on standard input
-and produces two Java source files as output. Starting with CUP 0.10k,
-the final command-line argument may be a filename, in which case the
-specification will be read from that file instead of from standard input.<p>
-
-In addition to the specification file, CUP's behavior can also be changed
-by passing various options to it. Legal options are documented in
-<code>Main.java</code> and include:
-<dl>
- <dt><tt>-package</tt> <i>name</i>
- <dd>Specify that the <tt>parser</tt> and <tt>sym</tt> classes are to be
- placed in the named package. By default, no package specification
- is put in the generated code (hence the classes default to the special
- "unnamed" package).
-
- <dt><tt>-parser</tt> <i>name</i>
- <dd>Output parser and action code into a file (and class) with the given
- name instead of the default of "<tt>parser</tt>".
-
- <dt><tt>-symbols</tt> <i>name</i>
- <dd>Output the symbol constant code into a class with the given
- name instead of the default of "<tt>sym</tt>".
-
- <dt><tt>-interface</tt>
- <dd>Outputs the symbol constant code as an <code>interface</code>
- rather than as a <code>class</code>.
-
- <dt><tt>-nonterms</tt>
- <dd>Place constants for non-terminals into the symbol constant class.
- The parser does not need these symbol constants, so they are not normally
- output. However, it can be very helpful to refer to these constants
- when debugging a generated parser.
-
- <dt><tt>-expect</tt> <i>number</i>
- <dd>During parser construction the system may detect that an ambiguous
- situation would occur at runtime. This is called a <i>conflict</i>.
- In general, the parser may be unable to decide whether to <i>shift</i>
- (read another symbol) or <i>reduce</i> (replace the recognized right
- hand side of a production with its left hand side). This is called a
- <i>shift/reduce conflict</i>. Similarly, the parser may not be able
- to decide between reduction with two different productions. This is
- called a <i>reduce/reduce conflict</i>. Normally, if one or more of
- these conflicts occur, parser generation is aborted. However, in
- certain carefully considered cases it may be advantageous to
- arbitrarily break such a conflict. In this case CUP uses YACC
- convention and resolves shift/reduce conflicts by shifting, and
- reduce/reduce conflicts using the "highest priority" production (the
- one declared first in the specification). In order to enable automatic
- breaking of conflicts the <tt>-expect</tt> option must be given
- indicating exactly how many conflicts are expected. Conflicts
- resolved by precedences and associativities are not reported.
-
- <dt><tt>-compact_red</tt>
- <dd>Including this option enables a table compaction optimization involving
- reductions. In particular, it allows the most common reduce entry in
- each row of the parse action table to be used as the default for that
- row. This typically saves considerable room in the tables, which can
- grow to be very large. This optimization has the effect of replacing
- all error entries in a row with the default reduce entry. While this
- may sound dangerous, if not down right incorrect, it turns out that this
- does not affect the correctness of the parser. In particular, some
- changes of this type are inherent in LALR parsers (when compared to
- canonical LR parsers), and the resulting parsers will still never
- read past the first token at which the error could be detected.
- The parser can, however, make extra erroneous reduces before detecting
- the error, so this can degrade the parser's ability to do
- <a href="#errors">error recovery</a>.
- (Refer to reference [2] pp. 244-247 or reference [3] pp. 190-194 for a
- complete explanation of this compaction technique.) <br><br>
-
- This option is typically used to work-around the java bytecode
- limitations on table initialization code sizes. However, CUP
- 0.10h introduced a string-encoding for the parser tables which
- is not subject to the standard method-size limitations.
- Consequently, use of this option should no longer be required
- for large grammars.
-
- <dt><tt>-nowarn</tt>
- <dd>This options causes all warning messages (as opposed to error messages)
- produced by the system to be suppressed.
-
- <dt><tt>-nosummary</tt>
- <dd>Normally, the system prints a summary listing such things as the
- number of terminals, non-terminals, parse states, etc. at the end of
- its run. This option suppresses that summary.
-
- <dt><tt>-progress</tt>
- <dd>This option causes the system to print short messages indicating its
- progress through various parts of the parser generation process.
-
- <dt><tt>-dump_grammar</tt>
- <dt><tt>-dump_states</tt>
- <dt><tt>-dump_tables</tt>
- <dt><tt>-dump</tt>
- <dd> These options cause the system to produce a human readable dump of
- the grammar, the constructed parse states (often needed to resolve
- parse conflicts), and the parse tables (rarely needed), respectively.
- The <tt>-dump</tt> option can be used to produce all of these dumps.
-
- <dt><tt>-time</tt>
- <dd>This option adds detailed timing statistics to the normal summary of
- results. This is normally of great interest only to maintainers of
- the system itself.
-
- <dt><tt>-debug</tt>
- <dd>This option produces voluminous internal debugging information about
- the system as it runs. This is normally of interest only to maintainers
- of the system itself.
-
- <dt><tt>-nopositions</tt>
- <dd>This option keeps CUP from generating code to propagate the left
- and right hand values of terminals to non-terminals, and then from
- non-terminals to other terminals. If the left and right values aren't
- going to be used by the parser, then it will save some runtime
- computation to not generate these position propagations. This option
- also keeps the left and right label variables from being generated, so
- any reference to these will cause an error.
-
- <dt><tt>-noscanner</tt>
- <dd>CUP 0.10j introduced <a href="#scanner">improved scanner
- integration</a> and a new interface,
- <code>java_cup.runtime.Scanner</code>. By default, the
- generated parser refers to this interface, which means you cannot
- use these parsers with CUP runtimes older than 0.10j. If your
- parser does not use the new scanner integration features, then you
- may specify the <code>-noscanner</code> option to suppress the
- <code>java_cup.runtime.Scanner</code> references and allow
- compatibility with old runtimes. Not many people should have reason
- to do this.
-
- <dt><tt>-version</tt>
- <dd>Invoking CUP with the <code>-version</code> flag will cause it
- to print out the working version of CUP and halt. This allows
- automated CUP version checking for Makefiles, install scripts and
- other applications which may require it.
-</dl>
-
-<a name="parser">
-<h3>4. Customizing the Parser</h3></a>
-
-Each generated parser consists of three generated classes. The
-<tt>sym</tt> class (which can be renamed using the <tt>-symbols</tt>
-option) simply contains a series of <tt>int</tt> constants,
-one for each terminal. Non-terminals are also included if the <tt>-nonterms</tt>
-option is given. The source file for the <tt>parser</tt> class (which can
-be renamed using the <tt>-parser</tt> option) actually contains two
-class definitions, the public <tt>parser</tt> class that implements the
-actual parser, and another non-public class (called <tt>CUP$action</tt>) which
-encapsulates all user actions contained in the grammar, as well as code from
-the <tt>action code</tt> declaration. In addition to user supplied code, this
-class contains one method: <tt>CUP$do_action</tt> which consists of a large
-switch statement for selecting and executing various fragments of user
-supplied action code. In general, all names beginning with the prefix of
-<tt>CUP$</tt> are reserved for internal uses by CUP generated code. <p>
-
-The <tt>parser</tt> class contains the actual generated parser. It is
-a subclass of <tt>java_cup.runtime.lr_parser</tt> which implements a
-general table driven framework for an LR parser. The generated <tt>parser</tt>
-class provides a series of tables for use by the general framework.
-Three tables are provided:
-<dl compact>
-<dt>the production table
-<dd>provides the symbol number of the left hand side non-terminal, along with
- the length of the right hand side, for each production in the grammar,
-<dt>the action table
-<dd>indicates what action (shift, reduce, or error) is to be taken on each
- lookahead symbol when encountered in each state, and
-<dt>the reduce-goto table
-<dd>indicates which state to shift to after reduces (under each non-terminal
-from each state).
-</dl>
-(Note that the action and reduce-goto tables are not stored as simple arrays,
-but use a compacted "list" structure to save a significant amount of space.
-See comments the runtime system source code for details.)<p>
-
-Beyond the parse tables, generated (or inherited) code provides a series
-of methods that can be used to customize the generated parser. Some of these
-methods are supplied by code found in part of the specification and can
-be customized directly in that fashion. The others are provided by the
-<tt>lr_parser</tt> base class and can be overridden with new versions (via
-the <tt>parser code</tt> declaration) to customize the system. Methods
-available for customization include:
-<dl compact>
-<dt><tt>public void user_init()</tt>
-<dd>This method is called by the parser prior to asking for the first token
- from the scanner. The body of this method contains the code from the
- <tt>init with</tt> clause of the the specification.
-<dt><a name="scan_method"><tt>public java_cup.runtime.Symbol scan()</tt></a>
-<dd>This method encapsulates the scanner and is called each time a new
- terminal is needed by the parser. The body of this method is
- supplied by the <tt>scan with</tt> clause of the specification, if
- present; otherwise it returns <code>getScanner().next_token()</code>.
-<dt><tt>public java_cup.runtime.Scanner getScanner()</tt>
-<dd>Returns the default scanner. See <a href="#scanner">section 5</a>.
-<dt><tt>public void setScanner(java_cup.runtime.Scanner s)</tt>
-<dd>Sets the default scanner. See <a href="#scanner">section 5</a>.
-<dt><tt> public void report_error(String message, Object info)</tt>
-<dd>This method should be called whenever an error message is to be issued. In
- the default implementation of this method, the first parameter provides
- the text of a message which is printed on <tt>System.err</tt>
- and the second parameter is simply ignored. It is very typical to
- override this method in order to provide a more sophisticated error
- reporting mechanism.
-<dt><tt>public void report_fatal_error(String message, Object info)</tt>
-<dd>This method should be called whenever a non-recoverable error occurs. It
- responds by calling <tt>report_error()</tt>, then aborts parsing
- by calling the parser method <tt>done_parsing()</tt>, and finally
- throws an exception. (In general <tt>done_parsing()</tt> should be called
- at any point that parsing needs to be terminated early).
-<dt><tt>public void syntax_error(Symbol cur_token)</tt>
-<dd>This method is called by the parser as soon as a syntax error is detected
- (but before error recovery is attempted). In the default implementation it
- calls: <tt>report_error("Syntax error", null);</tt>.
-<dt><tt>public void unrecovered_syntax_error(Symbol cur_token)</tt>
-<dd>This method is called by the parser if it is unable to recover from a
- syntax error. In the default implementation it calls:
- <tt>report_fatal_error("Couldn't repair and continue parse", null);</tt>.
-<dt><tt> protected int error_sync_size()</tt>
-<dd>This method is called by the parser to determine how many tokens it must
- successfully parse in order to consider an error recovery successful.
- The default implementation returns 3. Values below 2 are not recommended.
- See the section on <a href="#errors">error recovery</a> for details.
-</dl>
-
-Parsing itself is performed by the method <tt>public Symbol parse()</tt>.
-This method starts by getting references to each of the parse tables,
-then initializes a <tt>CUP$action</tt> object (by calling
-<tt>protected void init_actions()</tt>). Next it calls <tt>user_init()</tt>,
-then fetches the first lookahead token with a call to <tt>scan()</tt>.
-Finally, it begins parsing. Parsing continues until <tt>done_parsing()</tt>
-is called (this is done automatically, for example, when the parser
-accepts). It then returns a <tt>Symbol</tt> with the <tt>value</tt>
-instance variable containing the RESULT of the start production, or
-<tt>null</tt>, if there is no value.<p>
-
-In addition to the normal parser, the runtime system also provides a debugging
-version of the parser. This operates in exactly the same way as the normal
-parser, but prints debugging messages (by calling
-<tt>public void debug_message(String mess)</tt> whose default implementation
-prints a message to <tt>System.err</tt>).<p>
-
-Based on these routines, invocation of a CUP parser is typically done
-with code such as:
-<pre>
- /* create a parsing object */
- parser parser_obj = new parser();
-
- /* open input files, etc. here */
- Symbol parse_tree = null;
-
- try {
- if (do_debug_parse)
- parse_tree = parser_obj.debug_parse();
- else
- parse_tree = parser_obj.parse();
- } catch (Exception e) {
- /* do cleanup here - - possibly rethrow e */
- } finally {
- /* do close out here */
- }
-</pre>
-
-<a name="scanner">
-<h3>5. Scanner Interface</h3></a>
-
-In CUP 0.10j scanner integration was improved according to
-suggestions made by <a href="http://www.smartsc.com">David MacMahon</a>.
-The changes make it easier to incorporate JLex and other
-automatically-generated scanners into CUP parsers.<p>
-
-To use the new code, your scanner should implement the
-<code>java_cup.runtime.Scanner</code> interface, defined as:
-<pre>
-package java_cup.runtime;
-
-public interface Scanner {
- public Symbol next_token() throws java.lang.Exception;
-}
-</pre><p>
-
-In addition to the methods described in <a href="#parser">section
-4</a>, the <code>java_cup.runtime.lr_parser</code> class has two new
-accessor methods, <code>setScanner()</code> and <code>getScanner()</code>.
-The default implementation of <a href="#scan_method"><code>scan()</code></a>
-is:
-<pre>
- public Symbol scan() throws java.lang.Exception {
- Symbol sym = getScanner().next_token();
- return (sym!=null) ? sym : new Symbol(EOF_sym());
- }
-</pre><p>
-The generated parser also contains a constructor which takes a
-<code>Scanner</code> and calls <code>setScanner()</code> with it. In
-most cases, then, the <code>init with</code> and <code>scan
-with</code> directives may be omitted. You can simply create the
-parser with a reference to the desired scanner:
-<pre>
- /* create a parsing object */
- parser parser_obj = new parser(new my_scanner());
-</pre>
-or set the scanner after the parser is created:
-<pre>
- /* create a parsing object */
- parser parser_obj = new parser();
- /* set the default scanner */
- parser_obj.setScanner(new my_scanner());
-</pre><p>
-Note that because the parser uses look-ahead, resetting the scanner in
-the middle of a parse is not recommended. If you attempt to use the
-default implementation of <code>scan()</code> without first calling
-<code>setScanner()</code>, a <code>NullPointerException</code> will be
-thrown.<p>
-As an example of scanner integration, the following three lines in the
-lexer-generator input are all that is required to use a
-<a href="http://www.cs.princeton.edu/~appel/modern/java/JLex/">JLex</a>
-or <a href="http://www.jflex.de/">JFlex</A>
-scanner with CUP:
-<pre>
-%implements java_cup.runtime.Scanner
-%function next_token
-%type java_cup.runtime.Symbol
-</pre>
-The JLex directive <code>%cup</code>
-abbreviates the above three directive in JLex versions 1.2.5 and above.
-Invoking the parser with the JLex scanner is then simply:
-<pre>
-parser parser_obj = new parser( new Yylex( some_InputStream_or_Reader));
-</pre><p>
-
-Note CUP handles the JLex/JFlex convention of returning null on EOF
-without a problem, so an <code>%eofval</code> directive is not
-required in the JLex specification (this feature was added in CUP 0.10k).
-
-The simple_calc example in the CUP distribution illustrates the use of
-the scanner integration features with a hand-coded scanner.
-The CUP website has a minimal CUP/JLex integration example for study.<p>
-
-<a name="errors">
-<h3>6. Error Recovery</h3></a>
-
-A final important aspect of building parsers with CUP is
-support for syntactic error recovery. CUP uses the same
-error recovery mechanisms as YACC. In particular, it supports
-a special error symbol (denoted simply as <tt>error</tt>).
-This symbol plays the role of a special non-terminal which, instead of
-being defined by productions, instead matches an erroneous input
-sequence.<p>
-
-The error symbol only comes into play if a syntax error is
-detected. If a syntax error is detected then the parser tries to replace
-some portion of the input token stream with <tt>error</tt> and then
-continue parsing. For example, we might have productions such as:
-
-<pre><tt> stmt ::= expr SEMI | while_stmt SEMI | if_stmt SEMI | ... |
- error SEMI
- ;</tt></pre>
-
-This indicates that if none of the normal productions for <tt>stmt</tt> can
-be matched by the input, then a syntax error should be declared, and recovery
-should be made by skipping erroneous tokens (equivalent to matching and
-replacing them with <tt>error</tt>) up to a point at which the parse can
-be continued with a semicolon (and additional context that legally follows a
-statement). An error is considered to be recovered from if and only if a
-sufficient number of tokens past the <tt>error</tt> symbol can be successfully
-parsed. (The number of tokens required is determined by the
-<tt>error_sync_size()</tt> method of the parser and defaults to 3). <p>
-
-Specifically, the parser first looks for the closest state to the top
-of the parse stack that has an outgoing transition under
-<tt>error</tt>. This generally corresponds to working from
-productions that represent more detailed constructs (such as a specific
-kind of statement) up to productions that represent more general or
-enclosing constructs (such as the general production for all
-statements or a production representing a whole section of declarations)
-until we get to a place where an error recovery production
-has been provided for. Once the parser is placed into a configuration
-that has an immediate error recovery (by popping the stack to the first
-such state), the parser begins skipping tokens to find a point at
-which the parse can be continued. After discarding each token, the
-parser attempts to parse ahead in the input (without executing any
-embedded semantic actions). If the parser can successfully parse past
-the required number of tokens, then the input is backed up to the point
-of recovery and the parse is resumed normally (executing all actions).
-If the parse cannot be continued far enough, then another token is
-discarded and the parser again tries to parse ahead. If the end of
-input is reached without making a successful recovery (or there was no
-suitable error recovery state found on the parse stack to begin with)
-then error recovery fails.
-
-<a name="conclusion">
-<h3>7. Conclusion</h3></a>
-
-This manual has briefly described the CUP LALR parser generation system.
-CUP is designed to fill the same role as the well known YACC parser
-generator system, but is written in and operates entirely with Java code
-rather than C or C++. Additional details on the operation of the system can
-be found in the parser generator and runtime source code. See the CUP
-home page below for access to the API documentation for the system and its
-runtime.<p>
-
-This document covers version 0.10j of the system. Check the CUP home
-page:
-<a href="http://www.cs.princeton.edu/~appel/modern/java/CUP/">
-http://www.cs.princeton.edu/~appel/modern/java/CUP/</a>
-for the latest release information, instructions for downloading the
-system, and additional news about CUP. Bug reports and other
-comments for the developers should be sent to the CUP maintainer,
-C. Scott Ananian, at
-<a href="mailto:cananian@alumni.princeton.edu">
-cananian@alumni.princeton.edu</a><p>
-
-CUP was originally written by
-<a href="http://www.cs.cmu.edu/~hudson/">
-Scott Hudson</a>, in August of 1995.<p>
-
-It was extended to support precedence by
-<a href="http://www.princeton.edu/~frankf">
-Frank Flannery</a>, in July of 1996.<p>
-
-On-going improvements have been done by
-<A HREF="http://www.pdos.lcs.mit.edu/~cananian">
-C. Scott Ananian</A>, the CUP maintainer, from December of 1997 to the
-present.<p>
-
-<a name="refs">
-<h3>References</h3></a>
-<dl compact>
-
-<dt><a name = "YACCref">[1]</a>
-<dd>S. C. Johnson,
-"YACC &emdash; Yet Another Compiler Compiler",
-CS Technical Report #32,
-Bell Telephone Laboratories,
-Murray Hill, NJ,
-1975.
-
-<dt><a name = "dragonbook">[2]</a>
-<dd>A. Aho, R. Sethi, and J. Ullman,
-<i>Compilers: Principles, Techniques, and Tools</i>,
-Addison-Wesley Publishing,
-Reading, MA,
-1986.
-
-<dt><a name = "crafting">[3]</a>
-<dd>C. Fischer, and R. LeBlanc,
-<i>Crafting a Compiler with C</i>,
-Benjamin/Cummings Publishing,
-Redwood City, CA,
-1991.
-
-<dt><a name = "modernjava">[4]</a>
-<dd>Andrew W. Appel,
-<i>Modern Compiler Implementation in Java</i>,
-Cambridge University Press,
-New York, NY,
-1998.
-
-</dl>
-
-<h3><a name="appendixa">
-Appendix A. Grammar for CUP Specification Files</a> (0.10j)</h3>
-<hr><br>
-<pre><tt>java_cup_spec ::= package_spec import_list code_parts
- symbol_list precedence_list start_spec
- production_list
-package_spec ::= PACKAGE multipart_id SEMI | empty
-import_list ::= import_list import_spec | empty
-import_spec ::= IMPORT import_id SEMI
-code_part ::= action_code_part | parser_code_part |
- init_code | scan_code
-code_parts ::= code_parts code_part | empty
-action_code_part ::= ACTION CODE CODE_STRING opt_semi
-parser_code_part ::= PARSER CODE CODE_STRING opt_semi
-init_code ::= INIT WITH CODE_STRING opt_semi
-scan_code ::= SCAN WITH CODE_STRING opt_semi
-symbol_list ::= symbol_list symbol | symbol
-symbol ::= TERMINAL type_id declares_term |
- NON TERMINAL type_id declares_non_term |
- NONTERMINAL type_id declares_non_term |
- TERMINAL declares_term |
- NON TERMINAL declares_non_term |
- NONTERMIANL declared_non_term
-term_name_list ::= term_name_list COMMA new_term_id | new_term_id
-non_term_name_list ::= non_term_name_list COMMA new_non_term_id |
- new_non_term_id
-declares_term ::= term_name_list SEMI
-declares_non_term ::= non_term_name_list SEMI
-precedence_list ::= precedence_l | empty
-precedence_l ::= precedence_l preced + preced;
-preced ::= PRECEDENCE LEFT terminal_list SEMI
- | PRECEDENCE RIGHT terminal_list SEMI
- | PRECEDENCE NONASSOC terminal_list SEMI
-terminal_list ::= terminal_list COMMA terminal_id | terminal_id
-start_spec ::= START WITH nt_id SEMI | empty
-production_list ::= production_list production | production
-production ::= nt_id COLON_COLON_EQUALS rhs_list SEMI
-rhs_list ::= rhs_list BAR rhs | rhs
-rhs ::= prod_part_list PERCENT_PREC term_id |
- prod_part_list
-prod_part_list ::= prod_part_list prod_part | empty
-prod_part ::= symbol_id opt_label | CODE_STRING
-opt_label ::= COLON label_id | empty
-multipart_id ::= multipart_id DOT ID | ID
-import_id ::= multipart_id DOT STAR | multipart_id
-type_id ::= multipart_id
-terminal_id ::= term_id
-term_id ::= symbol_id
-new_term_id ::= ID
-new_non_term_id ::= ID
-nt_id ::= ID
-symbol_id ::= ID
-label_id ::= ID
-opt_semi ::= SEMI | empty
-
-</tt></pre>
-<hr><p><p>
-
-<h3><a name = "appendixb">Appendix B. A Very Simple Example Scanner<a></h3>
-<hr><br>
-<pre>
-<tt>// Simple Example Scanner Class
-
-import java_cup.runtime.*;
-import sym;
-
-public class scanner {
- /* single lookahead character */
- protected static int next_char;
-
- /* advance input by one character */
- protected static void advance()
- throws java.io.IOException
- { next_char = System.in.read(); }
-
- /* initialize the scanner */
- public static void init()
- throws java.io.IOException
- { advance(); }
-
- /* recognize and return the next complete token */
- public static Symbol next_token()
- throws java.io.IOException
- {
- for (;;)
- switch (next_char)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- /* parse a decimal integer */
- int i_val = 0;
- do {
- i_val = i_val * 10 + (next_char - '0');
- advance();
- } while (next_char >= '0' && next_char <= '9');
- return new Symbol(sym.NUMBER, new Integer(i_val));
-
- case ';': advance(); return new Symbol(sym.SEMI);
- case '+': advance(); return new Symbol(sym.PLUS);
- case '-': advance(); return new Symbol(sym.MINUS);
- case '*': advance(); return new Symbol(sym.TIMES);
- case '/': advance(); return new Symbol(sym.DIVIDE);
- case '%': advance(); return new Symbol(sym.MOD);
- case '(': advance(); return new Symbol(sym.LPAREN);
- case ')': advance(); return new Symbol(sym.RPAREN);
-
- case -1: return new Symbol(sym.EOF);
-
- default:
- /* in this simple scanner we just ignore everything else */
- advance();
- break;
- }
- }
-};
-</tt></pre>
-
-
-<a name=changes>
-<h3>Appendix C: Incompatibilites between CUP 0.9 and CUP 0.10</a></h3>
-
-CUP version 0.10a is a major overhaul of CUP. The changes are severe,
-meaning no backwards compatibility to older versions.
-
-The changes consist of:
-<ul>
-<li> <a href="#lex_inter">A different lexical interface</a>,
-<li> <a href="#new_dec">New terminal/non-terminal declarations</a>,
-<li> <a href="#label_ref">Different label references</a>,
-<li> <a href="#RESULT_pass">A different way of passing RESULT</a>,
-<li> <a href="#pos_prop">New position values and propagation</a>,
-<li> <a href="#ret_val">Parser now returns a value</a>,
-<li> <a href="#prec_add">Terminal precedence declarations</a> and
-<li> <a href="#con_prec">Rule contextual precedence assignment</a>
-</ul>
-
-<h5><a name="lex_inter">Lexical Interface</a></h5>
-
-CUP now interfaces with the lexer in a completely different
-manner. In the previous releases, a new class was used for every
-distinct type of terminal. This release, however, uses only one class:
-The <tt>Symbol</tt> class. The <tt>Symbol</tt> class has three instance
-variables which
-are significant to the parser when passing information from the lexer.
-The first is the <tt>value</tt> instance variable. This variable
-contains the
-value of that terminal. It is of the type declared as the terminal type
-in the parser specification file. The second two are the instance
-variables <tt>left</tt> and <tt>right</tt>. They should be filled with
-the <tt>int</tt> value of
-where in the input file, character-wise, that terminal was found.<p>
-
-For more information, refer to the manual on <a href="#lex_part">scanners</a>.
-
-<h5><a name="new_dec">Terminal/Non-Terminal Declarations</a></h5>
-
-Terminal and non-terminal declarations now can be declared in two
-different ways to indicate the values of the terminals or
-non-terminals. The previous declarations of the form
-
-<pre><tt>
-terminal <i>classname terminal</i> [, <i>terminal ...</i>];
-</tt></pre>
-
-still works. The classname, however indicates the type of the value of
-the terminal or non-terminal, and does not indicate the type of object
-placed on the parse stack.
-
-A declaration, such as:
-
-<pre><tt>
-terminal <i>terminal</i> [, <i>terminal ...</i>];
-</tt></pre>
-
-indicates the terminals in the list hold no value.<p>
-
-For more information, refer to the manual on <a
-href="#symbol_list">declarations</a>.
-
-<h5><a name="label_ref">Label References</a></h5>
-
-Label references do not refer to the object on the parse stack, as in
-the old CUP, but rather to the value of the <tt>value</tt>
-instance variable of
-the <tt>Symbol</tt> that represents that terminal or non-terminal. Hence,
-references to terminal and non-terminal values is direct, as opposed to
-the old CUP, where the labels referred to objects containing the value
-of the terminal or non-terminal.<p>
-
-For more information, refer to the manual on <a href="#label_part">labels</a>.
-
-<h5><a name="RESULT_pass">RESULT Value</a></h5>
-
-The <tt>RESULT</tt> variable refers directly to the value of the
-non-terminal
-to which a rule reduces, rather than to the object on the parse stack.
-Hence, <tt>RESULT</tt> is of the same type the non-terminal to which
-it reduces,
-as declared in the non-terminal declaration. Again, the reference is
-direct, rather than to something that will contain the data.<p>
-
-For more information, refer to the manual on <a href="#RES_part">RESULT</a>.
-
-<h5><a name="pos_prop">Position Propagation</a></h5>
-
-For every label, two more variables are declared, which are the label
-plus <tt>left</tt> or the label plus <tt>right</tt>. These correspond
-to the left and
-right locations in the input stream to which that terminal or
-non-terminal came from. These values are propagated from the input
-terminals, so that the starting non-terminal should have a left value of
-0 and a right value of the location of the last character read.<p>
-
-For more information, refer to the manual on <a href="#label_part">positions</a>.
-
-<h5><a name="ret_val">Return Value</a></h5>
-
-A call to <tt>parse()</tt> or <tt>debug_parse()</tt> returns a
-Symbol. This Symbol is the start non-terminal, so the <tt>value</tt>
-instance variable contains the final <tt>RESULT</tt> assignment.
-
-<h5><a name="prec_add">Precedence</a></h5>
-
-CUP now has precedenced terminals. a new declaration section,
-occurring between the terminal and non-terminal declarations and the
-grammar specifies the precedence and associativity of rules. The
-declarations are of the form:
-
-<pre><tt>
-precedence {left| right | nonassoc} <i>terminal</i>[, <i>terminal</i> ...];
-...
-</tt>
-</pre>
-
-The terminals are assigned a precedence, where terminals on the same
-line have equal precedences, and the precedence declarations farther
-down the list of precedence declarations have higher precedence.
-<tt>left, right</tt> and <tt>nonassoc</tt> specify the associativity
-of these terminals. left
-associativity corresponds to a reduce on conflict, right to a shift on
-conflict, and nonassoc to an error on conflict. Hence, ambiguous
-grammars may now be used.<p>
-
-For more information, refer to the manual on <a
-href="#precedence">precedence</a>.
-
-<h5><a name="con_prec">Contextual Precedence</a></h5>
-
-Finally the new CUP adds contextual precedence. A production may be
-declare as followed:
-
-<pre><tt>
-lhs ::= <i>{right hand side list of terminals, non-terminals and actions}</i>
- %prec <i>{terminal}</i>;
-</tt></pre>
-
-this production would then have a precedence equal to the terminal
-specified after the <tt>%prec</tt>. Hence, shift/reduce conflicts can be
-contextually resolved. Note that the <tt>%prec</tt> <i>terminal</i>
-part comes after all actions strings. It does not come before the
-last action string.<p>
-
-For more information, refer to the manual on <a href="#cpp">contextual
-precedence</a>.
-
-These changes implemented by:
-<h3>
-<a href="http://www.princeton.edu/~frankf">Frank Flannery</a><br>
-<a href="http://www.cs.princeton.edu">Department of Computer Science</a><br>
-<a href="http://www.princeton.edu">Princeton University</a><br>
-</h3>
-<a name=bugs>
-<h3>Appendix D: Bugs</a></h3>
-In this version of CUP it's difficult for the semantic action phrases (Java code attached
-to productions) to access the <tt>report_error</tt> method and other similar methods and
-objects defined in the <tt>parser code</tt> directive.
-<p>
-This is because the parsing tables (and parsing engine) are in one object (belonging to
-class <tt>parser</tt> or whatever name is specified by the <strong>-parser</strong> directive),
-and the semantic actions are in another object (of class <tt>CUP$actions</tt>).
-<p>
-However, there is a way to do it, though it's a bit inelegant.
-The action object has a <tt>private final</tt> field named
-<tt>parser</tt> that points to the parsing object. Thus,
-methods and instance variables of the parser can be accessed within semantic actions as:
-<pre>
- parser.report_error(message,info);
- x = parser.mydata;
-</pre>
-<p>
-Perhaps this will not be necessary in a future release, and that
-such methods and variables as <tt>report_error</tt> and
-<tt>mydata</tt> will be available
-directly from the semantic actions; we will achieve this by combining the
-"parser" object and the "actions" object together.
-
-<p>
-For a list of any other currently known bugs in CUP, see
-<A HREF="http://www.cs.princeton.edu/~appel/modern/java/CUP/bugs.html">
-http://www.cs.princeton.edu/~appel/modern/java/CUP/bugs.html</A>.
-
-<a name=version>
-<h3>Appendix E: Change log</a></h3>
-
-<dl>
-<dt>0.9e<dd>March 1996, Scott Hudson's original version.
-<dt>0.10a<dd>August 1996, <a href="#about">several major changes</a> to
-the interface.
-<dt>0.10b<dd>November 1996, fixes a few minor bugs.
-<dt>0.10c<dd>July 1997, fixes a bug related to precedence declarations.
-<dt>0.10e<dd>September 1997, fixes a bug introduced in 0.10c relating
-to <tt>nonassoc</tt> precedence. Thanks to
-<a href="http://www.cs.purdue.edu/homes/hosking">Tony Hosking</a>
-for reporting the bug and providing the fix.
-Also recognizes carriage-return character as white space and fixes a
-number of other small bugs.
-<dt>0.10f<dd>December 1997, was a maintenance release. The CUP source
-was cleaned up for JDK 1.1.
-<dt>0.10g<dd>March 1998, adds new features and fixes old bugs.
-The behavior of RESULT assignments was normalized, and a problem
-with implicit start productions was fixed. The CUP grammar was
-extended to allow array types for terminals and non-terminals, and
-a command-line flag was added to allow the generation of a symbol
-<i>interface</i>, rather than class. Bugs associated with multiple
-invocations of a single parser object and multiple CUP classes in one
-package have been stomped on. Documentation was updated, as well.
-<dt>0.10h-0.10i<dd>February 1999, are maintenance releases.
-<dt>0.10j<dd>July 1999, broadened the CUP input grammar to allow more
-flexibility and improved scanner integration via the
-<code>java_cup.runtime.Scanner</code> interface.
-</dl>
-
-
-<hr>
-
-<a name="trademark">
-Java and HotJava are
-trademarks of <a href="http://www.sun.com/">Sun Microsystems, Inc.</a>,
-and refer to Sun's Java programming language and HotJava browser
-technologies.
-CUP is not sponsored by or affiliated with Sun Microsystems, Inc.
-
-<hr>
-
-
-</body></html>
+++ /dev/null
-From toddk@MICROSOFT.com Tue Mar 24 22:07:19 1998
-Date: Fri, 30 Jan 1998 07:54:26 -0800
-From: Todd Knoblock <toddk@MICROSOFT.com>
-To: "'cananian@alumni.princeton.edu'" <cananian@alumni.Princeton.EDU>
-Subject: Java cup under Windows NT.
-
-I wanted to try java cup under Windows NT. Rather than transliterating the
-csh shell script, I put together a little makefile for it. I thought you
-might want to include it in the distribution so that it is available for the
-next person that wants to use java cup under Windows NT.
-
-Todd Knoblock
-
-To use, place this file in the root javacup directory (where the "java_cup"
-directory lives), and type "nmake" from that directory.
-
-[The makefile has been included in this directory. -- CSA 24-Mar-1998 ]
+++ /dev/null
-#\r
-# Windows NT makefile for java_cup\r
-# by Todd Knoblock, 28 January 1998.\r
-#\r
-# To run, type "nmake all" from the directory containing the make file.\r
-# Tested under nmake version 1.62.7022\r
-\r
-JVC=jvc\r
-# -x means disable extensions\r
-# -g means include debug information\r
-# -w2 means warning level 2.\r
-# Unfornately, anything above warning level 2 is noisy\r
-JVCFLAGS= -x -g -w2\r
-JVIEW=jview\r
-\r
-.SUFFIXES: .java .class\r
-\r
-.java.class:\r
- $(JVC) $(JVCFLAGS) $<\r
- \r
-all: runtime simple_calc java_cup test\r
-\r
-java_cup: java_cup\*.class\r
-\r
-runtime: java_cup\runtime\*.class\r
-\r
-simple_calc: java_cup\simple_calc\sym.java \\r
- java_cup\simple_calc\parser.java \\r
- java_cup\simple_calc\*.class\r
-\r
-\r
-java_cup\simple_calc\sym.java: java_cup java_cup\simple_calc\parser.cup \r
- $(JVIEW) java_cup.Main < java_cup\simple_calc\parser.cup\r
- @del -f -q java_cup\simple_calc\sym.java >nul 2>nul \r
- @del -f -q java_cup\simple_calc\parser.java >nul 2>nul \r
- move sym.java java_cup\simple_calc\ \r
- move parser.java java_cup\simple_calc\ \r
-\r
-java_cup\simple_calc\parser.java: java_cup\simple_calc\sym.java\r
-\r
-clean:\r
- @del -f -q java_cup\simple_calc\sym.java >nul 2>nul \r
- @del -f -q java_cup\simple_calc\parser.java >nul 2>nul \r
- @for %d in (java_cup java_cup\runtime java_cup\simple_calc) do \\r
- @pushd %d \\r
- & del -f -q *.class >nul 2>nul \\r
- & popd\r
-\r
-test: simple_calc\r
- @echo Executing the demo program. Answer should be 5050.\r
- echo 101*100/2; | $(JVIEW) java_cup.simple_calc.Main\r
+++ /dev/null
-Input:
-trigger role specification for tasks:
-role mutator operation:
-role definition:
-
-Generate:
-Role transition diagram
-
-
-Initial features:
-methods
-structs
-type system
-
-Language features:
-Single Inheritance
-Virtual methods
-Objects
-
-object metastate:
-1. flags: flag role1
-2. tags: tag tag1
-
-tag operations:
-tag tag1=new tag;
-tag tag2=incrementtag(tag tag1);
-tag tag3=no tag;
-
-metastate operations:
-
-task foo(type1 o1{role1||role2}, type2 o2{role3}) {
-
- exit(o1{role1'=false},o2{role3'=false},onew{role4=true});
-}
\ No newline at end of file
+++ /dev/null
-package Analysis.CallGraph;
-import IR.State;
-import IR.Flat.FlatMethod;
-import IR.Flat.FlatNode;
-import IR.Flat.FlatCall;
-import IR.Flat.FKind;
-import java.util.*;
-import IR.ClassDescriptor;
-import IR.MethodDescriptor;
-import IR.TypeDescriptor;
-
-public class CallGraph {
- State state;
- Hashtable methods;
- Hashtable methodmap;
-
- public CallGraph(State state) {
- this.state=state;
- methods=new Hashtable();
- methodmap=new Hashtable();
- buildMethodTable();
- buildGraph();
- }
-
- private void buildMethodTable() {
- //Iterator through classes
- Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
- while(it.hasNext()) {
- ClassDescriptor cn=(ClassDescriptor)it.next();
- Iterator methodit=cn.getMethods();
- //Iterator through methods
- while(methodit.hasNext()) {
- MethodDescriptor md=(MethodDescriptor)methodit.next();
- if (md.isStatic()||md.getReturnType()==null)
- continue;
- ClassDescriptor superdesc=cn.getSuperDesc();
- if (superdesc!=null) {
- Set possiblematches=superdesc.getMethodTable().getSet(md.getSymbol());
- boolean foundmatch=false;
- for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
- MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
- if (md.matches(matchmd)) {
- if (!methods.containsKey(matchmd))
- methods.put(matchmd,new HashSet());
- ((HashSet)methods.get(matchmd)).add(md);
- break;
- }
- }
- }
- }
- }
- }
-
-
- public Set getMethods(MethodDescriptor md, TypeDescriptor type) {
- return getMethods(md);
- }
-
- /** Given a call to MethodDescriptor, lists the methods which
- could actually be called due to virtual dispatch. */
- public Set getMethods(MethodDescriptor md) {
- HashSet ns=new HashSet();
- ns.add(md);
- Set s=(Set)methods.get(md);
- if (s!=null)
- for(Iterator it=s.iterator();it.hasNext();) {
- MethodDescriptor md2=(MethodDescriptor)it.next();
- ns.addAll(getMethods(md2));
- }
- return ns;
- }
-
- /** Given a call to MethodDescriptor, lists the methods which
- could actually be call by that method. */
- public Set getMethodCalls(MethodDescriptor md) {
- HashSet ns=new HashSet();
- ns.add(md);
- Set s=(Set)methodmap.get(md);
- if (s!=null)
- for(Iterator it=s.iterator();it.hasNext();) {
- MethodDescriptor md2=(MethodDescriptor)it.next();
- ns.addAll(getMethodCalls(md2));
- }
- return ns;
- }
-
- private void buildGraph() {
- Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
- while(it.hasNext()) {
- ClassDescriptor cn=(ClassDescriptor)it.next();
- Iterator methodit=cn.getMethods();
- //Iterator through methods
- while(methodit.hasNext()) {
- MethodDescriptor md=(MethodDescriptor)methodit.next();
- analyzeMethod(md);
- }
- }
- }
-
- private void analyzeMethod(MethodDescriptor md) {
- FlatMethod fm=state.getMethodFlat(md);
- HashSet toexplore=new HashSet();
- toexplore.add(fm);
- HashSet explored=new HashSet();
- //look at all the nodes in the flat representation
- while(!toexplore.isEmpty()) {
- FlatNode fn=(FlatNode)(toexplore.iterator()).next();
- toexplore.remove(fn);
- explored.add(fn);
- for(int i=0;i<fn.numNext();i++) {
- FlatNode fnnext=fn.getNext(i);
- if (!explored.contains(fnnext))
- toexplore.add(fnnext);
- }
- if (fn.kind()==FKind.FlatCall) {
- FlatCall fc=(FlatCall)fn;
- MethodDescriptor calledmethod=fc.getMethod();
- Set methodsthatcouldbecalled=fc.getThis()==null?getMethods(calledmethod):
- getMethods(calledmethod, fc.getThis().getType());
- if (!methodmap.containsKey(md))
- methodmap.put(md,new HashSet());
- ((HashSet)methodmap.get(md)).addAll(methodsthatcouldbecalled);
- }
- }
- }
-}
+++ /dev/null
-package Analysis.Locality;
-import IR.State;
-import IR.Flat.*;
-import java.util.*;
-import IR.MethodDescriptor;
-
-
-public class GenerateConversions {
- LocalityAnalysis locality;
- State state;
-
- /** Warning: This class modifies the code in place. */
-
- public GenerateConversions(LocalityAnalysis la, State state) {
- locality=la;
- this.state=state;
- doConversion();
- }
-
- private void doConversion() {
- Set<LocalityBinding> bindings=locality.getLocalityBindings();
- Iterator<LocalityBinding> bindit=bindings.iterator();
- while(bindit.hasNext()) {
- LocalityBinding lb=bindit.next();
- //Don't need to do conversion if it is already atomic
- if (lb.isAtomic())
- continue;
- converttoPtr(lb);
- converttoOid(lb);
- }
- }
-
- /* At the end of an atomic block, we need to convert any global
- * references that will be used again into OID's */
-
- private void converttoOid(LocalityBinding lb) {
- Hashtable<FlatNode, Integer> atomictab=locality.getAtomic(lb);
- Hashtable<FlatNode, Hashtable<TempDescriptor, Integer>> temptab=locality.getNodeTempInfo(lb);
- MethodDescriptor md=lb.getMethod();
- FlatMethod fm=state.getMethodFlat(md);
-
- Hashtable<FlatNode, Set<TempNodePair>> nodetotnpair=new Hashtable<FlatNode, Set<TempNodePair>>();
- Hashtable<FlatNode, Set<TempDescriptor>> nodetoconvs=new Hashtable<FlatNode, Set<TempDescriptor>>();
-
- Set<FlatNode> toprocess=fm.getNodeSet();
-
- while(!toprocess.isEmpty()) {
- FlatNode fn=toprocess.iterator().next();
- toprocess.remove(fn);
- boolean isatomic=atomictab.get(fn).intValue()>0;
- Hashtable<TempDescriptor, Integer> nodetemptab=temptab.get(fn);
-
- List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
- List<TempDescriptor> writes=Arrays.asList(fn.readsTemps());
-
- if (!isatomic&&fn.kind()==FKind.FlatAtomicExitNode
- &&!nodetoconvs.containsKey(fn))
- nodetoconvs.put(fn, new HashSet<TempDescriptor>());
-
-
- HashSet<TempNodePair> tempset=new HashSet<TempNodePair>();
- for(int i=0;i<fn.numPrev();i++) {
- FlatNode fnprev=fn.getPrev(i);
- Set<TempNodePair> prevset=nodetotnpair.get(fnprev);
- for(Iterator<TempNodePair> it=prevset.iterator();it.hasNext();) {
- TempNodePair tnp=it.next();
- if (reads.contains(tnp.getTemp())&&tnp.getNode()!=null) {
- //Value actually is read...
- nodetoconvs.get(tnp.getNode()).add(tnp.getTemp());
- }
- if (writes.contains(tnp.getTemp())) //value overwritten
- continue;
- if (!isatomic&&fn.kind()==FKind.FlatAtomicExitNode) {
- //Create new node and tag it with this exit
- if (tnp.getNode()==null) {
- TempNodePair tnp2=new TempNodePair(tnp.getTemp());
- tnp2.setNode(fn);
- tempset.add(tnp2);
- }
- } else
- tempset.add(tnp);
- }
- }
- if (isatomic) {
- //if this is in an atomic block, record temps that are written to
-
- /* NOTE: If this compiler is changed to maintain
- * OID/Ptr's in variables, then we need to use all
- * global temps that could be read and not just the
- * ones converted by globalconvnode*/
-
- if (fn.kind()!=FKind.FlatGlobalConvNode||
- ((FlatGlobalConvNode)fn).getLocality()==lb)
- //If globalconvnode, make sure we have the right locality
- for(Iterator<TempDescriptor> writeit=writes.iterator();writeit.hasNext();) {
- TempDescriptor wrtmp=writeit.next();
- if (nodetemptab.get(wrtmp)==LocalityAnalysis.GLOBAL) {
- TempNodePair tnp=new TempNodePair(wrtmp);
- tempset.add(tnp);
- }
- }
- }
- if (!nodetotnpair.containsKey(fn)||!nodetotnpair.get(fn).equals(tempset)) {
- //changes to set, so enqueue next nodes
- nodetotnpair.put(fn, tempset); //update set
- for(int i=0;i<fn.numNext();i++) {
- toprocess.add(fn.getNext(i));
- }
- }
- }
- //Place Convert to Oid nodes
- toprocess=fm.getNodeSet();
- for(Iterator<FlatNode> it=toprocess.iterator();it.hasNext();) {
- FlatNode fn=it.next();
- if (atomictab.get(fn).intValue()==0&&
- atomictab.get(fn.getPrev(0)).intValue()>0) {
- //sanity check
- assert(fn.kind()==FKind.FlatAtomicExitNode);
-
- //insert calls here...
- Set<TempDescriptor> tempset=nodetoconvs.get(fn);
- for(Iterator<TempDescriptor> tempit=tempset.iterator();tempit.hasNext();) {
- FlatGlobalConvNode fgcn=new FlatGlobalConvNode(tempit.next(), lb, false);
- atomictab.put(fgcn, atomictab.get(fn));
- temptab.put(fgcn, (Hashtable<TempDescriptor, Integer>) temptab.get(fn).clone());
- for(int i=0;i<fn.numPrev();i++) {
- FlatNode fnprev=fn.getPrev(i);
- for(int j=0;j<fnprev.numNext();j++) {
- if (fnprev.getNext(j)==fn) {
- //found index, change node
- fnprev.setNext(j, fgcn);
- break;
- }
- }
- }
- fgcn.addNext(fn);
- }
- }
- }
- }
-
- /* At the beginning of an atomic block, we need to convert any
- * OID's that will be used in the atomic block to pointers */
-
- private void converttoPtr(LocalityBinding lb) {
- Hashtable<FlatNode, Set<TempDescriptor>> nodetotranstemps=new Hashtable<FlatNode, Set<TempDescriptor>>();
- Hashtable<FlatNode, Integer> atomictab=locality.getAtomic(lb);
- Hashtable<FlatNode, Hashtable<TempDescriptor, Integer>> temptab=locality.getNodeTempInfo(lb);
- MethodDescriptor md=lb.getMethod();
- FlatMethod fm=state.getMethodFlat(md);
- Set<FlatNode> toprocess=fm.getNodeSet();
-
- while(!toprocess.isEmpty()) {
- FlatNode fn=toprocess.iterator().next();
- toprocess.remove(fn);
-
- if (atomictab.get(fn).intValue()>0) {
- //build set of transaction temps use by next nodes
- HashSet<TempDescriptor> transtemps=new HashSet<TempDescriptor>();
- for(int i=0;i<fn.numNext();i++) {
- FlatNode fnnext=fn.getNext(i);
- if (nodetotranstemps.containsKey(fnnext))
- transtemps.addAll(nodetotranstemps.get(fnnext));
- }
- //subtract out the ones we write to
- transtemps.removeAll(Arrays.asList(fn.writesTemps()));
- //add in the globals we read from
- TempDescriptor []readtemps=fn.readsTemps();
- for(int i=0;i<readtemps.length;i++) {
- TempDescriptor tmp=readtemps[i];
- if (temptab.get(fn).get(tmp).intValue()==LocalityAnalysis.GLOBAL) {
- transtemps.add(tmp);
- }
- }
- if (!nodetotranstemps.containsKey(fn)||!nodetotranstemps.get(fn).equals(transtemps)) {
- nodetotranstemps.put(fn, transtemps);
- for(int i=0;i<fn.numPrev();i++)
- toprocess.add(fn.getPrev(i));
- }
- }
- }
- toprocess=fm.getNodeSet();
- for(Iterator<FlatNode> it=toprocess.iterator();it.hasNext();) {
- FlatNode fn=it.next();
- if (atomictab.get(fn).intValue()>0&&
- atomictab.get(fn.getPrev(0)).intValue()==0) {
- //sanity check
- assert(fn.kind()==FKind.FlatAtomicEnterNode);
-
- //insert calls here...
- Set<TempDescriptor> tempset=nodetotranstemps.get(fn);
- for(Iterator<TempDescriptor> tempit=tempset.iterator();tempit.hasNext();) {
- FlatGlobalConvNode fgcn=new FlatGlobalConvNode(tempit.next(), lb, true);
- atomictab.put(fgcn, atomictab.get(fn));
- temptab.put(fgcn, (Hashtable<TempDescriptor, Integer>) temptab.get(fn).clone());
- fgcn.addNext(fn.getNext(0));
- fn.setNext(0, fgcn);
- }
- }
- }
- }
-}
+++ /dev/null
-package Analysis.Locality;
-
-import java.util.*;
-import Analysis.CallGraph.CallGraph;
-import IR.SymbolTable;
-import IR.State;
-import IR.TypeUtil;
-import IR.MethodDescriptor;
-import IR.Flat.*;
-
-public class LocalityAnalysis {
- State state;
- Stack lbtovisit;
- Hashtable<LocalityBinding,LocalityBinding> discovered;
- Hashtable<LocalityBinding, Set<LocalityBinding>> dependence;
- Hashtable<LocalityBinding, Hashtable<FlatNode,Hashtable<TempDescriptor, Integer>>> temptab;
- Hashtable<LocalityBinding, Hashtable<FlatNode, Integer>> atomictab;
- Hashtable<LocalityBinding, Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>>> tempstosave;
-
- CallGraph callgraph;
- TypeUtil typeutil;
- public static final Integer LOCAL=new Integer(0);
- public static final Integer GLOBAL=new Integer(1);
- public static final Integer EITHER=new Integer(2);
- public static final Integer CONFLICT=new Integer(3);
-
- public LocalityAnalysis(State state, CallGraph callgraph, TypeUtil typeutil) {
- this.typeutil=typeutil;
- this.state=state;
- this.discovered=new Hashtable<LocalityBinding,LocalityBinding>();
- this.dependence=new Hashtable<LocalityBinding, Set<LocalityBinding>>();
- this.temptab=new Hashtable<LocalityBinding, Hashtable<FlatNode,Hashtable<TempDescriptor, Integer>>>();
- this.atomictab=new Hashtable<LocalityBinding, Hashtable<FlatNode, Integer>>();
- this.lbtovisit=new Stack();
- this.callgraph=callgraph;
- this.tempstosave=new Hashtable<LocalityBinding, Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>>>();
-
- doAnalysis();
- }
-
- /** This method returns a set of LocalityBindings. A
- * LocalityBinding specifies a context a method can be invoked in.
- * It specifies whether the method is in a transaction and whether
- * its parameter objects are locals or globals. */
-
- public Set<LocalityBinding> getLocalityBindings() {
- return discovered.keySet();
- }
-
- /** This method returns a hashtable for a given LocalityBinding
- * that tells the current local/global status of temps at the each
- * node in the flat representation. */
-
- public Hashtable<FlatNode, Hashtable<TempDescriptor, Integer>> getNodeTempInfo(LocalityBinding lb) {
- return temptab.get(lb);
- }
-
- /** This method returns an hashtable for a given LocalitBinding
- * that tells whether a node in the flat represenation is in a
- * transaction or not. Integer values greater than 0 indicate
- * that the node is in a transaction and give the nesting depth.
- * The outermost AtomicEnterNode will have a value of 1 and the
- * outermost AtomicExitNode will have a value of 0. */
-
- public Hashtable<FlatNode, Integer> getAtomic(LocalityBinding lb) {
- return atomictab.get(lb);
- }
-
- /** This methods returns a hashtable for a given LocalityBinding
- * that tells which temps needs to be saved for each
- * AtomicEnterNode. */
-
- public Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>> getTemps(LocalityBinding lb) {
- return tempstosave.get(lb);
- }
-
- private void doAnalysis() {
- computeLocalityBindings();
- computeTempstoSave();
- }
-
- private void computeLocalityBindings() {
- LocalityBinding lbmain=new LocalityBinding(typeutil.getMain(), false);
- lbmain.setGlobal(0, LOCAL);
- lbtovisit.add(lbmain);
- discovered.put(lbmain, lbmain);
-
- while(!lbtovisit.empty()) {
- LocalityBinding lb=(LocalityBinding) lbtovisit.pop();
- Integer returnglobal=lb.getGlobalReturn();
- MethodDescriptor md=lb.getMethod();
- Hashtable<FlatNode,Hashtable<TempDescriptor, Integer>> temptable=new Hashtable<FlatNode,Hashtable<TempDescriptor, Integer>>();
- Hashtable<FlatNode, Integer> atomictable=new Hashtable<FlatNode, Integer>();
- computeCallsFlags(md, lb, temptable, atomictable);
- atomictab.put(lb, atomictable);
- temptab.put(lb, temptable);
-
- if (!md.isStatic()&&!returnglobal.equals(lb.getGlobalReturn())) {
- //return type is more precise now
- //rerun everything that call us
- lbtovisit.addAll(dependence.get(lb));
- }
- }
- }
-
-
- public void computeCallsFlags(MethodDescriptor md, LocalityBinding lb, Hashtable<FlatNode, Hashtable<TempDescriptor, Integer>> temptable, Hashtable<FlatNode, Integer> atomictable) {
- FlatMethod fm=state.getMethodFlat(md);
- HashSet<FlatNode> tovisit=new HashSet<FlatNode>();
- tovisit.add(fm.getNext(0));
- {
- // Build table for initial node
- Hashtable<TempDescriptor,Integer> table=new Hashtable<TempDescriptor,Integer>();
- temptable.put(fm, table);
- atomictable.put(fm, lb.isAtomic()?1:0);
- int offset=md.isStatic()?0:1;
- if (!md.isStatic()) {
- table.put(fm.getParameter(0), lb.getGlobalThis());
- }
- for(int i=offset;i<fm.numParameters();i++) {
- TempDescriptor temp=fm.getParameter(i);
- Integer b=lb.isGlobal(i-offset);
- table.put(temp,b);
- }
- }
-
- while(!tovisit.isEmpty()) {
- FlatNode fn=tovisit.iterator().next();
- tovisit.remove(fn);
- Hashtable<TempDescriptor, Integer> currtable=new Hashtable<TempDescriptor, Integer>();
- int atomicstate=0;
- for(int i=0;i<fn.numPrev();i++) {
- FlatNode prevnode=fn.getPrev(i);
- if (atomictable.containsKey(prevnode)) {
- atomicstate=atomictable.get(prevnode).intValue();
- }
- if (!temptable.containsKey(prevnode))
- continue;
- Hashtable<TempDescriptor, Integer> prevtable=temptable.get(prevnode);
- for(Iterator<TempDescriptor> tempit=prevtable.keySet().iterator();tempit.hasNext();) {
- TempDescriptor temp=tempit.next();
- Integer tmpint=prevtable.get(temp);
- Integer oldint=currtable.containsKey(temp)?currtable.get(temp):EITHER;
- Integer newint=merge(tmpint, oldint);
- currtable.put(temp, newint);
- }
- }
- atomictable.put(fn, atomicstate);
- // Process this node
- switch(fn.kind()) {
- case FKind.FlatAtomicEnterNode:
- processAtomicEnterNode((FlatAtomicEnterNode)fn, atomictable);
- break;
- case FKind.FlatAtomicExitNode:
- processAtomicExitNode((FlatAtomicExitNode)fn, atomictable);
- break;
- case FKind.FlatCall:
- processCallNode(lb, (FlatCall)fn, currtable, isAtomic(atomictable, fn));
- break;
- case FKind.FlatFieldNode:
- processFieldNode(lb, (FlatFieldNode)fn, isAtomic(atomictable, fn), currtable);
- break;
- case FKind.FlatSetFieldNode:
- processSetFieldNode(lb, (FlatSetFieldNode)fn, isAtomic(atomictable,fn), currtable);
- break;
- case FKind.FlatNew:
- processNew(lb, (FlatNew)fn, isAtomic(atomictable, fn), currtable);
- break;
- case FKind.FlatOpNode:
- processOpNode((FlatOpNode)fn, currtable);
- break;
- case FKind.FlatCastNode:
- processCastNode((FlatCastNode)fn, currtable);
- break;
- case FKind.FlatLiteralNode:
- processLiteralNode((FlatLiteralNode)fn, currtable);
- break;
- case FKind.FlatReturnNode:
- processReturnNode(lb, (FlatReturnNode)fn, currtable);
- break;
- case FKind.FlatSetElementNode:
- processSetElementNode(lb, (FlatSetElementNode)fn, currtable, isAtomic(atomictable, fn));
- break;
- case FKind.FlatElementNode:
- processElementNode(lb, (FlatElementNode)fn, currtable, isAtomic(atomictable, fn));
- break;
- case FKind.FlatCondBranch:
- case FKind.FlatBackEdge:
- case FKind.FlatNop:
- //No action needed for these
- break;
- case FKind.FlatFlagActionNode:
- case FKind.FlatCheckNode:
- case FKind.FlatTagDeclaration:
- throw new Error("Incompatible with tasks!");
- case FKind.FlatMethod:
- default:
- throw new Error();
- }
- Hashtable<TempDescriptor,Integer> oldtable=temptable.get(fn);
- if (oldtable==null||!oldtable.equals(currtable)) {
- // Update table for this node
- temptable.put(fn, currtable);
- for(int i=0;i<fn.numNext();i++) {
- tovisit.add(fn.getNext(i));
- }
- }
- }
- }
-
- private static boolean isAtomic(Hashtable<FlatNode, Integer> atomictable, FlatNode fn) {
- return atomictable.get(fn).intValue()>0;
- }
-
- private static Integer merge(Integer a, Integer b) {
- if (a==null||a.equals(EITHER))
- return b;
- if (b==null||b.equals(EITHER))
- return a;
- if (a.equals(b))
- return a;
- return CONFLICT;
- }
-
- void processCallNode(LocalityBinding currlb, FlatCall fc, Hashtable<TempDescriptor, Integer> currtable, boolean isatomic) {
- MethodDescriptor nodemd=fc.getMethod();
- Set methodset=fc.getThis()==null?callgraph.getMethods(nodemd):
- callgraph.getMethods(nodemd, fc.getThis().getType());
- Integer currreturnval=EITHER; //Start off with the either value
- for(Iterator methodit=methodset.iterator();methodit.hasNext();) {
- MethodDescriptor md=(MethodDescriptor) methodit.next();
- LocalityBinding lb=new LocalityBinding(md, isatomic);
- for(int i=0;i<fc.numArgs();i++) {
- TempDescriptor arg=fc.getArg(i);
- lb.setGlobal(i,currtable.get(arg));
- }
- if (fc.getThis()!=null) {
- Integer thistype=currtable.get(fc.getThis());
- if (thistype==null)
- thistype=EITHER;
- if(thistype.equals(CONFLICT))
- throw new Error("Using type that can be either local or global in context:\n"+currlb.getExplanation());
- if(thistype.equals(GLOBAL)&&!isatomic)
- throw new Error("Using global object outside of transaction in context:\n"+currlb.getExplanation());
- lb.setGlobalThis(thistype);
- } else
- lb.setGlobalThis(EITHER);//default value
- //lb is built
- if (!discovered.containsKey(lb)) {
- lb.setGlobalReturn(EITHER);
- lb.setParent(currlb);
- lbtovisit.add(lb);
- discovered.put(lb, lb);
- } else
- lb=discovered.get(lb);
- Integer returnval=lb.getGlobalReturn();
- currreturnval=merge(returnval, currreturnval);
- if (!dependence.containsKey(lb))
- dependence.put(lb, new HashSet<LocalityBinding>());
- dependence.get(lb).add(currlb);
- }
- if (fc.getReturnTemp()!=null) {
- currtable.put(fc.getReturnTemp(), currreturnval);
- }
- }
-
- void processFieldNode(LocalityBinding lb, FlatFieldNode ffn, boolean transaction, Hashtable<TempDescriptor, Integer> currtable) {
- Integer type=currtable.get(ffn.getSrc());
- TempDescriptor dst=ffn.getDst();
- if (type.equals(LOCAL)) {
- if (ffn.getField().isGlobal())
- currtable.put(dst,GLOBAL);
- else
- currtable.put(dst,LOCAL);
- } else if (type.equals(GLOBAL)) {
- if (!transaction)
- throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
- if (ffn.getField().getType().isPrimitive())
- currtable.put(dst, LOCAL); // primitives are local
- else
- currtable.put(dst, GLOBAL);
- } else if (type.equals(EITHER)) {
- if (ffn.getField().getType().isPrimitive())
- currtable.put(dst, LOCAL); // primitives are local
- else
- currtable.put(dst, EITHER);
- } else if (type.equals(CONFLICT)) {
- throw new Error("Access to object that could be either global or local in context:\n"+lb.getExplanation());
- }
- }
-
- //need to handle primitives
- void processSetFieldNode(LocalityBinding lb, FlatSetFieldNode fsfn, boolean transaction, Hashtable<TempDescriptor, Integer> currtable) {
- Integer srctype=currtable.get(fsfn.getSrc());
- Integer dsttype=currtable.get(fsfn.getDst());
-
- if (dsttype.equals(LOCAL)) {
- if (fsfn.getField().isGlobal()) {
- if (!(srctype.equals(GLOBAL)||srctype.equals(EITHER)))
- throw new Error("Writing possible local reference to global field in context: \n"+lb.getExplanation());
- } else {
- if (!(srctype.equals(LOCAL)||srctype.equals(EITHER)))
- throw new Error("Writing possible global reference to local object in context: \n"+lb.getExplanation());
- }
- } else if (dsttype.equals(GLOBAL)) {
- if (!transaction)
- throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
- //okay to store primitives in global object
- if (srctype.equals(LOCAL) && fsfn.getField().getType().isPrimitive())
- return;
- if (!(srctype.equals(GLOBAL)||srctype.equals(EITHER)))
- throw new Error("Writing possible local reference to global object in context:\n"+lb.getExplanation());
- } else if (dsttype.equals(EITHER)) {
- if (srctype.equals(CONFLICT))
- throw new Error("Using reference that could be local or global in context:\n"+lb.getExplanation());
- } else if (dsttype.equals(CONFLICT)) {
- throw new Error("Access to object that could be either global or local in context:\n"+lb.getExplanation());
- }
- }
-
- void processNew(LocalityBinding lb, FlatNew fn, boolean transaction, Hashtable<TempDescriptor, Integer> currtable) {
- if (fn.isGlobal()&&!transaction) {
- throw new Error("Allocating global object outside of transaction in context:"+lb.getExplanation());
- }
- if (fn.isGlobal())
- currtable.put(fn.getDst(), GLOBAL);
- else
- currtable.put(fn.getDst(), LOCAL);
- }
-
- void processOpNode(FlatOpNode fon, Hashtable<TempDescriptor, Integer> currtable) {
- /* Just propagate value */
- currtable.put(fon.getDest(), currtable.get(fon.getLeft()));
- }
-
- void processCastNode(FlatCastNode fcn, Hashtable<TempDescriptor, Integer> currtable) {
- currtable.put(fcn.getDst(), currtable.get(fcn.getSrc()));
- }
-
- void processLiteralNode(FlatLiteralNode fln, Hashtable<TempDescriptor, Integer> currtable) {
- //null is either
- if (fln.getValue()==null)
- currtable.put(fln.getDst(), EITHER);
- else
- currtable.put(fln.getDst(), LOCAL);
- }
-
- void processReturnNode(LocalityBinding lb, FlatReturnNode frn, Hashtable<TempDescriptor, Integer> currtable) {
- if(frn.getReturnTemp()!=null) {
- Integer returntype=currtable.get(frn.getReturnTemp());
- lb.setGlobalReturn(merge(returntype, lb.getGlobalReturn()));
- }
- }
-
- void processSetElementNode(LocalityBinding lb, FlatSetElementNode fsen, Hashtable<TempDescriptor, Integer> currtable, boolean isatomic) {
- Integer srctype=currtable.get(fsen.getSrc());
- Integer dsttype=currtable.get(fsen.getDst());
-
- if (dsttype.equals(LOCAL)) {
- if (!(srctype.equals(LOCAL)||srctype.equals(EITHER)))
- throw new Error("Writing possible global reference to local object in context:\n"+lb.getExplanation());
- } else if (dsttype.equals(GLOBAL)) {
- if (!(srctype.equals(GLOBAL)||srctype.equals(EITHER)))
- throw new Error("Writing possible local reference to global object in context:\n"+lb.getExplanation());
- if (!isatomic)
- throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
- } else if (dsttype.equals(EITHER)) {
- if (srctype.equals(CONFLICT))
- throw new Error("Using reference that could be local or global in context:\n"+lb.getExplanation());
- } else if (dsttype.equals(CONFLICT)) {
- throw new Error("Access to object that could be either global or local in context:\n"+lb.getExplanation());
- }
- }
-
- void processElementNode(LocalityBinding lb, FlatElementNode fen, Hashtable<TempDescriptor, Integer> currtable, boolean isatomic) {
- Integer type=currtable.get(fen.getSrc());
- TempDescriptor dst=fen.getDst();
- if (type.equals(LOCAL)) {
- currtable.put(dst,LOCAL);
- } else if (type.equals(GLOBAL)) {
- if (!isatomic)
- throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
- currtable.put(dst, GLOBAL);
- } else if (type.equals(EITHER)) {
- currtable.put(dst, EITHER);
- } else if (type.equals(CONFLICT)) {
- throw new Error("Access to object that could be either global or local in context:\n"+lb.getExplanation());
- }
- }
-
- void processAtomicEnterNode(FlatAtomicEnterNode fen, Hashtable<FlatNode, Integer> atomictable) {
- int atomic=atomictable.get(fen).intValue();
- atomictable.put(fen, new Integer(atomic+1));
- }
-
- void processAtomicExitNode(FlatAtomicExitNode fen, Hashtable<FlatNode, Integer> atomictable) {
- int atomic=atomictable.get(fen).intValue();
- atomictable.put(fen, new Integer(atomic-1));
- }
-
- private Hashtable<FlatNode, Set<TempDescriptor>> computeLiveTemps(FlatMethod fm) {
- Hashtable<FlatNode, Set<TempDescriptor>> nodetotemps=new Hashtable<FlatNode, Set<TempDescriptor>>();
-
- Set<FlatNode> toprocess=fm.getNodeSet();
-
- while(!toprocess.isEmpty()) {
- FlatNode fn=toprocess.iterator().next();
- toprocess.remove(fn);
-
- List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
- List<TempDescriptor> writes=Arrays.asList(fn.readsTemps());
-
- HashSet<TempDescriptor> tempset=new HashSet<TempDescriptor>();
- for(int i=0;i<fn.numNext();i++) {
- FlatNode fnnext=fn.getNext(i);
- if (nodetotemps.containsKey(fnnext))
- tempset.addAll(nodetotemps.get(fnnext));
- }
- tempset.removeAll(writes);
- tempset.addAll(reads);
- if (!nodetotemps.containsKey(fn)||
- nodetotemps.get(fn).equals(tempset)) {
- nodetotemps.put(fn, tempset);
- for(int i=0;i<fn.numPrev();i++)
- toprocess.add(fn.getPrev(i));
- }
- }
- return nodetotemps;
- }
-
- private void computeTempstoSave() {
- for(Iterator<LocalityBinding> lbit=getLocalityBindings().iterator();lbit.hasNext();) {
- LocalityBinding lb=lbit.next();
- computeTempstoSave(lb);
- }
- }
-
- /* Need to checkpoint all temps that could be read from along any
- * path that are either:
- 1) Written to by any assignment inside the transaction
- 2) Read from a global temp.
-
- Generate tempstosave map from
- localitybinding->flatatomicenternode->Set<TempDescriptors>
- */
-
- private void computeTempstoSave(LocalityBinding lb) {
- if (lb.isAtomic())
- return;
- Hashtable<FlatNode, Integer> atomictab=getAtomic(lb);
- Hashtable<FlatNode, Hashtable<TempDescriptor, Integer>> temptab=getNodeTempInfo(lb);
- MethodDescriptor md=lb.getMethod();
- FlatMethod fm=state.getMethodFlat(md);
-
- Hashtable<FlatNode, Set<TempDescriptor>> nodetotemps=computeLiveTemps(fm);
- Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>> nodetosavetemps=new Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>>();
- tempstosave.put(lb, nodetosavetemps);
-
- Hashtable<FlatNode, FlatAtomicEnterNode> nodemap=new Hashtable<FlatNode, FlatAtomicEnterNode>();
-
- HashSet<FlatNode> toprocess=new HashSet<FlatNode>();
- HashSet<FlatNode> discovered=new HashSet<FlatNode>();
- toprocess.add(fm);
- discovered.add(fm);
- while(!toprocess.isEmpty()) {
- FlatNode fn=toprocess.iterator().next();
- toprocess.remove(fn);
- boolean isatomic=atomictab.get(fn).intValue()>0;
- if (isatomic&&
- atomictab.get(fn.getPrev(0)).intValue()==0) {
- assert(fn.getPrev(0).kind()==FKind.FlatAtomicEnterNode);
- nodemap.put(fn, (FlatAtomicEnterNode)fn);
- nodetosavetemps.put((FlatAtomicEnterNode)fn, new HashSet<TempDescriptor>());
- } else if (isatomic) {
- FlatAtomicEnterNode atomicnode=nodemap.get(fn);
- Set<TempDescriptor> livetemps=nodetotemps.get(fn);
- List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
- List<TempDescriptor> writes=Arrays.asList(fn.readsTemps());
-
- for(Iterator<TempDescriptor> tempit=livetemps.iterator();tempit.hasNext();) {
- TempDescriptor tmp=tempit.next();
- if (writes.contains(tmp)) {
- nodetosavetemps.get(fn).add(tmp);
- } else if (reads.contains(tmp)&&temptab.get(fn).get(tmp)==GLOBAL) {
- nodetosavetemps.get(fn).add(tmp);
- }
- }
- }
- for(int i=0;i<fn.numNext();i++) {
- FlatNode fnnext=fn.getNext(i);
- if (!discovered.contains(fnnext)) {
- discovered.add(fnnext);
- toprocess.add(fnnext);
- if(isatomic) {
- nodemap.put(fnnext, nodemap.get(fn));
- }
- }
- }
- }
- }
-}
+++ /dev/null
-package Analysis.Locality;
-import IR.MethodDescriptor;
-
-public class LocalityBinding {
- private MethodDescriptor md;
- private Integer[] isglobal;
- private boolean isatomic;
- private Integer isglobalreturn;
- private Integer isglobalthis;
- private LocalityBinding parent;
-
- public LocalityBinding(MethodDescriptor md, boolean atomic) {
- this.md=md;
- isglobal=new Integer[md.numParameters()];
- isatomic=atomic;
- }
-
- /* Use this for an explanation */
- public void setParent(LocalityBinding lb) {
- parent=lb;
- }
-
- public String getExplanation() {
- if (parent==null)
- return toString();
- else
- return parent.getExplanation()+"\n"+toString();
- }
-
- public String toString() {
- String st=md.toString()+" ";
- for(int i=0;i<isglobal.length;i++)
- if (isglobal[i].equals(LocalityAnalysis.LOCAL))
- st+="local ";
- else if (isglobal[i].equals(LocalityAnalysis.GLOBAL))
- st+="global ";
- else if (isglobal[i].equals(LocalityAnalysis.EITHER))
- st+="either ";
- else if (isglobal[i].equals(LocalityAnalysis.CONFLICT))
- st+="conflict ";
- return st;
- }
-
- public void setGlobal(int i, Integer global) {
- isglobal[i]=global;
- }
-
- public Integer isGlobal(int i) {
- return isglobal[i];
- }
-
- public void setGlobalReturn(Integer global) {
- isglobalreturn=global;
- }
-
- public Integer getGlobalReturn() {
- return isglobalreturn;
- }
-
- public void setGlobalThis(Integer global) {
- isglobalthis=global;
- }
-
- public Integer getGlobalThis() {
- return isglobalthis;
- }
-
- public MethodDescriptor getMethod() {
- return md;
- }
-
- public boolean isAtomic() {
- return isatomic;
- }
-
- public boolean equals(Object o) {
- if (o instanceof LocalityBinding) {
- LocalityBinding lb=(LocalityBinding)o;
- if (md!=lb.md)
- return false;
- for(int i=0;i<isglobal.length;i++)
- if (!isglobal[i].equals(lb.isglobal[i]))
- return false;
- if (!isglobalthis.equals(lb.isglobalthis))
- return false;
- return (isatomic==lb.isatomic);
- }
- return false;
- }
-
- public int hashCode() {
- int hashcode=md.hashCode();
- for(int i=0;i<isglobal.length;i++) {
- hashcode=hashcode*31+(isglobal[i].intValue());
- }
- hashcode=hashcode*31+(isatomic?1:0);
- return hashcode;
- }
-}
+++ /dev/null
-package Analysis.Locality;
-import IR.Flat.*;
-
-
-public class TempNodePair {
- TempDescriptor tmp;
- FlatNode fn;
-
- public TempNodePair(TempDescriptor tmp) {
- this.tmp=tmp;
- }
-
- public TempDescriptor getTemp() {
- return tmp;
- }
-
- public void setNode(FlatNode fn) {
- this.fn=fn;
- }
-
- public FlatNode getNode() {
- return fn;
- }
-
- public boolean equals(Object o) {
- if (o instanceof TempNodePair) {
- TempNodePair tnp=(TempNodePair)o;
- if (tnp.fn!=null||fn!=null) {
- // need to check flat node equivalence also
- if (tnp.fn==null||fn==null||(!fn.equals(tnp.fn)))
- return false;
- }
- return tmp.equals(tnp.tmp);
- }
- return false;
- }
-
- public int hashCode() {
- return tmp.hashCode();
- }
-}
--- /dev/null
+package Analysis.OwnershipAnalysis;
+
+import IR.*;
+import IR.Flat.*;
+import java.util.*;
+import java.io.*;
+
+public class OwnershipGraph {
+
+ private int allocationDepth;
+ private TypeUtil typeUtil;
+
+ // there was already one other very similar reason
+ // for traversing heap nodes that is no longer needed
+ // instead of writing a new heap region visitor, use
+ // the existing method with a new mode to describe what
+ // actions to take during the traversal
+ protected static final int VISIT_HRN_WRITE_FULL = 0;
+
+ protected static TempDescriptor tdReturn = new TempDescriptor("_Return___");
+
+
+ public Hashtable<Integer, HeapRegionNode> id2hrn;
+ public Hashtable<TempDescriptor, LabelNode > td2ln;
+ public Hashtable<Integer, Integer > id2paramIndex;
+ public Hashtable<Integer, Integer > paramIndex2id;
+ public Hashtable<Integer, TempDescriptor> paramIndex2tdQ;
+
+ public HashSet<AllocationSite> allocationSites;
+
+
+
+
+ public OwnershipGraph(int allocationDepth, TypeUtil typeUtil) {
+ this.allocationDepth = allocationDepth;
+ this.typeUtil = typeUtil;
+
+ id2hrn = new Hashtable<Integer, HeapRegionNode>();
+ td2ln = new Hashtable<TempDescriptor, LabelNode >();
+ id2paramIndex = new Hashtable<Integer, Integer >();
+ paramIndex2id = new Hashtable<Integer, Integer >();
+ paramIndex2tdQ = new Hashtable<Integer, TempDescriptor>();
+
+ allocationSites = new HashSet <AllocationSite>();
+ }
+
+
+ // label nodes are much easier to deal with than
+ // heap region nodes. Whenever there is a request
+ // for the label node that is associated with a
+ // temp descriptor we can either find it or make a
+ // new one and return it. This is because temp
+ // descriptors are globally unique and every label
+ // node is mapped to exactly one temp descriptor.
+ protected LabelNode getLabelNodeFromTemp(TempDescriptor td) {
+ assert td != null;
+
+ if( !td2ln.containsKey(td) ) {
+ td2ln.put(td, new LabelNode(td) );
+ }
+
+ return td2ln.get(td);
+ }
+
+
+ // the reason for this method is to have the option
+ // creating new heap regions with specific IDs, or
+ // duplicating heap regions with specific IDs (especially
+ // in the merge() operation) or to create new heap
+ // regions with a new unique ID.
+ protected HeapRegionNode
+ createNewHeapRegionNode(Integer id,
+ boolean isSingleObject,
+ boolean isFlagged,
+ boolean isNewSummary,
+ boolean isParameter,
+ AllocationSite allocSite,
+ ReachabilitySet alpha,
+ String description) {
+
+ if( id == null ) {
+ id = OwnershipAnalysis.generateUniqueHeapRegionNodeID();
+ }
+
+ if( alpha == null ) {
+ if( isFlagged || isParameter ) {
+ alpha = new ReachabilitySet(new TokenTuple(id,
+ !isSingleObject,
+ TokenTuple.ARITY_ONE)
+ ).makeCanonical();
+ } else {
+ alpha = new ReachabilitySet(new TokenTupleSet()
+ ).makeCanonical();
+ }
+ }
+
+ HeapRegionNode hrn = new HeapRegionNode(id,
+ isSingleObject,
+ isFlagged,
+ isNewSummary,
+ allocSite,
+ alpha,
+ description);
+ id2hrn.put(id, hrn);
+ return hrn;
+ }
+
+
+
+ ////////////////////////////////////////////////
+ //
+ // Low-level referencee and referencer methods
+ //
+ // These methods provide the lowest level for
+ // creating references between ownership nodes
+ // and handling the details of maintaining both
+ // list of referencers and referencees.
+ //
+ ////////////////////////////////////////////////
+ protected void addReferenceEdge(OwnershipNode referencer,
+ HeapRegionNode referencee,
+ ReferenceEdge edge) {
+ assert referencer != null;
+ assert referencee != null;
+ assert edge != null;
+ assert edge.getSrc() == referencer;
+ assert edge.getDst() == referencee;
+
+ referencer.addReferencee(edge);
+ referencee.addReferencer(edge);
+ }
+
+ protected void removeReferenceEdge(OwnershipNode referencer,
+ HeapRegionNode referencee,
+ FieldDescriptor fieldDesc) {
+ assert referencer != null;
+ assert referencee != null;
+
+ ReferenceEdge edge = referencer.getReferenceTo(referencee,
+ fieldDesc);
+ assert edge != null;
+ assert edge == referencee.getReferenceFrom(referencer,
+ fieldDesc);
+
+ referencer.removeReferencee(edge);
+ referencee.removeReferencer(edge);
+ }
+
+ protected void clearReferenceEdgesFrom(OwnershipNode referencer,
+ FieldDescriptor fieldDesc,
+ boolean removeAll) {
+ assert referencer != null;
+
+ // get a copy of the set to iterate over, otherwise
+ // we will be trying to take apart the set as we
+ // are iterating over it, which won't work
+ Iterator<ReferenceEdge> i = referencer.iteratorToReferenceesClone();
+ while( i.hasNext() ) {
+ ReferenceEdge edge = i.next();
+
+ if( removeAll || edge.getFieldDesc() == fieldDesc ) {
+ HeapRegionNode referencee = edge.getDst();
+
+ removeReferenceEdge(referencer,
+ referencee,
+ edge.getFieldDesc() );
+ }
+ }
+ }
+
+ protected void clearReferenceEdgesTo(HeapRegionNode referencee,
+ FieldDescriptor fieldDesc,
+ boolean removeAll) {
+ assert referencee != null;
+
+ // get a copy of the set to iterate over, otherwise
+ // we will be trying to take apart the set as we
+ // are iterating over it, which won't work
+ Iterator<ReferenceEdge> i = referencee.iteratorToReferencersClone();
+ while( i.hasNext() ) {
+ ReferenceEdge edge = i.next();
+
+ if( removeAll || edge.getFieldDesc() == fieldDesc ) {
+ OwnershipNode referencer = edge.getSrc();
+ removeReferenceEdge(referencer,
+ referencee,
+ edge.getFieldDesc() );
+ }
+ }
+ }
+
+
+ protected void propagateTokensOverNodes(HeapRegionNode nPrime,
+ ChangeTupleSet c0,
+ HashSet<HeapRegionNode> nodesWithNewAlpha,
+ HashSet<ReferenceEdge> edgesWithNewBeta) {
+
+ HashSet<HeapRegionNode> todoNodes
+ = new HashSet<HeapRegionNode>();
+ todoNodes.add(nPrime);
+
+ HashSet<ReferenceEdge> todoEdges
+ = new HashSet<ReferenceEdge>();
+
+ Hashtable<HeapRegionNode, ChangeTupleSet> nodePlannedChanges
+ = new Hashtable<HeapRegionNode, ChangeTupleSet>();
+ nodePlannedChanges.put(nPrime, c0);
+
+ Hashtable<ReferenceEdge, ChangeTupleSet> edgePlannedChanges
+ = new Hashtable<ReferenceEdge, ChangeTupleSet>();
+
+
+ while( !todoNodes.isEmpty() ) {
+ HeapRegionNode n = todoNodes.iterator().next();
+ ChangeTupleSet C = nodePlannedChanges.get(n);
+
+ Iterator itrC = C.iterator();
+ while( itrC.hasNext() ) {
+ ChangeTuple c = (ChangeTuple) itrC.next();
+
+ if( n.getAlpha().contains(c.getSetToMatch() ) ) {
+ ReachabilitySet withChange = n.getAlpha().union(c.getSetToAdd() );
+ n.setAlphaNew(n.getAlphaNew().union(withChange) );
+ nodesWithNewAlpha.add(n);
+ }
+ }
+
+ Iterator<ReferenceEdge> referItr = n.iteratorToReferencers();
+ while( referItr.hasNext() ) {
+ ReferenceEdge edge = referItr.next();
+ todoEdges.add(edge);
+
+ if( !edgePlannedChanges.containsKey(edge) ) {
+ edgePlannedChanges.put(edge, new ChangeTupleSet().makeCanonical() );
+ }
+
+ edgePlannedChanges.put(edge, edgePlannedChanges.get(edge).union(C) );
+ }
+
+ Iterator<ReferenceEdge> refeeItr = n.iteratorToReferencees();
+ while( refeeItr.hasNext() ) {
+ ReferenceEdge edgeF = refeeItr.next();
+ HeapRegionNode m = edgeF.getDst();
+
+ ChangeTupleSet changesToPass = new ChangeTupleSet().makeCanonical();
+
+ Iterator<ChangeTuple> itrCprime = C.iterator();
+ while( itrCprime.hasNext() ) {
+ ChangeTuple c = itrCprime.next();
+ if( edgeF.getBeta().contains(c.getSetToMatch() ) ) {
+ changesToPass = changesToPass.union(c);
+ }
+ }
+
+ if( !changesToPass.isEmpty() ) {
+ if( !nodePlannedChanges.containsKey(m) ) {
+ nodePlannedChanges.put(m, new ChangeTupleSet().makeCanonical() );
+ }
+
+ ChangeTupleSet currentChanges = nodePlannedChanges.get(m);
+
+ if( !changesToPass.isSubset(currentChanges) ) {
+
+ nodePlannedChanges.put(m, currentChanges.union(changesToPass) );
+ todoNodes.add(m);
+ }
+ }
+ }
+
+ todoNodes.remove(n);
+ }
+
+ propagateTokensOverEdges(todoEdges, edgePlannedChanges, edgesWithNewBeta);
+ }
+
+
+ protected void propagateTokensOverEdges(
+ HashSet<ReferenceEdge> todoEdges,
+ Hashtable<ReferenceEdge, ChangeTupleSet> edgePlannedChanges,
+ HashSet<ReferenceEdge> edgesWithNewBeta) {
+
+
+ while( !todoEdges.isEmpty() ) {
+ ReferenceEdge edgeE = todoEdges.iterator().next();
+ todoEdges.remove(edgeE);
+
+ if( !edgePlannedChanges.containsKey(edgeE) ) {
+ edgePlannedChanges.put(edgeE, new ChangeTupleSet().makeCanonical() );
+ }
+
+ ChangeTupleSet C = edgePlannedChanges.get(edgeE);
+
+ ChangeTupleSet changesToPass = new ChangeTupleSet().makeCanonical();
+
+ Iterator<ChangeTuple> itrC = C.iterator();
+ while( itrC.hasNext() ) {
+ ChangeTuple c = itrC.next();
+ if( edgeE.getBeta().contains(c.getSetToMatch() ) ) {
+ ReachabilitySet withChange = edgeE.getBeta().union(c.getSetToAdd() );
+ edgeE.setBetaNew(edgeE.getBetaNew().union(withChange) );
+ edgesWithNewBeta.add(edgeE);
+ changesToPass = changesToPass.union(c);
+ }
+ }
+
+ OwnershipNode onSrc = edgeE.getSrc();
+
+ if( !changesToPass.isEmpty() && onSrc instanceof HeapRegionNode ) {
+ HeapRegionNode n = (HeapRegionNode) onSrc;
+
+ Iterator<ReferenceEdge> referItr = n.iteratorToReferencers();
+ while( referItr.hasNext() ) {
+ ReferenceEdge edgeF = referItr.next();
+
+ if( !edgePlannedChanges.containsKey(edgeF) ) {
+ edgePlannedChanges.put(edgeF, new ChangeTupleSet().makeCanonical() );
+ }
+
+ ChangeTupleSet currentChanges = edgePlannedChanges.get(edgeF);
+
+ if( !changesToPass.isSubset(currentChanges) ) {
+ todoEdges.add(edgeF);
+ edgePlannedChanges.put(edgeF, currentChanges.union(changesToPass) );
+ }
+ }
+ }
+ }
+ }
+
+
+ ////////////////////////////////////////////////////
+ //
+ // Assignment Operation Methods
+ //
+ // These methods are high-level operations for
+ // modeling program assignment statements using
+ // the low-level reference create/remove methods
+ // above.
+ //
+ // The destination in an assignment statement is
+ // going to have new references. The method of
+ // determining the references depends on the type
+ // of the FlatNode assignment and the predicates
+ // of the nodes and edges involved.
+ //
+ ////////////////////////////////////////////////////
+ public void assignTempXEqualToTempY(TempDescriptor x,
+ TempDescriptor y) {
+
+ LabelNode lnX = getLabelNodeFromTemp(x);
+ LabelNode lnY = getLabelNodeFromTemp(y);
+
+ clearReferenceEdgesFrom(lnX, null, true);
+
+ Iterator<ReferenceEdge> itrYhrn = lnY.iteratorToReferencees();
+ while( itrYhrn.hasNext() ) {
+ ReferenceEdge edgeY = itrYhrn.next();
+ HeapRegionNode referencee = edgeY.getDst();
+ ReferenceEdge edgeNew = edgeY.copy();
+ edgeNew.setSrc(lnX);
+
+ addReferenceEdge(lnX, referencee, edgeNew);
+ }
+ }
+
+
+ public void assignTempXEqualToTempYFieldF(TempDescriptor x,
+ TempDescriptor y,
+ FieldDescriptor f) {
+ LabelNode lnX = getLabelNodeFromTemp(x);
+ LabelNode lnY = getLabelNodeFromTemp(y);
+
+ clearReferenceEdgesFrom(lnX, null, true);
+
+ Iterator<ReferenceEdge> itrYhrn = lnY.iteratorToReferencees();
+ while( itrYhrn.hasNext() ) {
+ ReferenceEdge edgeY = itrYhrn.next();
+ HeapRegionNode hrnY = edgeY.getDst();
+ ReachabilitySet betaY = edgeY.getBeta();
+
+ Iterator<ReferenceEdge> itrHrnFhrn = hrnY.iteratorToReferencees();
+ while( itrHrnFhrn.hasNext() ) {
+ ReferenceEdge edgeHrn = itrHrnFhrn.next();
+ HeapRegionNode hrnHrn = edgeHrn.getDst();
+ ReachabilitySet betaHrn = edgeHrn.getBeta();
+
+ if( edgeHrn.getFieldDesc() == null ||
+ edgeHrn.getFieldDesc() == f ) {
+
+ ReferenceEdge edgeNew = new ReferenceEdge(lnX,
+ hrnHrn,
+ f,
+ false,
+ betaY.intersection(betaHrn) );
+
+ addReferenceEdge(lnX, hrnHrn, edgeNew);
+ }
+ }
+ }
+ }
+
+
+ public void assignTempXFieldFEqualToTempY(TempDescriptor x,
+ FieldDescriptor f,
+ TempDescriptor y) {
+ LabelNode lnX = getLabelNodeFromTemp(x);
+ LabelNode lnY = getLabelNodeFromTemp(y);
+
+ HashSet<HeapRegionNode> nodesWithNewAlpha = new HashSet<HeapRegionNode>();
+ HashSet<ReferenceEdge> edgesWithNewBeta = new HashSet<ReferenceEdge>();
+
+ Iterator<ReferenceEdge> itrXhrn = lnX.iteratorToReferencees();
+ while( itrXhrn.hasNext() ) {
+ ReferenceEdge edgeX = itrXhrn.next();
+ HeapRegionNode hrnX = edgeX.getDst();
+ ReachabilitySet betaX = edgeX.getBeta();
+
+ ReachabilitySet R = hrnX.getAlpha().intersection(edgeX.getBeta() );
+
+ Iterator<ReferenceEdge> itrYhrn = lnY.iteratorToReferencees();
+ while( itrYhrn.hasNext() ) {
+ ReferenceEdge edgeY = itrYhrn.next();
+ HeapRegionNode hrnY = edgeY.getDst();
+ ReachabilitySet O = edgeY.getBeta();
+
+
+ // propagate tokens over nodes starting from hrnSrc, and it will
+ // take care of propagating back up edges from any touched nodes
+ ChangeTupleSet Cy = O.unionUpArityToChangeSet(R);
+ propagateTokensOverNodes(hrnY, Cy, nodesWithNewAlpha, edgesWithNewBeta);
+
+
+ // then propagate back just up the edges from hrn
+ ChangeTupleSet Cx = R.unionUpArityToChangeSet(O);
+
+ HashSet<ReferenceEdge> todoEdges = new HashSet<ReferenceEdge>();
+
+ Hashtable<ReferenceEdge, ChangeTupleSet> edgePlannedChanges =
+ new Hashtable<ReferenceEdge, ChangeTupleSet>();
+
+ Iterator<ReferenceEdge> referItr = hrnX.iteratorToReferencers();
+ while( referItr.hasNext() ) {
+ ReferenceEdge edgeUpstream = referItr.next();
+ todoEdges.add(edgeUpstream);
+ edgePlannedChanges.put(edgeUpstream, Cx);
+ }
+
+ propagateTokensOverEdges(todoEdges,
+ edgePlannedChanges,
+ edgesWithNewBeta);
+
+
+
+ //System.out.println( edgeY.getBetaNew() + "\nbeing pruned by\n" + hrnX.getAlpha() );
+
+ // create the actual reference edge hrnX.f -> hrnY
+ ReferenceEdge edgeNew = new ReferenceEdge(hrnX,
+ hrnY,
+ f,
+ false,
+ edgeY.getBetaNew().pruneBy(hrnX.getAlpha() )
+ //edgeY.getBeta().pruneBy( hrnX.getAlpha() )
+ );
+ addReferenceEdge(hrnX, hrnY, edgeNew);
+
+ /*
+ if( f != null ) {
+ // we can do a strong update here if one of two cases holds
+ // SAVE FOR LATER, WITHOUT STILL CORRECT
+ if( (hrnX.getNumReferencers() == 1) ||
+ ( lnX.getNumReferencees() == 1 && hrnX.isSingleObject() )
+ ) {
+ clearReferenceEdgesFrom( hrnX, f, false );
+ }
+
+ addReferenceEdge( hrnX, hrnY, edgeNew );
+
+ } else {
+ // if the field is null, or "any" field, then
+ // look to see if an any field already exists
+ // and merge with it, otherwise just add the edge
+ ReferenceEdge edgeExisting = hrnX.getReferenceTo( hrnY, f );
+
+ if( edgeExisting != null ) {
+ edgeExisting.setBetaNew(
+ edgeExisting.getBetaNew().union( edgeNew.getBeta() )
+ );
+ // a new edge here cannot be reflexive, so existing will
+ // always be also not reflexive anymore
+ edgeExisting.setIsInitialParamReflexive( false );
+
+ } else {
+ addReferenceEdge( hrnX, hrnY, edgeNew );
+ }
+ }
+ */
+ }
+ }
+
+ Iterator<HeapRegionNode> nodeItr = nodesWithNewAlpha.iterator();
+ while( nodeItr.hasNext() ) {
+ nodeItr.next().applyAlphaNew();
+ }
+
+ Iterator<ReferenceEdge> edgeItr = edgesWithNewBeta.iterator();
+ while( edgeItr.hasNext() ) {
+ edgeItr.next().applyBetaNew();
+ }
+ }
+
+
+ public void assignTempEqualToParamAlloc(TempDescriptor td,
+ boolean isTask,
+ Integer paramIndex) {
+ assert td != null;
+
+ LabelNode lnParam = getLabelNodeFromTemp(td);
+ HeapRegionNode hrn = createNewHeapRegionNode(null,
+ false,
+ isTask,
+ false,
+ true,
+ null,
+ null,
+ "param" + paramIndex);
+
+ // this is a non-program-accessible label that picks up beta
+ // info to be used for fixing a caller of this method
+ TempDescriptor tdParamQ = new TempDescriptor(td+"specialQ");
+ LabelNode lnParamQ = getLabelNodeFromTemp(tdParamQ);
+
+ // keep track of heap regions that were created for
+ // parameter labels, the index of the parameter they
+ // are for is important when resolving method calls
+ Integer newID = hrn.getID();
+ assert !id2paramIndex.containsKey(newID);
+ assert !id2paramIndex.containsValue(paramIndex);
+ id2paramIndex.put(newID, paramIndex);
+ paramIndex2id.put(paramIndex, newID);
+ paramIndex2tdQ.put(paramIndex, tdParamQ);
+
+ ReachabilitySet beta = new ReachabilitySet(new TokenTuple(newID,
+ true,
+ TokenTuple.ARITY_ONE) );
+
+ // heap regions for parameters are always multiple object (see above)
+ // and have a reference to themselves, because we can't know the
+ // structure of memory that is passed into the method. We're assuming
+ // the worst here.
+
+ ReferenceEdge edgeFromLabel =
+ new ReferenceEdge(lnParam, hrn, null, false, beta);
+
+ ReferenceEdge edgeFromLabelQ =
+ new ReferenceEdge(lnParamQ, hrn, null, false, beta);
+
+ ReferenceEdge edgeReflexive =
+ new ReferenceEdge(hrn, hrn, null, true, beta);
+
+ addReferenceEdge(lnParam, hrn, edgeFromLabel);
+ addReferenceEdge(lnParamQ, hrn, edgeFromLabelQ);
+ addReferenceEdge(hrn, hrn, edgeReflexive);
+ }
+
+
+ public void assignReturnEqualToTemp(TempDescriptor x) {
+
+ LabelNode lnR = getLabelNodeFromTemp(tdReturn);
+ LabelNode lnX = getLabelNodeFromTemp(x);
+
+ clearReferenceEdgesFrom(lnR, null, true);
+
+ Iterator<ReferenceEdge> itrXhrn = lnX.iteratorToReferencees();
+ while( itrXhrn.hasNext() ) {
+ ReferenceEdge edgeX = itrXhrn.next();
+ HeapRegionNode referencee = edgeX.getDst();
+ ReferenceEdge edgeNew = edgeX.copy();
+ edgeNew.setSrc(lnR);
+
+ addReferenceEdge(lnR, referencee, edgeNew);
+ }
+ }
+
+
+ public void assignTempEqualToNewAlloc(TempDescriptor x,
+ AllocationSite as) {
+ assert x != null;
+ assert as != null;
+
+ age(as);
+
+ // after the age operation the newest (or zero-ith oldest)
+ // node associated with the allocation site should have
+ // no references to it as if it were a newly allocated
+ // heap region, so make a reference to it to complete
+ // this operation
+
+ Integer idNewest = as.getIthOldest(0);
+ HeapRegionNode hrnNewest = id2hrn.get(idNewest);
+ assert hrnNewest != null;
+
+ LabelNode lnX = getLabelNodeFromTemp(x);
+ clearReferenceEdgesFrom(lnX, null, true);
+
+ ReferenceEdge edgeNew =
+ new ReferenceEdge(lnX, hrnNewest, null, false, hrnNewest.getAlpha() );
+
+ addReferenceEdge(lnX, hrnNewest, edgeNew);
+ }
+
+
+ // use the allocation site (unique to entire analysis) to
+ // locate the heap region nodes in this ownership graph
+ // that should be aged. The process models the allocation
+ // of new objects and collects all the oldest allocations
+ // in a summary node to allow for a finite analysis
+ //
+ // There is an additional property of this method. After
+ // running it on a particular ownership graph (many graphs
+ // may have heap regions related to the same allocation site)
+ // the heap region node objects in this ownership graph will be
+ // allocated. Therefore, after aging a graph for an allocation
+ // site, attempts to retrieve the heap region nodes using the
+ // integer id's contained in the allocation site should always
+ // return non-null heap regions.
+ public void age(AllocationSite as) {
+
+ // aging adds this allocation site to the graph's
+ // list of sites that exist in the graph, or does
+ // nothing if the site is already in the list
+ allocationSites.add(as);
+
+ // get the summary node for the allocation site in the context
+ // of this particular ownership graph
+ HeapRegionNode hrnSummary = getSummaryNode(as);
+
+ // merge oldest node into summary
+ Integer idK = as.getOldest();
+ HeapRegionNode hrnK = id2hrn.get(idK);
+ mergeIntoSummary(hrnK, hrnSummary);
+
+ // move down the line of heap region nodes
+ // clobbering the ith and transferring all references
+ // to and from i-1 to node i. Note that this clobbers
+ // the oldest node (hrnK) that was just merged into
+ // the summary
+ for( int i = allocationDepth - 1; i > 0; --i ) {
+
+ // move references from the i-1 oldest to the ith oldest
+ Integer idIth = as.getIthOldest(i);
+ HeapRegionNode hrnI = id2hrn.get(idIth);
+ Integer idImin1th = as.getIthOldest(i - 1);
+ HeapRegionNode hrnImin1 = id2hrn.get(idImin1th);
+
+ transferOnto(hrnImin1, hrnI);
+ }
+
+ // as stated above, the newest node should have had its
+ // references moved over to the second oldest, so we wipe newest
+ // in preparation for being the new object to assign something to
+ Integer id0th = as.getIthOldest(0);
+ HeapRegionNode hrn0 = id2hrn.get(id0th);
+ assert hrn0 != null;
+
+ // clear all references in and out of newest node
+ clearReferenceEdgesFrom(hrn0, null, true);
+ clearReferenceEdgesTo(hrn0, null, true);
+
+
+ // now tokens in reachability sets need to "age" also
+ Iterator itrAllLabelNodes = td2ln.entrySet().iterator();
+ while( itrAllLabelNodes.hasNext() ) {
+ Map.Entry me = (Map.Entry)itrAllLabelNodes.next();
+ LabelNode ln = (LabelNode) me.getValue();
+
+ Iterator<ReferenceEdge> itrEdges = ln.iteratorToReferencees();
+ while( itrEdges.hasNext() ) {
+ ageTokens(as, itrEdges.next() );
+ }
+ }
+
+ Iterator itrAllHRNodes = id2hrn.entrySet().iterator();
+ while( itrAllHRNodes.hasNext() ) {
+ Map.Entry me = (Map.Entry)itrAllHRNodes.next();
+ HeapRegionNode hrnToAge = (HeapRegionNode) me.getValue();
+
+ ageTokens(as, hrnToAge);
+
+ Iterator<ReferenceEdge> itrEdges = hrnToAge.iteratorToReferencees();
+ while( itrEdges.hasNext() ) {
+ ageTokens(as, itrEdges.next() );
+ }
+ }
+
+
+ // after tokens have been aged, reset newest node's reachability
+ if( hrn0.isFlagged() ) {
+ hrn0.setAlpha(new ReachabilitySet(new TokenTupleSet(
+ new TokenTuple(hrn0)
+ )
+ ).makeCanonical()
+ );
+ } else {
+ hrn0.setAlpha(new ReachabilitySet(new TokenTupleSet()
+ ).makeCanonical()
+ );
+ }
+ }
+
+
+ protected HeapRegionNode getSummaryNode(AllocationSite as) {
+
+ Integer idSummary = as.getSummary();
+ HeapRegionNode hrnSummary = id2hrn.get(idSummary);
+
+ // If this is null then we haven't touched this allocation site
+ // in the context of the current ownership graph, so allocate
+ // heap region nodes appropriate for the entire allocation site.
+ // This should only happen once per ownership graph per allocation site,
+ // and a particular integer id can be used to locate the heap region
+ // in different ownership graphs that represents the same part of an
+ // allocation site.
+ if( hrnSummary == null ) {
+
+ boolean hasFlags = false;
+ if( as.getType().isClass() ) {
+ hasFlags = as.getType().getClassDesc().hasFlags();
+ }
+
+ hrnSummary = createNewHeapRegionNode(idSummary,
+ false,
+ hasFlags,
+ true,
+ false,
+ as,
+ null,
+ as + "\\n" + as.getType() + "\\nsummary");
+
+ for( int i = 0; i < as.getAllocationDepth(); ++i ) {
+ Integer idIth = as.getIthOldest(i);
+ assert !id2hrn.containsKey(idIth);
+ createNewHeapRegionNode(idIth,
+ true,
+ hasFlags,
+ false,
+ false,
+ as,
+ null,
+ as + "\\n" + as.getType() + "\\n" + i + " oldest");
+ }
+ }
+
+ return hrnSummary;
+ }
+
+
+ protected HeapRegionNode getShadowSummaryNode(AllocationSite as) {
+
+ Integer idShadowSummary = as.getSummaryShadow();
+ HeapRegionNode hrnShadowSummary = id2hrn.get(idShadowSummary);
+
+ if( hrnShadowSummary == null ) {
+
+ boolean hasFlags = false;
+ if( as.getType().isClass() ) {
+ hasFlags = as.getType().getClassDesc().hasFlags();
+ }
+
+ hrnShadowSummary = createNewHeapRegionNode(idShadowSummary,
+ false,
+ hasFlags,
+ true,
+ false,
+ as,
+ null,
+ as + "\\n" + as.getType() + "\\nshadowSum");
+
+ for( int i = 0; i < as.getAllocationDepth(); ++i ) {
+ Integer idShadowIth = as.getIthOldestShadow(i);
+ assert !id2hrn.containsKey(idShadowIth);
+ createNewHeapRegionNode(idShadowIth,
+ true,
+ hasFlags,
+ false,
+ false,
+ as,
+ null,
+ as + "\\n" + as.getType() + "\\n" + i + " shadow");
+ }
+ }
+
+ return hrnShadowSummary;
+ }
+
+
+ protected void mergeIntoSummary(HeapRegionNode hrn, HeapRegionNode hrnSummary) {
+ assert hrnSummary.isNewSummary();
+
+ // transfer references _from_ hrn over to hrnSummary
+ Iterator<ReferenceEdge> itrReferencee = hrn.iteratorToReferencees();
+ while( itrReferencee.hasNext() ) {
+ ReferenceEdge edge = itrReferencee.next();
+ ReferenceEdge edgeMerged = edge.copy();
+ edgeMerged.setSrc(hrnSummary);
+
+ HeapRegionNode hrnReferencee = edge.getDst();
+ ReferenceEdge edgeSummary = hrnSummary.getReferenceTo(hrnReferencee, edge.getFieldDesc() );
+
+ if( edgeSummary == null ) {
+ // the merge is trivial, nothing to be done
+ } else {
+ // otherwise an edge from the referencer to hrnSummary exists already
+ // and the edge referencer->hrn should be merged with it
+ edgeMerged.setBeta(edgeMerged.getBeta().union(edgeSummary.getBeta() ) );
+ }
+
+ addReferenceEdge(hrnSummary, hrnReferencee, edgeMerged);
+ }
+
+ // next transfer references _to_ hrn over to hrnSummary
+ Iterator<ReferenceEdge> itrReferencer = hrn.iteratorToReferencers();
+ while( itrReferencer.hasNext() ) {
+ ReferenceEdge edge = itrReferencer.next();
+ ReferenceEdge edgeMerged = edge.copy();
+ edgeMerged.setDst(hrnSummary);
+
+ OwnershipNode onReferencer = edge.getSrc();
+ ReferenceEdge edgeSummary = onReferencer.getReferenceTo(hrnSummary, edge.getFieldDesc() );
+
+ if( edgeSummary == null ) {
+ // the merge is trivial, nothing to be done
+ } else {
+ // otherwise an edge from the referencer to alpha_S exists already
+ // and the edge referencer->alpha_K should be merged with it
+ edgeMerged.setBeta(edgeMerged.getBeta().union(edgeSummary.getBeta() ) );
+ }
+
+ addReferenceEdge(onReferencer, hrnSummary, edgeMerged);
+ }
+
+ // then merge hrn reachability into hrnSummary
+ hrnSummary.setAlpha(hrnSummary.getAlpha().union(hrn.getAlpha() ) );
+ }
+
+
+ protected void transferOnto(HeapRegionNode hrnA, HeapRegionNode hrnB) {
+
+ // clear references in and out of node i
+ clearReferenceEdgesFrom(hrnB, null, true);
+ clearReferenceEdgesTo(hrnB, null, true);
+
+ // copy each edge in and out of A to B
+ Iterator<ReferenceEdge> itrReferencee = hrnA.iteratorToReferencees();
+ while( itrReferencee.hasNext() ) {
+ ReferenceEdge edge = itrReferencee.next();
+ HeapRegionNode hrnReferencee = edge.getDst();
+ ReferenceEdge edgeNew = edge.copy();
+ edgeNew.setSrc(hrnB);
+
+ addReferenceEdge(hrnB, hrnReferencee, edgeNew);
+ }
+
+ Iterator<ReferenceEdge> itrReferencer = hrnA.iteratorToReferencers();
+ while( itrReferencer.hasNext() ) {
+ ReferenceEdge edge = itrReferencer.next();
+ OwnershipNode onReferencer = edge.getSrc();
+ ReferenceEdge edgeNew = edge.copy();
+ edgeNew.setDst(hrnB);
+
+ addReferenceEdge(onReferencer, hrnB, edgeNew);
+ }
+
+ // replace hrnB reachability with hrnA's
+ hrnB.setAlpha(hrnA.getAlpha() );
+ }
+
+
+ protected void ageTokens(AllocationSite as, ReferenceEdge edge) {
+ edge.setBeta(edge.getBeta().ageTokens(as) );
+ }
+
+ protected void ageTokens(AllocationSite as, HeapRegionNode hrn) {
+ hrn.setAlpha(hrn.getAlpha().ageTokens(as) );
+ }
+
+
+ public void resolveMethodCall(FlatCall fc,
+ boolean isStatic,
+ FlatMethod fm,
+ OwnershipGraph ogCallee) {
+
+ // define rewrite rules and other structures to organize
+ // data by parameter/argument index
+ Hashtable<Integer, ReachabilitySet> paramIndex2rewriteH =
+ new Hashtable<Integer, ReachabilitySet>();
+
+ Hashtable<Integer, ReachabilitySet> paramIndex2rewriteJ =
+ new Hashtable<Integer, ReachabilitySet>();
+
+ Hashtable<Integer, ReachabilitySet> paramIndex2rewriteK =
+ new Hashtable<Integer, ReachabilitySet>();
+
+ Hashtable<Integer, ReachabilitySet> paramIndex2rewriteD =
+ new Hashtable<Integer, ReachabilitySet>();
+
+ // helpful structures
+ Hashtable<TokenTuple, Integer> paramToken2paramIndex =
+ new Hashtable<TokenTuple, Integer>();
+
+ Hashtable<Integer, TokenTuple> paramIndex2paramToken =
+ new Hashtable<Integer, TokenTuple>();
+
+ Hashtable<TokenTuple, Integer> paramTokenStar2paramIndex =
+ new Hashtable<TokenTuple, Integer>();
+
+ Hashtable<Integer, TokenTuple> paramIndex2paramTokenStar =
+ new Hashtable<Integer, TokenTuple>();
+
+ Hashtable<Integer, LabelNode> paramIndex2ln =
+ new Hashtable<Integer, LabelNode>();
+
+ Hashtable<Integer, HashSet<HeapRegionNode> > paramIndex2reachableCallerNodes =
+ new Hashtable<Integer, HashSet<HeapRegionNode> >();
+
+
+ // add a bogus entry with the identity rule for easy rewrite
+ // of new callee nodes and edges, doesn't belong to any parameter
+ Integer bogusID = new Integer(-1);
+ Integer bogusIndex = new Integer(-1);
+ TokenTuple bogusToken = new TokenTuple(bogusID, true, TokenTuple.ARITY_ONE);
+ TokenTuple bogusTokenStar = new TokenTuple(bogusID, true, TokenTuple.ARITY_MANY);
+ ReachabilitySet rsIdentity =
+ new ReachabilitySet(new TokenTupleSet(bogusToken).makeCanonical() ).makeCanonical();
+
+ paramIndex2rewriteH.put(bogusIndex, rsIdentity);
+ paramIndex2rewriteJ.put(bogusIndex, rsIdentity);
+ paramToken2paramIndex.put(bogusToken, bogusIndex);
+ paramIndex2paramToken.put(bogusIndex, bogusToken);
+ paramTokenStar2paramIndex.put(bogusTokenStar, bogusIndex);
+ paramIndex2paramTokenStar.put(bogusIndex, bogusTokenStar);
+
+
+ for( int i = 0; i < fm.numParameters(); ++i ) {
+ Integer paramIndex = new Integer(i);
+
+ assert ogCallee.paramIndex2id.containsKey(paramIndex);
+ Integer idParam = ogCallee.paramIndex2id.get(paramIndex);
+
+ assert ogCallee.id2hrn.containsKey(idParam);
+ HeapRegionNode hrnParam = ogCallee.id2hrn.get(idParam);
+ assert hrnParam != null;
+ paramIndex2rewriteH.put(paramIndex,
+
+ toShadowTokens(ogCallee, hrnParam.getAlpha() )
+ );
+
+ ReferenceEdge edgeReflexive_i = hrnParam.getReferenceTo(hrnParam, null);
+ assert edgeReflexive_i != null;
+ paramIndex2rewriteJ.put(paramIndex,
+ toShadowTokens(ogCallee, edgeReflexive_i.getBeta() )
+ );
+
+ TempDescriptor tdParamQ = ogCallee.paramIndex2tdQ.get(paramIndex);
+ assert tdParamQ != null;
+ LabelNode lnParamQ = ogCallee.td2ln.get(tdParamQ);
+ assert lnParamQ != null;
+ ReferenceEdge edgeSpecialQ_i = lnParamQ.getReferenceTo(hrnParam, null);
+ assert edgeSpecialQ_i != null;
+ paramIndex2rewriteK.put(paramIndex,
+ toShadowTokens(ogCallee, edgeSpecialQ_i.getBeta() )
+ );
+
+ TokenTuple p_i = new TokenTuple(hrnParam.getID(),
+ true,
+ TokenTuple.ARITY_ONE).makeCanonical();
+ paramToken2paramIndex.put(p_i, paramIndex);
+ paramIndex2paramToken.put(paramIndex, p_i);
+
+ TokenTuple p_i_star = new TokenTuple(hrnParam.getID(),
+ true,
+ TokenTuple.ARITY_MANY).makeCanonical();
+ paramTokenStar2paramIndex.put(p_i_star, paramIndex);
+ paramIndex2paramTokenStar.put(paramIndex, p_i_star);
+
+ // now depending on whether the callee is static or not
+ // we need to account for a "this" argument in order to
+ // find the matching argument in the caller context
+ TempDescriptor argTemp_i;
+ if( isStatic ) {
+ argTemp_i = fc.getArg(paramIndex);
+ } else {
+ if( paramIndex == 0 ) {
+ argTemp_i = fc.getThis();
+ } else {
+ argTemp_i = fc.getArg(paramIndex - 1);
+ }
+ }
+
+ // in non-static methods there is a "this" pointer
+ // that should be taken into account
+ if( isStatic ) {
+ assert fc.numArgs() == fm.numParameters();
+ } else {
+ assert fc.numArgs() + 1 == fm.numParameters();
+ }
+
+ LabelNode argLabel_i = getLabelNodeFromTemp(argTemp_i);
+ paramIndex2ln.put(paramIndex, argLabel_i);
+
+ ReachabilitySet D_i = new ReachabilitySet().makeCanonical();
+ Iterator<ReferenceEdge> edgeItr = argLabel_i.iteratorToReferencees();
+ while( edgeItr.hasNext() ) {
+ ReferenceEdge edge = edgeItr.next();
+ D_i = D_i.union(edge.getBeta() );
+ }
+
+ D_i = D_i.exhaustiveArityCombinations();
+
+ paramIndex2rewriteD.put(paramIndex, D_i);
+ }
+
+
+ HashSet<HeapRegionNode> nodesWithNewAlpha = new HashSet<HeapRegionNode>();
+ HashSet<ReferenceEdge> edgesWithNewBeta = new HashSet<ReferenceEdge>();
+
+ HashSet<ReferenceEdge> edgesReachable = new HashSet<ReferenceEdge>();
+ HashSet<ReferenceEdge> edgesUpstream = new HashSet<ReferenceEdge>();
+
+ Iterator lnArgItr = paramIndex2ln.entrySet().iterator();
+ while( lnArgItr.hasNext() ) {
+ Map.Entry me = (Map.Entry)lnArgItr.next();
+ Integer index = (Integer) me.getKey();
+ LabelNode lnArg_i = (LabelNode) me.getValue();
+
+ // rewrite alpha for the nodes reachable from argument label i
+ HashSet<HeapRegionNode> reachableNodes = new HashSet<HeapRegionNode>();
+ HashSet<HeapRegionNode> todoNodes = new HashSet<HeapRegionNode>();
+
+ // to find all reachable nodes, start with label referencees
+ Iterator<ReferenceEdge> edgeArgItr = lnArg_i.iteratorToReferencees();
+ while( edgeArgItr.hasNext() ) {
+ ReferenceEdge edge = edgeArgItr.next();
+ todoNodes.add(edge.getDst() );
+ }
+
+ // then follow links until all reachable nodes have been found
+ while( !todoNodes.isEmpty() ) {
+ HeapRegionNode hrn = todoNodes.iterator().next();
+ todoNodes.remove(hrn);
+ reachableNodes.add(hrn);
+
+ Iterator<ReferenceEdge> edgeItr = hrn.iteratorToReferencees();
+ while( edgeItr.hasNext() ) {
+ ReferenceEdge edge = edgeItr.next();
+
+ if( !reachableNodes.contains(edge.getDst() ) ) {
+ todoNodes.add(edge.getDst() );
+ }
+ }
+ }
+
+ // save for later
+ paramIndex2reachableCallerNodes.put(index, reachableNodes);
+
+ // now iterate over reachable nodes to update their alpha, and
+ // classify edges found as "argument reachable" or "upstream"
+ Iterator<HeapRegionNode> hrnItr = reachableNodes.iterator();
+ while( hrnItr.hasNext() ) {
+ HeapRegionNode hrn = hrnItr.next();
+
+ rewriteCallerNodeAlpha(fm.numParameters(),
+ index,
+ hrn,
+ paramIndex2rewriteH,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar);
+
+ nodesWithNewAlpha.add(hrn);
+
+ // look at all incoming edges to the reachable nodes
+ // and sort them as edges reachable from the argument
+ // label node, or upstream edges
+ Iterator<ReferenceEdge> edgeItr = hrn.iteratorToReferencers();
+ while( edgeItr.hasNext() ) {
+ ReferenceEdge edge = edgeItr.next();
+
+ OwnershipNode on = edge.getSrc();
+
+ if( on instanceof LabelNode ) {
+
+ LabelNode ln0 = (LabelNode) on;
+ if( ln0.equals(lnArg_i) ) {
+ edgesReachable.add(edge);
+ } else {
+ edgesUpstream.add(edge);
+ }
+
+ } else {
+
+ HeapRegionNode hrn0 = (HeapRegionNode) on;
+ if( reachableNodes.contains(hrn0) ) {
+ edgesReachable.add(edge);
+ } else {
+ edgesUpstream.add(edge);
+ }
+ }
+ }
+ }
+
+ // update reachable edges
+ Iterator<ReferenceEdge> edgeReachableItr = edgesReachable.iterator();
+ while( edgeReachableItr.hasNext() ) {
+ ReferenceEdge edgeReachable = edgeReachableItr.next();
+
+ rewriteCallerEdgeBeta(fm.numParameters(),
+ index,
+ edgeReachable,
+ paramIndex2rewriteJ,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar,
+ false,
+ null);
+
+ edgesWithNewBeta.add(edgeReachable);
+ }
+
+ // update upstream edges
+ Hashtable<ReferenceEdge, ChangeTupleSet> edgeUpstreamPlannedChanges
+ = new Hashtable<ReferenceEdge, ChangeTupleSet>();
+
+ Iterator<ReferenceEdge> edgeUpstreamItr = edgesUpstream.iterator();
+ while( edgeUpstreamItr.hasNext() ) {
+ ReferenceEdge edgeUpstream = edgeUpstreamItr.next();
+
+ rewriteCallerEdgeBeta(fm.numParameters(),
+ index,
+ edgeUpstream,
+ paramIndex2rewriteK,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar,
+ true,
+ edgeUpstreamPlannedChanges);
+
+ edgesWithNewBeta.add(edgeUpstream);
+ }
+
+ propagateTokensOverEdges(edgesUpstream,
+ edgeUpstreamPlannedChanges,
+ edgesWithNewBeta);
+ }
+
+
+ // commit changes to alpha and beta
+ Iterator<HeapRegionNode> nodeItr = nodesWithNewAlpha.iterator();
+ while( nodeItr.hasNext() ) {
+ nodeItr.next().applyAlphaNew();
+ }
+
+ Iterator<ReferenceEdge> edgeItr = edgesWithNewBeta.iterator();
+ while( edgeItr.hasNext() ) {
+ edgeItr.next().applyBetaNew();
+ }
+
+
+ // verify the existence of allocation sites and their
+ // shadows from the callee in the context of this caller graph
+ // then map allocated nodes of callee onto the caller shadows
+ // of them
+ Iterator<AllocationSite> asItr = ogCallee.allocationSites.iterator();
+ while( asItr.hasNext() ) {
+ AllocationSite allocSite = asItr.next();
+ HeapRegionNode hrnSummary = getSummaryNode(allocSite);
+
+ // assert that the shadow nodes have no reference edges
+ // because they're brand new to the graph, or last time
+ // they were used they should have been cleared of edges
+ HeapRegionNode hrnShadowSummary = getShadowSummaryNode(allocSite);
+ assert hrnShadowSummary.getNumReferencers() == 0;
+ assert hrnShadowSummary.getNumReferencees() == 0;
+
+ // then bring g_ij onto g'_ij and rewrite
+ transferOnto(hrnSummary, hrnShadowSummary);
+
+ HeapRegionNode hrnSummaryCallee = ogCallee.getSummaryNode(allocSite);
+ hrnShadowSummary.setAlpha(toShadowTokens(ogCallee, hrnSummaryCallee.getAlpha() ) );
+
+ // shadow nodes only are touched by a rewrite one time,
+ // so rewrite and immediately commit--and they don't belong
+ // to a particular parameter, so use a bogus param index
+ // that pulls a self-rewrite out of H
+ rewriteCallerNodeAlpha(fm.numParameters(),
+ bogusIndex,
+ hrnShadowSummary,
+ paramIndex2rewriteH,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar);
+
+ hrnShadowSummary.applyAlphaNew();
+
+
+ for( int i = 0; i < allocSite.getAllocationDepth(); ++i ) {
+ Integer idIth = allocSite.getIthOldest(i);
+ assert id2hrn.containsKey(idIth);
+ HeapRegionNode hrnIth = id2hrn.get(idIth);
+
+ Integer idShadowIth = -(allocSite.getIthOldest(i));
+ assert id2hrn.containsKey(idShadowIth);
+ HeapRegionNode hrnIthShadow = id2hrn.get(idShadowIth);
+ assert hrnIthShadow.getNumReferencers() == 0;
+ assert hrnIthShadow.getNumReferencees() == 0;
+
+ transferOnto(hrnIth, hrnIthShadow);
+
+ assert ogCallee.id2hrn.containsKey(idIth);
+ HeapRegionNode hrnIthCallee = ogCallee.id2hrn.get(idIth);
+ hrnIthShadow.setAlpha(toShadowTokens(ogCallee, hrnIthCallee.getAlpha() ) );
+
+ rewriteCallerNodeAlpha(fm.numParameters(),
+ bogusIndex,
+ hrnIthShadow,
+ paramIndex2rewriteH,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar);
+
+ hrnIthShadow.applyAlphaNew();
+ }
+ }
+
+
+ // for every heap region->heap region edge in the
+ // callee graph, create the matching edge or edges
+ // in the caller graph
+ Set sCallee = ogCallee.id2hrn.entrySet();
+ Iterator iCallee = sCallee.iterator();
+ while( iCallee.hasNext() ) {
+ Map.Entry meCallee = (Map.Entry)iCallee.next();
+ Integer idCallee = (Integer) meCallee.getKey();
+ HeapRegionNode hrnCallee = (HeapRegionNode) meCallee.getValue();
+
+ Iterator<ReferenceEdge> heapRegionsItrCallee = hrnCallee.iteratorToReferencees();
+ while( heapRegionsItrCallee.hasNext() ) {
+ ReferenceEdge edgeCallee = heapRegionsItrCallee.next();
+ HeapRegionNode hrnChildCallee = edgeCallee.getDst();
+ Integer idChildCallee = hrnChildCallee.getID();
+
+ // only address this edge if it is not a special reflexive edge
+ if( !edgeCallee.isInitialParamReflexive() ) {
+
+ // now we know that in the callee method's ownership graph
+ // there is a heap region->heap region reference edge given
+ // by heap region pointers:
+ // hrnCallee -> heapChildCallee
+ //
+ // or by the ownership-graph independent ID's:
+ // idCallee -> idChildCallee
+
+ // make the edge with src and dst so beta info is
+ // calculated once, then copy it for each new edge in caller
+ ReferenceEdge edgeNewInCallerTemplate = new ReferenceEdge(null,
+ null,
+ edgeCallee.getFieldDesc(),
+ false,
+ toShadowTokens(ogCallee, edgeCallee.getBeta() )
+ );
+ rewriteCallerEdgeBeta(fm.numParameters(),
+ bogusIndex,
+ edgeNewInCallerTemplate,
+ paramIndex2rewriteJ,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar,
+ false,
+ null);
+
+ edgeNewInCallerTemplate.applyBetaNew();
+
+
+ // So now make a set of possible source heaps in the caller graph
+ // and a set of destination heaps in the caller graph, and make
+ // a reference edge in the caller for every possible (src,dst) pair
+ HashSet<HeapRegionNode> possibleCallerSrcs =
+ getHRNSetThatPossiblyMapToCalleeHRN(ogCallee,
+ (HeapRegionNode) edgeCallee.getSrc(),
+ paramIndex2reachableCallerNodes);
+
+ HashSet<HeapRegionNode> possibleCallerDsts =
+ getHRNSetThatPossiblyMapToCalleeHRN(ogCallee,
+ edgeCallee.getDst(),
+ paramIndex2reachableCallerNodes);
+
+
+ // make every possible pair of {srcSet} -> {dstSet} edges in the caller
+ Iterator srcItr = possibleCallerSrcs.iterator();
+ while( srcItr.hasNext() ) {
+ HeapRegionNode src = (HeapRegionNode) srcItr.next();
+
+ if( !hasMatchingField(src, edgeCallee) ) {
+ // prune this source node possibility
+ continue;
+ }
+
+ Iterator dstItr = possibleCallerDsts.iterator();
+ while( dstItr.hasNext() ) {
+ HeapRegionNode dst = (HeapRegionNode) dstItr.next();
+
+ if( !hasMatchingType(edgeCallee, dst) ) {
+ // prune
+ continue;
+ }
+
+ // otherwise the caller src and dst pair can match the edge, so make it
+ ReferenceEdge edgeNewInCaller = edgeNewInCallerTemplate.copy();
+ edgeNewInCaller.setSrc(src);
+ edgeNewInCaller.setDst(dst);
+
+ ReferenceEdge edgeExisting = src.getReferenceTo(dst, edgeNewInCaller.getFieldDesc() );
+ if( edgeExisting == null ) {
+ // if this edge doesn't exist in the caller, create it
+ addReferenceEdge(src, dst, edgeNewInCaller);
+ } else {
+ // if it already exists, merge with it
+ edgeExisting.setBeta(edgeExisting.getBeta().union(edgeNewInCaller.getBeta() ) );
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ // return value may need to be assigned in caller
+ if( fc.getReturnTemp() != null ) {
+
+ LabelNode lnLhsCaller = getLabelNodeFromTemp(fc.getReturnTemp() );
+ clearReferenceEdgesFrom(lnLhsCaller, null, true);
+
+ LabelNode lnReturnCallee = ogCallee.getLabelNodeFromTemp(tdReturn);
+ Iterator<ReferenceEdge> edgeCalleeItr = lnReturnCallee.iteratorToReferencees();
+ while( edgeCalleeItr.hasNext() ) {
+ ReferenceEdge edgeCallee = edgeCalleeItr.next();
+
+ ReferenceEdge edgeNewInCallerTemplate = new ReferenceEdge(null,
+ null,
+ edgeCallee.getFieldDesc(),
+ false,
+ toShadowTokens(ogCallee, edgeCallee.getBeta() )
+ );
+ rewriteCallerEdgeBeta(fm.numParameters(),
+ bogusIndex,
+ edgeNewInCallerTemplate,
+ paramIndex2rewriteJ,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar,
+ false,
+ null);
+
+ edgeNewInCallerTemplate.applyBetaNew();
+
+
+ HashSet<HeapRegionNode> assignCallerRhs =
+ getHRNSetThatPossiblyMapToCalleeHRN(ogCallee,
+ edgeCallee.getDst(),
+ paramIndex2reachableCallerNodes);
+
+ Iterator<HeapRegionNode> itrHrn = assignCallerRhs.iterator();
+ while( itrHrn.hasNext() ) {
+ HeapRegionNode hrnCaller = itrHrn.next();
+
+ if( !hasMatchingType(edgeCallee, hrnCaller) ) {
+ // prune
+ continue;
+ }
+
+ // otherwise caller node can match callee edge, so make it
+ ReferenceEdge edgeNewInCaller = edgeNewInCallerTemplate.copy();
+ edgeNewInCaller.setSrc(lnLhsCaller);
+ edgeNewInCaller.setDst(hrnCaller);
+
+ ReferenceEdge edgeExisting = lnLhsCaller.getReferenceTo(hrnCaller, edgeNewInCaller.getFieldDesc() );
+ if( edgeExisting == null ) {
+
+ // if this edge doesn't exist in the caller, create it
+ addReferenceEdge(lnLhsCaller, hrnCaller, edgeNewInCaller);
+ } else {
+ // if it already exists, merge with it
+ edgeExisting.setBeta(edgeExisting.getBeta().union(edgeNewInCaller.getBeta() ) );
+ }
+ }
+ }
+ }
+
+
+ // merge the shadow nodes of allocation sites back down to normal capacity
+ Iterator<AllocationSite> allocItr = ogCallee.allocationSites.iterator();
+ while( allocItr.hasNext() ) {
+ AllocationSite as = allocItr.next();
+
+ // first age each allocation site enough times to make room for the shadow nodes
+ for( int i = 0; i < as.getAllocationDepth(); ++i ) {
+ age(as);
+ }
+
+ // then merge the shadow summary into the normal summary
+ HeapRegionNode hrnSummary = getSummaryNode(as);
+ assert hrnSummary != null;
+
+ HeapRegionNode hrnSummaryShadow = getShadowSummaryNode(as);
+ assert hrnSummaryShadow != null;
+
+ mergeIntoSummary(hrnSummaryShadow, hrnSummary);
+
+ // then clear off after merge
+ clearReferenceEdgesFrom(hrnSummaryShadow, null, true);
+ clearReferenceEdgesTo(hrnSummaryShadow, null, true);
+ hrnSummaryShadow.setAlpha(new ReachabilitySet().makeCanonical() );
+
+ // then transplant shadow nodes onto the now clean normal nodes
+ for( int i = 0; i < as.getAllocationDepth(); ++i ) {
+
+ Integer idIth = as.getIthOldest(i);
+ HeapRegionNode hrnIth = id2hrn.get(idIth);
+
+ Integer idIthShadow = as.getIthOldestShadow(i);
+ HeapRegionNode hrnIthShadow = id2hrn.get(idIthShadow);
+
+ transferOnto(hrnIthShadow, hrnIth);
+
+ // clear off shadow nodes after transfer
+ clearReferenceEdgesFrom(hrnIthShadow, null, true);
+ clearReferenceEdgesTo(hrnIthShadow, null, true);
+ hrnIthShadow.setAlpha(new ReachabilitySet().makeCanonical() );
+ }
+
+ // finally, globally change shadow tokens into normal tokens
+ Iterator itrAllLabelNodes = td2ln.entrySet().iterator();
+ while( itrAllLabelNodes.hasNext() ) {
+ Map.Entry me = (Map.Entry)itrAllLabelNodes.next();
+ LabelNode ln = (LabelNode) me.getValue();
+
+ Iterator<ReferenceEdge> itrEdges = ln.iteratorToReferencees();
+ while( itrEdges.hasNext() ) {
+ unshadowTokens(as, itrEdges.next() );
+ }
+ }
+
+ Iterator itrAllHRNodes = id2hrn.entrySet().iterator();
+ while( itrAllHRNodes.hasNext() ) {
+ Map.Entry me = (Map.Entry)itrAllHRNodes.next();
+ HeapRegionNode hrnToAge = (HeapRegionNode) me.getValue();
+
+ unshadowTokens(as, hrnToAge);
+
+ Iterator<ReferenceEdge> itrEdges = hrnToAge.iteratorToReferencees();
+ while( itrEdges.hasNext() ) {
+ unshadowTokens(as, itrEdges.next() );
+ }
+ }
+ }
+ }
+
+
+ protected boolean hasMatchingField(HeapRegionNode src, ReferenceEdge edge) {
+
+ // if no allocation site, then it's a match-everything region
+ AllocationSite asSrc = src.getAllocationSite();
+ if( asSrc == null ) {
+ return true;
+ }
+
+ TypeDescriptor tdSrc = asSrc.getType();
+ assert tdSrc != null;
+
+ // if it's not a class, it doesn't have any fields to match
+ if( !tdSrc.isClass() ) {
+ return false;
+ }
+
+ Iterator fieldsSrcItr = tdSrc.getClassDesc().getFields();
+ while( fieldsSrcItr.hasNext() ) {
+ FieldDescriptor fd = (FieldDescriptor) fieldsSrcItr.next();
+ if( fd == edge.getFieldDesc() ) {
+ return true;
+ }
+ }
+
+ // otherwise it is a class with fields
+ // but we didn't find a match
+ return false;
+ }
+
+
+ protected boolean hasMatchingType(ReferenceEdge edge, HeapRegionNode dst) {
+
+ // if the region has no type, matches everything
+ AllocationSite asDst = dst.getAllocationSite();
+ if( asDst == null ) {
+ return true;
+ }
+
+ TypeDescriptor tdDst = asDst.getType();
+ assert tdDst != null;
+
+ // if the type is not a class don't match because
+ // primitives are copied, no memory aliases
+ ClassDescriptor cdDst = tdDst.getClassDesc();
+ if( cdDst == null ) {
+ return false;
+ }
+
+ // if the field is null, it matches everything
+ FieldDescriptor fd = edge.getFieldDesc();
+ if( fd == null ) {
+ return true;
+ }
+ TypeDescriptor tdFd = fd.getType();
+ assert tdFd != null;
+
+ return typeUtil.isSuperorType(tdFd, tdDst);
+ }
+
+
+
+ protected void unshadowTokens(AllocationSite as, ReferenceEdge edge) {
+ edge.setBeta(edge.getBeta().unshadowTokens(as) );
+ }
+
+ protected void unshadowTokens(AllocationSite as, HeapRegionNode hrn) {
+ hrn.setAlpha(hrn.getAlpha().unshadowTokens(as) );
+ }
+
+
+ private ReachabilitySet toShadowTokens(OwnershipGraph ogCallee,
+ ReachabilitySet rsIn) {
+
+ ReachabilitySet rsOut = new ReachabilitySet(rsIn);
+
+ Iterator<AllocationSite> allocItr = ogCallee.allocationSites.iterator();
+ while( allocItr.hasNext() ) {
+ AllocationSite as = allocItr.next();
+
+ rsOut = rsOut.toShadowTokens(as);
+ }
+
+ return rsOut.makeCanonical();
+ }
+
+
+ private void rewriteCallerNodeAlpha(int numParameters,
+ Integer paramIndex,
+ HeapRegionNode hrn,
+ Hashtable<Integer, ReachabilitySet> paramIndex2rewriteH,
+ Hashtable<Integer, ReachabilitySet> paramIndex2rewriteD,
+ Hashtable<Integer, TokenTuple> paramIndex2paramToken,
+ Hashtable<Integer, TokenTuple> paramIndex2paramTokenStar) {
+
+ ReachabilitySet rules = paramIndex2rewriteH.get(paramIndex);
+ assert rules != null;
+
+ TokenTuple tokenToRewrite = paramIndex2paramToken.get(paramIndex);
+ assert tokenToRewrite != null;
+
+ ReachabilitySet r0 = new ReachabilitySet().makeCanonical();
+ Iterator<TokenTupleSet> ttsItr = rules.iterator();
+ while( ttsItr.hasNext() ) {
+ TokenTupleSet tts = ttsItr.next();
+ r0 = r0.union(tts.rewriteToken(tokenToRewrite,
+ hrn.getAlpha(),
+ false,
+ null) );
+ }
+
+ ReachabilitySet r1 = new ReachabilitySet().makeCanonical();
+ ttsItr = r0.iterator();
+ while( ttsItr.hasNext() ) {
+ TokenTupleSet tts = ttsItr.next();
+ r1 = r1.union(rewriteDpass(numParameters,
+ paramIndex,
+ tts,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar) );
+ }
+
+ hrn.setAlphaNew(hrn.getAlphaNew().union(r1) );
+ }
+
+
+ private void rewriteCallerEdgeBeta(int numParameters,
+ Integer paramIndex,
+ ReferenceEdge edge,
+ Hashtable<Integer, ReachabilitySet> paramIndex2rewriteJorK,
+ Hashtable<Integer, ReachabilitySet> paramIndex2rewriteD,
+ Hashtable<Integer, TokenTuple> paramIndex2paramToken,
+ Hashtable<Integer, TokenTuple> paramIndex2paramTokenStar,
+ boolean makeChangeSet,
+ Hashtable<ReferenceEdge, ChangeTupleSet> edgePlannedChanges) {
+
+ ReachabilitySet rules = paramIndex2rewriteJorK.get(paramIndex);
+ assert rules != null;
+
+ TokenTuple tokenToRewrite = paramIndex2paramToken.get(paramIndex);
+ assert tokenToRewrite != null;
+
+ ChangeTupleSet cts0 = new ChangeTupleSet().makeCanonical();
+
+ Iterator<TokenTupleSet> ttsItr = rules.iterator();
+ while( ttsItr.hasNext() ) {
+ TokenTupleSet tts = ttsItr.next();
+
+ Hashtable<TokenTupleSet, HashSet<TokenTupleSet> > forChangeSet =
+ new Hashtable<TokenTupleSet, HashSet<TokenTupleSet> >();
+
+ ReachabilitySet rTemp = tts.rewriteToken(tokenToRewrite,
+ edge.getBeta(),
+ true,
+ forChangeSet);
+
+ Iterator fcsItr = forChangeSet.entrySet().iterator();
+ while( fcsItr.hasNext() ) {
+ Map.Entry me = (Map.Entry)fcsItr.next();
+ TokenTupleSet ttsMatch = (TokenTupleSet) me.getKey();
+ HashSet<TokenTupleSet> ttsAddSet = (HashSet<TokenTupleSet>) me.getValue();
+ Iterator<TokenTupleSet> ttsAddItr = ttsAddSet.iterator();
+ while( ttsAddItr.hasNext() ) {
+ TokenTupleSet ttsAdd = ttsAddItr.next();
+
+ ChangeTuple ct = new ChangeTuple(ttsMatch,
+ ttsAdd
+ ).makeCanonical();
+
+ cts0 = cts0.union(ct);
+ }
+ }
+ }
+
+
+ ReachabilitySet r1 = new ReachabilitySet().makeCanonical();
+ ChangeTupleSet cts1 = new ChangeTupleSet().makeCanonical();
+
+ Iterator<ChangeTuple> ctItr = cts0.iterator();
+ while( ctItr.hasNext() ) {
+ ChangeTuple ct = ctItr.next();
+
+ ReachabilitySet rTemp = rewriteDpass(numParameters,
+ paramIndex,
+ ct.getSetToAdd(),
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar
+ ).makeCanonical();
+ r1 = r1.union(rTemp);
+
+ if( makeChangeSet ) {
+ assert edgePlannedChanges != null;
+
+ Iterator<TokenTupleSet> ttsTempItr = rTemp.iterator();
+ while( ttsTempItr.hasNext() ) {
+ TokenTupleSet tts = ttsTempItr.next();
+
+ ChangeTuple ctFinal = new ChangeTuple(ct.getSetToMatch(),
+ tts
+ ).makeCanonical();
+
+ cts1 = cts1.union(ctFinal);
+ }
+ }
+ }
+
+ if( makeChangeSet ) {
+ edgePlannedChanges.put(edge, cts1);
+ }
+
+ edge.setBetaNew(edge.getBetaNew().union(r1) );
+ }
+
+
+ private ReachabilitySet rewriteDpass(int numParameters,
+ Integer paramIndex,
+ TokenTupleSet ttsIn,
+ Hashtable<Integer, ReachabilitySet> paramIndex2rewriteD,
+ Hashtable<Integer, TokenTuple> paramIndex2paramToken,
+ Hashtable<Integer, TokenTuple> paramIndex2paramTokenStar) {
+
+ ReachabilitySet rsOut = new ReachabilitySet().makeCanonical();
+
+ boolean rewritten = false;
+
+ for( int j = 0; j < numParameters; ++j ) {
+ Integer paramIndexJ = new Integer(j);
+ ReachabilitySet D_j = paramIndex2rewriteD.get(paramIndexJ);
+ assert D_j != null;
+
+ if( paramIndexJ != paramIndex ) {
+ TokenTuple tokenToRewriteJ = paramIndex2paramToken.get(paramIndexJ);
+ assert tokenToRewriteJ != null;
+ if( ttsIn.containsTuple(tokenToRewriteJ) ) {
+ ReachabilitySet r = ttsIn.rewriteToken(tokenToRewriteJ,
+ D_j,
+ false,
+ null);
+ Iterator<TokenTupleSet> ttsItr = r.iterator();
+ while( ttsItr.hasNext() ) {
+ TokenTupleSet tts = ttsItr.next();
+ rsOut = rsOut.union(rewriteDpass(numParameters,
+ paramIndex,
+ tts,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar) );
+ rewritten = true;
+ }
+ }
+ }
+
+ TokenTuple tokenStarToRewriteJ = paramIndex2paramTokenStar.get(paramIndexJ);
+ assert tokenStarToRewriteJ != null;
+ if( ttsIn.containsTuple(tokenStarToRewriteJ) ) {
+ ReachabilitySet r = ttsIn.rewriteToken(tokenStarToRewriteJ,
+ D_j,
+ false,
+ null);
+ Iterator<TokenTupleSet> ttsItr = r.iterator();
+ while( ttsItr.hasNext() ) {
+ TokenTupleSet tts = ttsItr.next();
+ rsOut = rsOut.union(rewriteDpass(numParameters,
+ paramIndex,
+ tts,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar) );
+ rewritten = true;
+ }
+ }
+ }
+
+ if( !rewritten ) {
+ rsOut = rsOut.union(ttsIn);
+ }
+
+ return rsOut;
+ }
+
+
+ private HashSet<HeapRegionNode>
+ getHRNSetThatPossiblyMapToCalleeHRN(OwnershipGraph ogCallee,
+ HeapRegionNode hrnCallee,
+ Hashtable<Integer, HashSet<HeapRegionNode> > paramIndex2reachableCallerNodes
+ ) {
+
+ HashSet<HeapRegionNode> possibleCallerHRNs = new HashSet<HeapRegionNode>();
+
+ Integer paramIndexCallee = ogCallee.id2paramIndex.get(hrnCallee.getID() );
+
+ if( paramIndexCallee == null ) {
+ // this is a node allocated in the callee then and it has
+ // exactly one shadow node in the caller to map to
+ AllocationSite as = hrnCallee.getAllocationSite();
+ assert as != null;
+
+ int age = as.getAgeCategory(hrnCallee.getID() );
+ assert age != AllocationSite.AGE_notInThisSite;
+
+ Integer idCaller;
+ if( age == AllocationSite.AGE_summary ) {
+ idCaller = as.getSummaryShadow();
+ } else if( age == AllocationSite.AGE_oldest ) {
+ idCaller = as.getOldestShadow();
+ } else {
+ assert age == AllocationSite.AGE_in_I;
+
+ Integer I = as.getAge(hrnCallee.getID() );
+ assert I != null;
+
+ idCaller = as.getIthOldestShadow(I);
+ }
+
+ assert id2hrn.containsKey(idCaller);
+ HeapRegionNode hrnCaller = id2hrn.get(idCaller);
+ possibleCallerHRNs.add(hrnCaller);
+
+ } else {
+ // this is a node that was created to represent a parameter
+ // so it maps to a whole mess of heap regions
+ assert paramIndex2reachableCallerNodes.containsKey(paramIndexCallee);
+ possibleCallerHRNs = paramIndex2reachableCallerNodes.get(paramIndexCallee);
+ }
+
+ return possibleCallerHRNs;
+ }
+
+
+
+ ////////////////////////////////////////////////////
+ // in merge() and equals() methods the suffix A
+ // represents the passed in graph and the suffix
+ // B refers to the graph in this object
+ // Merging means to take the incoming graph A and
+ // merge it into B, so after the operation graph B
+ // is the final result.
+ ////////////////////////////////////////////////////
+ public void merge(OwnershipGraph og) {
+
+ if( og == null ) {
+ return;
+ }
+
+ mergeOwnershipNodes(og);
+ mergeReferenceEdges(og);
+ mergeId2paramIndex(og);
+ mergeAllocationSites(og);
+ }
+
+
+ protected void mergeOwnershipNodes(OwnershipGraph og) {
+ Set sA = og.id2hrn.entrySet();
+ Iterator iA = sA.iterator();
+ while( iA.hasNext() ) {
+ Map.Entry meA = (Map.Entry)iA.next();
+ Integer idA = (Integer) meA.getKey();
+ HeapRegionNode hrnA = (HeapRegionNode) meA.getValue();
+
+ // if this graph doesn't have a node the
+ // incoming graph has, allocate it
+ if( !id2hrn.containsKey(idA) ) {
+ HeapRegionNode hrnB = hrnA.copy();
+ id2hrn.put(idA, hrnB);
+
+ } else {
+ // otherwise this is a node present in both graphs
+ // so make the new reachability set a union of the
+ // nodes' reachability sets
+ HeapRegionNode hrnB = id2hrn.get(idA);
+ hrnB.setAlpha(hrnB.getAlpha().union(hrnA.getAlpha() ) );
+ }
+ }
+
+ // now add any label nodes that are in graph B but
+ // not in A
+ sA = og.td2ln.entrySet();
+ iA = sA.iterator();
+ while( iA.hasNext() ) {
+ Map.Entry meA = (Map.Entry)iA.next();
+ TempDescriptor tdA = (TempDescriptor) meA.getKey();
+ LabelNode lnA = (LabelNode) meA.getValue();
+
+ // if the label doesn't exist in B, allocate and add it
+ LabelNode lnB = getLabelNodeFromTemp(tdA);
+ }
+ }
+
+ protected void mergeReferenceEdges(OwnershipGraph og) {
+
+ // heap regions
+ Set sA = og.id2hrn.entrySet();
+ Iterator iA = sA.iterator();
+ while( iA.hasNext() ) {
+ Map.Entry meA = (Map.Entry)iA.next();
+ Integer idA = (Integer) meA.getKey();
+ HeapRegionNode hrnA = (HeapRegionNode) meA.getValue();
+
+ Iterator<ReferenceEdge> heapRegionsItrA = hrnA.iteratorToReferencees();
+ while( heapRegionsItrA.hasNext() ) {
+ ReferenceEdge edgeA = heapRegionsItrA.next();
+ HeapRegionNode hrnChildA = edgeA.getDst();
+ Integer idChildA = hrnChildA.getID();
+
+ // at this point we know an edge in graph A exists
+ // idA -> idChildA, does this exist in B?
+ assert id2hrn.containsKey(idA);
+ HeapRegionNode hrnB = id2hrn.get(idA);
+ ReferenceEdge edgeToMerge = null;
+
+ Iterator<ReferenceEdge> heapRegionsItrB = hrnB.iteratorToReferencees();
+ while( heapRegionsItrB.hasNext() &&
+ edgeToMerge == null ) {
+
+ ReferenceEdge edgeB = heapRegionsItrB.next();
+ HeapRegionNode hrnChildB = edgeB.getDst();
+ Integer idChildB = hrnChildB.getID();
+
+ // don't use the ReferenceEdge.equals() here because
+ // we're talking about existence between graphs
+ if( idChildB.equals(idChildA) &&
+ edgeB.getFieldDesc() == edgeA.getFieldDesc() ) {
+ edgeToMerge = edgeB;
+ }
+ }
+
+ // if the edge from A was not found in B,
+ // add it to B.
+ if( edgeToMerge == null ) {
+ assert id2hrn.containsKey(idChildA);
+ HeapRegionNode hrnChildB = id2hrn.get(idChildA);
+ edgeToMerge = edgeA.copy();
+ edgeToMerge.setSrc(hrnB);
+ edgeToMerge.setDst(hrnChildB);
+ addReferenceEdge(hrnB, hrnChildB, edgeToMerge);
+ }
+ // otherwise, the edge already existed in both graphs
+ // so merge their reachability sets
+ else {
+ // just replace this beta set with the union
+ assert edgeToMerge != null;
+ edgeToMerge.setBeta(
+ edgeToMerge.getBeta().union(edgeA.getBeta() )
+ );
+ if( !edgeA.isInitialParamReflexive() ) {
+ edgeToMerge.setIsInitialParamReflexive(false);
+ }
+ }
+ }
+ }
+
+ // and then again with label nodes
+ sA = og.td2ln.entrySet();
+ iA = sA.iterator();
+ while( iA.hasNext() ) {
+ Map.Entry meA = (Map.Entry)iA.next();
+ TempDescriptor tdA = (TempDescriptor) meA.getKey();
+ LabelNode lnA = (LabelNode) meA.getValue();
+
+ Iterator<ReferenceEdge> heapRegionsItrA = lnA.iteratorToReferencees();
+ while( heapRegionsItrA.hasNext() ) {
+ ReferenceEdge edgeA = heapRegionsItrA.next();
+ HeapRegionNode hrnChildA = edgeA.getDst();
+ Integer idChildA = hrnChildA.getID();
+
+ // at this point we know an edge in graph A exists
+ // tdA -> idChildA, does this exist in B?
+ assert td2ln.containsKey(tdA);
+ LabelNode lnB = td2ln.get(tdA);
+ ReferenceEdge edgeToMerge = null;
+
+ // labels never have edges with a field
+ //assert edgeA.getFieldDesc() == null;
+
+ Iterator<ReferenceEdge> heapRegionsItrB = lnB.iteratorToReferencees();
+ while( heapRegionsItrB.hasNext() &&
+ edgeToMerge == null ) {
+
+ ReferenceEdge edgeB = heapRegionsItrB.next();
+ HeapRegionNode hrnChildB = edgeB.getDst();
+ Integer idChildB = hrnChildB.getID();
+
+ // labels never have edges with a field
+ //assert edgeB.getFieldDesc() == null;
+
+ // don't use the ReferenceEdge.equals() here because
+ // we're talking about existence between graphs
+ if( idChildB.equals(idChildA) &&
+ edgeB.getFieldDesc() == edgeA.getFieldDesc() ) {
+ edgeToMerge = edgeB;
+ }
+ }
+
+ // if the edge from A was not found in B,
+ // add it to B.
+ if( edgeToMerge == null ) {
+ assert id2hrn.containsKey(idChildA);
+ HeapRegionNode hrnChildB = id2hrn.get(idChildA);
+ edgeToMerge = edgeA.copy();
+ edgeToMerge.setSrc(lnB);
+ edgeToMerge.setDst(hrnChildB);
+ addReferenceEdge(lnB, hrnChildB, edgeToMerge);
+ }
+ // otherwise, the edge already existed in both graphs
+ // so merge their reachability sets
+ else {
+ // just replace this beta set with the union
+ edgeToMerge.setBeta(
+ edgeToMerge.getBeta().union(edgeA.getBeta() )
+ );
+ if( !edgeA.isInitialParamReflexive() ) {
+ edgeToMerge.setIsInitialParamReflexive(false);
+ }
+ }
+ }
+ }
+ }
+
+ // you should only merge ownership graphs that have the
+ // same number of parameters, or if one or both parameter
+ // index tables are empty
+ protected void mergeId2paramIndex(OwnershipGraph og) {
+ if( id2paramIndex.size() == 0 ) {
+ id2paramIndex = og.id2paramIndex;
+ paramIndex2id = og.paramIndex2id;
+ paramIndex2tdQ = og.paramIndex2tdQ;
+ return;
+ }
+
+ if( og.id2paramIndex.size() == 0 ) {
+ return;
+ }
+
+ assert id2paramIndex.size() == og.id2paramIndex.size();
+ }
+
+ protected void mergeAllocationSites(OwnershipGraph og) {
+ allocationSites.addAll(og.allocationSites);
+ }
+
+
+
+ // it is necessary in the equals() member functions
+ // to "check both ways" when comparing the data
+ // structures of two graphs. For instance, if all
+ // edges between heap region nodes in graph A are
+ // present and equal in graph B it is not sufficient
+ // to say the graphs are equal. Consider that there
+ // may be edges in graph B that are not in graph A.
+ // the only way to know that all edges in both graphs
+ // are equally present is to iterate over both data
+ // structures and compare against the other graph.
+ public boolean equals(OwnershipGraph og) {
+
+ if( og == null ) {
+ return false;
+ }
+
+ if( !areHeapRegionNodesEqual(og) ) {
+ return false;
+ }
+
+ if( !areLabelNodesEqual(og) ) {
+ return false;
+ }
+
+ if( !areReferenceEdgesEqual(og) ) {
+ return false;
+ }
+
+ if( !areId2paramIndexEqual(og) ) {
+ return false;
+ }
+
+ // if everything is equal up to this point,
+ // assert that allocationSites is also equal--
+ // this data is redundant and kept for efficiency
+ assert allocationSites.equals(og.allocationSites);
+
+ return true;
+ }
+
+ protected boolean areHeapRegionNodesEqual(OwnershipGraph og) {
+
+ if( !areallHRNinAalsoinBandequal(this, og) ) {
+ return false;
+ }
+
+ if( !areallHRNinAalsoinBandequal(og, this) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ static protected boolean areallHRNinAalsoinBandequal(OwnershipGraph ogA,
+ OwnershipGraph ogB) {
+ Set sA = ogA.id2hrn.entrySet();
+ Iterator iA = sA.iterator();
+ while( iA.hasNext() ) {
+ Map.Entry meA = (Map.Entry)iA.next();
+ Integer idA = (Integer) meA.getKey();
+ HeapRegionNode hrnA = (HeapRegionNode) meA.getValue();
+
+ if( !ogB.id2hrn.containsKey(idA) ) {
+ return false;
+ }
+
+ HeapRegionNode hrnB = ogB.id2hrn.get(idA);
+ if( !hrnA.equalsIncludingAlpha(hrnB) ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ protected boolean areLabelNodesEqual(OwnershipGraph og) {
+
+ if( !areallLNinAalsoinBandequal(this, og) ) {
+ return false;
+ }
+
+ if( !areallLNinAalsoinBandequal(og, this) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ static protected boolean areallLNinAalsoinBandequal(OwnershipGraph ogA,
+ OwnershipGraph ogB) {
+ Set sA = ogA.td2ln.entrySet();
+ Iterator iA = sA.iterator();
+ while( iA.hasNext() ) {
+ Map.Entry meA = (Map.Entry)iA.next();
+ TempDescriptor tdA = (TempDescriptor) meA.getKey();
+
+ if( !ogB.td2ln.containsKey(tdA) ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ protected boolean areReferenceEdgesEqual(OwnershipGraph og) {
+ if( !areallREinAandBequal(this, og) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ static protected boolean areallREinAandBequal(OwnershipGraph ogA,
+ OwnershipGraph ogB) {
+
+ // check all the heap region->heap region edges
+ Set sA = ogA.id2hrn.entrySet();
+ Iterator iA = sA.iterator();
+ while( iA.hasNext() ) {
+ Map.Entry meA = (Map.Entry)iA.next();
+ Integer idA = (Integer) meA.getKey();
+ HeapRegionNode hrnA = (HeapRegionNode) meA.getValue();
+
+ // we should have already checked that the same
+ // heap regions exist in both graphs
+ assert ogB.id2hrn.containsKey(idA);
+
+ if( !areallREfromAequaltoB(ogA, hrnA, ogB) ) {
+ return false;
+ }
+
+ // then check every edge in B for presence in A, starting
+ // from the same parent HeapRegionNode
+ HeapRegionNode hrnB = ogB.id2hrn.get(idA);
+
+ if( !areallREfromAequaltoB(ogB, hrnB, ogA) ) {
+ return false;
+ }
+ }
+
+ // then check all the label->heap region edges
+ sA = ogA.td2ln.entrySet();
+ iA = sA.iterator();
+ while( iA.hasNext() ) {
+ Map.Entry meA = (Map.Entry)iA.next();
+ TempDescriptor tdA = (TempDescriptor) meA.getKey();
+ LabelNode lnA = (LabelNode) meA.getValue();
+
+ // we should have already checked that the same
+ // label nodes exist in both graphs
+ assert ogB.td2ln.containsKey(tdA);
+
+ if( !areallREfromAequaltoB(ogA, lnA, ogB) ) {
+ return false;
+ }
+
+ // then check every edge in B for presence in A, starting
+ // from the same parent LabelNode
+ LabelNode lnB = ogB.td2ln.get(tdA);
+
+ if( !areallREfromAequaltoB(ogB, lnB, ogA) ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ static protected boolean areallREfromAequaltoB(OwnershipGraph ogA,
+ OwnershipNode onA,
+ OwnershipGraph ogB) {
+
+ Iterator<ReferenceEdge> itrA = onA.iteratorToReferencees();
+ while( itrA.hasNext() ) {
+ ReferenceEdge edgeA = itrA.next();
+ HeapRegionNode hrnChildA = edgeA.getDst();
+ Integer idChildA = hrnChildA.getID();
+
+ assert ogB.id2hrn.containsKey(idChildA);
+
+ // at this point we know an edge in graph A exists
+ // onA -> idChildA, does this exact edge exist in B?
+ boolean edgeFound = false;
+
+ OwnershipNode onB = null;
+ if( onA instanceof HeapRegionNode ) {
+ HeapRegionNode hrnA = (HeapRegionNode) onA;
+ onB = ogB.id2hrn.get(hrnA.getID() );
+ } else {
+ LabelNode lnA = (LabelNode) onA;
+ onB = ogB.td2ln.get(lnA.getTempDescriptor() );
+ }
+
+ Iterator<ReferenceEdge> itrB = onB.iteratorToReferencees();
+ while( itrB.hasNext() ) {
+ ReferenceEdge edgeB = itrB.next();
+ HeapRegionNode hrnChildB = edgeB.getDst();
+ Integer idChildB = hrnChildB.getID();
+
+ if( idChildA.equals(idChildB) &&
+ edgeA.getFieldDesc() == edgeB.getFieldDesc() ) {
+
+ // there is an edge in the right place with the right field,
+ // but do they have the same attributes?
+ if( edgeA.getBeta().equals(edgeB.getBeta() ) ) {
+
+ edgeFound = true;
+ //} else {
+ //return false;
+ }
+ }
+ }
+
+ if( !edgeFound ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ protected boolean areId2paramIndexEqual(OwnershipGraph og) {
+ return id2paramIndex.size() == og.id2paramIndex.size();
+ }
+
+
+ public boolean hasPotentialAlias(Integer paramIndex1, Integer paramIndex2) {
+
+ // get parameter's heap region
+ assert paramIndex2id.containsKey(paramIndex1);
+ Integer idParam1 = paramIndex2id.get(paramIndex1);
+
+ assert id2hrn.containsKey(idParam1);
+ HeapRegionNode hrnParam1 = id2hrn.get(idParam1);
+ assert hrnParam1 != null;
+
+ // get tokens for this parameter
+ TokenTuple p1 = new TokenTuple(hrnParam1.getID(),
+ true,
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ TokenTuple pStar1 = new TokenTuple(hrnParam1.getID(),
+ true,
+ TokenTuple.ARITY_MANY).makeCanonical();
+
+
+ // get tokens for the other parameter
+ assert paramIndex2id.containsKey(paramIndex2);
+ Integer idParam2 = paramIndex2id.get(paramIndex2);
+
+ assert id2hrn.containsKey(idParam2);
+ HeapRegionNode hrnParam2 = id2hrn.get(idParam2);
+ assert hrnParam2 != null;
+
+ TokenTuple p2 = new TokenTuple(hrnParam2.getID(),
+ true,
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ TokenTuple pStar2 = new TokenTuple(hrnParam2.getID(),
+ true,
+ TokenTuple.ARITY_MANY).makeCanonical();
+
+
+ // get special label p_q for first parameter
+ TempDescriptor tdParamQ1 = paramIndex2tdQ.get(paramIndex1);
+ assert tdParamQ1 != null;
+ LabelNode lnParamQ1 = td2ln.get(tdParamQ1);
+ assert lnParamQ1 != null;
+
+ // then get the edge from label q to parameter's hrn
+ ReferenceEdge edgeSpecialQ1 = lnParamQ1.getReferenceTo(hrnParam1, null);
+ assert edgeSpecialQ1 != null;
+
+ // if the beta of this edge has tokens from both parameters in one
+ // token tuple set, then there is a potential alias between them
+ ReachabilitySet beta1 = edgeSpecialQ1.getBeta();
+ assert beta1 != null;
+
+ if( beta1.containsTupleSetWithBoth(p1, p2) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(pStar1, p2) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(p1, pStar2) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(pStar1, pStar2) ) {
+ return true;
+ }
+
+ return false;
+ }
+
+
+ public boolean hasPotentialAlias(Integer paramIndex, AllocationSite as) {
+
+ // get parameter's heap region
+ assert paramIndex2id.containsKey(paramIndex);
+ Integer idParam = paramIndex2id.get(paramIndex);
+
+ assert id2hrn.containsKey(idParam);
+ HeapRegionNode hrnParam = id2hrn.get(idParam);
+ assert hrnParam != null;
+
+ // get tokens for this parameter
+ TokenTuple p = new TokenTuple(hrnParam.getID(),
+ true,
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ TokenTuple pStar = new TokenTuple(hrnParam.getID(),
+ true,
+ TokenTuple.ARITY_MANY).makeCanonical();
+
+ // get special label p_q
+ TempDescriptor tdParamQ = paramIndex2tdQ.get(paramIndex);
+ assert tdParamQ != null;
+ LabelNode lnParamQ = td2ln.get(tdParamQ);
+ assert lnParamQ != null;
+
+ // then get the edge from label q to parameter's hrn
+ ReferenceEdge edgeSpecialQ = lnParamQ.getReferenceTo(hrnParam, null);
+ assert edgeSpecialQ != null;
+
+ // look through this beta set for potential aliases
+ ReachabilitySet beta = edgeSpecialQ.getBeta();
+ assert beta != null;
+
+
+ // get tokens for summary node
+ TokenTuple gs = new TokenTuple(as.getSummary(),
+ true,
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ TokenTuple gsStar = new TokenTuple(as.getSummary(),
+ true,
+ TokenTuple.ARITY_MANY).makeCanonical();
+
+ if( beta.containsTupleSetWithBoth(p, gs) ) {
+ return true;
+ }
+ if( beta.containsTupleSetWithBoth(pStar, gs) ) {
+ return true;
+ }
+ if( beta.containsTupleSetWithBoth(p, gsStar) ) {
+ return true;
+ }
+ if( beta.containsTupleSetWithBoth(pStar, gsStar) ) {
+ return true;
+ }
+
+ // check for other nodes
+ for( int i = 0; i < as.getAllocationDepth(); ++i ) {
+
+ // the other nodes of an allocation site are single, no stars
+ TokenTuple gi = new TokenTuple(as.getIthOldest(i),
+ false,
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ if( beta.containsTupleSetWithBoth(p, gi) ) {
+ return true;
+ }
+ if( beta.containsTupleSetWithBoth(pStar, gi) ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ public boolean hasPotentialAlias(AllocationSite as1, AllocationSite as2) {
+
+ // get tokens for summary nodes
+ TokenTuple gs1 = new TokenTuple(as1.getSummary(),
+ true,
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ TokenTuple gsStar1 = new TokenTuple(as1.getSummary(),
+ true,
+ TokenTuple.ARITY_MANY).makeCanonical();
+
+ // get summary node's alpha
+ Integer idSum1 = as1.getSummary();
+ assert id2hrn.containsKey(idSum1);
+ HeapRegionNode hrnSum1 = id2hrn.get(idSum1);
+ assert hrnSum1 != null;
+ ReachabilitySet alphaSum1 = hrnSum1.getAlpha();
+ assert alphaSum1 != null;
+
+
+ // and for the other one
+ TokenTuple gs2 = new TokenTuple(as2.getSummary(),
+ true,
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ TokenTuple gsStar2 = new TokenTuple(as2.getSummary(),
+ true,
+ TokenTuple.ARITY_MANY).makeCanonical();
+
+ // get summary node's alpha
+ Integer idSum2 = as2.getSummary();
+ assert id2hrn.containsKey(idSum2);
+ HeapRegionNode hrnSum2 = id2hrn.get(idSum2);
+ assert hrnSum2 != null;
+ ReachabilitySet alphaSum2 = hrnSum2.getAlpha();
+ assert alphaSum2 != null;
+
+ // does either one report reachability from the other tokens?
+ if( alphaSum1.containsTuple(gsStar2) ) {
+ return true;
+ }
+ if( alphaSum2.containsTuple(gsStar1) ) {
+ return true;
+ }
+
+ // only check non-star token if they are different sites
+ if( as1 != as2 ) {
+ if( alphaSum1.containsTuple(gs2) ) {
+ return true;
+ }
+ if( alphaSum2.containsTuple(gs1) ) {
+ return true;
+ }
+ }
+
+
+ // check sum2 against alloc1 nodes
+ for( int i = 0; i < as1.getAllocationDepth(); ++i ) {
+ Integer idI1 = as1.getIthOldest(i);
+ assert id2hrn.containsKey(idI1);
+ HeapRegionNode hrnI1 = id2hrn.get(idI1);
+ assert hrnI1 != null;
+ ReachabilitySet alphaI1 = hrnI1.getAlpha();
+ assert alphaI1 != null;
+
+ // the other nodes of an allocation site are single, no stars
+ TokenTuple gi1 = new TokenTuple(as1.getIthOldest(i),
+ false,
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ if( alphaSum2.containsTuple(gi1) ) {
+ return true;
+ }
+ if( alphaI1.containsTuple(gs2) ) {
+ return true;
+ }
+ if( alphaI1.containsTuple(gsStar2) ) {
+ return true;
+ }
+ }
+
+ // check sum1 against alloc2 nodes
+ for( int i = 0; i < as2.getAllocationDepth(); ++i ) {
+ Integer idI2 = as2.getIthOldest(i);
+ assert id2hrn.containsKey(idI2);
+ HeapRegionNode hrnI2 = id2hrn.get(idI2);
+ assert hrnI2 != null;
+ ReachabilitySet alphaI2 = hrnI2.getAlpha();
+ assert alphaI2 != null;
+
+ TokenTuple gi2 = new TokenTuple(as2.getIthOldest(i),
+ false,
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ if( alphaSum1.containsTuple(gi2) ) {
+ return true;
+ }
+ if( alphaI2.containsTuple(gs1) ) {
+ return true;
+ }
+ if( alphaI2.containsTuple(gsStar1) ) {
+ return true;
+ }
+
+ // while we're at it, do an inner loop for alloc2 vs alloc1 nodes
+ for( int j = 0; j < as1.getAllocationDepth(); ++j ) {
+ Integer idI1 = as1.getIthOldest(j);
+
+ // if these are the same site, don't look for the same token, no alias
+ // different tokens of the same site could alias together though
+ if( idI1 == idI2 ) {
+ continue;
+ }
+
+ HeapRegionNode hrnI1 = id2hrn.get(idI1);
+ ReachabilitySet alphaI1 = hrnI1.getAlpha();
+ TokenTuple gi1 = new TokenTuple(as1.getIthOldest(j),
+ false,
+ TokenTuple.ARITY_ONE).makeCanonical();
+ if( alphaI2.containsTuple(gi1) ) {
+ return true;
+ }
+ if( alphaI1.containsTuple(gi2) ) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+
+ // for writing ownership graphs to dot files
+ public void writeGraph(Descriptor methodDesc,
+ FlatNode fn,
+ boolean writeLabels,
+ boolean labelSelect,
+ boolean pruneGarbage,
+ boolean writeReferencers,
+ boolean writeParamMappings
+ ) throws java.io.IOException {
+ writeGraph(
+ methodDesc.getSymbol() +
+ methodDesc.getNum() +
+ fn.toString(),
+ writeLabels,
+ labelSelect,
+ pruneGarbage,
+ writeReferencers,
+ writeParamMappings
+ );
+ }
+
+ public void writeGraph(Descriptor methodDesc,
+ boolean writeLabels,
+ boolean labelSelect,
+ boolean pruneGarbage,
+ boolean writeReferencers,
+ boolean writeParamMappings
+ ) throws java.io.IOException {
+
+ writeGraph(methodDesc+"COMPLETE",
+ writeLabels,
+ labelSelect,
+ pruneGarbage,
+ writeReferencers,
+ writeParamMappings
+ );
+ }
+
+ public void writeGraph(Descriptor methodDesc,
+ Integer numUpdate,
+ boolean writeLabels,
+ boolean labelSelect,
+ boolean pruneGarbage,
+ boolean writeReferencers,
+ boolean writeParamMappings
+ ) throws java.io.IOException {
+
+ writeGraph(methodDesc+"COMPLETE"+String.format("%05d", numUpdate),
+ writeLabels,
+ labelSelect,
+ pruneGarbage,
+ writeReferencers,
+ writeParamMappings
+ );
+ }
+
+ public void writeGraph(String graphName,
+ boolean writeLabels,
+ boolean labelSelect,
+ boolean pruneGarbage,
+ boolean writeReferencers,
+ boolean writeParamMappings
+ ) throws java.io.IOException {
+
+ // remove all non-word characters from the graph name so
+ // the filename and identifier in dot don't cause errors
+ graphName = graphName.replaceAll("[\\W]", "");
+
+ BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+".dot") );
+ bw.write("digraph "+graphName+" {\n");
+
+ HashSet<HeapRegionNode> visited = new HashSet<HeapRegionNode>();
+
+ // then visit every heap region node
+ if( !pruneGarbage ) {
+ Set s = id2hrn.entrySet();
+ Iterator i = s.iterator();
+ while( i.hasNext() ) {
+ Map.Entry me = (Map.Entry)i.next();
+ HeapRegionNode hrn = (HeapRegionNode) me.getValue();
+ if( !visited.contains(hrn) ) {
+ traverseHeapRegionNodes(VISIT_HRN_WRITE_FULL,
+ hrn,
+ bw,
+ null,
+ visited,
+ writeReferencers);
+ }
+ }
+ }
+
+ bw.write(" graphTitle[label=\""+graphName+"\",shape=box];\n");
+
+ if( writeParamMappings ) {
+ Set df = paramIndex2id.entrySet();
+ Iterator ih = df.iterator();
+ while( ih.hasNext() ) {
+ Map.Entry meh = (Map.Entry)ih.next();
+ Integer pi = (Integer) meh.getKey();
+ Integer id = (Integer) meh.getValue();
+ bw.write(" pindex"+pi+"[label=\""+pi+" to "+id+"\",shape=box];\n");
+ }
+ }
+
+ // then visit every label node, useful for debugging
+ if( writeLabels ) {
+ Set s = td2ln.entrySet();
+ Iterator i = s.iterator();
+ while( i.hasNext() ) {
+ Map.Entry me = (Map.Entry)i.next();
+ LabelNode ln = (LabelNode) me.getValue();
+
+ if( labelSelect ) {
+ String labelStr = ln.getTempDescriptorString();
+ if( labelStr.startsWith("___temp") ||
+ labelStr.startsWith("___dst") ||
+ labelStr.startsWith("___srctmp") ||
+ labelStr.startsWith("___neverused") ) {
+ continue;
+ }
+ }
+
+ bw.write(ln.toString() + ";\n");
+
+ Iterator<ReferenceEdge> heapRegionsItr = ln.iteratorToReferencees();
+ while( heapRegionsItr.hasNext() ) {
+ ReferenceEdge edge = heapRegionsItr.next();
+ HeapRegionNode hrn = edge.getDst();
+
+ if( pruneGarbage && !visited.contains(hrn) ) {
+ traverseHeapRegionNodes(VISIT_HRN_WRITE_FULL,
+ hrn,
+ bw,
+ null,
+ visited,
+ writeReferencers);
+ }
+
+ bw.write(" " + ln.toString() +
+ " -> " + hrn.toString() +
+ "[label=\"" + edge.toGraphEdgeString() +
+ "\",decorate];\n");
+ }
+ }
+ }
+
+
+ bw.write("}\n");
+ bw.close();
+ }
+
+ protected void traverseHeapRegionNodes(int mode,
+ HeapRegionNode hrn,
+ BufferedWriter bw,
+ TempDescriptor td,
+ HashSet<HeapRegionNode> visited,
+ boolean writeReferencers
+ ) throws java.io.IOException {
+
+ if( visited.contains(hrn) ) {
+ return;
+ }
+ visited.add(hrn);
+
+ switch( mode ) {
+ case VISIT_HRN_WRITE_FULL:
+
+ String attributes = "[";
+
+ if( hrn.isSingleObject() ) {
+ attributes += "shape=box";
+ } else {
+ attributes += "shape=Msquare";
+ }
+
+ if( hrn.isFlagged() ) {
+ attributes += ",style=filled,fillcolor=lightgrey";
+ }
+
+ attributes += ",label=\"ID" +
+ hrn.getID() +
+ "\\n" +
+ hrn.getDescription() +
+ "\\n" +
+ hrn.getAlphaString() +
+ "\"]";
+
+ bw.write(" " + hrn.toString() + attributes + ";\n");
+ break;
+ }
+
+
+ // useful for debugging
+ if( writeReferencers ) {
+ OwnershipNode onRef = null;
+ Iterator refItr = hrn.iteratorToReferencers();
+ while( refItr.hasNext() ) {
+ onRef = (OwnershipNode) refItr.next();
+
+ switch( mode ) {
+ case VISIT_HRN_WRITE_FULL:
+ bw.write(" " + hrn.toString() +
+ " -> " + onRef.toString() +
+ "[color=lightgray];\n");
+ break;
+ }
+ }
+ }
+
+ Iterator<ReferenceEdge> childRegionsItr = hrn.iteratorToReferencees();
+ while( childRegionsItr.hasNext() ) {
+ ReferenceEdge edge = childRegionsItr.next();
+ HeapRegionNode hrnChild = edge.getDst();
+
+ switch( mode ) {
+ case VISIT_HRN_WRITE_FULL:
+ bw.write(" " + hrn.toString() +
+ " -> " + hrnChild.toString() +
+ "[label=\"" + edge.toGraphEdgeString() +
+ "\",decorate];\n");
+ break;
+ }
+
+ traverseHeapRegionNodes(mode,
+ hrnChild,
+ bw,
+ td,
+ visited,
+ writeReferencers);
+ }
+ }
+}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import Util.*;
-
-public class Allocations extends Namer {
- public Allocations() {}
-
- public String nodeLabel(GraphNode gn) {
- return "";
- }
-
- public String nodeOption(GraphNode gn) {
- FlagState fs=(FlagState)gn;
- if (fs.isSourceNode())
- return "peripheries=2, URL=\"" + fs.getClassDescriptor().toString() + "_" + fs.getLabel() + ".html\"";
- else
- return "";
- }
-
- public String edgeLabel(Edge e) {
- return "";
- }
-
- public String edgeOption(Edge e) {
- return "";
- }
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import IR.*;
-import Analysis.TaskStateAnalysis.*;
-import IR.Tree.*;
-import IR.Flat.*;
-import java.util.*;
-import Util.Edge;
-
-
-public class EGEdge extends Edge{
- EGTaskNode target;
-
-
- public EGEdge(EGTaskNode target){
- super(target);
- this.target = target;
- }
-
- public EGTaskNode getTarget(){
- return target;
- }
-
- public int hashCode(){
- return target.hashCode();
- }
-
- public boolean equals(Object o) {
- if (o instanceof EGEdge) {
- EGEdge e=(EGEdge)o;
- return e.target.equals(target);
- }
- return false;
- }
-
-
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import Analysis.TaskStateAnalysis.*;
-import IR.*;
-import IR.Tree.*;
-import IR.Flat.*;
-import java.util.*;
-import Util.GraphNode;
-
-public class EGTaskNode extends TaskNode {
- private boolean source=false;
- private int loopmarker=0;
- private boolean multipleparams=false;
- private boolean optional = false;
- private boolean marked=false;
- private boolean tomention=true;
- private int type = 0;
- private FlagState fs;
- private TaskDescriptor td;
- protected HashSet edges = new HashSet();
- public EGTaskNode(){
- super("default");
- this.fs = null;
- this.td = null;
- }
-
- public EGTaskNode(String name){
- super(name);
- this.fs = null;
- this.td = null;
- }
-
- public EGTaskNode(String name, FlagState fs){
- super(name);
- this.fs = fs;
- this.td = null;
- }
-
- public EGTaskNode(String name, TaskDescriptor td){
- super(name);
- this.fs = null;
- this.td = td;
- }
-
- public EGTaskNode(String name, FlagState fs, TaskDescriptor td){
- super(name);
- this.fs = fs;
- this.td = td;
- }
-
- public int hashCode(){
- return getLabel().hashCode();
- }
-
- public boolean equals(Object o){
- if(o instanceof EGTaskNode){
- EGTaskNode tn=(EGTaskNode) o;
- return (tn.getLabel().compareTo(this.getLabel())==0) ? true : false;
- }
- return false;
- }
-
- public HashSet getEdgeSet(){
- return edges;
- }
-
- public void addEdge(EGEdge newedge) {
- newedge.setSource(this);
- edges.add(newedge);
- EGTaskNode tonode=newedge.getTarget();
- tonode.inedges.addElement(newedge);
- }
-
- public Iterator edges(){
- return edges.iterator();
- }
-
- public TaskDescriptor getTD(){
- return td;
- }
-
- public void setSource(){
- source = true;
- }
-
- public boolean isSource(){
- return source;
- }
-
- public int getuid(){
- return uid;
- }
-
- public void doSelfLoopMarking(){
- loopmarker=1;
- }
-
- public void doLoopMarking(){
- loopmarker=2;
- }
-
- public boolean isSelfLoop(){
- if (loopmarker==1) return true;
- else return false;
- }
-
- public boolean isLoop(){
- if (loopmarker==2) return true;
- else return false;
- }
-
- public void setMultipleParams(){
- multipleparams=true;
- }
-
- public boolean isMultipleParams(){
- return multipleparams;
- }
-
- public void setOptional(){
- optional = true;
- }
-
- public boolean isOptional(){
- return optional;
- }
-
- public void mark(){
- marked = true;
- }
-
- public void unMark(){
- marked = false;
- }
-
- public boolean isMarked(){
- return marked;
- }
-
- public String getFSName(){
- if(fs == null) return "no flag";
- else return fs.getTextLabel();
- }
-
- public FlagState getFS(){
- return fs;
- }
-
- public void dontMention(){
- tomention = false;
- }
-
- public boolean toMention(){
- return tomention;
- }
-
- public void setAND(){
- type = 1;
- }
-
- public void setOR(){
- type = 0;
- }
-
- public int type(){
- return type;
- }
-
-
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import java.util.*;
-import IR.State;
-import IR.SymbolTable;
-import IR.ClassDescriptor;
-import IR.TaskDescriptor;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.FileOutputStream;
-import Util.Edge;
-
-public class ExecutionGraph {
-
- private TaskAnalysis taskanalysis;
- private State state;
- private Hashtable graph;
- private Hashtable executiongraph;
- private SymbolTable tasks;
-
- public ExecutionGraph(State state, TaskAnalysis ta){
- this.taskanalysis=ta;
- this.state=state;
- this.tasks = this.state. getTaskSymbolTable();
- this.graph=new Hashtable();
- this.executiongraph = new Hashtable();
- }
-
- public Hashtable getExecutionGraph(){
- return executiongraph;
- }
-
- public void createExecutionGraph() throws java.io.IOException {
- /*Explore the taskanalysis structure*/
- System.out.println("------- BUILDING THE EXECUTION GRAPH -------");
- Enumeration e=taskanalysis.flagstates.keys();
-
- while (e.hasMoreElements()) {
- System.out.println("\nBuilding class :");
- ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
- System.out.println("\t"+(cdtemp.getSymbol())+ "\n");
- exploreGraph(cdtemp);
- test();
- adapt(cdtemp);
- }
- printDOTFile();
-
- }
-
- private void exploreGraph(ClassDescriptor cd) {
-
- LinkedList fifo = new LinkedList();
- Vector sourceNodeList = new Vector();
- Enumeration e;
- graph.clear();
-
- /* Search for starting nodes */
- Collection nodes = ((Hashtable)taskanalysis.flagstates.get(cd)).values();
- Iterator it = nodes.iterator();
- while (it.hasNext()) {
- FlagState fs = (FlagState)it.next();
- if(fs.isSourceNode()){
- sourceNodeList.addElement(fs);
- }
- }
-
- /* Perform the Breadth first search algorithm and build ExecutionGraph */
- FlagState fstemp, fstemp2;
- Iterator sourceit = sourceNodeList.iterator();
- while( sourceit.hasNext() ){
- FlagState fs = (FlagState)sourceit.next();
-
- fs.doMarking();
- fifo.addLast(fs);
-
- while ( !fifo.isEmpty() ){
-
- fstemp = (FlagState)fifo.getFirst();
- fifo.removeFirst();
-
- System.out.println("IN FS : "+fstemp.getTextLabel());
-
- Iterator edges = fstemp.edges();
- if (edges.hasNext()){
-
- //build corresponding nodes of the ExecutionGraph
- createNode(fstemp);
-
- //add the other non marked (prevent looping) fses to the fifo
- while(edges.hasNext()){
-
- FEdge edge = (FEdge)edges.next();
- fstemp2 = (FlagState)edge.getTarget();
-
- if ( !fstemp2.isMarked() ) {
- fstemp2.doMarking();
- fifo.addLast(fstemp2);
- }
- }
-
- //if the flagstate is not entirely processed, back into fifo
- if (!isFinished(fstemp)){
- fifo.addLast(fstemp);
- }
- }
-
- }
- }
- }
-
- private void createNode(FlagState fs){
- Enumeration allocatingtasks;
- EGTaskNode tn;
- EGTaskNode target;
- FEdge edge;
- //the idea is to look at the inedges to find the "parents" nodes. Then create the "children" and link them to the "parents".
- if (fs.isSourceNode()){
- //in the case of sourcenode, "parents" are the allocating tasks
- for (Iterator inedges = ((Vector)fs.getAllocatingTasks()).iterator(); inedges.hasNext();){
- String tname = new String(((TaskDescriptor)inedges.next()).getSymbol());
- //the hashkey for source EGTaskNodes is : nextfs+taskname.
- String key1 = new String(fs.getTextLabel()+tname);
- //get the parent
- if (graph.containsKey(key1)){
- tn = (EGTaskNode)graph.get(key1);
- }
- else{//if not existing, create it
- tn = new EGTaskNode(tname,(TaskDescriptor)tasks.get(tname));
- tn.setSource();
- }
- //create the children. the key is : nextfs+taskname+previousfs (that ensures that only one node can have that key).
- for (Iterator edges = fs.edges(); edges.hasNext();){
- edge = (FEdge)edges.next();
- target=new EGTaskNode(edge.getLabel(), fs, (TaskDescriptor)tasks.get(edge.getLabel()));
- String key2 = new String(((FlagState)edge.getTarget()).getTextLabel()+target.getName()+((FlagState)edge.getSource()).getTextLabel());
- //mark if is self loop
- if (((FlagState)edge.getTarget()).isMarked()){
- target.doSelfLoopMarking();
- }
- //check if child already exists. if not, create it.
- //link to the parent.
- if (graph.containsKey(key2)){
- target = (EGTaskNode)graph.get(key2);
- EGEdge newedge=new EGEdge(target);
- tn.addEdge(newedge);
- }
- else {
- EGEdge newedge=new EGEdge(target);
- tn.addEdge(newedge);
- }
- //put child in graph
- graph.put(key2, target);
- }
- //put parent in graph
- graph.put(key1, tn);
- }
- }
-
- for (Iterator inedges = fs.inedges(); inedges.hasNext();){
- //regular case, "parents" are the inedges.
- FEdge in=(FEdge)inedges.next();
- if (!in.isProcessed()){
- //the key to search is : nextfs+taskname+previousfs.
- String key1 = new String(fs.getTextLabel()+in.getLabel()+((FlagState)in.getSource()).getTextLabel());
- tn = (EGTaskNode)graph.get(key1);
- //if the TaskNode does not exist, that means that we are in the case of a loop.
- //The fs will not be entirely processed, will be put back in the fifo until the TaskNode has finaly been created.
- if (tn != null){
- //same process than with the sourcenode.
- for (Iterator edges = fs.edges(); edges.hasNext();){
- edge = (FEdge)edges.next();
- target=new EGTaskNode(edge.getLabel(), fs, (TaskDescriptor)tasks.get(edge.getLabel()));
- String key2 = new String(((FlagState)edge.getTarget()).getTextLabel()+target.getName()+((FlagState)edge.getSource()).getTextLabel());
- if (((String)((FlagState)edge.getTarget()).getTextLabel()).compareTo(fs.getTextLabel())==0){
- target.doSelfLoopMarking();
- }
- if (graph.containsKey(key2)){
- target = (EGTaskNode)graph.get(key2);
- EGEdge newedge=new EGEdge(target);
- tn.addEdge(newedge);
- }
- else {
- EGEdge newedge=new EGEdge(target);
- tn.addEdge(newedge);
- }
- graph.put(key2, target);
- }
- graph.put(key1, tn);
- in.setProcessed();
- }
- }
- }
- }
-
- //put the graph into executiongraph
- private void adapt(ClassDescriptor cd) {
- Vector tasknodes = new Vector();
- tasknodes.addAll(graph.values());
- executiongraph.put(cd,tasknodes);
- }
- //print the contain of graph
- private void test() {
- System.out.println("\nGraph contains :");
- Collection c = graph.values();
- for ( Iterator it = c.iterator(); it.hasNext();){
- EGTaskNode tn = (EGTaskNode)it.next();
- System.out.println(tn.getTextLabel()+" ID "+tn.getLabel()+" FS "+tn.getFSName());
- }
- }
-
- //test if a flagstate has been entirely processed
- private boolean isFinished(FlagState fs){
-
- for (Iterator inedges = fs.inedges(); inedges.hasNext();){
-
- FEdge in=(FEdge)inedges.next();
-
- if (!in.isProcessed()){
- String key1 = new String(fs.getTextLabel()+in.getLabel()+((FlagState)in.getSource()).getTextLabel());
-
- if (graph.get(key1)==null){
- //except for the case of self loop, if the pointed tn is not present, fs is not totally processed
- if (((String)((FlagState)in.getSource()).getTextLabel()).compareTo(fs.getTextLabel())!=0){
- return false;
- }
- }
-
- }
- }
- return true;
- }
-
-
- //********DEBUG
- //create dot files execution_classname_.dot
- private void printDOTFile()throws java.io.IOException {
- Enumeration e = executiongraph.keys();
- while (e.hasMoreElements()){
- createDOTFile((ClassDescriptor)e.nextElement());
- }
- }
-
- private void createDOTFile(ClassDescriptor cd) throws java.io.IOException {
- Vector v = (Vector)executiongraph.get(cd);
- java.io.PrintWriter output;
- File dotfile_flagstates= new File("execution"+cd.getSymbol()+".dot");
- FileOutputStream dotstream=new FileOutputStream(dotfile_flagstates,true);
- output = new java.io.PrintWriter(dotstream, true);
- output.println("digraph dotvisitor {");
- output.println("\tnode [fontsize=10,height=\"0.1\", width=\"0.1\"];");
- output.println("\tedge [fontsize=6];");
- traverse(output, v);
- output.println("}\n");
- }
-
- private void traverse(java.io.PrintWriter output, Vector v) {
- EGTaskNode tn;
-
- for(Iterator it1 = v.iterator(); it1.hasNext();){
- tn = (EGTaskNode)it1.next();
- output.println("\t"+tn.getLabel()+" [label=\""+tn.getTextLabel()+"\"");
- if (tn.isSelfLoop()) output.println(", shape=box");
- if (tn.isMultipleParams()) output.println(", color=blue");
- output.println("];");
-
-
- for(Iterator it2 = tn.edges();it2.hasNext();){
- output.println("\t"+tn.getLabel()+" -> "+((EGTaskNode)((EGEdge)it2.next()).getTarget()).getLabel()+";");
- }
- }
- }
- //*********************
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import IR.*;
-import Analysis.TaskStateAnalysis.*;
-import IR.Tree.*;
-import IR.Flat.*;
-import java.util.*;
-import Util.Edge;
-
-/* Edge *****************/
-
-public class FEdge extends Edge {
-
- private String label;
- /** Class Constructor
- *
- */
- public FEdge(FlagState target, String label) {
- super(target);
- this.label = label;
- }
-
- public String getLabel() {
- return label;
- }
-
- public int hashCode(){
- return target.hashCode()^label.hashCode();
- }
-
- public boolean equals(Object o) {
- if (o instanceof FEdge) {
- FEdge e=(FEdge)o;
- return e.label.equals(label)&&
- e.target.equals(target);
- }
- return false;
- }
-
-
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import Analysis.TaskStateAnalysis.*;
-import IR.*;
-import IR.Tree.*;
-import IR.Flat.*;
-import java.util.*;
-import java.io.*;
-import Util.GraphNode;
-
-/** This class is used to hold the flag states that a class in the Bristlecone
- * program can exist in, during runtime.
- */
-public class FlagState extends GraphNode {
- public static final int ONETAG=1;
- public static final int NOTAGS=0;
- public static final int MULTITAGS=-1;
-
- private int uid;
- private static int nodeid=0;
-
- private final HashSet flagstate;
- private final ClassDescriptor cd;
- private final Hashtable<TagDescriptor,Integer> tags;
- private boolean issourcenode;
- private Vector tasks;
-
- private boolean marked=false;
-
-
- /** Class constructor
- * Creates a new flagstate with all flags set to false.
- * @param cd ClassDescriptor
- */
- public FlagState(ClassDescriptor cd) {
- this.flagstate=new HashSet();
- this.cd=cd;
- this.tags=new Hashtable<TagDescriptor,Integer>();
- this.uid=FlagState.nodeid++;
- this.issourcenode=false;
- }
-
- /** Class constructor
- * Creates a new flagstate with flags set according to the HashSet.
- * If the flag exists in the hashset, it's set to true else set to false.
- * @param cd ClassDescriptor
- * @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
- */
- private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
- this.flagstate=flagstate;
- this.cd=cd;
- this.tags=tags;
- this.uid=FlagState.nodeid++;
- this.issourcenode=false;
-
- }
-
- public int getuid() {
- return uid;
- }
-
- public boolean isMarked() {
- return marked;
- }
-
- public void doUnmarking() {
- marked = false;
- }
-
- public void doMarking() {
- marked = true;
- }
-
- /** Accessor method
- * @param fd FlagDescriptor
- * @return true if the flagstate contains fd else false.
- */
- public boolean get(FlagDescriptor fd) {
- return flagstate.contains(fd);
- }
-
- /** Checks if the flagstate is a source node.
- * @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
- */
-
- public boolean isSourceNode(){
- return issourcenode;
- }
-
- /** Sets the flagstate as a source node.
- */
- public void setAsSourceNode(){
- if(!issourcenode){
- issourcenode=true;
- this.tasks=new Vector();
- }
- }
-
- public void addAllocatingTask(TaskDescriptor task){
- tasks.add(task);
- }
-
- public Vector getAllocatingTasks(){
- return tasks;
- }
-
-
- public String toString() {
- return cd.toString()+getTextLabel();
- }
-
- /** @return Iterator over the flags in the flagstate.
- */
-
- public Iterator getFlags() {
- return flagstate.iterator();
- }
-
- public int numFlags(){
- return flagstate.size();
- }
-
- public FlagState[] setTag(TagDescriptor tag){
- HashSet newset1=(HashSet)flagstate.clone();
- Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
-
- if (tags.containsKey(tag)){
- //Code could try to remove flag that doesn't exist
-
- switch (tags.get(tag).intValue()){
- case ONETAG:
- newtags1.put(tag,new Integer(MULTITAGS));
- return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
- case MULTITAGS:
- return new FlagState[] {this};
- default:
- throw new Error();
- }
- } else {
- newtags1.put(tag,new Integer(ONETAG));
- return new FlagState[] {new FlagState(newset1,cd,newtags1)};
- }
- }
-
- public int getTagCount(String tagtype){
- for (Enumeration en=getTags();en.hasMoreElements();){
- TagDescriptor td=(TagDescriptor)en.nextElement();
- if (tagtype.equals(td.getSymbol()))
- return tags.get(td).intValue(); //returns either ONETAG or MULTITAG
- }
- return NOTAGS;
- }
-
- public FlagState[] clearTag(TagDescriptor tag){
- if (tags.containsKey(tag)){
- switch(tags.get(tag).intValue()){
- case ONETAG:
- HashSet newset=(HashSet)flagstate.clone();
- Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
- newtags.remove(tag);
- return new FlagState[]{new FlagState(newset,cd,newtags)};
-
- case MULTITAGS:
- //two possibilities - count remains 2 or becomes 1
- //2 case
- HashSet newset1=(HashSet)flagstate.clone();
- Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
-
- //1 case
- HashSet newset2=(HashSet)flagstate.clone();
- Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
- newtags1.put(tag,new Integer(ONETAG));
- return new FlagState[] {new FlagState(newset1, cd, newtags2),
- new FlagState(newset2, cd, newtags2)};
- default:
- throw new Error();
- }
- } else {
- throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
- }
- }
-
- /** Creates a string description of the flagstate
- * e.g. a flagstate with five flags could look like 01001
- * @param flags an array of flagdescriptors.
- * @return string representation of the flagstate.
- */
- public String toString(FlagDescriptor[] flags)
- {
- StringBuffer sb = new StringBuffer(flagstate.size());
- for(int i=0;i < flags.length; i++)
- {
- if (get(flags[i]))
- sb.append(1);
- else
- sb.append(0);
- }
-
- return new String(sb);
- }
-
- /** Accessor method
- * @return returns the classdescriptor of the flagstate.
- */
-
- public ClassDescriptor getClassDescriptor(){
- return cd;
- }
-
- /** Sets the status of a specific flag in a flagstate after cloning it.
- * @param fd FlagDescriptor of the flag whose status is being set.
- * @param status boolean value
- * @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
- */
-
- public FlagState setFlag(FlagDescriptor fd, boolean status) {
- HashSet newset=(HashSet) flagstate.clone();
- Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
- if (status)
- newset.add(fd);
- else if (newset.contains(fd)){
- newset.remove(fd);
- }
-
- return new FlagState(newset, cd, newtags);
- }
-
- /** Tests for equality of two flagstate objects.
- */
-
- public boolean equals(Object o) {
- if (o instanceof FlagState) {
- FlagState fs=(FlagState)o;
- if (fs.cd!=cd)
- return false;
- return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
- }
- return false;
- }
-
- public int hashCode() {
- return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
- }
-
- public String getLabel() {
- return "N"+uid;
- }
-
-
-
-
- public String getTextLabel() {
- String label=null;
- for(Iterator it=getFlags();it.hasNext();) {
- FlagDescriptor fd=(FlagDescriptor) it.next();
- if (label==null)
- label=fd.toString();
- else
- label+=", "+fd.toString();
- }
- for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
- TagDescriptor td=(TagDescriptor)en_tags.nextElement();
- switch (tags.get(td).intValue()){
- case ONETAG:
- if (label==null)
- label=td.toString()+"(1)";
- else
- label+=", "+td.toString()+"(1)";
- break;
- case MULTITAGS:
- if (label==null)
- label=td.toString()+"(n)";
- else
- label+=", "+td.toString()+"(n)";
- break;
- default:
- break;
- }
- }
- if (label==null)
- return " ";
- return label;
- }
-
- public Enumeration getTags(){
- return tags.keys();
- }
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import IR.*;
-import Util.Namer;
-import java.util.*;
-import Util.GraphNode;
-import Util.Edge;
-
-public class GarbageAnalysis extends Namer {
- State state;
- TaskAnalysis taskanalysis;
- HashSet garbagestates;
- HashSet possiblegarbagestates;
-
-
- public GarbageAnalysis(State state, TaskAnalysis taskanalysis) {
- this.state=state;
- this.taskanalysis=taskanalysis;
- this.garbagestates=new HashSet();
- this.possiblegarbagestates=new HashSet();
- doAnalysis();
- }
-
- public void doAnalysis() {
- for(Iterator it=state.getClassSymbolTable().getDescriptorsIterator();it.hasNext();) {
- ClassDescriptor cd=(ClassDescriptor) it.next();
- if (taskanalysis.getFlagStates(cd)==null)
- continue;
- analyzeClass(cd);
- }
- }
-
- public void analyzeClass(ClassDescriptor cd) {
- Set flagstatenodes=taskanalysis.getFlagStates(cd);
- HashSet garbage=new HashSet();
- HashSet possiblegarbage=new HashSet();
-
- for(Iterator fsit=flagstatenodes.iterator();fsit.hasNext();) {
- FlagState fs=(FlagState)fsit.next();
- if (fs.numedges()==0)
- garbage.add(fs);
- }
-
- Stack tovisit=new Stack();
- tovisit.addAll(garbage);
- possiblegarbage.addAll(garbage);
- while(!tovisit.isEmpty()) {
- FlagState fs=(FlagState)tovisit.pop();
- for(int i=0;i<fs.numinedges();i++) {
- Edge e=fs.getinedge(i);
- FlagState fsnew=(FlagState) e.getSource();
- if (!possiblegarbage.contains(fsnew)) {
- possiblegarbage.add(fsnew);
- tovisit.push(fsnew);
- }
- }
- }
- garbagestates.addAll(garbage);
- possiblegarbagestates.addAll(possiblegarbage);
- }
-
- public String nodeLabel(GraphNode gn) {
- return "";
- }
-
- public String nodeOption(GraphNode gn) {
- if (garbagestates.contains(gn)) {
- return "color=green";
- } else if (possiblegarbagestates.contains(gn)) {
- return "color=blue";
- } else
- return "color=red";
- }
-
- public String edgeLabel(Edge e) {
- return "";
- }
-
- public String edgeOption(Edge e) {
- return "";
- }
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import java.util.*;
-import IR.*;
-import IR.Tree.*;
-import IR.Flat.*;
-import java.io.*;
-import Util.Edge;
-
-public class OptionalTaskDescriptor{
- public TaskDescriptor td;
- public HashSet flagstates;
- public int depth;
- public HashSet<HashSet> exitfses;
- public Predicate predicate;
- private static int nodeid=0;
- private int uid;
-
- protected OptionalTaskDescriptor(TaskDescriptor td, HashSet flagstates, int depth, Predicate predicate){
- this.td = td;
- this.flagstates = flagstates;
- this.depth = depth;
- this.exitfses = new HashSet();
- this.predicate = predicate;
- this.uid = OptionalTaskDescriptor.nodeid++;
-
- }
-
- public boolean equals(Object o){
- if (o instanceof OptionalTaskDescriptor) {
- OptionalTaskDescriptor otd = (OptionalTaskDescriptor) o;
- if (this.td.getSymbol().compareTo(otd.td.getSymbol())==0)
- if(this.flagstates.equals(otd.flagstates))
- if(this.predicate.equals(otd.predicate))
- return true;
- return false;
- }
- else return false;
-
- }
-
- public int hashCode() {
- return td.getSymbol().hashCode()+flagstates.hashCode()+predicate.hashCode();
- }
-
- public String tostring() {
- return "Optional task "+td.getSymbol();
- }
-
- public int getuid() {
- return uid;
- }
-
-
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import java.util.*;
-import IR.*;
-import IR.Tree.*;
-import IR.Flat.*;
-import Util.Edge;
-
-public class Predicate{
- public Hashtable<String, VarDescriptor> vardescriptors;
- public Hashtable<String, HashSet<FlagExpressionNode>> flags;
- public Hashtable<String, TagExpressionList> tags; //if there is a tag change, we stop the analysis
-
- public Predicate(){
- this.vardescriptors = new Hashtable();
- this.flags = new Hashtable();
- this.tags = new Hashtable();
- }
-
- public boolean equals(Object o){
- if(o instanceof Predicate){
- Predicate p = (Predicate) o;
- if(this.vardescriptors.equals(p.vardescriptors))
- return true;
- return false;
- }
- else return false;
- }
-
- public int hashCode(){
- return vardescriptors.hashCode();
- }
-
-
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import java.util.*;
-import IR.*;
-import IR.Tree.*;
-import IR.Flat.*;
-import java.io.*;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.FileOutputStream;
-import Util.Edge;
-
-public class SafetyAnalysis {
-
- private Hashtable executiongraph;
- private Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution; //to use to build code
- private static final int OR = 0;
- private static final int AND = 1;
- private Hashtable reducedgraph;
- private String classname;
- private State state;
- private TaskAnalysis taskanalysis;
- private Hashtable<ClassDescriptor, Hashtable> optionaltaskdescriptors;
-
- private ClassDescriptor processedclass;
-
-
- public Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> getResult(){
- return safeexecution;
- }
-
- public Hashtable<ClassDescriptor, Hashtable> getOptionalTaskDescriptors(){
- return optionaltaskdescriptors;
- }
-
- /*Structure that stores a possible optional
- task which would be safe to execute and
- the possible flagstates the object could
- be in before executing the task during an
- execution without failure*/
-
- /*Constructor*/
- public SafetyAnalysis(Hashtable executiongraph, State state, TaskAnalysis taskanalysis){
- this.executiongraph = executiongraph;
- this.safeexecution = new Hashtable();
- this.reducedgraph = new Hashtable();
- this.state = state;
- this.taskanalysis = taskanalysis;
- this.optionaltaskdescriptors = new Hashtable();
- }
-
- /*finds the the source node in the execution graph*/
- private EGTaskNode findSourceNode(Vector nodes){
- for(Iterator it = nodes.iterator(); it.hasNext();){
- EGTaskNode tn = (EGTaskNode)it.next();
- if(tn.isSource()){
- return tn;
- }
- }
- return null;
- }
-
- /*returns the nodes corresponding to the tasks
- that can fire with the object in flagstate
- previousflagstate*/
- private Vector findEGTaskNode(String previousflagstate, Vector nodes){
- Vector tns = new Vector();
- for(Iterator it = nodes.iterator(); it.hasNext();){
- EGTaskNode tn = (EGTaskNode)it.next();
- if(tn.getFSName().compareTo(previousflagstate)==0)
- tns.add(tn);
- }
- if(tns.size() == 0)
- return null;
- else if (tns.size() > 1){
- for(Iterator it = tns.iterator(); it.hasNext();){
- EGTaskNode tn = (EGTaskNode)it.next();
- tn.setAND();
- }
- }
- return tns;
- }
-
- /*returns the executiongraph corresponding to the classname*/
- private Vector getConcernedClass( String classname ){
- Enumeration e = executiongraph.keys();
- while( e.hasMoreElements() ){
- ClassDescriptor cd = (ClassDescriptor)e.nextElement();
- if (classname.compareTo(cd.getSymbol())==0)
- return (Vector)executiongraph.get(cd);
- }
- return null;
- }
-
- /*Actual method used by the compiler.
- It computes the analysis for every
- possible flagstates of every classes*/
- public void buildPath() throws java.io.IOException {
- /*Explore the taskanalysis structure*/
- System.out.println("------- ANALYSING OPTIONAL TASKS -------");
- Enumeration e=taskanalysis.flagstates.keys();
-
- while (e.hasMoreElements()) {
- System.out.println("\nAnalysing class :");
- processedclass=(ClassDescriptor)e.nextElement();
- classname = processedclass.getSymbol();
- Hashtable newhashtable = new Hashtable();
- optionaltaskdescriptors.put(processedclass, newhashtable);
- Hashtable cdhashtable = new Hashtable();
-
- System.out.println("\t"+classname+ "\n");
- //get the graph result of executiongraph class
- Vector nodes = new Vector();
- nodes = getConcernedClass( classname );
- if(nodes==null) {
- System.out.println("Impossible to find "+classname+". Unexpected.");
- continue;
- }
- else if(nodes.size()==0){
- System.out.println("Nothing to do");
- continue;
- }
-
- //mark the graph
- EGTaskNode sourcenode = findSourceNode(nodes);
- doGraphMarking(sourcenode);
- createDOTFile( classname );
- reducedgraph.clear();
-
- Collection fses = ((Hashtable)taskanalysis.flagstates.get(processedclass)).values();
- Iterator itfses = fses.iterator();
- while (itfses.hasNext()) {
- FlagState fs = (FlagState)itfses.next();
- Hashtable fsresult = new Hashtable();
- //get the tasknodes possible to execute with the flagstate before failure
- HashSet tempnodes = new HashSet();
- Vector tns = new Vector();
- System.out.println("Analysing "+fs.getTextLabel());
- tns = findEGTaskNode(fs.getTextLabel(), nodes);
- if(tns==null) {
- System.out.println("\tNo task corresponding, terminal FS");
- continue;
- }
- System.out.println("\tProcessing...");
-
- //compute the result for all the nodes contained in tns.
- //return the intersection of tns that are the same task and union for others.
-
- HashSet availabletasks = new HashSet();
- availabletasks = computeTns(tns);
-
- //removeDoubles(availabletasks);
-
- for(Iterator it = availabletasks.iterator(); it.hasNext();){
- OptionalTaskDescriptor otd = (OptionalTaskDescriptor)it.next();
- resultingFS(otd, classname);
- }
-
- cdhashtable.put(fs, availabletasks);
- }
-
- safeexecution.put(processedclass, cdhashtable);
-
- }
- cleanPredicates();
- printTEST();
-
-
- }
-
- private void printTEST(){
-
- Enumeration e = safeexecution.keys();
- while (e.hasMoreElements()) {
- ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
- System.out.println("\nTesting class : "+cdtemp.getSymbol()+"\n");
- Hashtable hashtbtemp = safeexecution.get(cdtemp);
- Enumeration fses = hashtbtemp.keys();
- while(fses.hasMoreElements()){
- FlagState fs = (FlagState)fses.nextElement();
- System.out.println("\t"+fs.getTextLabel()+"\n\tSafe tasks to execute :\n");
- HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
- for(Iterator otd_it = availabletasks.iterator(); otd_it.hasNext();){
- OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
- System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
- System.out.println("\t\tDepth : "+otd.depth);
- System.out.println("\t\twith flags :");
- for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
- System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
- }
- System.out.println("\t\tand exitflags :");
- for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
- HashSet temphs = (HashSet)fseshash.next();
- System.out.println("");
- for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
- System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
- }
- }
- Predicate predicate = otd.predicate;
- System.out.println("\t\tPredicate constains :");
- Collection c = predicate.vardescriptors.values();
- for(Iterator varit = c.iterator(); varit.hasNext();){
- VarDescriptor vard = (VarDescriptor)varit.next();
- System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
- }
- System.out.println("\t\t------------");
- }
- }
-
- System.out.println("\n\n\n\tOptionaltaskdescriptors contains : ");
- Collection c_otd = optionaltaskdescriptors.get(cdtemp).values();
- for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
- OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
- System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
- System.out.println("\t\tDepth : "+otd.depth);
- System.out.println("\t\twith flags :");
- for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
- System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
- }
- System.out.println("\t\tand exitflags :");
- for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
- HashSet temphs = (HashSet)fseshash.next();
- System.out.println("");
- for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
- System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
- }
- }
- Predicate predicate = otd.predicate;
- System.out.println("\t\tPredicate contains :");
- Collection c = predicate.vardescriptors.values();
- for(Iterator varit = c.iterator(); varit.hasNext();){
- VarDescriptor vard = (VarDescriptor)varit.next();
- System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
- HashSet temphash = predicate.flags.get(vard.getName());
- if(temphash == null) System.out.println("null hashset");
- else System.out.println("\t\t\t"+temphash.size()+" flag(s)");
-
- }
- System.out.println("\t\t------------");
- }
- }
-
-
- }
-
- /*Marks the executiongraph :
- -optionals
- -multiple
- -AND and OR nodes
- */
- private void doGraphMarking(EGTaskNode extremity) throws java.io.IOException{
- //detects if there is a loop or no more nodes to explore
- if (extremity.isMarked() || !((Iterator)extremity.edges()).hasNext()){
- if (!((Iterator)extremity.edges()).hasNext()) extremity.mark();
- reducedgraph.put(extremity.getuid(), extremity);
- }
- else {
- //do the marking
- process(extremity);
- reducedgraph.put(extremity.getuid(), extremity);
- extremity.mark();
- //calls doGraphMarking recursively with the next nodes as params
- for( Iterator it = extremity.edges(); it.hasNext(); ){
- EGEdge edge = (EGEdge)it.next();
- doGraphMarking((EGTaskNode)edge.getTarget());
- }
- }
- }
-
- private void process(EGTaskNode tn){
- testIfOptional(tn);
- testIfAND(tn);
- testIfNextIsSelfLoop(tn);
- testIfRuntime(tn);
- testIfMultiple(tn);
- }
-
- private void testIfOptional(EGTaskNode tn){
- for(Iterator edges = tn.edges(); edges.hasNext();){
- EGEdge edge = (EGEdge)edges.next();
- EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
- if (nexttn.getTD()!=null)
- if(nexttn.getTD().isOptional(classname))
- nexttn.setOptional();
- }
- }
-
- private void testIfMultiple(EGTaskNode tn){
- for(Iterator edges = tn.edges(); edges.hasNext();){
- EGEdge edge = (EGEdge)edges.next();
- EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
- if (nexttn.getTD() == null ) return;//to be fixed
- if( nexttn.getTD().numParameters() > 1 ){
- nexttn.setMultipleParams();
- }
- }
- }
-
- //maybe a little bug to fix
- private void testIfRuntime(EGTaskNode tn){
- for(Iterator edges = tn.edges(); edges.hasNext();){
- EGEdge edge = (EGEdge)edges.next();
- EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
- if( ((String)nexttn.getName()).compareTo("Runtime") == 0 )
- nexttn.setAND();
- }
- }
-
- /*That correspond to the case where it is
- not possible for us to choose a path of
- execution. The optional task has to be
- present in all the possible executions
- at this point. So we mark the node as an
- AND node.*/
- private void testIfAND(EGTaskNode tn){
- Vector vtemp = new Vector();
- Vector tomark = new Vector();
- for(Iterator edges = tn.edges(); edges.hasNext();){
- EGEdge edge = (EGEdge)edges.next();
- EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
- int contains = 0;
- for (Iterator it = vtemp.iterator(); it.hasNext();){
- EGTaskNode nexttn2 = (EGTaskNode)it.next();
- if (nexttn.getName()==nexttn2.getName()){
- contains = 1;
- tomark.add(nexttn);
- tomark.add(nexttn2);
- }
- }
- if (contains == 0) vtemp.add(nexttn);
- }
-
- for(Iterator it2 = tomark.iterator(); it2.hasNext();)
- ((EGTaskNode)it2.next()).setAND();
- }
-
- //maybe little bug to fix
- private void testIfNextIsSelfLoop(EGTaskNode tn){
- for(Iterator edges = tn.edges(); edges.hasNext();){
- EGEdge edge = (EGEdge)edges.next();
- EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
- if(nexttn.isSelfLoop()) nexttn.setAND();
- }
- }
-
-
- /*recursive method that returns a set of OptionalTaskDescriptors
- The computation basically consist in returning the
- intersection or union of sets depending on the nature
- of the node : OR -> UNION
- AND -> INTERSECTION
- The method also looks for tag changes.
- */
- private HashSet determineIfIsSafe(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
- Predicate temppredicate = new Predicate();
- if(tn == null) return null;
- if(!tagChange(tn)){
- if(tn.isOptional()){
- HashSet temp = new HashSet();
- if( tn.isMultipleParams() ){
- if( goodMultiple(tn) ){
- temppredicate = combinePredicates(predicate, returnPredicate(tn));
- System.out.println("Good multiple, Optional "+tn.getName());
- }
- else return temp;
- }
- else temppredicate = combinePredicates(temppredicate, predicate);
- //if the tn is optional and there is no more nodes/presence of a loop
- //create the OptionalTaskDescriptor and return it as a singleton.
- if( !((Iterator)tn.edges()).hasNext() || tn.isSelfLoop()){
- HashSet fstemp = new HashSet();
- fstemp.add(tn.getFS());
- OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
- //System.out.println("Create Optionaltaskdescriptor number "+otd.getuid()+" hascode "+otd.hashCode());
- if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
- otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
- }
- else optionaltaskdescriptors.get(processedclass).put(otd, otd);
- temp.add(otd);
- return temp;
- }
- else if(visited.contains(tn)){
- return temp;
- }
- //else compute the edges, create the OptionalTaskDescriptor and add it to the set.
- else{
- int newdepth = depth + 1;
- visited.add(tn);
- HashSet newhashset = new HashSet(visited);
- HashSet fstemp = new HashSet();
- fstemp.add(tn.getFS());
- OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
- //System.out.println("Create Optionaltaskdescriptor number "+otd.getuid()+" hascode "+otd.hashCode());
- if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
- otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
- }
- else optionaltaskdescriptors.get(processedclass).put(otd, otd);
- temp = computeEdges(tn, newdepth, newhashset, temppredicate);
- temp.add(otd);
- return temp;
- }
- }
- else{
- HashSet temp = new HashSet();
- if( tn.isMultipleParams() ){
- if( goodMultiple(tn) ){
- temppredicate = combinePredicates(predicate, returnPredicate(tn));
- System.out.println("Good multiple, not Optional "+tn.getName());
- }
- else{
- System.out.println("Bad multiple, not Optional "+tn.getName());
- return temp;
- }
- }
- else temppredicate = combinePredicates(temppredicate, predicate);
- //if not optional but terminal just return an empty set.
- if( !((Iterator)tn.edges()).hasNext() || visited.contains(tn) || tn.isSelfLoop()){
- return temp;
- }
- //if not terminal return the computation of the edges.
- else{
- int newdepth = depth + 1;
- visited.add(tn);
- HashSet newhashset = new HashSet(visited);
- return computeEdges(tn, newdepth, newhashset, temppredicate);
- }
- }
- }
- //if there has been a tag change return an empty set.
- else{
- HashSet temp = new HashSet();
- return temp;
- }
- }
-
- private boolean goodMultiple(EGTaskNode tn){
- TaskDescriptor td = tn.getTD();
- HashSet classes = new HashSet();
- for(int i = 0 ; i<td.numParameters(); i++){
- ClassDescriptor cd = td.getParamType(i).getClassDesc();
- if(cd.getSymbol().compareTo(classname)!=0)
- classes.add(cd);
- }
-
-
- Stack stack = new Stack();
- FlatMethod fm = state.getMethodFlat(td);
- FlatNode fn = (FlatNode)fm;
-
- Stack nodestack=new Stack();
- HashSet discovered=new HashSet();
- nodestack.push(fm);
- discovered.add(fm);
-
- //Iterating through the nodes
- while(!nodestack.isEmpty()) {
- FlatNode fn1 = (FlatNode) nodestack.pop();
- if (fn1.kind()==FKind.FlatFlagActionNode) {
- FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
- if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
- for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
- TempFlagPair tfp=(TempFlagPair)it_tfp.next();
- TempDescriptor tempd = tfp.getTemp();
- if (classes.contains((ClassDescriptor)((TypeDescriptor)tempd.getType()).getClassDesc()))
- return false;//return false if a taskexit modifies one of the other parameters
- }
- continue; // avoid queueing the return node if reachable
- }
- }
- /* Queue other nodes past this one */
- for(int i=0;i<fn1.numNext();i++) {
- FlatNode fnext=fn1.getNext(i);
- if (!discovered.contains(fnext)) {
- discovered.add(fnext);
- nodestack.push(fnext);
- }
- }
- }
- return true;
-
- }
-
- private Predicate returnPredicate(EGTaskNode tn){
- Predicate result = new Predicate();
- TaskDescriptor td = tn.getTD();
- for(int i=0; i<td.numParameters(); i++){
- TypeDescriptor typed = td.getParamType(i);
- if(((ClassDescriptor)typed.getClassDesc()).getSymbol().compareTo(classname)!=0){
- VarDescriptor vd = td.getParameter(i);
- result.vardescriptors.put(vd.getName(), vd);
- HashSet flaglist = new HashSet();
- flaglist.add((FlagExpressionNode)td.getFlag(vd));
- result.flags.put( vd.getName(), flaglist);
- if((TagExpressionList)td.getTag(vd) != null)
- result.tags.put( vd.getName(), (TagExpressionList)td.getTag(vd));
- }
- }
- return result;
- }
-
- /*check if there has been a tag Change*/
- private boolean tagChange(EGTaskNode tn){
- if(tn.getTD() == null) return false;//to be fixed
- FlatMethod fm = state.getMethodFlat(tn.getTD());
- FlatNode fn = (FlatNode)fm;
-
- Stack nodestack=new Stack();
- HashSet discovered=new HashSet();
- nodestack.push(fm);
- discovered.add(fm);
-
- //Iterating through the nodes
- while(!nodestack.isEmpty()) {
- FlatNode fn1 = (FlatNode) nodestack.pop();
- if (fn1.kind()==FKind.FlatFlagActionNode) {
- FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
- if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
- Iterator it_ttp=ffan.getTempTagPairs();
- if(it_ttp.hasNext()){
- System.out.println("Tag change detected in Task "+tn.getName());
- return true;
- }
- else continue; // avoid queueing the return node if reachable
- }
- }
-
- /* Queue other nodes past this one */
- for(int i=0;i<fn1.numNext();i++) {
- FlatNode fnext=fn1.getNext(i);
- if (!discovered.contains(fnext)) {
- discovered.add(fnext);
- nodestack.push(fnext);
- }
- }
- }
- return false;
- }
-
-
- private HashSet computeEdges(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
- Hashtable andlist = new Hashtable();
- Vector orlist = new Vector();
- for(Iterator edges = tn.edges(); edges.hasNext();){
- EGTaskNode tntemp = (EGTaskNode)((EGEdge)edges.next()).getTarget();
- if(tntemp.type() == OR) orlist.add(tntemp);
- else if(tntemp.type() == AND){
- if(andlist.containsKey(tntemp.getName())){
- ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
- else{
- Vector vector = new Vector();
- vector.add(tntemp);
- andlist.put(tntemp.getName(), vector);
- }
- }
- }
-
- return (createUnion(computeOrVector(orlist, depth, visited, predicate), computeAndList(andlist, depth, visited, predicate)));
- }
-
- private HashSet computeTns(Vector tns){
- Hashtable andlist = new Hashtable();
- Vector orlist = new Vector();
- for(Iterator nodes = tns.iterator(); nodes.hasNext();){
- EGTaskNode tntemp = (EGTaskNode)nodes.next();
- if(tntemp.type() == OR) orlist.add(tntemp);
- else if(tntemp.type() == AND){
- if(andlist.containsKey(tntemp.getName())){
- ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
- else{
- Vector vector = new Vector();
- vector.add(tntemp);
- andlist.put(tntemp.getName(), vector);
- }
- }
- }
-
- return (createUnion(computeOrVector(orlist, 0), computeAndList(andlist, 0)));
-
- }
-
- private HashSet computeOrVector( Vector orlist, int depth, HashSet visited, Predicate predicate){
- if(orlist.isEmpty()){
- HashSet temp = new HashSet();
- return temp;
- }
- else{
- HashSet temp = new HashSet();
- for(Iterator tns = orlist.iterator(); tns.hasNext();){
- EGTaskNode tn = (EGTaskNode)tns.next();
- temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
- }
- return temp;
- }
-
- }
-
- private HashSet computeOrVector( Vector orlist, int depth){
- if(orlist.isEmpty()){
- HashSet temp = new HashSet();
- return temp;
- }
- else{
- HashSet temp = new HashSet();
- for(Iterator tns = orlist.iterator(); tns.hasNext();){
- EGTaskNode tn = (EGTaskNode)tns.next();
- HashSet visited = new HashSet();
- Predicate predicate = new Predicate();
- temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
- }
- return temp;
- }
-
- }
-
- private HashSet computeAndList(Hashtable andlist, int depth, HashSet visited, Predicate predicate){
- if( andlist.isEmpty()){
- HashSet temp = new HashSet();
- return temp;
- }
- else{
- HashSet temp = new HashSet();
- Collection c = andlist.values();
- for(Iterator vectors = c.iterator(); vectors.hasNext();){
- Vector vector = (Vector)vectors.next();
- temp = createUnion(computeAndVector(vector, depth, visited, predicate), temp);
- }
- return temp;
- }
-
- }
-
- private HashSet computeAndList(Hashtable andlist, int depth){
- if( andlist.isEmpty()){
- HashSet temp = new HashSet();
- return temp;
- }
- else{
- HashSet temp = new HashSet();
- Collection c = andlist.values();
- for(Iterator vectors = c.iterator(); vectors.hasNext();){
- Vector vector = (Vector)vectors.next();
- temp = createUnion(computeAndVector(vector, depth), temp);
- }
- return temp;
- }
-
- }
-
- private HashSet computeAndVector(Vector vector, int depth, HashSet visited, Predicate predicate){
- HashSet temp = new HashSet();
- boolean init = true;
- for(Iterator tns = vector.iterator(); tns.hasNext();){
- EGTaskNode tn = (EGTaskNode)tns.next();
- if (init){
- init = false;
- temp = determineIfIsSafe(tn, depth, visited, predicate);
- }
- else{
- temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
- }
- }
- return temp;
- }
-
- private HashSet computeAndVector(Vector vector, int depth){
- HashSet temp = new HashSet();
- boolean init = true;
- for(Iterator tns = vector.iterator(); tns.hasNext();){
- EGTaskNode tn = (EGTaskNode)tns.next();
- if (init){
- init = false;
- HashSet visited = new HashSet();
- Predicate predicate = new Predicate();
- temp = determineIfIsSafe(tn, depth, visited, predicate);
- }
- else{
- HashSet visited = new HashSet();
- Predicate predicate = new Predicate();
- temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
- }
- }
- return temp;
- }
-
- private HashSet createUnion( HashSet A, HashSet B){
- A.addAll(B);
-
- return A;
- }
-
-
- private HashSet createIntersection( HashSet A, HashSet B){
- HashSet result = new HashSet();
- HashSet processed = new HashSet();
- for(Iterator b_it = B.iterator(); b_it.hasNext();){
- OptionalTaskDescriptor otd_b = (OptionalTaskDescriptor)b_it.next();
- for(Iterator a_it = A.iterator(); a_it.hasNext();){
- OptionalTaskDescriptor otd_a = (OptionalTaskDescriptor)a_it.next();
- if(((String)otd_a.td.getSymbol()).compareTo((String)otd_b.td.getSymbol())==0){
- processed.add(otd_a);
- processed.add(otd_b);
-
- HashSet newfs = new HashSet();
- newfs.addAll(otd_a.flagstates);
- newfs.addAll(otd_b.flagstates);
- int newdepth = (otd_a.depth < otd_b.depth) ? otd_a.depth : otd_b.depth;
- OptionalTaskDescriptor newotd = new OptionalTaskDescriptor(otd_b.td, newfs, newdepth, combinePredicates(otd_a.predicate, otd_b.predicate));
- if(optionaltaskdescriptors.get(processedclass).get(newotd)!=null){
- //System.out.println("OTD found");
- //System.out.println("before "+newotd.getuid());
- newotd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(newotd);
- //System.out.println("after "+newotd.getuid());
- }
- else optionaltaskdescriptors.get(processedclass).put(newotd, newotd);
- result.add(newotd);
- }
- }
- }
-
- for(Iterator a_it = A.iterator(); a_it.hasNext();){
- OptionalTaskDescriptor otd = (OptionalTaskDescriptor)a_it.next();
- if(!processed.contains(otd))
- optionaltaskdescriptors.get(processedclass).remove(otd);
- }
- for(Iterator b_it = B.iterator(); b_it.hasNext();){
- OptionalTaskDescriptor otd = (OptionalTaskDescriptor)b_it.next();
- if(!processed.contains(otd))
- optionaltaskdescriptors.get(processedclass).remove(otd);
- }
- return result;
- }
-
- private Predicate combinePredicates(Predicate A, Predicate B){
- Predicate result = new Predicate();
- result.vardescriptors.putAll(A.vardescriptors);
- result.flags.putAll(A.flags);
- result.tags.putAll(A.tags);
- Collection c = B.vardescriptors.values();
- for(Iterator varit = c.iterator(); varit.hasNext();){//maybe change that
- VarDescriptor vd = (VarDescriptor)varit.next();
- if(result.vardescriptors.containsKey(vd.getName())) System.out.println("Already in ");
- else {
- //System.out.println("Not already in...");
- result.vardescriptors.put(vd.getName(), vd);
- }
- }
- Collection vardesc = result.vardescriptors.values();
- for(Iterator varit = vardesc.iterator(); varit.hasNext();){
- VarDescriptor vd = (VarDescriptor)varit.next();
- HashSet bflags = B.flags.get(vd.getName());
- if( bflags == null ){
- //System.out.println("not in B");
- continue;
- }
- else{
- if (result.flags.containsKey(vd.getName())) ((HashSet)result.flags.get(vd.getName())).addAll(bflags);
- else result.flags.put(vd.getName(), bflags);
- }
- TagExpressionList btags = B.tags.get(vd.getName());
- if( btags != null ){
- if (result.tags.containsKey(vd.getName())) System.out.println("Tag found but there should be nothing to do because same tag");
- else result.tags.put(vd.getName(), btags);
- }
- }
- return result;
- }
-
- /////////DEBUG
- /*Thoose two tasks create the dot file named markedgraph.dot */
-
- private void createDOTFile(String classname) throws java.io.IOException {
- Collection v = reducedgraph.values();
- java.io.PrintWriter output;
- File dotfile_flagstates= new File("markedgraph_"+classname+".dot");
- FileOutputStream dotstream=new FileOutputStream(dotfile_flagstates,true);
- output = new java.io.PrintWriter(dotstream, true);
- output.println("digraph dotvisitor {");
- output.println("\tnode [fontsize=10,height=\"0.1\", width=\"0.1\"];");
- output.println("\tedge [fontsize=6];");
- traverse(output, v);
- output.println("}\n");
- }
-
- private void traverse(java.io.PrintWriter output, Collection v) {
- EGTaskNode tn;
-
- for(Iterator it1 = v.iterator(); it1.hasNext();){
- tn = (EGTaskNode)it1.next();
- output.println("\t"+tn.getLabel()+" [label=\""+tn.getTextLabel()+"\"");
- if (tn.isOptional()){
- if (tn.isMultipleParams()) output.println(", shape = tripleoctagon");
- else output.println(", shape=doubleoctagon");
- }
- else if (tn.isMultipleParams()) output.println(", shape=octagon");
- if (tn.type()==AND) output.println(", color=blue");
- output.println("];");
-
- for(Iterator it2 = tn.edges();it2.hasNext();){
- EGTaskNode tn2 = (EGTaskNode)((Edge)it2.next()).getTarget();
- output.println("\t"+tn.getLabel()+" -> "+tn2.getLabel()+";");
- }
- }
- }
-
- ////////////////////
- /* returns a set of the possible sets of flagstates
- resulting from the execution of the optional task.
- To do it with have to look for TaskExit FlatNodes
- in the IR.
- */
- private void resultingFS(OptionalTaskDescriptor otd, String classname){
- Stack stack = new Stack();
- HashSet result = new HashSet();
- FlatMethod fm = state.getMethodFlat((TaskDescriptor)otd.td);
- FlatNode fn = (FlatNode)fm;
-
- Stack nodestack=new Stack();
- HashSet discovered=new HashSet();
- nodestack.push(fm);
- discovered.add(fm);
-
- //Iterating through the nodes
- while(!nodestack.isEmpty()) {
- FlatNode fn1 = (FlatNode) nodestack.pop();
- if (fn1.kind()==FKind.FlatFlagActionNode) {
- FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
- if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
- //***
- //System.out.println("TASKEXIT");
- //***
- HashSet tempset = new HashSet();
- for(Iterator it_fs = otd.flagstates.iterator(); it_fs.hasNext();){
- FlagState fstemp = (FlagState)it_fs.next();
- for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
- TempFlagPair tfp=(TempFlagPair)it_tfp.next();
- TempDescriptor td = tfp.getTemp();
- if (((String)((ClassDescriptor)((TypeDescriptor)td.getType()).getClassDesc()).getSymbol()).compareTo(classname)==0){
- fstemp=fstemp.setFlag(tfp.getFlag(),ffan.getFlagChange(tfp));
- }
- }
- //System.out.println("new flag : "+fstemp.getTextLabel());
- tempset.add(fstemp);
- }
- result.add(tempset);
- continue; // avoid queueing the return node if reachable
- }
- }else if (fn1.kind()==FKind.FlatReturnNode) {
- //***
- //System.out.println("RETURN NODE REACHABLE WITHOUT TASKEXITS");
- //***
- result.add(otd.flagstates);
- }
-
- /* Queue other nodes past this one */
- for(int i=0;i<fn1.numNext();i++) {
- FlatNode fnext=fn1.getNext(i);
- if (!discovered.contains(fnext)) {
- discovered.add(fnext);
- nodestack.push(fnext);
- }
- }
- }
- otd.exitfses=result;
- }
-
- private void cleanPredicates(){
-
- }
-
-
-}
-
-
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import IR.*;
-import Analysis.TaskStateAnalysis.*;
-import IR.Tree.*;
-import IR.Flat.*;
-import java.util.*;
-import Util.Edge;
-
-
-public class TEdge extends Edge{
-
- public TEdge(TaskNode target){
- super(target);
- }
-
- public int hashCode(){
- return target.hashCode();
- }
-
-
- public boolean equals(Object o) {
- if (o instanceof TEdge) {
- TEdge e=(TEdge)o;
- return e.target.equals(target);
- }
- return false;
- }
-
-
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-
-import java.util.Hashtable;
-import java.util.Stack;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Arrays;
-import Util.Edge;
-import Analysis.CallGraph.CallGraph;
-import IR.SymbolTable;
-import IR.State;
-import IR.TagDescriptor;
-import IR.TaskDescriptor;
-import IR.MethodDescriptor;
-import IR.Flat.*;
-
-public class TagAnalysis {
- State state;
- Hashtable flagmap;
- Stack tovisit;
- Hashtable discovered;
- Hashtable tasktotagbindings;
- Hashtable tasktoflagstates;
- CallGraph callgraph;
-
- public TagAnalysis(State state, CallGraph callgraph) {
- this.state=state;
- this.flagmap=new Hashtable();
- this.discovered=new Hashtable();
- this.tovisit=new Stack();
- this.tasktoflagstates=new Hashtable();
- this.tasktotagbindings=new Hashtable();
- this.callgraph=callgraph;
- doAnalysis();
- }
-
- public Set getFlagStates(TaskDescriptor task) {
- return (Set)tasktoflagstates.get(task);
- }
-
- private void doAnalysis() {
- Set rootset=computeRootSet();
- computeTagBindings(rootset);
- TagBinding.SCC scc=TagBinding.DFS.computeSCC(discovered.keySet());
- for(int i=0;i<scc.numSCC();i++) {
- Set component=scc.getSCC(i);
- HashSet flagset=new HashSet();
- for(Iterator compit=flagset.iterator();compit.hasNext();) {
- TagBinding tb=(TagBinding)compit.next();
- flagset.addAll(tb.getAllocations());
- for(Iterator edgeit=tb.edges();edgeit.hasNext();) {
- Edge e=(Edge)edgeit.next();
- TagBinding tb2=(TagBinding)e.getTarget();
- flagset.addAll(tb2.getAllocations());
- }
- }
- for(Iterator compit=flagset.iterator();compit.hasNext();) {
- TagBinding tb=(TagBinding)compit.next();
- tb.getAllocations().addAll(flagset);
- }
- }
-
- SymbolTable tasktable=state.getTaskSymbolTable();
- for(Iterator taskit=tasktable.getDescriptorsIterator();taskit.hasNext();) {
- TaskDescriptor task=(TaskDescriptor)taskit.next();
- HashSet roottags=(HashSet)tasktotagbindings.get(task);
- HashSet taskflags=(HashSet)tasktoflagstates.get(task);
- for(Iterator tagit=roottags.iterator();tagit.hasNext();) {
- TagBinding tb=(TagBinding)tagit.next();
- taskflags.addAll(tb.getAllocations());
- }
- }
- }
-
- private Set computeRootSet() {
- HashSet rootset=new HashSet();
- SymbolTable tasktable=state.getTaskSymbolTable();
- for(Iterator taskit=tasktable.getDescriptorsIterator();taskit.hasNext();) {
- TaskDescriptor task=(TaskDescriptor)taskit.next();
- HashSet roottags=new HashSet();
- HashSet taskflags=new HashSet();
- FlatMethod fm=state.getMethodFlat(task);
- computeCallsFlags(fm, null, roottags, taskflags);
- rootset.addAll(roottags);
- tasktotagbindings.put(task,roottags);
- tasktoflagstates.put(task,taskflags);
- }
- return rootset;
- }
-
-private void computeCallsFlags(FlatMethod fm, Hashtable parammap, Set tagbindings, Set newflags) {
- Set nodeset=fm.getNodeSet();
- for(Iterator nodeit=nodeset.iterator();nodeit.hasNext();) {
- FlatNode fn=(FlatNode)nodeit.next();
- if(fn.kind()==FKind.FlatCall) {
- FlatCall fc=(FlatCall)fn;
- MethodDescriptor nodemd=fc.getMethod();
- Set methodset=fc.getThis()==null?callgraph.getMethods(nodemd):
- callgraph.getMethods(nodemd, fc.getThis().getType());
-
- for(Iterator methodit=methodset.iterator();methodit.hasNext();) {
- MethodDescriptor md=(MethodDescriptor) methodit.next();
- TagBinding nodetb=new TagBinding(md);
- for(int i=0;i<md.numParameters();i++) {
- TempDescriptor temp=fc.getArg(i);
- TagDescriptor tag=temp.getTag();
- if (tag==null&¶mmap!=null&¶mmap.containsKey(temp)) {
- tag=(TagDescriptor)parammap.get(temp);
- }
- if (tag!=null)
- nodetb.setBinding(i,tag);
- }
- if (!discovered.containsKey(nodetb)) {
- discovered.put(nodetb,nodetb);
- tovisit.add(nodetb);
- } else
- nodetb=(TagBinding)discovered.get(nodetb);
- tagbindings.add(nodetb);
- }
- } else if (fn.kind()==FKind.FlatFlagActionNode) {
- FlatFlagActionNode ffan=(FlatFlagActionNode)fn;
- if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
- TempDescriptor ffantemp=null;
- {
- /* Compute type */
-
- Iterator it=ffan.getTempFlagPairs();
- if (it.hasNext()) {
- TempFlagPair tfp=(TempFlagPair)it.next();
- ffantemp=tfp.getTemp();
- } else {
- it=ffan.getTempTagPairs();
- if (!it.hasNext())
- throw new Error();
- TempTagPair ttp=(TempTagPair)it.next();
- ffantemp=ttp.getTemp();
- }
- }
- FlagState fs=new FlagState(ffantemp.getType().getClassDesc());
- for(Iterator it=ffan.getTempFlagPairs();it.hasNext();) {
- TempFlagPair tfp=(TempFlagPair)it.next();
- if (ffan.getFlagChange(tfp))
- fs=fs.setFlag(tfp.getFlag(), true);
- else
- fs=fs.setFlag(tfp.getFlag(), false);
- }
-
- HashSet fsset=new HashSet();
- fsset.add(fs);
-
- for(Iterator it=ffan.getTempTagPairs();it.hasNext();) {
- HashSet oldfsset=fsset;
- fsset=new HashSet();
-
- TempTagPair ttp=(TempTagPair)it.next();
- if (ffan.getTagChange(ttp)) {
- TagDescriptor tag=ttp.getTag();
- if (tag==null&¶mmap!=null&¶mmap.containsKey(ttp.getTagTemp())) {
- tag=(TagDescriptor)parammap.get(ttp.getTagTemp());
- }
- for(Iterator setit=oldfsset.iterator();setit.hasNext();) {
- FlagState fs2=(FlagState)setit.next();
- fsset.addAll(Arrays.asList(fs2.setTag(tag)));
- }
- } else
- throw new Error("Don't clear tag in new object allocation");
- }
-
- for(Iterator setit=fsset.iterator();setit.hasNext();) {
- FlagState fs2=(FlagState)setit.next();
- if (!flagmap.containsKey(fs2))
- flagmap.put(fs2,fs2);
- else
- fs2=(FlagState) flagmap.get(fs2);
- newflags.add(fs2);
- }
- }
- }
- }
-}
-
- private void computeTagBindings(Set roots) {
- tovisit.addAll(roots);
-
- for(Iterator it=roots.iterator();it.hasNext();) {
- TagBinding tb=(TagBinding)it.next();
- discovered.put(tb,tb);
- }
-
- while(!tovisit.empty()) {
- TagBinding tb=(TagBinding) tovisit.pop();
- MethodDescriptor md=tb.getMethod();
- FlatMethod fm=state.getMethodFlat(md);
- /* Build map from temps -> tagdescriptors */
- Hashtable parammap=new Hashtable();
- int offset=md.isStatic()?0:1;
-
-
- for(int i=0;i<fm.numParameters();i++) {
- TempDescriptor temp=fm.getParameter(i);
- int offsetindex=i-offset;
- if (offsetindex>=0) {
- TagDescriptor tag=tb.getBinding(offsetindex);
-
- if (tag!=null) {
- parammap.put(temp,tag);
- }
- }
- }
-
- HashSet newtags=new HashSet();
-
- computeCallsFlags(fm, parammap, newtags, tb.getAllocations());
-
- for(Iterator tagit=newtags.iterator();tagit.hasNext();) {
- TagBinding newtag=(TagBinding)tagit.next();
- Edge e=new Edge(newtag);
- tb.addEdge(e);
- }
- }
- }
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import IR.MethodDescriptor;
-import IR.TagDescriptor;
-import Util.GraphNode;
-import java.util.HashSet;
-import java.util.Set;
-
-public class TagBinding extends GraphNode {
- private MethodDescriptor md;
- private TagDescriptor[] tdarray;
- private HashSet allocations;
-
- public TagBinding(MethodDescriptor md) {
- this.md=md;
- tdarray=new TagDescriptor[md.numParameters()];
- allocations=new HashSet();
- }
-
- public String toString() {
- String st=md.toString();
- for(int i=0;i<tdarray.length;i++)
- st+=tdarray[i]+" ";
- return st;
- }
-
- public Set getAllocations() {
- return allocations;
- }
-
- public void setBinding(int i, TagDescriptor td) {
- tdarray[i]=td;
- }
-
- public MethodDescriptor getMethod() {
- return md;
- }
-
- public TagDescriptor getBinding(int i) {
- return tdarray[i];
- }
-
- public boolean equals(Object o) {
- if (o instanceof TagBinding) {
- TagBinding tb=(TagBinding)o;
- if (md!=tb.md)
- return false;
- for(int i=0;i<tdarray.length;i++)
- if (tdarray[i]!=null) {
- if (!tdarray[i].equals(tb.tdarray[i]))
- return false;
- } else if(tb.tdarray[i]!=null)
- return false;
- return true;
- }
- return false;
- }
-
- public int hashCode() {
- int hashcode=md.hashCode();
- for(int i=0;i<tdarray.length;i++) {
- if (tdarray[i]!=null)
- hashcode^=tdarray[i].hashCode();
- }
- return hashcode;
- }
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import IR.*;
-import IR.Tree.*;
-import IR.Flat.*;
-import java.util.*;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.FileOutputStream;
-
-public class TaskAnalysis {
- State state;
- Hashtable flagstates;
- Hashtable flags;
- Hashtable extern_flags;
- Queue<FlagState> toprocess;
- TagAnalysis taganalysis;
- Hashtable cdtorootnodes;
-
- TypeUtil typeutil;
-
- /**
- * Class Constructor
- *
- * @param state a flattened State object
- * @see State
- */
- public TaskAnalysis(State state, TagAnalysis taganalysis)
- {
- this.state=state;
- this.typeutil=new TypeUtil(state);
- this.taganalysis=taganalysis;
-
- }
-
- /** Builds a table of flags for each class in the Bristlecone program.
- * It creates two hashtables: one which holds the ClassDescriptors and arrays of
- * FlagDescriptors as key-value pairs; the other holds the ClassDescriptor and the
- * number of external flags for that specific class.
- */
-
- private void getFlagsfromClasses() {
- flags=new Hashtable();
- extern_flags = new Hashtable();
-
- /** Iterate through the classes used in the program to build the table of flags
- */
- for(Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator();it_classes.hasNext();) {
-
- ClassDescriptor cd = (ClassDescriptor)it_classes.next();
- Vector vFlags=new Vector();
- FlagDescriptor flag[];
- int ctr=0;
-
-
- /* Adding the flags of the super class */
- if (cd.getSuper()!=null) {
- ClassDescriptor superdesc=cd.getSuperDesc();
-
- for(Iterator it_cflags=superdesc.getFlags();it_cflags.hasNext();) {
- FlagDescriptor fd = (FlagDescriptor)it_cflags.next();
- vFlags.add(fd);
- }
- }
-
- for(Iterator it_cflags=cd.getFlags();it_cflags.hasNext();) {
- FlagDescriptor fd = (FlagDescriptor)it_cflags.next();
- vFlags.add(fd);
- }
-
- if (vFlags.size()!=0) {
- flag=new FlagDescriptor[vFlags.size()];
-
- for(int i=0;i < vFlags.size() ; i++) {
- if (((FlagDescriptor)vFlags.get(i)).getExternal()) {
- flag[ctr]=(FlagDescriptor)vFlags.get(i);
- vFlags.remove(flag[ctr]);
- ctr++;
- }
- }
- for(int i=0;i < vFlags.size() ; i++) {
- flag[i+ctr]=(FlagDescriptor)vFlags.get(i);
- }
- extern_flags.put(cd,new Integer(ctr));
- flags.put(cd,flag);
-
- }
- }
- }
- /** Method which starts up the analysis
- *
- */
-
- public void taskAnalysis() throws java.io.IOException {
- flagstates=new Hashtable();
- Hashtable<FlagState,FlagState> sourcenodes;
- cdtorootnodes=new Hashtable();
-
- getFlagsfromClasses();
-
- int externs;
- toprocess=new LinkedList<FlagState>();
-
- for(Iterator it_classes=(Iterator)flags.keys();it_classes.hasNext();) {
- ClassDescriptor cd=(ClassDescriptor)it_classes.next();
- externs=((Integer)extern_flags.get(cd)).intValue();
- FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd);
- flagstates.put(cd,new Hashtable<FlagState,FlagState>());
- cdtorootnodes.put(cd,new Vector());
- }
-
-
- ClassDescriptor startupobject=typeutil.getClass(TypeUtil.StartupClass);
-
- sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(startupobject);
- FlagState fsstartup=new FlagState(startupobject);
-
-
- FlagDescriptor[] fd=(FlagDescriptor[])flags.get(startupobject);
-
- fsstartup=fsstartup.setFlag(fd[0],true);
- fsstartup.setAsSourceNode();
- ((Vector)cdtorootnodes.get(startupobject)).add(fsstartup);
-
- sourcenodes.put(fsstartup,fsstartup);
- toprocess.add(fsstartup);
-
- /** Looping through the flagstates in the toprocess queue to perform the state analysis */
- while (!toprocess.isEmpty()) {
- FlagState trigger=toprocess.poll();
- createPossibleRuntimeStates(trigger);
-
- analyseTasks(trigger);
- }
-
- /** Creating DOT files */
- Enumeration e=flagstates.keys();
-
- while (e.hasMoreElements()) {
- ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
- createDOTfile(cdtemp);
- }
- }
-
-
- /** Analyses the set of tasks based on the given flagstate, checking
- * to see which tasks are triggered and what new flagstates are created
- * from the base flagstate.
- * @param fs A FlagState object which is used to analyse the task
- * @see FlagState
- */
-
-private void analyseTasks(FlagState fs) {
- ClassDescriptor cd=fs.getClassDescriptor();
- Hashtable<FlagState,FlagState> sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(cd);
-
- for(Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator();it_tasks.hasNext();) {
- TaskDescriptor td = (TaskDescriptor)it_tasks.next();
- String taskname=td.getSymbol();
-
- /** counter to keep track of the number of parameters (of the task being analyzed) that
- * are satisfied by the flagstate.
- */
- int trigger_ctr=0;
- TempDescriptor temp=null;
- FlatMethod fm = state.getMethodFlat(td);
-
- for(int i=0; i < td.numParameters(); i++) {
- FlagExpressionNode fen=td.getFlag(td.getParameter(i));
- TagExpressionList tel=td.getTag(td.getParameter(i));
-
- /** Checking to see if the parameter is of the same type/class as the
- * flagstate's and also if the flagstate fs triggers the given task*/
- if (typeutil.isSuperorType(td.getParamType(i).getClassDesc(),cd)
- && isTaskTrigger_flag(fen,fs)
- && isTaskTrigger_tag(tel,fs)) {
- temp=fm.getParameter(i);
- trigger_ctr++;
- }
- }
-
- if (trigger_ctr==0) //Look at next task
- continue;
-
- if (trigger_ctr>1)
- throw new Error("Illegal Operation: A single flagstate cannot satisfy more than one parameter of a task.");
-
-
- Set newstates=taganalysis.getFlagStates(td);
- for(Iterator fsit=newstates.iterator();fsit.hasNext();) {
- FlagState fsnew=(FlagState) fsit.next();
- fsnew.setAsSourceNode();
- fsnew.addAllocatingTask(td);
- ((Vector)cdtorootnodes.get(fsnew.getClassDescriptor())).add(fsnew);
-
- if (! ((Hashtable<FlagState,FlagState>)flagstates.get(fsnew.getClassDescriptor())).containsKey(fsnew)) {
- ((Hashtable<FlagState,FlagState>)flagstates.get(fsnew.getClassDescriptor())).put(fsnew, fsnew);
- toprocess.add(fsnew);
- }
- }
-
- Stack nodestack=new Stack();
- HashSet discovered=new HashSet();
- nodestack.push(fm);
- discovered.add(fm);
- //Iterating through the nodes
-
- while(!nodestack.isEmpty()) {
- FlatNode fn1 = (FlatNode) nodestack.pop();
-
- if (fn1.kind()==FKind.FlatReturnNode) {
- /* Self edge */
- FEdge newedge=new FEdge(fs, taskname);
- fs.addEdge(newedge);
- continue;
- } else if (fn1.kind()==FKind.FlatFlagActionNode) {
- FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
- if (ffan.getTaskType() == FlatFlagActionNode.PRE) {
- if (ffan.getTempFlagPairs().hasNext()||ffan.getTempTagPairs().hasNext())
- throw new Error("PRE FlagActions not supported");
-
- } else if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
- Vector<FlagState> fsv_taskexit=evalTaskExitNode(ffan,cd,fs,temp);
- for(Enumeration en=fsv_taskexit.elements();en.hasMoreElements();){
- FlagState fs_taskexit=(FlagState)en.nextElement();
- if (!sourcenodes.containsKey(fs_taskexit)) {
- toprocess.add(fs_taskexit);
- }
- //seen this node already
- fs_taskexit=canonicalizeFlagState(sourcenodes,fs_taskexit);
- FEdge newedge=new FEdge(fs_taskexit,taskname);
- fs.addEdge(newedge);
- }
- continue;
- }
- }
- /* Queue other nodes past this one */
- for(int i=0;i<fn1.numNext();i++) {
- FlatNode fnext=fn1.getNext(i);
- if (!discovered.contains(fnext)) {
- discovered.add(fnext);
- nodestack.push(fnext);
- }
- }
- }
- }
-}
-
-
-/** Determines whether the given flagstate satisfies a
- * single parameter in the given task.
- * @param fen FlagExpressionNode
- * @see FlagExpressionNode
- * @param fs FlagState
- * @see FlagState
- * @return <CODE>true</CODE> if fs satisfies the boolean expression
- denoted by fen else <CODE>false</CODE>.
- */
-
-
-private boolean isTaskTrigger_flag(FlagExpressionNode fen,FlagState fs) {
- if (fen==null)
- return true;
- else if (fen instanceof FlagNode)
- return fs.get(((FlagNode)fen).getFlag());
- else
- switch (((FlagOpNode)fen).getOp().getOp()) {
- case Operation.LOGIC_AND:
- return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) && (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
- case Operation.LOGIC_OR:
- return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) || (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
- case Operation.LOGIC_NOT:
- return !(isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs));
- default:
- return false;
- }
-}
-
-private boolean isTaskTrigger_tag(TagExpressionList tel, FlagState fs){
-
- if (tel!=null){
- for (int i=0;i<tel.numTags() ; i++){
- switch (fs.getTagCount(tel.getType(i))){
- case FlagState.ONETAG:
- case FlagState.MULTITAGS:
- break;
- case FlagState.NOTAGS:
- return false;
- }
- }
- }
- return true;
-}
-
-/*private int tagTypeCount(TagExpressionList tel, String tagtype){
- int ctr=0;
- for(int i=0;i<tel.numTags() ; i++){
- if (tel.getType(i).equals(tagtype))
- ctr++;
- }
- return ctr;
-} */
-
- private Vector<FlagState> evalTaskExitNode(FlatFlagActionNode ffan,ClassDescriptor cd,FlagState fs, TempDescriptor temp){
- FlagState fstemp=fs;
- Vector<FlagState> processed=new Vector<FlagState>();
-
- //Process the flag changes
-
- for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
- TempFlagPair tfp=(TempFlagPair)it_tfp.next();
- if (temp==tfp.getTemp())
- fstemp=fstemp.setFlag(tfp.getFlag(),ffan.getFlagChange(tfp));
- }
-
- //Process the tag changes
-
- processed.add(fstemp);
-
- //Process clears first
- for(Iterator it_ttp=ffan.getTempTagPairs();it_ttp.hasNext();) {
- TempTagPair ttp=(TempTagPair)it_ttp.next();
-
- if (temp==ttp.getTemp()) {
- Vector<FlagState> oldprocess=processed;
- processed=new Vector<FlagState>();
-
- for (Enumeration en=oldprocess.elements();en.hasMoreElements();){
- FlagState fsworking=(FlagState)en.nextElement();
- if (!ffan.getTagChange(ttp)){
- processed.addAll(Arrays.asList(fsworking.clearTag(ttp.getTag())));
- } else processed.add(fsworking);
- }
- }
- }
- //Process sets next
- for(Iterator it_ttp=ffan.getTempTagPairs();it_ttp.hasNext();) {
- TempTagPair ttp=(TempTagPair)it_ttp.next();
-
- if (temp==ttp.getTemp()) {
- Vector<FlagState> oldprocess=processed;
- processed=new Vector<FlagState>();
-
- for (Enumeration en=oldprocess.elements();en.hasMoreElements();){
- FlagState fsworking=(FlagState)en.nextElement();
- if (ffan.getTagChange(ttp)){
- processed.addAll(Arrays.asList(fsworking.setTag(ttp.getTag())));
- } else processed.add(fsworking);
- }
- }
- }
- return processed;
- }
-
-
- private FlagState canonicalizeFlagState(Hashtable sourcenodes, FlagState fs){
- if (sourcenodes.containsKey(fs))
- return (FlagState)sourcenodes.get(fs);
- else{
- sourcenodes.put(fs,fs);
- return fs;
- }
- }
-
- /** Creates a DOT file using the flagstates for a given class
- * @param cd ClassDescriptor of the class
- * @throws java.io.IOException
- * @see ClassDescriptor
- */
-
- public void createDOTfile(ClassDescriptor cd) throws java.io.IOException {
- File dotfile_flagstates= new File("graph"+cd.getSymbol()+".dot");
- FileOutputStream dotstream=new FileOutputStream(dotfile_flagstates,true);
- FlagState.DOTVisitor.visit(dotstream,((Hashtable)flagstates.get(cd)).values());
- }
-
- /** Returns the flag states for the class descriptor. */
- public Set getFlagStates(ClassDescriptor cd) {
- if (flagstates.containsKey(cd))
- return ((Hashtable)flagstates.get(cd)).keySet();
- else
- return null;
- }
-
-
- private void createPossibleRuntimeStates(FlagState fs) {
- ClassDescriptor cd = fs.getClassDescriptor();
- Hashtable<FlagState,FlagState> sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(cd);
- FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd);
- int externs=((Integer)extern_flags.get(cd)).intValue();
-
- if(externs==0)
- return;
-
- int noOfIterations=(1<<externs) - 1;
- boolean BoolValTable[]=new boolean[externs];
-
-
- for(int i=0; i < externs ; i++) {
- BoolValTable[i]=fs.get(fd[i]);
- }
-
- for(int k=0; k<noOfIterations; k++) {
- for(int j=0; j < externs ;j++) {
- if ((k% (1<<j)) == 0)
- BoolValTable[j]=(!BoolValTable[j]);
- }
-
- FlagState fstemp=fs;
-
- for(int i=0; i < externs;i++) {
- fstemp=fstemp.setFlag(fd[i],BoolValTable[i]);
- }
- if (!sourcenodes.containsKey(fstemp))
- toprocess.add(fstemp);
-
- fstemp=canonicalizeFlagState(sourcenodes,fstemp);
- fs.addEdge(new FEdge(fstemp,"Runtime"));
- }
- }
-
- public Vector getRootNodes(ClassDescriptor cd){
- return (Vector)cdtorootnodes.get(cd);
- }
-
-
-
-}
-
+++ /dev/null
-Task Analysis:
-
-Algorithm:
-
-
-
-1. Obtain the flags for each class in the program(Incase, a class has
-a super class, the super's flags, if any, are included in the list of
-flags for the class)
-
-2. Create a new flagstate for the StartupObject class with the
-initialstate flag set to true. Append this flagstate to the queue,
-QMAIN.
-
-3. Pop the head of QMAIN and use this flagstate FS to evaluate which
-task triggers on this.
-
-4. Add all runtime transitions (external flag changes) from FS to
-QMAIN and ADJLIST(as edges from FS) ensuring that the new states don't
-exist in QMAIN.
-
-5. Iterate through the list of tasks using FS.
-
-6. If a task is triggered,
-
- a. If FS satisfies more than one parameter of the task, throw
-an error stating that this is an illegal operation.
-
- b. If 6a is not true, then add a transition for this task to
-FS using step 7. Before performing step 7, make sure that the task
-doesn't already exist as a transition to FS. Keep track of the temp
-(as TEMP) whose flags form the triggering flagstate.
-
-7. Search through the FFANS in this task:
-
- a. For NewObject node,
-
- i. If the new object is of a class which has both
-types of flags, create the new flagstate and append to QMAIN. Set its
-set of transitions to the empty set.
-
- b. For the task exit node, apply the flag changes to the
-tempflag pairs corresponding to TEMP and create the new flagstate.
-Add this state along with the task as an Edge to FS in the FS
-transition set. Add the state to QMAIN.
-
- c. For the PRE node, throw an error stating that this type of
-node isn't supported anymore in Bristlecone.
-
-8. Repeat steps 3-7 until QMAIN is empty.
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import Util.*;
-
-public class TaskEdges extends Namer{
- public TaskEdges(){}
-
- public String nodeLabel(GraphNode gn) {
- return "";
- }
-
- public String nodeOption(GraphNode gn) {
- return "";
- }
-
-
- public String edgeLabel(Edge edge){
- return "";
- }
-
-
- public String edgeOption(Edge edge){
- return "URL=\""+edge.getLabel()+".html\"";
- }
-
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import java.util.*;
-import IR.State;
-import IR.SymbolTable;
-import IR.ClassDescriptor;
-import IR.TaskDescriptor;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.FileOutputStream;
-
-public class TaskGraph {
- TaskAnalysis taskanalysis;
- State state;
- Hashtable cdtonodes;
- Hashtable nodes;
- Hashtable<TaskNode,TaskNode> alltasknodes;
-
- //Colors
- String colors[]={"red","blue","green","brown","orange","pink","black","grey","olivedrab","yellow"};
-
- public TaskGraph(State state, TaskAnalysis taskanalysis) {
- this.state=state;
- this.taskanalysis=taskanalysis;
- this.cdtonodes=new Hashtable();
- this.alltasknodes=new Hashtable<TaskNode,TaskNode>();
-
- for(Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();classit.hasNext();) {
- ClassDescriptor cd=(ClassDescriptor) classit.next();
- if (cd.hasFlags())
- produceTaskNodes(cd);
- }
- produceAllTaskNodes();
- }
-
-
- public void createDOTfiles() {
- for(Iterator it_classes=(Iterator)cdtonodes.keys();it_classes.hasNext();) {
- ClassDescriptor cd=(ClassDescriptor) it_classes.next();
- Set tasknodes=getTaskNodes(cd);
- if (tasknodes!=null) {
- try {
- File dotfile_tasknodes=new File("graph"+cd.getSymbol()+"_task.dot");
- FileOutputStream dotstream=new FileOutputStream(dotfile_tasknodes,true);
- TaskNode.DOTVisitor.visit(dotstream,tasknodes);
- } catch(Exception e) {
- e.printStackTrace();
- throw new Error();
- }
- }
- }
- }
-
- /** Returns the set of TaskNodes for the class descriptor cd */
-
- public Set getTaskNodes(ClassDescriptor cd) {
- if (cdtonodes.containsKey(cd))
- return ((Hashtable)cdtonodes.get(cd)).keySet();
- else
- return null;
- }
-
- private TaskNode canonicalizeTaskNode(Hashtable nodes, TaskNode node){
- if (nodes.containsKey(node))
- return (TaskNode)nodes.get(node);
- else{
- nodes.put(node,node);
- return (TaskNode)node;
- }
- }
-
- private void produceTaskNodes(ClassDescriptor cd) {
- Set fsnodes=taskanalysis.getFlagStates(cd);
- if (fsnodes==null)
- return;
-
- Hashtable<TaskNode,TaskNode> tasknodes=new Hashtable<TaskNode,TaskNode>();
- cdtonodes.put(cd, tasknodes);
-
- for(Iterator it=fsnodes.iterator();it.hasNext();) {
- FlagState fs=(FlagState)it.next();
- Iterator it_inedges=fs.inedges();
- TaskNode tn,sn;
-
- if (fs.isSourceNode()) {
- sn=new TaskNode("Start Node");
- if(fs.edges().hasNext()){
- addEdges(fs,sn,tasknodes);
- }
- }
-
- while(it_inedges.hasNext()){
-
- FEdge inedge=(FEdge)it_inedges.next();
- tn=new TaskNode(inedge.getLabel());
- if(fs.edges().hasNext()){
- addEdges(fs,tn,tasknodes);
- }
- }
- }
- }
-
- private void produceAllTaskNodes(){
- alltasknodes=new Hashtable<TaskNode,TaskNode>();
-
- for(Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator();it_tasks.hasNext();){
- TaskDescriptor td=(TaskDescriptor)it_tasks.next();
- TaskNode tn=new TaskNode(td.getSymbol());
- alltasknodes.put(tn,tn);
- }
- TaskNode tn_runtime=new TaskNode("Runtime");
- alltasknodes.put(tn_runtime,tn_runtime);
-
- int ColorID=0;
- for(Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();classit.hasNext()&&ColorID<10;) {
- ClassDescriptor cd=(ClassDescriptor) classit.next();
- Set fsnodes;
-
- if (cd.hasFlags()&&((fsnodes=taskanalysis.getFlagStates(cd))!=null)){
- //
- System.out.println("\nWorking on fses of Class: "+cd.getSymbol());
- //
- for(Iterator it=fsnodes.iterator();it.hasNext();) {
- FlagState fs=(FlagState)it.next();
- //
- System.out.println("Evaluating fs: "+fs.getTextLabel());
- //
- Iterator it_inedges=fs.inedges();
- TaskNode tn,sn;
-
-
- if (fs.isSourceNode()){
- //
- System.out.println("A sourcenode");
- //
- if(fs.edges().hasNext()){
- Vector allocatingtasks=fs.getAllocatingTasks();
- //
- if (allocatingtasks.iterator().hasNext())
- System.out.println("has been allocated by "+allocatingtasks.size()+" tasks");
- //
- for(Iterator it_at=allocatingtasks.iterator();it_at.hasNext();){
- TaskDescriptor allocatingtd=(TaskDescriptor)it_at.next();
- //
- System.out.println(allocatingtd.getSymbol());
- //
- tn=new TaskNode(allocatingtd.getSymbol());
-
- addEdges(fs,tn,alltasknodes,ColorID);
- }
- }
- }
-
- while(it_inedges.hasNext()){
- FEdge inedge=(FEdge)it_inedges.next();
- tn=new TaskNode(inedge.getLabel());
- if(fs.edges().hasNext()){
- addEdges(fs,tn,alltasknodes,ColorID);
- }
- }
- }
- ColorID++;
- }
-
- }
- }
-
- public Set getAllTaskNodes(){
- return alltasknodes.keySet();
- }
-
-
-
-
-
-
-
-
- /* private void mergeAllNodes(){
- Hashtable alltasks=new Hashtable();
- for(Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();classit.hasNext();) {
- ClassDescriptor cd=(ClassDescriptor) classit.next();
- Set tnodes=((Hashtable)cdtonodes.get(cd)).keyset();
- while (it_tnodes=tnodes.iterator();it_nodes.hasNext()){
- TaskNode tn=it_nodes.next();
- if (alltasks.containsKey(tn)){
- while(tn.
- }
- }
-
-
-
-
- }
-
- */
-
- private void addEdges(FlagState fs, TaskNode tn,Hashtable<TaskNode,TaskNode> tasknodes){
-
- // Hashtable<TaskNode,TaskNode> tasknodes=(Hashtable<TaskNode,TaskNode>)cdtonodes.get(fs.getClassDescriptor());
- tn=(TaskNode)canonicalizeTaskNode(tasknodes, tn);
- for (Iterator it_edges=fs.edges();it_edges.hasNext();){
- TaskNode target=new TaskNode(((FEdge)it_edges.next()).getLabel());
- target=(TaskNode)canonicalizeTaskNode(tasknodes,target);
-
- TEdge newedge=new TEdge(target);
- if (! tn.edgeExists(newedge))
- tn.addEdge(newedge);
- }
-
- }
-
- private void addEdges(FlagState fs, TaskNode tn,Hashtable<TaskNode,TaskNode> tasknodes,int ColorID){
-
- tn=(TaskNode)canonicalizeTaskNode(tasknodes, tn);
- for (Iterator it_edges=fs.edges();it_edges.hasNext();){
- TaskNode target=new TaskNode(((FEdge)it_edges.next()).getLabel());
- target=(TaskNode)canonicalizeTaskNode(tasknodes,target);
-
- TEdge newedge=new TEdge(target);
- newedge.setDotNodeParameters("style=bold, color = "+colors[ColorID]);
- if (! tn.edgeExists(newedge))
- tn.addEdge(newedge);
- }
-
- }
-
-}
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import Analysis.TaskStateAnalysis.*;
-import IR.*;
-import IR.Tree.*;
-import IR.Flat.*;
-import java.util.*;
-import java.io.*;
-import Util.GraphNode;
-
-public class TaskNode extends GraphNode {
-
- private final String name;
- protected int uid;
- private static int nodeid=0;
- // private int loopmarker=0;
- //private boolean multipleparams=false;
- /**Class Constructor
- * Creates a new TaskNode using the TaskDescriptor.
- * @param tasknode TaskDescriptor
- */
- public TaskNode(String name){
- this.name=name;
- this.uid=TaskNode.nodeid++;
- }
-
- /**Returns the string representation of the node
- * @return string representation of the tasknode (e.g "Task foo")
- */
- public String getTextLabel() {
- return "Task "+name;
- }
-
- public String getLabel() {
- return "N"+uid;
- }
-
- public String getName(){
- return name;
- }
-
- // public int getuid(){
- //return uid;
- //}
-
-
- /**toString method.
- * @return string representation of the tasknode (e.g "Task foo")
- */
- public String toString(){
- return getTextLabel();
- }
-
- public int hashCode(){
- return name.hashCode();
-
- }
-
- public boolean equals(Object o) {
- if (o instanceof TaskNode) {
- TaskNode tn=(TaskNode)o;
- return (tn.name.equals(name));
- }
- return false;
- }
-
- public boolean edgeExists(TEdge newedge){
- if(edges.isEmpty())
- return false;
- else
- return edges.contains(newedge);
- }
-
-}
-
-
-
+++ /dev/null
-package Analysis.TaskStateAnalysis;
-import Util.*;
-
-public class TaskNodeNamer extends Namer{
- public TaskNodeNamer(){}
-
- public String nodeLabel(GraphNode gn){
- return "";
- }
-
- public String nodeOption(GraphNode gn){
- return "URL=\""+gn.getName()+".html\"";
- }
-
-}
+++ /dev/null
-public class BankAccount\r
-{\r
- //can't init here, won't compile, do it in the constructor\r
- \r
- //nine digits\r
- String AccountNumber; //field #1\r
- \r
- //account owner's name\r
- //always 10 chars\r
- //pad with @\r
- String FirstName; //field #2 \r
- String MiddleName; //field #3\r
- String LastName; //field #4\r
- \r
- //1 == Savings\r
- //2 == Checking\r
- //3 == Teller\r
- String AccountType; //field #5\r
- \r
- //ints only, should use floats in the future\r
- //1234567890\r
- //assumes balance does is never negative\r
- //always 10 chars\r
- //pad with @\r
- String Balance; //field #6\r
- \r
- //four digits\r
- String PIN; //field #7\r
- \r
- public BankAccount()\r
- {\r
- \r
- }\r
- \r
- public BankAccount(String account, String first, String middle, String last, String type, String balance, String pin)\r
- {\r
- if(account != null)\r
- AccountNumber = account;\r
- if(first != null) \r
- FirstName = first;\r
- if(middle != null)\r
- MiddleName = middle;\r
- if(last != null)\r
- LastName = last;\r
- if(type != null)\r
- AccountType = type;\r
- if(balance != null)\r
- Balance = balance;\r
- if(pin != null)\r
- PIN = pin;\r
- }\r
- \r
- public void modifyAccount(String account, String first, String middle, String last, String type, String balance, String pin)\r
- {\r
- if(account != null)\r
- AccountNumber = account;\r
- if(first != null) \r
- FirstName = first;\r
- if(middle != null)\r
- MiddleName = middle;\r
- if(last != null)\r
- LastName = last;\r
- if(type != null)\r
- AccountType = type;\r
- if(balance != null)\r
- Balance = balance;\r
- if(pin != null)\r
- PIN = pin;\r
- }\r
-}\r
+++ /dev/null
-//Banking Application Server\r
-\r
-/* Startup object is generated with the initialstate flag set by the\r
- * system to start the computation up */\r
-\r
-task Startup(StartupObject s{initialstate})\r
-{\r
- System.printString("Starting\n");\r
- ServerSocket ss = new ServerSocket(8080);\r
- System.printString("Creating ServerSocket\n");\r
- BankDatabase Bank = new BankDatabase(){DatabaseInit};\r
- taskexit(s{!initialstate}); /* Turns initial state flag off, so this task won't refire */\r
-}\r
-\r
-task AcceptConnection(ServerSocket ss{SocketPending})\r
-{\r
- BankAppSocket bas = new BankAppSocket(){BASocketInit};\r
- ss.accept(bas);\r
- System.printString("Connected\n");\r
-}\r
-\r
-//i think this task could probably be broken up into smaller tasks\r
-task ProcessRequest(BankAppSocket bas{IOPending && BASocketInit}, BankDatabase Bank{DatabaseInit})\r
-{\r
- String message = new String(bas.receive());\r
- //System.printString(message);\r
- \r
- //login\r
- if(message.startsWith("1"))\r
- {\r
- String account = message.subString(1, 10);\r
- String pin = message.subString(10, 14);\r
- \r
- for(int i = 0; i < Bank.numOfAccounts; i++)\r
- {\r
- if(Bank.database[i].AccountNumber.equals(account) && Bank.database[i].PIN.equals(pin))\r
- {\r
- bas.send("Login OK");\r
- //System.printString("Login OK");\r
- }\r
- else\r
- {\r
- bas.send("Login Error");\r
- //System.printString("Login Error");\r
- }\r
- }\r
- }\r
- //logout\r
- else if(message.startsWith("2"))\r
- {\r
- String account = message.subString(1, 10);\r
- \r
- //find the account\r
- for(int i = 0; i < Bank.numOfAccounts; i++)\r
- {\r
- if(Bank.database[i].AccountNumber.equals(account))\r
- {\r
- bas.send("Logout OK");\r
- //System.printString("Logout OK");\r
- }\r
- else\r
- {\r
- bas.send("Logout Error");\r
- //System.printString("Logout Error");\r
- }\r
- }\r
- }\r
- //create\r
- else if(message.startsWith("3"))\r
- {\r
- String account = message.subString(1, 10);\r
- String first = message.subString(10, 20);\r
- String middle = message.subString(20, 30);\r
- String last = message.subString(30, 40);\r
- String type = message.subString(40, 41);\r
- String balance = message.subString(41, 51);\r
- String pin = message.subString(51, 55);\r
- \r
- //find first empty space\r
- int id = -1;\r
- for(int i = 0; i < Bank.numOfAccounts; i++)\r
- {\r
- if(Bank.database[i].AccountNumber.equals("@@@@@@@@@"))\r
- id = i;\r
- }\r
- \r
- if(id != -1)\r
- {\r
- //should check for input errors first but...\r
- Bank.database[id].AccountNumber = first;\r
- Bank.database[id].FirstName = middle;\r
- Bank.database[id].MiddleName = last;\r
- Bank.database[id].LastName = last;\r
- Bank.database[id].AccountType = type;\r
- Bank.database[id].Balance = balance;\r
- Bank.database[id].PIN = pin;\r
- \r
- Bank.numOfAccounts++;\r
- \r
- bas.send(Bank.database[id].AccountNumber);\r
- //System.printString(Bank.database[id].AccountNumber);\r
- }\r
- else\r
- {\r
- bas.send("Create Error");\r
- //System.printString("Create Error");\r
- }\r
- }\r
- //delete\r
- else if(message.startsWith("4"))\r
- {\r
- String account = message.subString(1, 10);\r
- \r
- //find the account\r
- int id = -1;\r
- for(int i = 0; i < Bank.numOfAccounts; i++)\r
- {\r
- if(Bank.database[i].AccountNumber.equals(account))\r
- id = i;\r
- }\r
- \r
- if(id != -1)\r
- {\r
- Bank.database[id].AccountNumber = "@@@@@@@@@@";\r
- Bank.database[id].FirstName = "@@@@@@@@@@";\r
- Bank.database[id].MiddleName = "@@@@@@@@@@";\r
- Bank.database[id].LastName = "@@@@@@@@@@";\r
- Bank.database[id].AccountType = "@";\r
- Bank.database[id].Balance = "@@@@@@@@@@";\r
- Bank.database[id].PIN = "@@@@";\r
- Bank.numOfAccounts--;\r
- \r
- bas.send("Close Account OK");\r
- //System.printString("Close Account OK");\r
- }\r
- else\r
- {\r
- bas.send("Close Account Error");\r
- //System.printString("Close Account Error");\r
- }\r
- }\r
- //modify\r
- else if(message.startsWith("5"))\r
- {\r
- String account = message.subString(1, 10);\r
- String field = message.subString(10, 11);\r
- //two digits 00-99\r
- String numBytes = message.subString(11, 13);\r
- String data = message.subString(13, 13 + Integer.parseInt(numBytes));\r
- \r
- //find the account\r
- int id = -1;\r
- for(int i = 0; i < Bank.numOfAccounts; i++)\r
- {\r
- if(Bank.database[i].AccountNumber.equals(account))\r
- id = i;\r
- }\r
- \r
- if(id != -1)\r
- {\r
- //maybe shouldn't allow changes to some of these fields\r
- if(field.equals("1"))\r
- {\r
- Bank.database[id].AccountNumber = data;\r
- }\r
- else if(field.equals("2"))\r
- {\r
- Bank.database[id].FirstName = data;\r
- }\r
- else if(field.equals("3"))\r
- {\r
- Bank.database[id].MiddleName = data;\r
- }\r
- else if(field.equals("4"))\r
- {\r
- Bank.database[id].LastName = data;\r
- }\r
- else if(field.equals("5"))\r
- {\r
- Bank.database[id].AccountType = data;\r
- }\r
- else if(field.equals("6"))\r
- {\r
- Bank.database[id].Balance = data;\r
- }\r
- else if(field.equals("7"))\r
- {\r
- Bank.database[id].PIN = data;\r
- }\r
- \r
- bas.send("Modify OK");\r
- //System.printString("Modify OK");\r
- }\r
- else\r
- {\r
- bas.send("Modify Error");\r
- //System.printString("Modify Error");\r
- }\r
- }\r
- //check account info\r
- else if(message.startsWith("6"))\r
- {\r
- String account = message.subString(1, 10);\r
- \r
- //find the account\r
- int id = -1;\r
- for(int i = 0; i < Bank.numOfAccounts; i++)\r
- {\r
- if(Bank.database[i].AccountNumber.equals(account))\r
- id = i;\r
- }\r
- \r
- if(id != -1)\r
- {\r
- StringBuffer strBuffer = new StringBuffer(Bank.database[id].AccountNumber);\r
- strBuffer.append(Bank.database[id].FirstName);\r
- strBuffer.append(Bank.database[id].MiddleName);\r
- strBuffer.append(Bank.database[id].LastName);\r
- strBuffer.append(Bank.database[id].AccountType);\r
- strBuffer.append(Bank.database[id].Balance);\r
- strBuffer.append(Bank.database[id].PIN);\r
- \r
- bas.send(strBuffer.toString());\r
- //System.printString(strBuffer.toString());\r
- }\r
- else\r
- {\r
- bas.send("Check Account Info Error");\r
- //System.printString("Check Account Info Error");\r
- }\r
- \r
- }\r
- //deposit\r
- //more string operations or a Float Object could be useful here \r
- else if(message.startsWith("7"))\r
- {\r
- String account = message.subString(1, 10);\r
- //two digits 00-99\r
- //dollar part only\r
- String numBytes = message.subString(10, 12);\r
- //get dollars\r
- String data = message.subString(12, 12 + Integer.parseInt(numBytes));\r
- \r
- \r
- //find the account\r
- int id = -1;\r
- for(int i = 0; i < Bank.numOfAccounts; i++)\r
- {\r
- if(Bank.database[i].AccountNumber.equals(account))\r
- id = i;\r
- }\r
- \r
- if(id != -1)\r
- { \r
- Integer sum = new Integer(Integer.parseInt(Bank.database[id].Balance) + Integer.parseInt(data));\r
- \r
- StringBuffer sumBuffer = new StringBuffer(sum.toString());\r
- \r
- int padding = 10 - sumBuffer.length();\r
- \r
- for(int i = 0; i < padding; i++)\r
- {\r
- sumBuffer.append("@");\r
- }\r
- \r
- //assumes no overflow\r
- Bank.database[id].Balance = sumBuffer.toString();\r
- \r
- bas.send("Deposit OK");\r
- //System.printString("Deposit OK");\r
- }\r
- else\r
- {\r
- bas.send("Deposit Error");\r
- //System.printString("Deposit Error");\r
- }\r
- }\r
- //withdraw\r
- else if(message.startsWith("8"))\r
- {\r
- String account = message.subString(1, 10);\r
- //two digits 00-99\r
- //dollar part only\r
- String numBytes = message.subString(10, 12);\r
- //get dollars\r
- String data = message.subString(12, 12 + Integer.parseInt(numBytes));\r
- \r
- //find the account\r
- int id = -1;\r
- for(int i = 0; i < Bank.numOfAccounts; i++)\r
- {\r
- if(Bank.database[i].AccountNumber.equals(account))\r
- id = i;\r
- }\r
- \r
- if(id != -1)\r
- {\r
- Integer difference = new Integer(Integer.parseInt(Bank.database[id].Balance) - Integer.parseInt(data));\r
- \r
- if(difference.intValue() >= 0)\r
- {\r
- StringBuffer difBuffer = new StringBuffer(difference.toString());\r
- \r
- int padding = 10 - difBuffer.length();\r
- \r
- for(int i = 0; i < padding; i++)\r
- {\r
- difBuffer.append("@");\r
- }\r
- \r
- //assumes no overflow\r
- Bank.database[id].Balance = difBuffer.toString();\r
- \r
- bas.send("Withdraw OK");\r
- //System.printString("Withdraw OK");\r
- }\r
- else\r
- {\r
- bas.send("Overdraw Error");\r
- //System.printString("Overdraw Error");\r
- }\r
- }\r
- else\r
- {\r
- bas.send("Withdraw Error");\r
- //System.printString("Withdraw Error");\r
- }\r
- }\r
- //check balance\r
- else if(message.startsWith("9"))\r
- {\r
- String account = message.subString(1, 10);\r
- \r
- int id = -1;\r
- for(int i = 0; i < Bank.numOfAccounts; i++)\r
- {\r
- if(Bank.database[i].AccountNumber.equals(account))\r
- id = i;\r
- }\r
- \r
- if(id != -1)\r
- {\r
- bas.send(Bank.database[id].Balance);\r
- //System.printString(Bank.database[id].Balance);\r
- }\r
- else\r
- {\r
- bas.send("Check Balance Error");\r
- //System.printString("Check Balance Error");\r
- }\r
- }\r
- else\r
- {\r
- bas.send("Message Error");\r
- //System.printString("Message Error");\r
- }\r
-}\r
+++ /dev/null
-101010101Tony@@@@@@Stone@@@@@Smith@@@@@2123456@@@@8888
\ No newline at end of file
+++ /dev/null
-public class BankAppSocket extends Socket\r
-{\r
- flag BASocketInit;\r
- \r
- public BankAppSocket()\r
- {\r
- \r
- }\r
- \r
- public void send(String message)\r
- {\r
- write(message.getBytes());\r
- }\r
- \r
- public String receive()\r
- {\r
- byte buffer[] = new byte[64];\r
- \r
- int numbytes = read(buffer);\r
- \r
- //it's subString() not substring() like in Java\r
- String message = (new String(buffer)).subString(0, numbytes);\r
- \r
- return message;\r
- }\r
-}\r
+++ /dev/null
-101010101Tony@@@@@@Stone@@@@@Smith@@@@@2123456@@@@8888
\ No newline at end of file
+++ /dev/null
-public class BankDatabase\r
-{\r
- flag DatabaseInit;\r
-\r
- BankAccount[] database;\r
- int numOfAccounts;\r
- \r
- public BankDatabase()\r
- {\r
- //6 pre-created accounts\r
- numOfAccounts = 6;\r
- \r
- //10 account limit\r
- database = new BankAccount[10];\r
- \r
- for(int i = 0; i < 10; i++)\r
- {\r
- database[i] = new BankAccount();\r
- }\r
- \r
- //some hardcoded values\r
- database[0].modifyAccount("123456789", "John@@@@@@", "Q@@@@@@@@@", "Public@@@@", "1", "256000001@", "2007");\r
- database[1].modifyAccount("987654321", "Nancy@@@@@", "H@@@@@@@@@", "Private@@@", "2", "166@@@@@@@", "1234");\r
- database[2].modifyAccount("000111000", "Paul@@@@@@", "Wellington", "Franks@@@@", "1", "454225@@@@", "0000");\r
- database[3].modifyAccount("211411911", "Felix@@@@@", "the@@@@@@@", "Cat@@@@@@@", "3", "0@@@@@@@@@", "9999");\r
- database[4].modifyAccount("111000111", "Paul@@@@@@", "Wellington", "Franks@@@@", "2", "1128989@@@", "0000");\r
- //empty\r
- database[5].modifyAccount("@@@@@@@@@", "@@@@@@@@@@", "@@@@@@@@@@", "@@@@@@@@@@", "@", "@@@@@@@@@@", "@@@@");\r
- database[6].modifyAccount("@@@@@@@@@", "@@@@@@@@@@", "@@@@@@@@@@", "@@@@@@@@@@", "@", "@@@@@@@@@@", "@@@@");\r
- database[7].modifyAccount("@@@@@@@@@", "@@@@@@@@@@", "@@@@@@@@@@", "@@@@@@@@@@", "@", "@@@@@@@@@@", "@@@@");\r
- database[8].modifyAccount("@@@@@@@@@", "@@@@@@@@@@", "@@@@@@@@@@", "@@@@@@@@@@", "@", "@@@@@@@@@@", "@@@@");\r
- database[9].modifyAccount("@@@@@@@@@", "@@@@@@@@@@", "@@@@@@@@@@", "@@@@@@@@@@", "@", "@@@@@@@@@@", "@@@@");\r
- \r
- //test read into database[5]\r
- ReadFile(5);\r
- \r
- //test write from database[5]\r
- WriteFile(database[5].AccountNumber, database[5].FirstName, database[5].MiddleName, database[5].LastName, database[5].AccountType, database[5].Balance, database[5].PIN);\r
- }\r
- \r
- /* what, no destructor?\r
- public ~BankDatabase()\r
- {\r
- //test write from database[5] \r
- }*/\r
- \r
- public void ReadFile(int index) \r
- {\r
- //need to check if read/write works the way I think it does\r
- String filename="BankAppRead.dat";\r
- FileInputStream fis = new FileInputStream(filename);\r
- \r
- byte account[] = new byte[9];\r
- byte first[] = new byte[10];\r
- byte middle[] = new byte[10];\r
- byte last[] = new byte[10];\r
- byte type[] = new byte[1];\r
- byte balance[] = new byte[10];\r
- byte pin[] = new byte[4];\r
- \r
- //read one account for now\r
- fis.read(account);\r
- fis.read(first);\r
- fis.read(middle);\r
- fis.read(last);\r
- fis.read(type);\r
- fis.read(balance);\r
- fis.read(pin);\r
- \r
- fis.close();\r
- \r
- String S1 = new String(account);\r
- //System.printString(S1);\r
- String S2 = new String(first);\r
- //System.printString(S2);\r
- String S3 = new String(middle);\r
- //System.printString(S3);\r
- String S4 = new String(last);\r
- //System.printString(S4);\r
- String S5 = new String(type);\r
- //System.printString(S5);\r
- String S6 = new String(balance);\r
- //System.printString(S6);\r
- String S7 = new String(pin);\r
- //System.printString(S7);\r
- \r
- //read into one account for now\r
- database[index].modifyAccount(S1, S2, S3, S4, S5, S6, S7);\r
- }\r
- \r
- public void WriteFile(String account, String first, String middle, String last, String type, String balance, String pin) \r
- {\r
- String filename="BankAppWrite.dat";\r
- FileOutputStream fos = new FileOutputStream(filename);\r
- \r
- //write one account for now\r
- fos.write(account.getBytes());\r
- fos.write(first.getBytes());\r
- fos.write(middle.getBytes());\r
- fos.write(last.getBytes());\r
- fos.write(type.getBytes());\r
- fos.write(balance.getBytes());\r
- fos.write(pin.getBytes());\r
- \r
- fos.close();\r
- }\r
-}\r
+++ /dev/null
-// Bank App in Java
-
-// Author: Danish Lakhani
-
-// BankAppServer - Bank Application Server that services one client at a time
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-class BankAppClientTeller
-{
- static int SUCCESS = 0;
- static int ERROR = 1;
-
- static int LOGIN_ACCOUNT = 1;
- static int LOGIN_PIN = 2;
-
- static int ACCOUNT_SAVINGS = 1;
- static int ACCOUNT_CHECKING = 2;
- static int ACCOUNT_TELLER = 3;
-
- private Socket mySocket = null;
- private PrintWriter out = null;
- private BufferedReader in = null;
- private static int serverPort = 44444;
-
- public BankAppClientTeller()
- {
- }
-
- private void establishConnection()
- throws IOException
- {
- System.out.println("Connecting to server...");
- mySocket = new Socket("localhost", serverPort);
- out = new PrintWriter(mySocket.getOutputStream(), true);
- in = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
- System.out.println("Connection Established!");
- }
-
- private void closeConnection()
- throws IOException
- {
- if (out != null)
- out.close();
- if (in != null)
- in.close();
- if (mySocket != null)
- mySocket.close();
- }
-
- private void displayMenu()
- {
- System.out.println("\nBankAppClientTeller");
- System.out.println("----------------");
- System.out.println("1. Login");
- System.out.println("2. Logout");
- System.out.println("3. Deposit");
- System.out.println("4. Withdraw");
- System.out.println("5. Check Balance");
- System.out.println("6. Open Account");
- System.out.println("7. Close Account");
- System.out.println("8. Modify Account");
- System.out.println("9. Check Account Info");
- System.out.println("0. Exit\n");
- System.out.print("Enter Choice: ");
- return;
- }
-
- private void startClient()
- throws IOException
- {
- int clientQuit = 0;
- int status = SUCCESS;
- int isConnected = 0;
- boolean loggedIn = false;
- BufferedReader local_in = new BufferedReader(new InputStreamReader(System.in));
- while (clientQuit == 0)
- {
- if (!loggedIn)
- establishConnection();
- isConnected = 1;
- while (isConnected == 1)
- {
- displayMenu();
- String input = local_in.readLine();
- int selection = Integer.parseInt(input);
- String response;
- switch (selection)
- {
- case 0:
- System.out.println("Exitting...");
- out.println("EXIT");
- System.exit(0);
- break;
- case 1:
- System.out.println("Login");
- out.println("LOGIN");
- response = in.readLine();
- if (response.equals("OK"))
- {
- System.out.print("Enter account number: ");
- String accountNumber = local_in.readLine();
- System.out.print("Enter PIN: ");
- String pinNumber = local_in.readLine();
- out.println(accountNumber);
- out.println(pinNumber);
- response = in.readLine();
- if (response.equals(accountNumber))
- {
- System.out.println("Login Successful! Account: " + response);
- loggedIn = true;
- }
- else
- {
- System.out.println(response);
- }
- }
- else
- {
- System.out.println(response);
- }
- break;
- case 2:
- System.out.println("Logout");
- out.println("LOGOUT");
- response = in.readLine();
- if (response.equals("OK"))
- {
- response = in.readLine();
- System.out.println("Logout Successful! Account: " + response);
- }
- else
- {
- System.out.println(response);
- }
- break;
- case 3:
- System.out.println("Deposit");
- out.println("TELLERDEPOSIT");
- response = in.readLine();
- if (response.equals("OK"))
- {
- System.out.print("Enter Account Number: ");
- String accNum = local_in.readLine();
- out.println(accNum);
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- break;
- }
- System.out.print("Enter Deposit Amount: ");
- String depAmount = local_in.readLine();
- out.println(depAmount);
- response = in.readLine();
- if (response.equals("OK"))
- {
- response = in.readLine();
- }
- }
- System.out.println(response);
- break;
- case 4:
- System.out.println("Withdraw");
- out.println("TELLERWITHDRAW");
- response = in.readLine();
- if (response.equals("OK"))
- {
- System.out.print("Enter Account Number: ");
- String accNum = local_in.readLine();
- out.println(accNum);
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- break;
- }
- System.out.print("Enter Withdrawal Amount: ");
- String wdAmount = local_in.readLine();
- out.println(wdAmount);
- response = in.readLine();
- if (response.equals("OK"))
- {
- response = in.readLine();
- }
- }
- System.out.println(response);
- break;
- case 5:
- System.out.println("Check Balance");
- out.println("TELLERCHECK");
- response = in.readLine();
- if (response.equals("OK"))
- {
- System.out.print("Enter Account Number: ");
- String accNum = local_in.readLine();
- out.println(accNum);
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- break;
- }
- response = in.readLine();
- }
- System.out.println(response);
- break;
- case 6:
- System.out.println("Account Open");
- out.println("TELLEROPEN");
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- break;
- }
- System.out.print("Enter Account Number: ");
- out.println(local_in.readLine());
- System.out.print("Enter First Name: ");
- out.println(local_in.readLine());
- System.out.print("Enter Middle Name: ");
- out.println(local_in.readLine());
- System.out.print("Enter Last Name: ");
- out.println(local_in.readLine());
- System.out.print("Enter Account Type: ");
- out.println(local_in.readLine());
- System.out.print("Enter Initial Balance: ");
- out.println(local_in.readLine());
- System.out.print("Enter PIN: ");
- out.println(local_in.readLine());
- response = in.readLine();
- if (response.equals("OK"))
- response = in.readLine();
- System.out.println(response);
- break;
- case 7:
- System.out.println("Account Close");
- out.println("TELLERCLOSE");
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- break;
- }
- System.out.print("Enter Account Number: ");
- out.println(local_in.readLine());
- response = in.readLine();
- if (response.equals("OK"))
- response = in.readLine();
- System.out.println(response);
- break;
- case 8:
- System.out.println("Modify Account");
- out.println("TELLERMODIFY");
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- break;
- }
- System.out.print("Enter Account Number: ");
- String accNum = local_in.readLine();
- out.println(accNum);
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- break;
- }
- int done = 0;
- while (done == 0)
- {
- System.out.println("1. Change Name");
- System.out.println("2. Change Type");
- System.out.println("3. Change PIN");
- System.out.println("4. Change Balance");
- System.out.println("5. Done\n");
- System.out.print("Enter Choice: ");
- int choice = Integer.parseInt(local_in.readLine());
- switch (choice)
- {
- case 1:
- out.println("CHANGENAME");
- System.out.print("Enter New First Name: ");
- out.println(local_in.readLine());
- System.out.print("Enter New Middle Name: ");
- out.println(local_in.readLine());
- System.out.print("Enter New Last Name: ");
- out.println(local_in.readLine());
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- }
- break;
- case 2:
- out.println("CHANGETYPE");
- System.out.print("Enter New Account Type: ");
- out.println(local_in.readLine());
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- }
- break;
- case 3:
- out.println("CHANGEPIN");
- System.out.print("Enter New PIN: ");
- out.println(local_in.readLine());
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- }
- break;
- case 4:
- out.println("CHANGEBALANCE");
- System.out.print("Enter New Balance: ");
- out.println(local_in.readLine());
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- }
- break;
- case 5:
- done = 1;
- out.println("DONE");
- break;
- default:
- System.out.println("Invalid selection");
- break;
- }
- }
- response = in.readLine();
- System.out.println(response);
- break;
- case 9:
- System.out.println("View Account");
- out.println("TELLERVIEW");
- response = in.readLine();
- if (!response.equals("OK"))
- {
- System.out.println(response);
- break;
- }
- System.out.print("Enter Account Number: ");
- String accNumber = local_in.readLine();
- out.println(accNumber);
- response = in.readLine();
- if (response.equals("OK"))
- response = in.readLine();
- System.out.println(response);
- break;
- default:
- System.out.println("Invalid Selection");
- break;
- }
- System.out.println("Press Enter to Continue...");
- local_in.readLine();
- }
- }
- }
-
- public static void main(String [] args)
- throws IOException
- {
- System.out.println("BankAppClientTeller in Java");
- BankAppClientTeller client = new BankAppClientTeller();
- client.startClient();
- }
-}
+++ /dev/null
-// Bank App in Java
-
-// Author: Danish Lakhani
-
-// BankAppServer - Bank Application Server that services one client at a time
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-class BankAppServer
-{
- static int SUCCESS = 0;
- static int ERROR = 1;
-
- static int LOGIN_ACCOUNT = 1;
- static int LOGIN_PIN = 2;
-
- static int ACCOUNT_SAVINGS = 1;
- static int ACCOUNT_CHECKING = 2;
- static int ACCOUNT_TELLER = 3;
-
- private ServerSocket serverSocket = null;
- private Socket clientSocket = null;
- private PrintWriter out = null;
- private BufferedReader in = null;
- private static int serverPort = 44444;
- private AccountDatabase accounts = null;
-
- private boolean isLoggedIn = false;
- private Integer activeAccount = 0;
- private Integer tellerCode = 0;
-
- public BankAppServer()
- {
-// initializeServer();
- }
-
- private void initializeServer()
- {
- //Initialize Database
- accounts = new AccountDatabase();
-
- //Initialize Server Socket
- System.out.print("Creating Server Socket...");
- try {
- serverSocket = new ServerSocket(serverPort);
- } catch (IOException e) {
- System.out.println("Cannot listen on port " + serverPort);
- System.exit(-1);
- }
- System.out.println("Done");
- }
-
- private void establishConnection()
- throws IOException
- {
- System.out.print("Waiting for connection...");
- try {
- clientSocket = serverSocket.accept();
- } catch (IOException e) {
- System.out.println("Accept failed");
- System.exit(-1);
- }
- out = new PrintWriter(clientSocket.getOutputStream(), true);
- in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
- System.out.println("Connection Established!");
- }
-
- private int authenticateUser(Integer accountNumber, Integer pin)
- {
- if (!accounts.accountExists(accountNumber))
- return LOGIN_ACCOUNT;
- if (accounts.getPin(accountNumber) != pin)
- return LOGIN_PIN;
- return SUCCESS;
- }
-
- private int login()
- throws IOException
- {
- out.println("OK");
- Integer accountNumber = new Integer(in.readLine());
- System.out.println("Account number: " + accountNumber);
- Integer pin = new Integer(in.readLine());
- System.out.println("PIN: " + pin);
- System.out.println("Authenticating...");
- int status = authenticateUser(accountNumber, pin);
- if (status == SUCCESS)
- {
- out.println(accountNumber);
- isLoggedIn = true;
- tellerCode = 0;
- activeAccount = 0;
- if (accounts.isTeller(accountNumber))
- tellerCode = accountNumber;
- else
- activeAccount = accountNumber;
- System.out.println("Logged Success");
- return SUCCESS;
- }
- else {
- if (status == LOGIN_ACCOUNT)
- out.println("ERROR: login failed: Account " + accountNumber + " does not exist.");
- else
- out.println("ERROR: login failed: Incorrect pin.");
- }
- System.out.println("Login Failed");
- return ERROR;
- }
-
- private void closeConnection()
- throws IOException
- {
- out.close();
- in.close();
- clientSocket.close();
-// serverSocket.close();
- }
-
- private void processDeposit(Integer accountNumber) throws IOException
- {
- String inVal;
- if (!accounts.accountExists(accountNumber))
- {
- out.println("ERROR: Account " + accountNumber + " not found.");
- return;
- }
-
- out.println("OK");
-
- //Get Deposit Amount
- inVal = in.readLine();
- Double depAmount = new Double(inVal);
- if (depAmount <= 0)
- {
- out.println("ERROR: Negative or zero deposit amount");
- return;
- }
-
- accounts.deposit(accountNumber, depAmount);
- out.println("OK");
- out.println("$" + depAmount + " deposited successfully! Account: " + accountNumber + " New Balance: " + accounts.getBalance(accountNumber));
- return;
- }
-
- private void processWithdrawal(Integer accountNumber) throws IOException
- {
- String inVal;
- if (!accounts.accountExists(accountNumber))
- {
- out.println("ERROR: Account " + accountNumber + " not found.");
- return;
- }
-
- out.println("OK");
-
- //Get withdrawal amount
- inVal = in.readLine();
- Double wdAmount = new Double(inVal);
- if (wdAmount <= 0)
- {
- out.println("ERROR: Negative or zero withdrawal amount");
- return;
- }
-// else if (wdAmount > accounts.getBalance(accountNumber))
-// {
-// out.println("ERROR: Insufficient funds. Balance = " + accounts.getBalance(accountNumber));
-// return;
-// }
-
- accounts.withdraw(accountNumber, wdAmount);
- out.println("OK");
- out.println("$" + wdAmount + " withdrawn successfully! Account: " + accountNumber + " New Balance: " + accounts.getBalance(accountNumber));
- return;
- }
-
- private void processBalanceCheck(Integer accountNumber)
- {
- out.println("OK");
- out.println("Account: " + accountNumber + " Balance: " + accounts.getBalance(accountNumber));
- return;
- }
-
- private void startServer()
- throws IOException
- {
- int serverQuit = 0;
- int status = SUCCESS;
- int isConnected = 0;
- initializeServer();
- while (serverQuit == 0)
- {
- establishConnection();
- isConnected = 1;
- accounts.loadDatabase();
- while (isConnected == 1)
- {
- System.out.println("Waiting for request...");
- // Wait for requests
- String request = in.readLine();
- if (request == null)
- continue;
-
- System.out.println("Request: " + request);
-
- // Service requests
- if (request.equals("EXIT"))
- {
- accounts.storeDatabase();
- isLoggedIn = false;
- activeAccount = 0;
- tellerCode = 0;
- closeConnection();
- isConnected = 0;
- continue;
- }
-
- if (request.equals("LOGIN"))
- {
- if (isLoggedIn)
- {
- out.println("ERROR: Already logged in. Please logout.");
- continue;
- }
- status = login();
- if (status == ERROR)
- {
-// isConnected = 0;
- continue;
- }
- }
-
- if (!isLoggedIn)
- {
- out.println("ERROR: Not logged in");
- continue;
- }
-
- if (request.equals("LOGOUT"))
- {
- out.println("OK");
- if (tellerCode == 0)
- out.println(activeAccount);
- else
- out.println(tellerCode);
- accounts.storeDatabase();
- isLoggedIn = false;
- activeAccount = 0;
- tellerCode = 0;
-// closeConnection();
-// isConnected = 0;
- }
-
- if (request.equals("DEPOSIT"))
- {
- processDeposit(activeAccount);
- }
-
- if (request.equals("WITHDRAW"))
- {
- processWithdrawal(activeAccount);
- }
-
- if (request.equals("CHECK"))
- {
- processBalanceCheck(activeAccount);
- }
-
- if (request.equals("TELLERDEPOSIT"))
- {
- if (tellerCode == 0)
- {
- out.println("ERROR: Teller not logged in");
- continue;
- }
- out.println("OK");
- Integer acc = new Integer(in.readLine());
- processDeposit(acc);
- }
-
- if (request.equals("TELLERWITHDRAW"))
- {
- if (tellerCode == 0)
- {
- out.println("ERROR: Teller not logged in");
- continue;
- }
- out.println("OK");
- Integer acc = new Integer(in.readLine());
- processWithdrawal(acc);
- }
-
- if (request.equals("TELLERCHECK"))
- {
- if (tellerCode == 0)
- {
- out.println("ERROR: Teller not logged in");
- continue;
- }
- out.println("OK");
- Integer acc = new Integer(in.readLine());
- processBalanceCheck(acc);
- }
-
- if (request.equals("TELLEROPEN"))
- {
- if (tellerCode == 0)
- {
- out.println("ERROR: Teller not logged in");
- continue;
- }
- out.println("OK");
- Integer accNum = new Integer(in.readLine());
- String fName = in.readLine();
- String mName = in.readLine();
- String lName = in.readLine();
- Integer accType = new Integer(in.readLine());
- Double bal = new Double(in.readLine());
- Integer pNum = new Integer(in.readLine());
- status = accounts.openAccount(accNum, fName, mName, lName, accType, bal, pNum);
- if (status == ERROR)
- {
- out.println("ERROR: Account " + accNum + " already exists.");
- continue;
- }
- out.println("OK");
- out.println("Account Number: " + accNum + " " +
- "Customer Name: " + fName + " " + mName + " " + lName + " " +
- "Account Type: " + ((accType == ACCOUNT_SAVINGS)?"SAVINGS":(accType == ACCOUNT_CHECKING)?"CHECKING":"TELLER") + " " +
- "Balance: $" + bal + " " +
- "PIN: " + pNum + " ");
- }
-
- if (request.equals("TELLERCLOSE"))
- {
- if (tellerCode == 0)
- {
- out.println("ERROR: Teller not logged in");
- continue;
- }
- out.println("OK");
- Integer accNum = new Integer(in.readLine());
- status = accounts.closeAccount(accNum);
- if (status == ERROR)
- {
- out.println("ERROR: Account " + accNum + " does not exist.");
- continue;
- }
- out.println("OK");
- out.println("Account " + accNum + " closed successfully");
- }
-
- if (request.equals("TELLERMODIFY"))
- {
- if (tellerCode == 0)
- {
- out.println("ERROR: Teller not logged in");
- continue;
- }
- out.println("OK");
- Integer accNum = new Integer(in.readLine());
- if (!accounts.accountExists(accNum))
- {
- out.println("ERROR: Account " + accNum + " does not exist.");
- continue;
- }
- out.println("OK");
- String inVal;
- while (!(inVal = in.readLine()).equals("DONE"))
- {
- if (inVal.equals("CHANGENAME"))
- {
- String fName = in.readLine();
- String mName = in.readLine();
- String lName = in.readLine();
- accounts.modifyName(accNum, fName, mName, lName);
- out.println("OK");
- }
- else if (inVal.equals("CHANGETYPE"))
- {
- Integer newType = new Integer(in.readLine());
- if (newType.intValue() < 1 || newType.intValue() > 3)
- {
- out.println("ERROR: Invalid account type: " + newType + ". Must be 1-3.");
- continue;
- }
- accounts.modifyType(accNum, newType);
- out.println("OK");
- }
- else if (inVal.equals("CHANGEPIN"))
- {
- Integer newPin = new Integer(in.readLine());
- if ((newPin < 0) || (newPin > 9999))
- {
- out.println("ERROR: Invalid pin " + newPin + ". Must be 0000-9999.");
- continue;
- }
- accounts.modifyPin(accNum, newPin);
- out.println("OK");
- }
- else if (inVal.equals("CHANGEBALANCE"))
- {
- Double newBal = new Double(in.readLine());
- accounts.modifyBalance(accNum, newBal);
- out.println("OK");
- }
- }
- out.println("Account Number: " + accNum + " " +
- "Customer Name: " + accounts.nameString(accNum) + " " +
- "Account Type: " + accounts.typeString(accNum) + " " +
- "Balance: $" + accounts.getBalance(accNum) + " " +
- "PIN: " + accounts.getPin(accNum) + " ");
- }
-
- if (request.equals("TELLERVIEW"))
- {
- if (tellerCode == 0)
- {
- out.println("ERROR: Teller not logged in");
- continue;
- }
- out.println("OK");
- Integer accNum = new Integer(in.readLine());
- if (!accounts.accountExists(accNum))
- {
- out.println("ERROR: Account " + accNum + " does not exist.");
- continue;
- }
- out.println("OK");
- out.println("Account Number: " + accNum + " " +
- "Customer Name: " + accounts.nameString(accNum) + " " +
- "Account Type: " + accounts.typeString(accNum) + " " +
- "Balance: $" + accounts.getBalance(accNum) + " " +
- "PIN: " + accounts.getPin(accNum) + " ");
- }
- }
- }
- }
-
- public static void main(String [] args)
- throws IOException
- {
- System.out.println("BankAppServer in Java");
- BankAppServer server = new BankAppServer();
- server.startServer();
- }
-}
-
-class AccountEntry
-{
- Integer accountNumber;
- String firstName;
- String middleName;
- String lastName;
- Integer accountType;
- Double balance;
- Integer pin;
-
- public AccountEntry(Integer accNum, String fName, String mName, String lName, Integer accType, Double bal, Integer pNum)
- {
- accountNumber = accNum;
- firstName = fName;
- middleName = mName;
- lastName = lName;
- accountType = accType;
- balance = bal;
- pin = pNum;
- }
-}
-
-
-class AccountDatabase
-{
- static int ACCOUNT_SAVINGS = 1;
- static int ACCOUNT_CHECKING = 2;
- static int ACCOUNT_TELLER = 3;
- static int SUCCESS = 0;
- static int ERROR = 1;
-
- static String dbfilename = "accts.txt";
-
- Vector<AccountEntry> entries = null;
-
- public AccountDatabase()
- {
- entries = new Vector<AccountEntry>();
- }
-
- public void loadDatabase()
- {
- entries.removeAllElements();
- try {
- BufferedReader fin = new BufferedReader(new FileReader(dbfilename));
- String str;
- while ((str = fin.readLine()) != null)
- {
- Integer accNum = new Integer(str);
- String fName = fin.readLine();
- String mName = fin.readLine();
- String lName = fin.readLine();
- Integer accType = new Integer(fin.readLine());
- Double bal = new Double(fin.readLine());
- Integer pNum = new Integer(fin.readLine());
- AccountEntry newEntry = new AccountEntry(accNum, fName, mName, lName, accType, bal, pNum);
- entries.add(newEntry);
- }
- fin.close();
- } catch (IOException e) {
- System.out.println("Cannot open database file");
- System.exit(-1);
- }
- printAccounts();
- }
-
- public void storeDatabase()
- {
- try {
- BufferedWriter fout = new BufferedWriter(new FileWriter(dbfilename));
- for (int i = 0; i < entries.size(); i++)
- {
- AccountEntry acc = (AccountEntry)entries.elementAt(i);
- fout.write(acc.accountNumber.toString());
- fout.newLine();
- fout.write(acc.firstName);
- fout.newLine();
- fout.write(acc.middleName);
- fout.newLine();
- fout.write(acc.lastName);
- fout.newLine();
- fout.write(acc.accountType.toString());
- fout.newLine();
- fout.write(acc.balance.toString());
- fout.newLine();
- fout.write(acc.pin.toString());
- fout.newLine();
- }
- fout.close();
- } catch (IOException e) {
- System.out.println("Cannot write to database file");
- System.exit(-1);
- }
- }
-
- public AccountEntry getAccount(Integer accNum)
- {
- for (int i = 0; i < entries.size(); i++)
- {
- AccountEntry acc = (AccountEntry)entries.elementAt(i);
- if (acc.accountNumber.equals(accNum))
- return acc;
- }
- return null;
- }
-
- public void deposit(Integer accNum, Double amount)
- {
- AccountEntry acc = getAccount(accNum);
- acc.balance += amount;
- }
-
- public void withdraw(Integer accNum, Double amount)
- {
- AccountEntry acc = getAccount(accNum);
- acc.balance -= amount;
- }
-
- public Double getBalance(Integer accNum)
- {
- AccountEntry acc = getAccount(accNum);
- return acc.balance;
- }
-
- public int getPin(Integer accNum)
- {
- AccountEntry acc = getAccount(accNum);
- if (acc != null)
- return acc.pin.intValue();
- return -1;
- }
-
- public boolean accountExists(Integer accNum)
- {
- AccountEntry acc = getAccount(accNum);
- if (acc != null)
- return true;
- return false;
- }
-
- public boolean isTeller(Integer accNum)
- {
- AccountEntry acc = getAccount(accNum);
- if (acc.accountType.equals(ACCOUNT_TELLER))
- return true;
- return false;
- }
-
- public Integer openAccount(Integer accNum, String fName, String mName, String lName, Integer accType, Double bal, Integer pNum)
- {
- if (accountExists(accNum))
- return ERROR;
- AccountEntry acc = new AccountEntry(accNum, fName, mName, lName, accType, bal, pNum);
- entries.add(acc);
- return SUCCESS;
- }
-
- public Integer closeAccount(Integer accNum)
- {
- if (accountExists(accNum))
- {
- AccountEntry acc = getAccount(accNum);
- entries.remove(acc);
- return SUCCESS;
- }
- else
- return ERROR;
- }
-
- public String nameString(Integer accNum)
- {
- AccountEntry acc = getAccount(accNum);
- if (acc != null)
- {
- return (acc.firstName + " " + acc.middleName + " " + acc.lastName);
- }
- return "";
- }
-
- public String typeString(Integer accNum)
- {
- AccountEntry acc = getAccount(accNum);
- if (acc != null)
- {
- return ((acc.accountType == ACCOUNT_SAVINGS)?"SAVINGS":(acc.accountType == ACCOUNT_CHECKING)?"CHECKING":"TELLER");
- }
- return "";
- }
-
- public void modifyName(Integer accNum, String fName, String mName, String lName)
- {
- AccountEntry acc = getAccount(accNum);
- if (acc != null)
- {
- acc.firstName = fName;
- acc.middleName = mName;
- acc.lastName = lName;
- }
- return;
- }
-
- public void modifyType(Integer accNum, Integer newType)
- {
- AccountEntry acc = getAccount(accNum);
- if (acc != null)
- {
- acc.accountType = newType;
- }
- return;
- }
-
- public void modifyPin(Integer accNum, Integer newPin)
- {
- AccountEntry acc = getAccount(accNum);
- if (acc != null)
- {
- acc.pin = newPin;
- }
- return;
- }
-
- public void modifyBalance(Integer accNum, Double newBal)
- {
- AccountEntry acc = getAccount(accNum);
- if (acc != null)
- {
- acc.balance = newBal;
- }
- return;
- }
-
- public void printAccounts()
- {
- System.out.println("entries.size = " + entries.size());
- for (int i = 0; i < entries.size(); i++)
- {
- System.out.println("Entry " + i);
- AccountEntry acc = entries.elementAt(i);
- System.out.println("1 " + acc.accountNumber.toString());
- System.out.println("2 " + acc.firstName);
- System.out.println("3 " + acc.middleName);
- System.out.println("4 " + acc.lastName);
- System.out.println("5 " + acc.accountType.toString());
- System.out.println("6 " + acc.balance.toString());
- System.out.println("7 " + acc.pin.toString());
- }
- }
-}
+++ /dev/null
-// Bank App in Java
-
-// Author: Danish Lakhani
-
-import java.io.*;
-import java.net.*;
-
-class BankAppTestClient
-{
- public static void main(String [] args)
- throws IOException
- {
- BufferedReader local_in = new BufferedReader(new InputStreamReader(System.in));
- String sendline;
-
- System.out.println("Client");
-
- sendline = local_in.readLine();
-if (sendline == null)
- sendline = "localhost";
- System.out.println("Connecting to server...");
- Socket mySocket = new Socket(sendline, 8000);
-
- System.out.println("Connected!!");
-
- PrintWriter out = new PrintWriter(mySocket.getOutputStream(), true);
- BufferedReader in = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
-
-
-
- while (true)
- {
- System.out.print("Send: ");
- sendline = local_in.readLine();
-
- if (!sendline.equals("no"))
- {
- out.println(sendline);
- }
- else
- {
- System.out.print("Reading: ");
- String inString = in.readLine();
- System.out.println(inString);
- }
- }
- }
-}
+++ /dev/null
-1111
-Danish
-Salim
-Lakhani
-1
-2000.0
-1234
-1000
-Danish
-Teller
-Lakhani
-3
-0.0
-2000
+++ /dev/null
--initializerandom -injectinstructionfailures 45 0.0001667 10 -debugtask
+++ /dev/null
-task Startup(StartupObject s{initialstate}) {
- System.printString("Chat Server Benchmark");
- RoomObject ro=new RoomObject() {Initialized};
- ServerSocket ss=new ServerSocket(8000);
- taskexit(s{!initialstate});
-}
-
-task AcceptConnection(ServerSocket ss{SocketPending}) {
- ChatSocket cs=new ChatSocket() {Initialized};
- ss.accept(cs);
- cs.write("Please choose a chatroom".getBytes());
-}
-
-task ReadRequest(ChatSocket cs{Initialized && IOPending}) {
- if (cs.processRead()) {
- taskexit(cs{!Initialized, ProcessRoom});
- }
-}
-
-task ProcessRoom(ChatSocket cs{ProcessRoom}, RoomObject ro{Initialized}) {
- cs.processRoom(ro);
- taskexit(cs{!ProcessRoom, InRoom});
-}
-
-task Message(ChatSocket cs{InRoom && IOPending}) {
- byte buffer[]=new byte[1024];
- int length=cs.read(buffer);
- Message m=new Message(buffer, length, cs){};
-}
-
-task SendMessage(Message m{!Sent}) {
- String st=(new String(m.buffer)).subString(0, m.length);
- m.cs.room.sendToRoom(m.cs,st.getBytes());
- taskexit(m {Sent});
-}
+++ /dev/null
-public class ChatSocket extends Socket {
- flag Initialized;
- flag ProcessRoom;
- flag InRoom;
- Room room;
- String roomrequest;
-
- public ChatSocket() {
- }
-
- public boolean processRead() {
- byte buffer[]=new byte[1024];
- int length=read(buffer);
- String st=new String(buffer);
- String curr=st.subString(0, length);
- if (roomrequest!=null) {
- StringBuffer sb=new StringBuffer(roomrequest);
- sb.append(curr);
- curr=sb.toString();
- }
- roomrequest=curr;
- if (roomrequest.indexOf("\n")>=0) {
- return true;
- }
- return false;
- }
- public void processRoom(RoomObject ro) {
- ro.getChatRoom(roomrequest).addParticipant(this);
- }
-}
+++ /dev/null
-public class Message {
- flag Sent;
- ChatSocket cs;
- byte buffer[];
- int length;
-
- public Message(byte[] b, int l, ChatSocket cs) {
- this.cs=cs;
- this.buffer=b;
- this.length=l;
- }
-}
+++ /dev/null
-import java.awt.*;
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-public class NetsClient extends Thread {
-
- static boolean debug;
-
- public static void main(String argv[]) {
-
- String host=null;
- int numberofclients=0;
- int numberofmessages=0;
- int groups=0;
- int port=4321;
-
- NetsClient.debug=false;
- try {
- host=argv[0];
- port=Integer.parseInt(argv[1]);
- numberofclients=Integer.parseInt(argv[2]);
- numberofmessages=Integer.parseInt(argv[3]);
- groups=Integer.parseInt(argv[4]);
- }
- catch (Exception e) {
- System.out.println("NetsClient host port numberofclients numberofmessages debugflag");
- }
- try {
- NetsClient.debug=(Integer.parseInt(argv[5])==1);
- } catch (Exception e) {}
-
- NetsClient[][] tarray=new NetsClient[groups][numberofclients];
- for (int g=0;g<groups;g++) {
- for (int i = 0; i < numberofclients; i++) {
- String room="group"+g;
- tarray[g][i] = new NetsClient(i, host, port,
- numberofmessages, numberofclients, room);
- if (debug)
- System.out.println("Attempting to start "+i);
- tarray[g][i].connectt();
- }
-
- try {
- Thread.sleep(1000);
- } catch (Exception e) {};
- for (int i = 0; i < numberofclients; i++)
- tarray[g][i].start();
- try {
- for (int i = 0; i < numberofclients; i++) {
- tarray[g][i].join();
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- System.out.println(e);
- }
- }
-
- int messages=0;
- for (int g=0;g<groups;g++)
- for(int i=0;i<numberofclients;i++)
- messages+=tarray[g][i].lines;
-
- System.out.println("ChatClient");
- System.out.println("numclients:" + numberofclients);
- System.out.println("groups:"+groups);
- System.out.println("port:" + port);
- System.out.println("number of messages:" + numberofmessages);
-
- System.out.println("Lines="+messages+" out of "+groups*numberofclients*(numberofclients-1)*numberofmessages);
- }
-
- public NetsClient(int clientnumber, String host,
- int port, int nom, int noc, String room) {
- this.port=port;
- this.clientnumber=clientnumber;
- this.host=host;
- this.nom=nom;
- this.noc=noc;
- this.room=room;
- }
-
- String room;
- int nom, noc,clientnumber,port;
- String host;
- Socket sock;
- PrintStream pout;
- InputStream in;
- OutputStream out;
- //DataInputStream din;
- BufferedReader d;
- int lines=0;
-
- public void connectt() {
- try{
- sock = new Socket(host, port); // unix server
- if (debug)
- System.out.println("connection made");
- in = sock.getInputStream();
- out = sock.getOutputStream();
- pout = new PrintStream(out);
- //din = new DataInputStream(in);
- pout.println(room);
- pout.flush();
- }
- catch (UnknownHostException e ) {
- System.out.println("can't find host");
- }
- catch (IOException e) {
- System.out.println("Error connecting to host");
- }
- }
-
- public void run() {
- if (debug)
- System.out.println("client thread started");
- int ns=0;
-
- try {
- for(int nr=0;nr<noc*nom;nr++) {
- if ((nr%noc)==clientnumber) {
- ns++;
- pout.println(room+"|"+clientnumber+"|hello#"+ns);
- }
- while(in.available()>0) {
- int nchar=in.read();
- if (nchar==10)
- lines++;
- }
- }
- pout.flush();
- long time=System.currentTimeMillis();
- while((System.currentTimeMillis()-time)<8*1000) {
- if(in.available()>0) {
- int nchar=in.read();
- time=System.currentTimeMillis();
- if (nchar==10)
- lines++;
- } else try {Thread.sleep(2);} catch (Exception e) {}
- }
- }
-
- catch (UnknownHostException e ) {System.out.println("can't find host"); }
- catch ( IOException e ) {System.out.println("Error connecting to host");}
-
- }
-
-} // end of client class
+++ /dev/null
-public class Room {
- String name;
- HashSet participants;
- public Room(String n) {
- name=n;
- participants=new HashSet();
- }
-
- void addParticipant(ChatSocket cs) {
- participants.add(cs);
- cs.room=this;
- }
-
- void sendToRoom(ChatSocket caller, byte [] message) {
- HashMapIterator hmi=participants.iterator();
- while(hmi.hasNext()) {
- ChatSocket cs=(ChatSocket) hmi.next();
- if (cs!=caller)
- cs.write(message);
- }
- }
-}
+++ /dev/null
-public class RoomObject {
- flag Initialized;
- HashMap rooms;
- public RoomObject() {
- rooms=new HashMap();
- }
-
- Room getChatRoom(String name) {
- if (rooms.containsKey(name))
- return (Room) rooms.get(name);
- Room r=new Room(name);
- rooms.put(name, r);
- return r;
- }
-}
+++ /dev/null
-import java.io.*;
-public class analyze {
- public static void main(String[] q) {
- int sum=0;
- int count=0;
- try {
- BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
- while(true) {
- String s=br.readLine();
- String x=s.substring(6,s.indexOf(' ',6));
-
- sum+=(new Integer(x)).intValue();
- count++;
- System.out.println(sum+" "+(((double)sum)/count));
- }
- } catch(Exception e) {}
- }
-
-
-
-}
+++ /dev/null
-#!/bin/bash
-./runtest.sh taskchat.bin &> tasklog
-mkdir task
-mv *.log task
-./runtest.sh threadchat.bin &> threadlog
-mkdir thread
-mv *.log thread
\ No newline at end of file
+++ /dev/null
-#!/bin/bash
-let i=0
-while [ $i -le 100 ];
-do
-./$1 &> $i.log &
-sleep 1
-java NetsClient 127.0.0.1 8000 2 50 8 1
-killall -SIGUSR2 $1
-sleep 1
-killall -9 $1
-let "i+=1"
-done
\ No newline at end of file
+++ /dev/null
-public class ChatServer {
-
- public static int main(String arg[]) {
- System.printString("Chat Server Benchmark");
- RoomObject ro=new RoomObject();
- ServerSocket ss=new ServerSocket(8000);
- acceptConnection(ss,ro);
- }
-
- public static void acceptConnection(ServerSocket ss, RoomObject ro) {
- while(true) {
- Socket s=ss.accept();
- ChatThread cs=new ChatThread(s, ro);
- cs.start();
- }
- }
-}
+++ /dev/null
-public class ChatThread extends Thread {
- Room room;
- String roomrequest;
- Socket sock;
- RoomObject ro;
-
- public ChatThread(Socket sock, RoomObject ro) {
- this.sock=sock;
- this.ro=ro;
- }
-
- public void run() {
- sock.write("Please choose a chatroom".getBytes());
- ReadRequest();
- ProcessRoom();
- while(true)
- Message();
- }
-
- public void ReadRequest() {
- while (!processRead())
- ;
- }
-
- private void ProcessRoom() {
- processRoom(ro);
- }
-
- public void Message() {
- byte buffer[]=new byte[1024];
- int length=sock.read(buffer);
- if (length>0) {
- String st=(new String(buffer)).subString(0, length);
- room.sendToRoom(this, st.getBytes());
- }
- }
-
- public boolean processRead() {
- byte buffer[]=new byte[1024];
- int length=sock.read(buffer);
- String st=new String(buffer);
- String curr=st.subString(0, length);
- if (roomrequest!=null) {
- StringBuffer sb=new StringBuffer(roomrequest);
- sb.append(curr);
- curr=sb.toString();
- }
- roomrequest=curr;
- if (roomrequest.indexOf("\n")>=0) {
- return true;
- }
- return false;
- }
- public void processRoom(RoomObject ro) {
- ro.getChatRoom(roomrequest).addParticipant(this);
- }
-}
+++ /dev/null
-public class Room {
- String name;
- HashSet participants;
- public Room(String n) {
- name=n;
- participants=new HashSet();
- }
-
- synchronized void addParticipant(ChatThread cs) {
- participants.add(cs);
- cs.room=this;
- }
-
- synchronized void sendToRoom(ChatThread caller, byte [] message) {
- HashMapIterator hmi=participants.iterator();
- while(hmi.hasNext()) {
- ChatThread cs=(ChatThread) hmi.next();
- if (cs!=caller)
- cs.sock.write(message);
- }
- }
-}
+++ /dev/null
-public class RoomObject {
- HashMap rooms;
- public RoomObject() {
- rooms=new HashMap();
- }
-
- synchronized Room getChatRoom(String name) {
- if (rooms.containsKey(name))
- return (Room) rooms.get(name);
- Room r=new Room(name);
- rooms.put(name, r);
- return r;
- }
-}
+++ /dev/null
-task Startup(StartupObject s{initialstate}) {
- System.printString("Chat Server Benchmark");
- RoomObject ro=new RoomObject() {Initialized};
- ServerSocket ss=new ServerSocket(8000);
- taskexit(s{!initialstate});
-}
-
-task AcceptConnection(ServerSocket ss{SocketPending}) {
- tag t=new tag(link);
- ChatSocket cs=new ChatSocket() {Initialized}{t};
- cs.sock=ss.accept(t);
- cs.sock.write("Please choose a chatroom".getBytes());
-}
-
-task ReadRequest(ChatSocket cs{Initialized}{link l}, Socket s{IOPending}{link l}) {
- if (cs.processRead(s)) {
- taskexit(cs{!Initialized, ProcessRoom});
- }
-}
-
-task ProcessRoom(ChatSocket cs{ProcessRoom}, RoomObject ro{Initialized}) {
- cs.processRoom(ro);
- taskexit(cs{!ProcessRoom, InRoom});
-}
-
-task Message(ChatSocket cs{InRoom}{link l}, Socket s{IOPending}{link l}) {
- byte buffer[]=new byte[1024];
- int length=s.read(buffer);
- Message m=new Message(buffer, length, cs){};
-}
-
-task SendMessage(Message m{!Sent}) {
- String st=(new String(m.buffer)).subString(0, m.length);
- m.cs.room.sendToRoom(m.cs,st.getBytes());
- taskexit(m {Sent});
-}
+++ /dev/null
-public class ChatSocket {
- flag Initialized;
- flag ProcessRoom;
- flag InRoom;
- Room room;
- String roomrequest;
- Socket sock;
-
- public ChatSocket() {
- }
-
- public boolean processRead(Socket s) {
- byte buffer[]=new byte[1024];
- int length=s.read(buffer);
- String st=new String(buffer);
- String curr=st.subString(0, length);
- if (roomrequest!=null) {
- StringBuffer sb=new StringBuffer(roomrequest);
- sb.append(curr);
- curr=sb.toString();
- }
- roomrequest=curr;
- if (roomrequest.indexOf("\n")>=0) {
- return true;
- }
- return false;
- }
- public void processRoom(RoomObject ro) {
- ro.getChatRoom(roomrequest).addParticipant(this);
- }
-}
+++ /dev/null
-public class Message {
- flag Sent;
- ChatSocket cs;
- byte buffer[];
- int length;
-
- public Message(byte[] b, int l, ChatSocket cs) {
- this.cs=cs;
- this.buffer=b;
- this.length=l;
- }
-}
+++ /dev/null
-public class Room {
- String name;
- HashSet participants;
- public Room(String n) {
- name=n;
- participants=new HashSet();
- }
-
- void addParticipant(ChatSocket cs) {
- participants.add(cs);
- cs.room=this;
- }
-
- void sendToRoom(ChatSocket caller, byte [] message) {
- HashMapIterator hmi=participants.iterator();
- while(hmi.hasNext()) {
- ChatSocket cs=(ChatSocket) hmi.next();
- if (cs!=caller)
- cs.sock.write(message);
- }
- }
-}
+++ /dev/null
-public class RoomObject {
- flag Initialized;
- HashMap rooms;
- public RoomObject() {
- rooms=new HashMap();
- }
-
- Room getChatRoom(String name) {
- if (rooms.containsKey(name))
- return (Room) rooms.get(name);
- Room r=new Room(name);
- rooms.put(name, r);
- return r;
- }
-}
+++ /dev/null
-public class Query extends Socket {
- flag requested;
- flag processed;
- flag received;
- public int state;
-
- private String hostname;
- private String path;
-
- private StringBuffer response;
-
- public Query(String hostname, String path) {
- this.hostname=hostname;
- this.path=path;
- response=new StringBuffer();
- state=0;
- }
-
- public void makeConnection() {
- InetAddress address=InetAddress.getByName(hostname);
- int port=80;
- fd=nativeBind(address.getAddress(), port);
- nativeConnect(fd, address.getAddress(), port);
- }
-
- public String getHostName() {
- return hostname;
- }
-
- public String getPath() {
- return path;
- }
-
- public void outputFile() {
- StringBuffer sb=new StringBuffer(hostname);
- sb.append(path);
- FileOutputStream fos=new FileOutputStream(sb.toString().replace('/','#'));
- fos.write(response.toString().getBytes());
- fos.close();
- }
-
- public String makewebcanonical(String page) {
- StringBuffer b=new StringBuffer(getHostName(page));
- b.append("/");
- b.append(getPathName(page));
- return b.toString();
- }
-
- public String getHostName(String page) {
- String http=new String("http://");
- if (page.indexOf(http)==-1) {
- return getHostName();
- } else {
- int beginindex=page.indexOf(http)+http.length();
- int endindex=page.indexOf('/',beginindex+1);
- if ((beginindex==-1)) {
- System.printString("ERROR");
- }
- if (endindex==-1)
- endindex=page.length();
- return page.subString(beginindex, endindex);
- }
- }
-
- public String getPathName(String page) {
- String http=new String("http://");
- if (page.indexOf(http)==-1) {
- String path=getPath();
- int lastindex=path.lastindexOf('/');
- if (lastindex==-1)
- return page;
-
- StringBuffer sb=new StringBuffer(path.subString(0,lastindex+1));
- sb.append(page);
- return sb.toString();
- } else {
- int beginindex=page.indexOf(http)+http.length();
- int nextindex=page.indexOf('/',beginindex+1);
- if ((beginindex==-1)||(nextindex==-1))
- return new String("index.html");
- return page.subString(nextindex+1, page.length()-1);
- }
- }
-}
+++ /dev/null
-public class QueryList {
- flag initialized;
- HashSet queries;
-
- public QueryList() {
- queries=new HashSet();
- }
- public boolean checkQuery(String x) {
- return queries.contains(x);
- }
- public void addQuery(String x) {
- queries.add(x);
- }
-}
+++ /dev/null
-task Startup(StartupObject s {initialstate}) {
- String firstmachine=s.parameters[0];
- String firstpage=s.parameters[1];
- QueryList ql=new QueryList() {initialized};
- Query firstquery=new Query(firstmachine, firstpage){};
- taskexit(s{!initialstate});
-}
-
-task requestQuery(Query q{!requested}) {
- String hostname=q.getHostName();
- q.makeConnection();
- StringBuffer req=new StringBuffer("GET ");
- req.append("/");
- req.append(q.getPath());
- req.append(" HTTP/1.1\r\nHost:");
- req.append(q.getHostName());
- req.append("\r\n\r\n");
- q.write(req.toString().getBytes());
- taskexit(q{requested});
-}
-
-task readResponse(Query q{requested && ! received && IOPending}) {
- // state 0 - nothing
- // state 1 - \r
- // state 2 - \r\n
- // state 3 - \r\n\r
- // state 4 - \r\n\r\n
- if (q.state<4) {
- if (q.state==0) {
- byte[] b=new byte[1];
- int numchars=q.read(b);
- if ((numchars==1) && (b[0]=='\r'))
- q.state++;
- } else if (q.state==1) {
- byte[] b=new byte[1];
- int numchars=q.read(b);
- if (numchars==1) {
- if (b[0]=='\n')
- q.state++;
- else
- q.state=0;
- }
- } else if (q.state==2) {
- byte[] b=new byte[1];
- int numchars=q.read(b);
- if (numchars==1) {
- if (b[0]=='\r')
- q.state++;
- else
- q.state=0;
- }
- } else if (q.state==3) {
- byte[] b=new byte[1];
- int numchars=q.read(b);
- if (numchars==1) {
- if (b[0]=='\n')
- q.state++;
- else
- q.state=0;
- }
- }
- } else {
- byte[] buffer=new byte[1024];
- int numchars=q.read(buffer);
- if (numchars==0) {
- q.close();
- taskexit(q{received});
- } else {
- String curr=(new String(buffer)).subString(0,numchars);
- q.response.append(curr);
- }
- }
-}
-
-task processPage(Query q{received&&!processed}, QueryList ql{initialized}) {
- int index=0;
- String href=new String("href=\"");
- String searchstr=q.response.toString();
- boolean cont=true;
- q.outputFile();
-
- while(cont) {
- int mindex=searchstr.indexOf(href,index);
- if (mindex!=-1) {
-
- int endquote=searchstr.indexOf('"', mindex+href.length());
- if (endquote!=-1) {
- String match=searchstr.subString(mindex+href.length(), endquote);
- String match2=q.makewebcanonical(match);
- if (match2!=null&&!ql.checkQuery(match2)) {
- ql.addQuery(match2);
- System.printString(q.getHostName(match));
- System.printString(" ");
- System.printString(q.getPathName(match));
- System.printString("\n");
- Query newq=new Query(q.getHostName(match), q.getPathName(match)){};
- }
- index=endquote;
- } else cont=false;
- } else cont=false;
- }
- taskexit(q{processed});
-}
+++ /dev/null
-public class Query {
- flag requested;
- flag processed;
- flag received;
- public int state;
-
- private String hostname;
- private String path;
-
- private StringBuffer response;
-
- public Query(String hostname, String path) {
- this.hostname=hostname;
- this.path=path;
- response=new StringBuffer();
- state=0;
- }
-
- public void makeConnection(Socket s) {
- InetAddress address=InetAddress.getByName(hostname);
- int port=80;
- s.fd=Socket.nativeBind(address.getAddress(), port);
- s.nativeConnect(s.fd, address.getAddress(), port);
- }
-
- public String getHostName() {
- return hostname;
- }
-
- public String getPath() {
- return path;
- }
-
- public void outputFile() {
- StringBuffer sb=new StringBuffer(hostname);
- sb.append(path);
- FileOutputStream fos=new FileOutputStream(sb.toString().replace('/','#'));
- fos.write(response.toString().getBytes());
- fos.close();
- }
-
- public String makewebcanonical(String page) {
- StringBuffer b=new StringBuffer(getHostName(page));
- b.append("/");
- b.append(getPathName(page));
- return b.toString();
- }
-
- public String getHostName(String page) {
- String http=new String("http://");
- if (page.indexOf(http)==-1) {
- return getHostName();
- } else {
- int beginindex=page.indexOf(http)+http.length();
- int endindex=page.indexOf('/',beginindex+1);
- if ((beginindex==-1)) {
- System.printString("ERROR");
- }
- if (endindex==-1)
- endindex=page.length();
- return page.subString(beginindex, endindex);
- }
- }
-
- public String getPathName(String page) {
- String http=new String("http://");
- if (page.indexOf(http)==-1) {
- String path=getPath();
- int lastindex=path.lastindexOf('/');
- if (lastindex==-1)
- return page;
-
- StringBuffer sb=new StringBuffer(path.subString(0,lastindex+1));
- sb.append(page);
- return sb.toString();
- } else {
- int beginindex=page.indexOf(http)+http.length();
- int nextindex=page.indexOf('/',beginindex+1);
- if ((beginindex==-1)||(nextindex==-1))
- return new String("index.html");
- return page.subString(nextindex+1, page.length()-1);
- }
- }
-}
+++ /dev/null
-public class QueryList {
- flag initialized;
- HashSet queries;
-
- public QueryList() {
- queries=new HashSet();
- }
- public boolean checkQuery(String x) {
- return queries.contains(x);
- }
- public void addQuery(String x) {
- queries.add(x);
- }
-}
+++ /dev/null
-task Startup(StartupObject s {initialstate}) {
- String firstmachine=s.parameters[0];
- String firstpage=s.parameters[1];
- QueryList ql=new QueryList() {initialized};
- tag t=new tag(connect);
- Socket sock=new Socket(){}{t};
- Query firstquery=new Query(firstmachine, firstpage){}{t};
- taskexit(s{!initialstate});
-}
-
-task requestQuery(Query q{!requested}{connect t}, Socket s{}{connect t}) {
- String hostname=q.getHostName();
- q.makeConnection(s);
- StringBuffer req=new StringBuffer("GET ");
- req.append("/");
- req.append(q.getPath());
- req.append(" HTTP/1.1\r\nHost:");
- req.append(q.getHostName());
- req.append("\r\n\r\n");
- s.write(req.toString().getBytes());
- taskexit(q{requested});
-}
-
-task readResponse(Query q{requested && ! received}{connect t},Socket s{IOPending}{connect t}) {
- // state 0 - nothing
- // state 1 - \r
- // state 2 - \r\n
- // state 3 - \r\n\r
- // state 4 - \r\n\r\n
- if (q.state<4) {
- if (q.state==0) {
- byte[] b=new byte[1];
- int numchars=s.read(b);
- if ((numchars==1) && (b[0]=='\r'))
- q.state++;
- } else if (q.state==1) {
- byte[] b=new byte[1];
- int numchars=s.read(b);
- if (numchars==1) {
- if (b[0]=='\n')
- q.state++;
- else
- q.state=0;
- }
- } else if (q.state==2) {
- byte[] b=new byte[1];
- int numchars=s.read(b);
- if (numchars==1) {
- if (b[0]=='\r')
- q.state++;
- else
- q.state=0;
- }
- } else if (q.state==3) {
- byte[] b=new byte[1];
- int numchars=s.read(b);
- if (numchars==1) {
- if (b[0]=='\n')
- q.state++;
- else
- q.state=0;
- }
- }
- } else {
- byte[] buffer=new byte[1024];
- int numchars=s.read(buffer);
- if (numchars==0) {
- s.close();
- taskexit(q{received});
- } else {
- String curr=(new String(buffer)).subString(0,numchars);
- q.response.append(curr);
- }
- }
-}
-
-task processPage(Query q{received&&!processed}, QueryList ql{initialized}) {
- int index=0;
- String href=new String("href=\"");
- String searchstr=q.response.toString();
- boolean cont=true;
- q.outputFile();
-
- while(cont) {
- int mindex=searchstr.indexOf(href,index);
- if (mindex!=-1) {
-
- int endquote=searchstr.indexOf('"', mindex+href.length());
- if (endquote!=-1) {
- String match=searchstr.subString(mindex+href.length(), endquote);
- String match2=q.makewebcanonical(match);
- if (match2!=null&&!ql.checkQuery(match2)) {
- ql.addQuery(match2);
- System.printString(q.getHostName(match));
- System.printString(" ");
- System.printString(q.getPathName(match));
- System.printString("\n");
- tag t=new tag(connect);
- Socket s=new Socket(){}{t};
- Query newq=new Query(q.getHostName(match), q.getPathName(match)){}{t};
- }
- index=endquote;
- } else cont=false;
- } else cont=false;
- }
- taskexit(q{processed});
-}
+++ /dev/null
-public class Query {
- private String hostname;
- private String path;
-
- private StringBuffer response;
-
- public Query(String hostname, String path) {
- this.hostname=hostname;
- this.path=path;
- response=new StringBuffer();
- }
-
- public String getHostName() {
- return hostname;
- }
-
- public String getPath() {
- return path;
- }
-
- public void outputFile() {
- StringBuffer sb=new StringBuffer(hostname);
- sb.append(path);
- FileOutputStream fos=new FileOutputStream(sb.toString().replace('/','#'));
- fos.write(response.toString().getBytes());
- fos.close();
- }
-
- public String makewebcanonical(String page) {
- StringBuffer b=new StringBuffer(getHostName(page));
- b.append("/");
- b.append(getPathName(page));
- return b.toString();
- }
-
- public String getHostName(String page) {
- String http=new String("http://");
- if (page.indexOf(http)==-1) {
- return getHostName();
- } else {
- int beginindex=page.indexOf(http)+http.length();
- int endindex=page.indexOf('/',beginindex+1);
- if ((beginindex==-1)) {
- System.printString("ERROR");
- }
- if (endindex==-1)
- endindex=page.length();
- return page.subString(beginindex, endindex);
- }
- }
-
- public String getPathName(String page) {
- String http=new String("http://");
- if (page.indexOf(http)==-1) {
- String path=getPath();
- int lastindex=path.lastindexOf('/');
- if (lastindex==-1)
- return page;
-
- StringBuffer sb=new StringBuffer(path.subString(0,lastindex+1));
- sb.append(page);
- return sb.toString();
- } else {
- int beginindex=page.indexOf(http)+http.length();
- int nextindex=page.indexOf('/',beginindex+1);
- if ((beginindex==-1)||(nextindex==-1))
- return new String("index.html");
- return page.subString(nextindex+1, page.length());
- }
- }
-}
+++ /dev/null
-public class QueryList {
- HashSet queries;
-
- public QueryList() {
- queries=new HashSet();
- }
- public boolean checkQuery(String x) {
- return queries.contains(x);
- }
- public void addQuery(String x) {
- queries.add(x);
- }
-}
+++ /dev/null
-public class QueryQueue {
- HashSet queries;
-
- public QueryQueue() {
- queries=new HashSet();
- }
- public synchronized Query getQuery() {
- if (queries.isEmpty())
- return null;
- Query q=(Query) queries.iterator().next();
- queries.remove(q);
- return q;
- }
- public synchronized void addQuery(Query x) {
- queries.add(x);
- }
-}
+++ /dev/null
-public class QueryThread extends Thread {
- QueryQueue toprocess;
- QueryList ql;
- public QueryThread(QueryQueue qq, QueryList ql) {
- toprocess=qq;
- this.ql=ql;
- }
-
- public void run() {
- while(true) {
- Query q=null;
- while(q==null) {
- q=toprocess.getQuery();
- if (q==null)
- Thread.sleep(2);
- }
- String hostname=q.getHostName();
- System.printString("Processing ");
- System.printString(hostname);
- System.printString(" ");
- System.printString(q.getPath());
- System.printString("\n");
- Socket s=new Socket(hostname, 80);
- requestQuery(q, s);
- readResponse(q, s);
- q.outputFile();
- processPage(q, ql);
- s.close();
- }
- }
-
- void requestQuery(Query q, Socket sock) {
- StringBuffer req=new StringBuffer("GET ");
- req.append("/");
- req.append(q.getPath());
- req.append(" HTTP/1.1\r\nHost:");
- req.append(q.getHostName());
- req.append("\r\n\r\n");
- sock.write(req.toString().getBytes());
- }
-
- void readResponse(Query q, Socket sock) {
- // state 0 - nothing
- // state 1 - \r
- // state 2 - \r\n
- // state 3 - \r\n\r
- // state 4 - \r\n\r\n
- int state=0;
- while(true) {
- if (state<4) {
- if (state==0) {
- byte[] b=new byte[1];
- int numchars=sock.read(b);
- if ((numchars==1)) {
- if (b[0]=='\r') {
- state++;
- }
- } else
- return;
- } else if (state==1) {
- byte[] b=new byte[1];
- int numchars=sock.read(b);
- if (numchars==1) {
- if (b[0]=='\n')
- state++;
- else
- state=0;
- } else return;
- } else if (state==2) {
- byte[] b=new byte[1];
- int numchars=sock.read(b);
- if (numchars==1) {
- if (b[0]=='\r')
- state++;
- else
- state=0;
- } else return;
- } else if (state==3) {
- byte[] b=new byte[1];
- int numchars=sock.read(b);
- if (numchars==1) {
- if (b[0]=='\n')
- state++;
- else
- state=0;
- } else return;
- }
- } else {
- byte[] buffer=new byte[1024];
- int numchars=sock.read(buffer);
- if (numchars==0)
- return;
- else {
- String curr=(new String(buffer)).subString(0,numchars);
- q.response.append(curr);
- }
- }
- }
- }
-
- void processPage(Query q, QueryList ql) {
- int index=0;
- String href=new String("href=\"");
- String searchstr=q.response.toString();
- boolean cont=true;
- while(cont) {
- int mindex=searchstr.indexOf(href,index);
- if (mindex!=-1) {
-
- int endquote=searchstr.indexOf('"', mindex+href.length());
- if (endquote!=-1) {
- String match=searchstr.subString(mindex+href.length(), endquote);
- String match2=q.makewebcanonical(match);
- if (match2!=null&&!ql.checkQuery(match2)) {
- ql.addQuery(match2);
- System.printString(q.getHostName(match));
- System.printString(" ");
- System.printString(q.getPathName(match));
- System.printString("\n");
- Query newq=new Query(q.getHostName(match), q.getPathName(match));
- toprocess.addQuery(newq);
- }
- index=endquote;
- } else cont=false;
- } else cont=false;
- }
- }
-
-}
+++ /dev/null
-public class Spider {
-
-
-
- public static void main(String[] parameters) {
- String firstmachine=parameters[0];
- String firstpage=parameters[1];
- QueryList ql=new QueryList();
- QueryQueue toprocess=new QueryQueue();
- Query firstquery=new Query(firstmachine, firstpage);
- toprocess.addQuery(firstquery);
- QueryThread qt1=new QueryThread(toprocess, ql);
- qt1.start();
- QueryThread qt2=new QueryThread(toprocess, ql);
- qt2.start();
- QueryThread qt3=new QueryThread(toprocess, ql);
- qt3.start();
- while(true)
- Thread.sleep(1000000);
- }
-
-
-}
+++ /dev/null
-#!/bin/bash
-mkdir $1
-cd $1
-../$2 127.0.0.1 test/0.html &> log &
-fcount=`ls -al 127*`
-let "count=0"
-while true
-do
-sleep 60
-fnewcount=`ls -al 127*`
-if [ "$fnewcount" != "$fcount" ]
- then
- let "count=0"
- fcount="$fnewcount"
-fi
-let "count+=1"
-if [ $count = "3" ]
-then
-break
-fi
-done
-killall -SIGUSR2 $2
-sleep 1
-killall -9 $2
-cd ..
\ No newline at end of file
+++ /dev/null
-import java.io.*;
-
-public class generate {
- public static void main(String x[]) {
- int MAX=100;
- int current=0;
- int currentref=1;
- while(current<MAX) {
- try {
- String filename=current+".html";
- FileOutputStream fos=new FileOutputStream(filename);
- PrintStream ps=new PrintStream(fos);
- int count=0;
- while(true) {
- if ((count++)>2)
- break;
- int cc=currentref%MAX;
- String reffile=cc+".html";
- ps.println("<a href=\""+reffile+"\">"+reffile+"</a>");
- currentref++;
- }
- current++;
- fos.close();
- } catch (Exception e) {e.printStackTrace();}
- }
- }
-
-
-}
+++ /dev/null
-#!/bin/bash
-let i=62
-while [ $i -le 100 ]
-do
-./dotest THREAD$i threadspider.bin
-./dotest TASK$i taskspider.bin
-let "i+=1"
-done
\ No newline at end of file
+++ /dev/null
-public class Board {
- // TicTacToe Board flags
- flag init;
-
- int[][] board;
-
- int winningplayer;
-
- public Board() {
- winningplayer = -1;
- board = new int[3][3];
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- board[i][j] = 0;
- }
-
- public int makeMove(int row, int col) {
- if (boardFull() == 1) {
- winningplayer = 0;
- return 2;
- }
- if (board[row][col] != 0) { // Space taken
- return -1;
- }
- else {
- board[row][col] = 1;
- if (checkForWin(1) == 1) { // Check if player won
- winningplayer = 1;
- return 2;
- }
- // Computer makes move
- if (computerMakeMove() == 1) { // If made move successful
- if (checkForWin(2) == 1) { // Check if computer won
- winningplayer = 2;
- return 2;
- }
- }
- else { // Board full, no winner
- winningplayer = 0;
- return 2;
- }
- }
- return 1;
- }
-
- public int boardFull() {
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- if (board[i][j] == 0)
- return 0;
- return 1;
- }
-
- public int computerMakeMove() {
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- if (board[i][j] == 0) {
- board[i][j] = 2;
- return 1;
- }
- return 0;
- }
-
- public int checkForWin(int p) {
- // Add logic for checking if player p wins
- // Horiz
-
- if ((board[0][0] == p) && (board[0][1] == p) && (board[0][2] == p) ||
- (board[1][0] == p) && (board[1][1] == p) && (board[1][2] == p) ||
- (board[2][0] == p) && (board[2][1] == p) && (board[2][2] == p)) {
- return 1;
- }
-
- // Vert
- if ((board[0][0] == p) && (board[1][0] == p) && (board[2][0] == p) ||
- (board[0][1] == p) && (board[1][1] == p) && (board[2][1] == p) ||
- (board[0][2] == p) && (board[1][2] == p) && (board[2][2] == p)) {
- return 1;
- }
-
- //Diag
- if ((board[0][0] == p) && (board[1][1] == p) && (board[2][2] == p) ||
- (board[0][2] == p) && (board[1][1] == p) && (board[2][0] == p)) {
- return 1;
- }
-
- return 0;
- }
-
- public int winner() {
- return winningplayer;
- }
-}
+++ /dev/null
-/* Startup object is generated with the initialstate flag set by the
- * system to start the computation up */
-
-// Create ServerSocket
-task Startup(StartupObject s {initialstate}) {
- System.printString("TTT Server Starting...\n");
- ServerSocket ss = new ServerSocket(8000);
- System.printString("Creating ServerSocket\n");
- Board tttBoard = new Board() {init};
- taskexit(s {!initialstate}); // Turn off initial state flag
-}
-
-//Listen for a request and accept request
-task AcceptConnection(ServerSocket ss{SocketPending}) {
- System.printString("Waiting for connection...\n");
- TTTServerSocket ttts = new TTTServerSocket() {TTTSInitialize};
- System.printString("Calling accept...\n");
- ss.accept(ttts);
- System.printString("Connected...\n");
-}
-
-// Process incoming requests
-task ProcessRequest(TTTServerSocket ttts{IOPending && TTTSInitialize}) {
- System.printString("Request received...");
- int action = ttts.receive();
- if (action == 1) { // Make move
- taskexit(ttts {MakeMove});
- }
- else { // Send Error
- taskexit(ttts {SendError});
- }
-}
-
-task ProcessMove(TTTServerSocket ttts{MakeMove}, Board tttBoard{init}) {
- System.printString("Processing player's move...");
- int result = tttBoard.makeMove(ttts.getRow(), ttts.getCol());
- if (result == 1) { //Move made, send board display
- taskexit(ttts {!MakeMove, SendBoard});
- }
- else if (result == 2) { //Move made, game over
- taskexit(ttts {!MakeMove, SendDone});
- }
- else {// Error
- taskexit(ttts {!MakeMove, SendError});
- }
-}
-
-task SendBoardDisplay(TTTServerSocket ttts{SendBoard}, Board tttBoard{init}) {
- ttts.sendBoardDisplay(tttBoard);
-}
-
-task GameOver(TTTServerSocket ttts{SendDone}, Board tttBoard{init}) {
- ttts.sendDone(tttBoard.winner());
-}
-
-task SendErrorMessage(TTTServerSocket ttts{SendError}, Board tttBoard{init}) {
- ttts.sendError();
-}
+++ /dev/null
-public class TTTServerSocket extends Socket {
- // TTTServerSocket flags
- flag TTTSInitialize;
-
- flag MakeMove;
- flag SendError;
- flag SendBoard;
- flag SendDone;
-
- String request;
- int row, col;
-
- //Constructor
- public TTTServerSocket(){
- System.printString("Constructing TTTServerSocket....\n");
- }
-
- public int receive()
- {
- byte b1[] = new byte[1024];
- read(b1);
- request = new String(b1);
- System.printString("request: ");
- System.printString(request);
- if (parseTransaction() == 1) {
- return 1;
- }
- return 0;
- }
-
- // Parse request
- public int parseTransaction(){
- int start = request.indexOf('_');
- String s = request.subString(start+1);
-//_move:3:3
- if (s.startsWith("move")==true){
- //Get row
- int i1 = s.indexOf(':');
- String rowStr = new String(s.subString(i1+1, i1+2));
- row = Integer.parseInt(rowStr);
-
- //Get col
- String s2 = new String(s.subString(i1+2));
- int i2 = s2.indexOf(':');
- String colStr = new String(s.subString(i2+1, i2+2));
- col = Integer.parseInt(colStr);
- return 1;
-
- }
- // Error transaction
- return -1;
- }
-
- public int getRow(){
- return row;
- }
- public int getCol(){
- return col;
- }
-
- public void sendBoardDisplay(Board theBoard) {
- StringBuffer line1 = new String ("display_");
-
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- if (theBoard.board[i][j] == 1)
- line1.append("X");
- else if (theBoard.board[i][j] == 2)
- line1.append("O");
- else
- line1.append("-");
- }
- line1.append("_");
- }
- String towrite = new String(line1);
- write(towrite.getBytes());
- return;
- }
-
- public void sendDone(int winner) {
- StringBuffer line1 = new String ("done_");
- if (winner == 0)
- line1.append("tie");
- else if (winner == 1)
- line1.append("player");
- else
- line1.append("computer");
-
- String towrite = new String(line1);
- write(towrite.getBytes());
- return;
- }
-
- public void sendError() {
- StringBuffer line1 = new String ("error_wrongmove");
-
- String towrite = new String(line1);
- write(towrite.getBytes());
- return;
- }
-}
+++ /dev/null
-import java.net.*;\r
-import java.io.*;\r
-\r
-public class TTTServer\r
-{\r
- //the tictactoe game board\r
- //2d 3x3 char array\r
- private static char[][] board;\r
- //keeps track of how many turns have past\r
- private static int numOfTurns;\r
- //ints used to store the location of the cell the user will input\r
- private static int row;\r
- private static int col;\r
- private static boolean notDone;\r
- \r
- private static void resetGame()\r
- {\r
- numOfTurns = 0;\r
- row = 0;\r
- col = 0;\r
- \r
- for(int i = 0; i < 3; i++)\r
- {\r
- for(int j = 0; j < 3; j++)\r
- {\r
- board[i][j] = ' ';\r
- }\r
- }\r
- }\r
- \r
- private static void displayBoard()\r
- {\r
- System.out.println("--------------------");\r
- System.out.println("[R,C][ 1 ][ 2 ][ 3 ]");\r
- System.out.println("--------------------");\r
- System.out.println("[ 1 ]| " + board[0][0] + " | " + board[0][1] +\r
- " | " + board[0][2] + " | ");\r
- System.out.println("--------------------");\r
- System.out.println("[ 2 ]| " + board[1][0] + " | " + board[1][1] +\r
- " | " + board[1][2] + " | ");\r
- System.out.println("--------------------");\r
- System.out.println("[ 3 ]| " + board[2][0] + " | " + board[2][1] +\r
- " | " + board[2][2] + " | ");\r
- System.out.println("--------------------"); \r
- }\r
- \r
- //put the move on the board and update numOfTurns\r
- private static void markMove(char xo)\r
- {\r
- board[row - 1][col - 1] = xo;\r
- numOfTurns++;\r
- }\r
- \r
- //check for a winner or a tie\r
- //true == winner or tie\r
- private static boolean checkWinner(char xo)\r
- {\r
- //horizontal win\r
- if(board[0][0] == xo && board[0][0] == board[0][1] &&\r
- board[0][1] == board[0][2])\r
- {\r
- System.out.println(xo + " is the winner!");\r
- return true;\r
- }\r
- //horizontal win\r
- else if(board[1][0] == xo && board[1][0] == board[1][1] &&\r
- board[1][1] == board[1][2])\r
- {\r
- System.out.println(xo + " is the winner!");\r
- return true;\r
- }\r
- //horizontal win\r
- else if(board[2][0] == xo && board[2][0] == board[2][1] &&\r
- board[2][1] == board[2][2])\r
- {\r
- System.out.println(xo + " is the winner!");\r
- return true;\r
- } \r
- //vertial win\r
- else if(board[0][0] == xo && board[0][0] == board[1][0] &&\r
- board[1][0] == board[2][0])\r
- {\r
- System.out.println(xo + " is the winner!");\r
- return true;\r
- }\r
- //vertial win\r
- else if(board[0][1] == xo && board[0][1] == board[1][1] &&\r
- board[1][1] == board[2][1])\r
- {\r
- System.out.println(xo + " is the winner!");\r
- return true;\r
- }\r
- //vertial win\r
- else if(board[0][2] == xo && board[0][2] == board[1][2] &&\r
- board[1][2] == board[2][2])\r
- {\r
- System.out.println(xo + " is the winner!");\r
- return true;\r
- }\r
- //diagonal win\r
- else if(board[0][0] == xo && board[0][0] == board[1][1] &&\r
- board[1][1] == board[2][2])\r
- {\r
- System.out.println(xo + " is the winner!");\r
- return true;\r
- }\r
- //diagonal win\r
- else if(board[0][2] == xo && board[0][2] == board[1][1] &&\r
- board[1][1] == board[2][0])\r
- {\r
- System.out.println(xo + " is the winner!");\r
- return true;\r
- }\r
- //tie game\r
- //board is full\r
- else if(numOfTurns == 9)\r
- {\r
- System.out.println("Tie Game!");\r
- return true; \r
- }\r
- //no winner yet\r
- else\r
- return false;\r
- }\r
- \r
- //the logic that happens for each turn for X or O\r
- public static void turnLogic(char xo, int r, int c)\r
- {\r
- if(xo == 'X')\r
- {\r
- System.out.println("\n" + xo + "'s turn.");\r
- System.out.println("Please enter your move as two separate integers: ");\r
- //-1 -1 to quit\r
- row = readInt();\r
- col = readInt();\r
- System.out.println("\nYou entered (" + row + "," + col + ")\n");\r
- }\r
- else if(xo == 'O')\r
- {\r
- System.out.println("\n" + xo + "'s turn.");\r
- row = r;\r
- col = c;\r
- }\r
- \r
- markMove(xo);\r
- displayBoard();\r
-\r
- //check for a winner and quit cond.\r
- if(checkWinner(xo) || (row == -1 && col == -1))\r
- notDone = false;\r
- }\r
- \r
- public static void main(String[] args)\r
- { \r
- //the sockets to be used\r
- ServerSocket mySocket = null;\r
- Socket myConnection= null;\r
- //string that will hold the message to be received and sent\r
- String myString = null;\r
- //input buffer\r
- BufferedReader myInput = null;\r
- //output buffer\r
- PrintStream myOutput = null;\r
- //loop variable\r
- notDone = true;\r
- \r
- board = new char[3][3];\r
- resetGame();\r
- \r
- //start server\r
- try\r
- {\r
- //create new socket\r
- mySocket = new ServerSocket(8080);\r
- System.out.println("Server Port: " + mySocket.getLocalPort());\r
- \r
- displayBoard();\r
- \r
- //accept incoming tcp connection\r
- myConnection = mySocket.accept();\r
- \r
- //create and read the message from the client to the input buffer\r
- myInput = new BufferedReader(new InputStreamReader(myConnection.getInputStream()));\r
- \r
- //create and print the message to the output buffer\r
- myOutput = new PrintStream(myConnection.getOutputStream());\r
- \r
- //loop for nine times at most\r
- while(numOfTurns != 9 && notDone == true)\r
- {\r
- switch(numOfTurns % 2)\r
- {\r
- //even case\r
- case 0: \r
- turnLogic('X', 0, 0);\r
- myOutput.println(row + " " + col); \r
- break;\r
- \r
- //odd case\r
- case 1:\r
- myString = myInput.readLine(); \r
- \r
- //was "quit" received?\r
- if(myString.equals("quit"))\r
- {\r
- notDone = false;\r
- }\r
- else\r
- {\r
- int r = Integer.parseInt(myString.substring(0, 1));\r
- int c = Integer.parseInt(myString.substring(2, 3));\r
- turnLogic('O', r, c);\r
- }\r
- break;\r
- \r
- //should not happen\r
- default:\r
- System.out.println("Program Error!");\r
- break;\r
- }\r
- }\r
- \r
- //close buffers\r
- myInput.close();\r
- myOutput.close();\r
- \r
- //close socket\r
- myConnection.close();\r
- }\r
- catch(IOException e)\r
- {\r
- System.err.println(e);\r
- System.exit(1);\r
- }\r
- }\r
- \r
- //some good stuff to read user ints, maybe too much?\r
- public static int readInt() throws NumberFormatException\r
- {\r
- String inputString = null;\r
- inputString = readWord();\r
- \r
- return Integer.parseInt(inputString);\r
- }\r
-\r
- //read a lot \r
- public static String readWord()\r
- {\r
- String result = "";\r
- char next;\r
-\r
- next = readChar();\r
- while (Character.isWhitespace(next))\r
- next = readChar();\r
-\r
- while(!(Character.isWhitespace(next)))\r
- {\r
- result = result + next;\r
- next = readChar();\r
- }\r
-\r
- if (next == '\r')\r
- {\r
- next = readChar();\r
- \r
- if (next != '\n')\r
- {\r
- System.err.println("Error.");\r
- System.exit(1);\r
- }\r
- }\r
-\r
- return result;\r
- }\r
-\r
- //read one\r
- public static char readChar()\r
- {\r
- int charAsInt = -1; \r
- \r
- try\r
- {\r
- charAsInt = System.in.read();\r
- }\r
- catch(IOException e)\r
- {\r
- System.err.println(e);\r
- System.exit(1);\r
- }\r
-\r
- return (char)charAsInt;\r
- }\r
-}\r
+++ /dev/null
-public class Board {
- // TicTacToe Board flags
- flag init;
-
- int[][] board;
-
- int winningplayer;
-
- public Board() {
- winningplayer = -1;
- board = new int[3][3];
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- board[i][j] = 0;
- }
-
- public int makeMove(int row, int col) {
- if (boardFull() == 1) {
- winningplayer = 0;
- return 2;
- }
- if (board[row][col] != 0) { // Space taken
- return -1;
- }
- else {
- board[row][col] = 1;
- if (checkForWin(1) == 1) { // Check if player won
- winningplayer = 1;
- return 2;
- }
- // Computer makes move
- if (computerMakeMove() == 1) { // If made move successful
- if (checkForWin(2) == 1) { // Check if computer won
- winningplayer = 2;
- return 2;
- }
- }
- else { // Board full, no winner
- winningplayer = 0;
- return 2;
- }
- }
- return 1;
- }
-
- public int boardFull() {
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- if (board[i][j] == 0)
- return 0;
- return 1;
- }
-
- public int computerMakeMove() {
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- if (board[i][j] == 0) {
- board[i][j] = 2;
- return 1;
- }
- return 0;
- }
-
- public int checkForWin(int p) {
- // Add logic for checking if player p wins
- // Horiz
-
- if ((board[0][0] == p) && (board[0][1] == p) && (board[0][2] == p) ||
- (board[1][0] == p) && (board[1][1] == p) && (board[1][2] == p) ||
- (board[2][0] == p) && (board[2][1] == p) && (board[2][2] == p)) {
- return 1;
- }
-
- // Vert
- if ((board[0][0] == p) && (board[1][0] == p) && (board[2][0] == p) ||
- (board[0][1] == p) && (board[1][1] == p) && (board[2][1] == p) ||
- (board[0][2] == p) && (board[1][2] == p) && (board[2][2] == p)) {
- return 1;
- }
-
- //Diag
- if ((board[0][0] == p) && (board[1][1] == p) && (board[2][2] == p) ||
- (board[0][2] == p) && (board[1][1] == p) && (board[2][0] == p)) {
- return 1;
- }
-
- return 0;
- }
-
- public int winner() {
- return winningplayer;
- }
-}
+++ /dev/null
-/* Startup object is generated with the initialstate flag set by the
- * system to start the computation up */
-
-// Create ServerSocket
-task Startup(StartupObject s {initialstate}) {
- System.printString("TTT Server Starting...\n");
- ServerSocket ss = new ServerSocket(8000);
- System.printString("Creating ServerSocket\n");
- Board tttBoard = new Board() {init};
- taskexit(s {!initialstate}); // Turn off initial state flag
-}
-
-//Listen for a request and accept request
-task AcceptConnection(ServerSocket ss{SocketPending}) {
- System.printString("Waiting for connection...\n");
- tag t=new tag(connect);
- TTTServerSocket ttts = new TTTServerSocket() {ReceiveRequest}{t};
- System.printString("Calling accept...\n");
- ss.accept(t);
- System.printString("Connected...\n");
-}
-
-// Process incoming requests
-task ProcessRequest(TTTServerSocket ttts{ReceiveRequest}{connect l}, Socket s{IOPending}{connect l}) {
- System.printString("Request received...");
- int action = ttts.receive(s);
- if (action == 1) { // Make move
- taskexit(ttts {!ReceiveRequest,MakeMove});
- }
- else { // Send Error
- taskexit(ttts {!ReceiveRequest,SendError});
- }
-}
-
-task ProcessMove(TTTServerSocket ttts{MakeMove}, Board tttBoard{init}) {
- System.printString("Processing player's move...");
- int result = tttBoard.makeMove(ttts.getRow(), ttts.getCol());
- if (result == 1) { //Move made, send board display
- taskexit(ttts {!MakeMove, SendBoard});
- }
- else if (result == 2) { //Move made, game over
- taskexit(ttts {!MakeMove, SendDone});
- }
- else {// Error
- taskexit(ttts {!MakeMove, SendError});
- }
-}
-
-task SendBoardDisplay(TTTServerSocket ttts{SendBoard}{connect l}, Board tttBoard{init}, Socket s{}{connect l}) {
- ttts.sendBoardDisplay(tttBoard, s);
- taskexit(ttts {/*!SendBoard,*/ ReceiveRequest});
-
-}
-
-task GameOver(TTTServerSocket ttts{SendDone}{connect l}, Board tttBoard{init}, Socket s{}{connect l}) {
- ttts.sendDone(tttBoard.winner(), s);
-// taskexit(ttts {!SendDone},tttBoard{!init});
-
-}
-
-task SendErrorMessage(TTTServerSocket ttts{SendError}{connect l}, Board tttBoard{init}, Socket s{}{connect l}) {
- //System.printString("Error\n");
- ttts.sendError(s);
- taskexit(ttts {/*!SendError,*/ ReceiveRequest});
-
-}
+++ /dev/null
-public class TTTServerSocket {
- // TTTServerSocket flags
- flag ReceiveRequest;
-
- flag MakeMove;
- flag SendError;
- flag SendBoard;
- flag SendDone;
-
- String request;
- int row, col;
-
- //Constructor
- public TTTServerSocket(){
- System.printString("Constructing TTTServerSocket....\n");
- }
-
- public int receive(Socket s)
- {
- byte b1[] = new byte[1024];
- s.read(b1);
- request = new String(b1);
- System.printString("request: ");
- System.printString(request);
- if (parseTransaction() == 1) {
- System.printString(request);
- return 1;
- }
- System.printString("Error receiving...\n");
- return 0;
- }
-
- // Parse request
- public int parseTransaction(){
- int start = request.indexOf('_');
- //System.printString("start parse");
- String s = request.subString(start+1);
- //System.printString("before checking the string");
-//_move:3:3
- if (s.startsWith("move")==true){
- //Get row
- int i1 = s.indexOf(':');
- String rowStr = new String(s.subString(i1+1, i1+2));
- row = Integer.parseInt(rowStr);
-
- //System.printString("row");
-
- //Get col
- String s2 = new String(s.subString(i1+2));
- int i2 = s2.indexOf(':');
- String colStr = new String(s2.subString(i2+1, i2+2));
- col = Integer.parseInt(colStr);
- return 1;
-
-
-
- }
- // Error transaction
- return -1;
- }
-
- public int getRow(){
- return row;
- }
- public int getCol(){
- return col;
- }
-
- public void sendBoardDisplay(Board theBoard, Socket s) {
- StringBuffer line1 = new StringBuffer("\n\n");
-
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- if (theBoard.board[i][j] == 1)
- line1.append("X");
- else if (theBoard.board[i][j] == 2)
- line1.append("O");
- else
- line1.append("-");
- }
- line1.append("\n");
- }
- String towrite = new String(line1);
- s.write(towrite.getBytes());
- return;
- }
-
- public void sendDone(int winner, Socket s) {
- StringBuffer line1 = new StringBuffer ("done_");
- if (winner == 0)
- line1.append("tie");
- else if (winner == 1)
- line1.append("player");
- else
- line1.append("computer");
-
- String towrite = new String(line1);
- s.write(towrite.getBytes());
- return;
- }
-
- public void sendError(Socket s) {
- StringBuffer line1 = new StringBuffer ("error_wrongmove");
-
- String towrite = new String(line1);
- s.write(towrite.getBytes());
- return;
- }
-}
+++ /dev/null
-public class Inventory {
- // Inventory flags
- flag TransInitialize;
-
- // Transaction variables
- int numitems;
- HashMap map;
- int balance;
-
- // Constructor
- public Inventory(){
- map = new HashMap();
- balance=100000;
- }
-
- public Inventory(int howmany) {
- numitems = howmany;// howmany keeps track of the number of items
- // in the inventory
- map = new HashMap();
- }
-
- // Add item to a list of inventory
- public int additem(String name, int quantity, int price){
- ItemInfo newitem = new ItemInfo(quantity, price);
- balance-=quantity*price;
-
- // Get the item from hash
- if (map.containsKey(name) == false) {
- map.put(name, newitem);
- } else {
- ItemInfo i = (ItemInfo) map.get(name);
- i.quantity += quantity;
- i.price = price;
- map.put(name, i);
- }
- return 0;
- }
-
- // Buy item from a given list of inventory
- public int buyitem(String name, int quantity){
- if (map.containsKey(name) == false) {
- // System.printString("Error - Item does not exist");
- return -1;
- } else {
- ItemInfo i = (ItemInfo) map.get(name);
- if (i.quantity == 0) {
- // System.printString("Error - Item unavailable");
- return -1;
- }
- if ((i.quantity-quantity) < 0 ) {
- // System.printString("Error - Available qty is less: Cannot Buy\n");
- return -1;
- } else {
- i.quantity -= quantity;
- map.put(name, i);
- balance+=quantity*i.price;
- return i.price;
- }
- }
- return 0;
- }
-
- //Display the inventory list
- //Display the inventory list
- public synchronized void inventory(Socket s){
- HashMapIterator i = new HashMapIterator(map, 0);// Gets key from the hashmap= name of item
- HashMapIterator j = new HashMapIterator(map, 1);//Gets the value from hashmap
- int totalvalue=balance;
- while (i.hasNext() == true) {
- StringBuffer sb = new StringBuffer("");
- Object o = i.next();
- String name = o.toString();
- ItemInfo oo = (ItemInfo) j.next();
- sb.append(name);
- sb.append(" ");
- Integer q = new Integer(oo.quantity);
- sb.append(q.toString());
- sb.append(" ");
- Integer p = new Integer(oo.price);
- sb.append(p.toString());
- sb.append("\n");
- totalvalue+=oo.quantity*oo.price;
- s.write(sb.toString().getBytes());
- }
- StringBuffer sb=new StringBuffer("");
- sb.append("Total value: ");
- sb.append((new Integer(totalvalue)).toString());
- sb.append("\n");
- s.write(sb.toString().getBytes());
- }
-}
+++ /dev/null
-class ItemInfo {
- int quantity;
- int price;
- ItemInfo(int x, int y) {
- quantity = x;
- price = y;
- }
-}
+++ /dev/null
-public class Logger {
- //Logger flag
- flag Initialize;
- FileOutputStream fos;
-
-
- //Constructor
- public Logger(){
- fos=new FileOutputStream("request.log");//Open request.log file
- }
-
- //Logs filename as per client requests
- public void logrequest(String filename){
- String request = new String("\nNew Request received: ");
- fos.write(request.getBytes());
- fos.write(filename.getBytes());
- fos.flush();
- }
-
- public void logrequest(){
- String request = new String("\nNew Request received: ");
- fos.write(request.getBytes());
- fos.flush();
- }
-
- public void closerequest() {
- fos.close();
- }
-}
+++ /dev/null
-/* Startup object is generated with the initialstate flag set by the
- * system to start the computation up */
-
-// Create New ServerSocket
-task Startup(StartupObject s {initialstate}) {
-// System.printString("W> Starting\n");
- ServerSocket ss = new ServerSocket(9000);
-// System.printString("W> Creating ServerSocket\n");
- Logger log = new Logger() {Initialize};
- Inventory inventorylist = new Inventory(){TransInitialize};
- taskexit(s {!initialstate}); /* Turns initial state flag off, so this task won't refire */
-}
-
-//Listen for a request and accept request
-task AcceptConnection(ServerSocket ss{SocketPending}) {
-// System.printString("W> Waiting for connection...\n");
- WebServerSocket web = new WebServerSocket() {!WritePending, !TransPending, WebInitialize};
- ss.accept(web);
-// System.printString("W> Connected... \n");
-}
-
-// Process the incoming http request
-task ProcessRequest(WebServerSocket web{IOPending && WebInitialize}) {
-//task ProcessRequest(WebServerSocket web{IOPending}) {
- //System.printString("W> Inside ProcessRequest... \n");
- if (web.clientrequest()) {
- if(web.checktrans()==false)
- // Not special transaction , do normal filesending
- taskexit(web {WritePending, LogPending,!WebInitialize}); //Sets the WritePending and LogPending flag true
- else
- // Invoke special inventory transaction
- taskexit(web {TransPending, LogPending,!WebInitialize});
- }
-}
-
-//Do the WriteIO on server socket and send the requested file to Client
-task SendFile(WebServerSocket web{WritePending}) {
-// System.printString("W> Inside SendFile ... \n");
- web.sendfile();
- web.close();
- taskexit(web {!WritePending});
-}
-
-// Log the Client request
-task LogRequest(WebServerSocket web{LogPending}, Logger log{Initialize}) {
-//Task fired when both
-// LogPending and Initialize flags are true
-// System.printString("L > Inside logrequest\n");
- log.logrequest(web.filename);
- taskexit(web {!LogPending});
-}
-
-//Transaction on Inventory
-task Transaction(WebServerSocket web{TransPending}, Inventory inventorylist{TransInitialize}){ //Task for WebServerTransactions
-// System.printString("T > Inside Transaction\n");
- // Parse
- int op = web.parseTransaction();
- // Check for the kind of operation
- if (op == 0 ) { /* Add */
-// System.printString("DEBUG > Calling add transaction\n");
- Integer qty = new Integer(web.parsed[2]);
- Integer price = new Integer(web.parsed[3]);
- int ret = inventorylist.additem(web.parsed[1], qty.intValue(), price.intValue());
- if (ret == 0) {
- web.httpresponse();
- StringBuffer s = new StringBuffer("Added Item ");
- s.append(web.parsed[1]);
- s.append(" Quantity ");
- s.append(web.parsed[2]);
- s.append(" Price ");
- s.append(web.parsed[3]);
- s.append("\n");
- String towrite = new String(s);
- web.write(towrite.getBytes());
- } else {
- web.httpresponse();
- String s = new String("Error encountered");
- web.write(s.getBytes());
- }
- } else if (op == 1) { /* Buy */
-// System.printString("DEBUG > Calling buy transaction\n");
- Integer qty = new Integer(web.parsed[2]);
- int ret = inventorylist.buyitem(web.parsed[1], qty.intValue());
- if (ret >= 0) {
- web.httpresponse();
- StringBuffer s = new StringBuffer("Bought item ");
- s.append(web.parsed[1]);
- s.append(" Quantity ");
- s.append(web.parsed[2]);
- s.append(" Cost ");
- Integer cost = new Integer(ret*qty.intValue());
- String c = cost.toString();
- s.append(c);
- String towrite = new String(s);
- web.write(towrite.getBytes());
- } else {
- web.httpresponse();
- String s = new String("Error encountered");
- web.write(s.getBytes());
- }
- } else if (op == 2) { /* Inventory */
-// System.printString("DEBUG > Calling inventory transaction\n");
- web.httpresponse();
- inventorylist.inventory(web);
- } else { /* Error */
-// System.printString("T > Error - Unknown transaction\n");
- }
- //Invoke close operations
- web.close();
- taskexit(web {!TransPending});
-}
+++ /dev/null
-public class WebServerSocket extends Socket {
- // Websocket flag
- flag LogPending;
- flag WritePending;
- flag TransPending;
- flag WebInitialize;
-
- //Filename requested by the client
- String filename;
- String[] parsed;
- String prefix;
-
- //Constructor
- public WebServerSocket(){
- parsed = new String[4];
- }
-
- //Send the http header for web browser display
- public void httpresponse(){
- StringBuffer header = new StringBuffer("HTTP/1.0 200 OK\n");
- header.append("Content-type: text/html\n");
- header.append("\n\n");
- String temp_str = new String(header);
- write(temp_str.getBytes());
- return;
-
- }
-
- // Send the html file , read from file one byte at a time
- public void sendfile() {
- StringBuffer req_file = new StringBuffer("./htmlfiles/");
- req_file.append(filename);
- String filepath = new String(req_file);
- FileInputStream def_file = new FileInputStream(filepath);
- int status = def_file.getfd();//Checks if the file is present in
- //current directory
- httpresponse();
- if (status == -1){
- StringBuffer response = new StringBuffer("404: not found: ");//Send 404 error if
- // file not found
- response.append(filename);
- String buffer = new String(response);
- write(buffer.getBytes());
- def_file.close();
- return;
- }
- byte buf[] = new byte[16];
- int ret;
-
- while ((ret = def_file.read(buf)) > 0) {// Read from file and write
- // one byte at a time into the socket
- byte tosend[] = new byte[ret];
- for (int i = 0; i < ret; i++) {
- tosend[i] = buf[i];
- }
- write(tosend);
- //String str = new String(tosend);
- }
- def_file.close();
- }
-
- //Read the client request and extract the filename from it
- public boolean clientrequest(){
- byte b1[] = new byte[1024];
- int numbytes=read(b1);//Read client request from web server socket
- String curr=(new String(b1)).subString(0, numbytes);
- if (prefix!=null) {
- StringBuffer sb=new StringBuffer(prefix);
- sb.append(curr);
- curr=sb.toString();
- }
- prefix=curr;
- if(prefix.indexOf("\r\n\r\n")>=0) {
-
- int index = prefix.indexOf('/');//Parse the GET client request to find filename
- int end = prefix.indexOf('H');
- filename = prefix.subString((index+1), (end-1));
- return true;
- }
- return false;
- }
-
- // Parse for the prefix in the client request
- // This is helpful to find if the prefix is a special transaction
- public boolean checktrans(){
- if (filename.startsWith("trans") == true) {
- return true;
- } else {
- return false;
- }
- }
-
- //Parse for the substrings in the filename and use it to obtain the
- //kind of operation, name of item, quantity of item, price of item
- //e.g. trans_add_car_2_10000 is the filename
- //store in the parsed[] string , add,car,2,1000
- public int parseTransaction(){
- int start = filename.indexOf('_');
- String s = filename.subString(start+1);
-
- if (s.startsWith("add")==true){
- // System.printString("DEBUG > ADD\n");
- int i1 = s.indexOf('_');
- parsed[0] = new String(s.subString(0,i1));
-
- int i2 = s.indexOf('_',i1+1);
- parsed[1] = new String(s.subString(i1+1,i2));
-
- int i3 = s.indexOf('_',i2+1);
- parsed[2] = new String(s.subString(i2+1,i3));
-
- String s3 = s.subString(i3+1);
- parsed[3] = s3;
-
- return 0;
-
- }
- if (s.startsWith("buy")==true){
- // System.printString("DEBUG > BUY\n");
- int i1 = s.indexOf('_');
- parsed[0] = s.subString(0,i1);
-
- int i2 = s.indexOf('_', i1+1);
- parsed[1] = s.subString(i1+1,i2);
-
- String s2 = s.subString(i2+1);
- parsed[2] = s2;
-
- parsed[3] = "";
-
- return 1;
- }
- if (s.startsWith("inventory")==true){
- // System.printString("DEBUG > INVENTORY\n");
- return 2;
-
- }
- // Error transaction
- return -1;
- }
-}
+++ /dev/null
-#!/bin/sh
-
-rm result_inventory
-#For every trans_inventory* file remove the lines starting with pre and sort the file
-for file in `ls trans_inventory*`
-do
- echo "Doing $file"
- grep -v pre $file > ${file}.nopre
- sort -n ${file}.nopre > runs/${file}.sorted
-done
-
-\rm *.nopre
-cd runs
-let x=0;
-#for every sorted file created above diff it with the orginial file called pure/trans_inventory.sorted and print the total success or failures occured
-for file in `ls *sorted`
-do
- echo -n "Diffing $file...";
- diff $file ./pure/trans_inventory.sorted
- if [ $? -ne 0 ]
- then
- let "x+=1";
- else
- echo " success ";
- fi
-done
-
-echo "RESULT: x is $x";
-echo -n "RESULT: Total files compared is "
-ls *sorted | wc -l
-
-cd ..
+++ /dev/null
-
-book 258 50
-bread 9590 4
-car 39 10000
-coke 2620 5
-pen 601 5
-soap 42 7
+++ /dev/null
-#!/bin/bash
-
-let i=0; #Keeps count of number of times the server is launched
-
-rm output #Errors and total number of run count are redirected to this file
-
-#Sets the BRISTLECONE parameter with a certain instruction count, probability and
-#number of failures that can be injected
-export BRISTLECONE="-initializerandom -injectinstructionfailures 10 0.00001667 1 -debugtask"
-rm -rf results
-mkdir results
-cd results
-while [ $i -le 299 ]; # The number of runs
-do
- ../trans.bin & #Launch server executable in background
- sleep 2;
- ../Workload/workloaderror 127.0.0.1 2>/dev/null & #Run the first workload
- echo $i >> output;
- sleep 5;
- process=`ps | grep workloaderror | grep -v grep | awk '{print $1}'`
- kill -9 $process #Kill the first workload
- if [ $? -eq 0 ] #Launch the second worload only if the Failure is injected in the first workload
- then
- ../Workload/workloadtrans 127.0.0.1 2>/dev/null
- else
- echo "No Fault Injected" >> output
- fi;
- let "i+=1";
- ps | grep trans | grep -v grep | awk '{print $1}' | xargs kill -9 #Kill the server
- sleep 1;
-done
+++ /dev/null
-#!/bin/bash
-
-let i=0; #Keeps count of number of times the server is launched
-
-rm output #Errors and total number of run count are redirected to this file
-
-#Sets the BRISTLECONE parameter with a certain instruction count, probability and
-#number of failures that can be injected
-#export BRISTLECONE="-initializerandom -injectinstructionfailures 10 0.00001667 1 -debugtask"
-export BRISTLECONE="-initializerandom -injectinstructionfailures 35 0.00001667 50"
-rm -rf results
-mkdir results
-cd results
-while [ $i -le 201 ]; # The number of runs
- do
- mkdir trial$i
- cd trial$i
- let errorcount=0
- let count=0
- ../../trans.bin &> log & #Launch server executable in background
- sleep 2;
- ../../Workload/workload 127.0.0.1 2>/dev/null & #Run the first workload
- echo $i >> ../output;
- while true
- do
- process=`ps | grep wget | grep -v grep | awk '{print $1}'`
- sleep 1
- process2=`ps | grep wget | grep -v grep | awk '{print $1}'`
- if [ "$process" != "" ]
- then
- if [ "$process" = "$process2" ]
- then
- let "count=1"
- kill -9 $process #Kill the first workload
- if [ $? -eq 0 ] #Launch the second worload only if the Failure is injected in the first workload
- then
- let "errorcount+=1"
- fi
- fi
-else
- if [ "$process2" != "" ]
- then
- let "count=1"
- else
- let "count+=1"
- if [ $count == 30 ]
- then
- break
- fi
- fi
- fi
-done
-echo Errorcount=$errorcount >> ../output
-let "i+=1";
-process=`ps | grep workload | grep -v grep | awk '{print $1}'`
-kill -9 $process
-process=`ps | grep trans | grep -v grep | awk '{print $1}'`
-cat ../../gdbquery | gdb ../../trans.bin $process &> output
-kill -1 $process
-sleep 1
-kill $process
-sleep 1;
-cd ..
-done
+++ /dev/null
-public class generate {
-
- public static void main(String x[]) {
- int j=1;
- int cost=1;
- System.out.println("#!/bin/bash");
- for(int i=0;i<2200;i++) {
- int price=cost*50;
- int jbuy=j-1;
- System.out.println("wget http://$1:9000/trans_add_f"+i+"_"+j+"_"+price);
- System.out.println("wget http://$1:9000/trans_buy_f"+i+"_"+jbuy);
- if (cost>3) cost=1; else cost++;
- if (j>4) j=1; else j++;
- }
- System.out.println("wget http://$1:9000/trans_inventory");
- }
-
-
-}
+++ /dev/null
-#!/bin/bash
-wget http://$1:9000/trans_add_f0_1_50
-wget http://$1:9000/trans_buy_f0_0
-wget http://$1:9000/trans_add_f1_2_100
-wget http://$1:9000/trans_buy_f1_1
-wget http://$1:9000/trans_add_f2_3_150
-wget http://$1:9000/trans_buy_f2_2
-wget http://$1:9000/trans_add_f3_4_200
-wget http://$1:9000/trans_buy_f3_3
-wget http://$1:9000/trans_add_f4_5_50
-wget http://$1:9000/trans_buy_f4_4
-wget http://$1:9000/trans_add_f5_1_100
-wget http://$1:9000/trans_buy_f5_0
-wget http://$1:9000/trans_add_f6_2_150
-wget http://$1:9000/trans_buy_f6_1
-wget http://$1:9000/trans_add_f7_3_200
-wget http://$1:9000/trans_buy_f7_2
-wget http://$1:9000/trans_add_f8_4_50
-wget http://$1:9000/trans_buy_f8_3
-wget http://$1:9000/trans_add_f9_5_100
-wget http://$1:9000/trans_buy_f9_4
-wget http://$1:9000/trans_add_f10_1_150
-wget http://$1:9000/trans_buy_f10_0
-wget http://$1:9000/trans_add_f11_2_200
-wget http://$1:9000/trans_buy_f11_1
-wget http://$1:9000/trans_add_f12_3_50
-wget http://$1:9000/trans_buy_f12_2
-wget http://$1:9000/trans_add_f13_4_100
-wget http://$1:9000/trans_buy_f13_3
-wget http://$1:9000/trans_add_f14_5_150
-wget http://$1:9000/trans_buy_f14_4
-wget http://$1:9000/trans_add_f15_1_200
-wget http://$1:9000/trans_buy_f15_0
-wget http://$1:9000/trans_add_f16_2_50
-wget http://$1:9000/trans_buy_f16_1
-wget http://$1:9000/trans_add_f17_3_100
-wget http://$1:9000/trans_buy_f17_2
-wget http://$1:9000/trans_add_f18_4_150
-wget http://$1:9000/trans_buy_f18_3
-wget http://$1:9000/trans_add_f19_5_200
-wget http://$1:9000/trans_buy_f19_4
-wget http://$1:9000/trans_add_f20_1_50
-wget http://$1:9000/trans_buy_f20_0
-wget http://$1:9000/trans_add_f21_2_100
-wget http://$1:9000/trans_buy_f21_1
-wget http://$1:9000/trans_add_f22_3_150
-wget http://$1:9000/trans_buy_f22_2
-wget http://$1:9000/trans_add_f23_4_200
-wget http://$1:9000/trans_buy_f23_3
-wget http://$1:9000/trans_add_f24_5_50
-wget http://$1:9000/trans_buy_f24_4
-wget http://$1:9000/trans_add_f25_1_100
-wget http://$1:9000/trans_buy_f25_0
-wget http://$1:9000/trans_add_f26_2_150
-wget http://$1:9000/trans_buy_f26_1
-wget http://$1:9000/trans_add_f27_3_200
-wget http://$1:9000/trans_buy_f27_2
-wget http://$1:9000/trans_add_f28_4_50
-wget http://$1:9000/trans_buy_f28_3
-wget http://$1:9000/trans_add_f29_5_100
-wget http://$1:9000/trans_buy_f29_4
-wget http://$1:9000/trans_add_f30_1_150
-wget http://$1:9000/trans_buy_f30_0
-wget http://$1:9000/trans_add_f31_2_200
-wget http://$1:9000/trans_buy_f31_1
-wget http://$1:9000/trans_add_f32_3_50
-wget http://$1:9000/trans_buy_f32_2
-wget http://$1:9000/trans_add_f33_4_100
-wget http://$1:9000/trans_buy_f33_3
-wget http://$1:9000/trans_add_f34_5_150
-wget http://$1:9000/trans_buy_f34_4
-wget http://$1:9000/trans_add_f35_1_200
-wget http://$1:9000/trans_buy_f35_0
-wget http://$1:9000/trans_add_f36_2_50
-wget http://$1:9000/trans_buy_f36_1
-wget http://$1:9000/trans_add_f37_3_100
-wget http://$1:9000/trans_buy_f37_2
-wget http://$1:9000/trans_add_f38_4_150
-wget http://$1:9000/trans_buy_f38_3
-wget http://$1:9000/trans_add_f39_5_200
-wget http://$1:9000/trans_buy_f39_4
-wget http://$1:9000/trans_add_f40_1_50
-wget http://$1:9000/trans_buy_f40_0
-wget http://$1:9000/trans_add_f41_2_100
-wget http://$1:9000/trans_buy_f41_1
-wget http://$1:9000/trans_add_f42_3_150
-wget http://$1:9000/trans_buy_f42_2
-wget http://$1:9000/trans_add_f43_4_200
-wget http://$1:9000/trans_buy_f43_3
-wget http://$1:9000/trans_add_f44_5_50
-wget http://$1:9000/trans_buy_f44_4
-wget http://$1:9000/trans_add_f45_1_100
-wget http://$1:9000/trans_buy_f45_0
-wget http://$1:9000/trans_add_f46_2_150
-wget http://$1:9000/trans_buy_f46_1
-wget http://$1:9000/trans_add_f47_3_200
-wget http://$1:9000/trans_buy_f47_2
-wget http://$1:9000/trans_add_f48_4_50
-wget http://$1:9000/trans_buy_f48_3
-wget http://$1:9000/trans_add_f49_5_100
-wget http://$1:9000/trans_buy_f49_4
-wget http://$1:9000/trans_add_f50_1_150
-wget http://$1:9000/trans_buy_f50_0
-wget http://$1:9000/trans_add_f51_2_200
-wget http://$1:9000/trans_buy_f51_1
-wget http://$1:9000/trans_add_f52_3_50
-wget http://$1:9000/trans_buy_f52_2
-wget http://$1:9000/trans_add_f53_4_100
-wget http://$1:9000/trans_buy_f53_3
-wget http://$1:9000/trans_add_f54_5_150
-wget http://$1:9000/trans_buy_f54_4
-wget http://$1:9000/trans_add_f55_1_200
-wget http://$1:9000/trans_buy_f55_0
-wget http://$1:9000/trans_add_f56_2_50
-wget http://$1:9000/trans_buy_f56_1
-wget http://$1:9000/trans_add_f57_3_100
-wget http://$1:9000/trans_buy_f57_2
-wget http://$1:9000/trans_add_f58_4_150
-wget http://$1:9000/trans_buy_f58_3
-wget http://$1:9000/trans_add_f59_5_200
-wget http://$1:9000/trans_buy_f59_4
-wget http://$1:9000/trans_add_f60_1_50
-wget http://$1:9000/trans_buy_f60_0
-wget http://$1:9000/trans_add_f61_2_100
-wget http://$1:9000/trans_buy_f61_1
-wget http://$1:9000/trans_add_f62_3_150
-wget http://$1:9000/trans_buy_f62_2
-wget http://$1:9000/trans_add_f63_4_200
-wget http://$1:9000/trans_buy_f63_3
-wget http://$1:9000/trans_add_f64_5_50
-wget http://$1:9000/trans_buy_f64_4
-wget http://$1:9000/trans_add_f65_1_100
-wget http://$1:9000/trans_buy_f65_0
-wget http://$1:9000/trans_add_f66_2_150
-wget http://$1:9000/trans_buy_f66_1
-wget http://$1:9000/trans_add_f67_3_200
-wget http://$1:9000/trans_buy_f67_2
-wget http://$1:9000/trans_add_f68_4_50
-wget http://$1:9000/trans_buy_f68_3
-wget http://$1:9000/trans_add_f69_5_100
-wget http://$1:9000/trans_buy_f69_4
-wget http://$1:9000/trans_add_f70_1_150
-wget http://$1:9000/trans_buy_f70_0
-wget http://$1:9000/trans_add_f71_2_200
-wget http://$1:9000/trans_buy_f71_1
-wget http://$1:9000/trans_add_f72_3_50
-wget http://$1:9000/trans_buy_f72_2
-wget http://$1:9000/trans_add_f73_4_100
-wget http://$1:9000/trans_buy_f73_3
-wget http://$1:9000/trans_add_f74_5_150
-wget http://$1:9000/trans_buy_f74_4
-wget http://$1:9000/trans_add_f75_1_200
-wget http://$1:9000/trans_buy_f75_0
-wget http://$1:9000/trans_add_f76_2_50
-wget http://$1:9000/trans_buy_f76_1
-wget http://$1:9000/trans_add_f77_3_100
-wget http://$1:9000/trans_buy_f77_2
-wget http://$1:9000/trans_add_f78_4_150
-wget http://$1:9000/trans_buy_f78_3
-wget http://$1:9000/trans_add_f79_5_200
-wget http://$1:9000/trans_buy_f79_4
-wget http://$1:9000/trans_add_f80_1_50
-wget http://$1:9000/trans_buy_f80_0
-wget http://$1:9000/trans_add_f81_2_100
-wget http://$1:9000/trans_buy_f81_1
-wget http://$1:9000/trans_add_f82_3_150
-wget http://$1:9000/trans_buy_f82_2
-wget http://$1:9000/trans_add_f83_4_200
-wget http://$1:9000/trans_buy_f83_3
-wget http://$1:9000/trans_add_f84_5_50
-wget http://$1:9000/trans_buy_f84_4
-wget http://$1:9000/trans_add_f85_1_100
-wget http://$1:9000/trans_buy_f85_0
-wget http://$1:9000/trans_add_f86_2_150
-wget http://$1:9000/trans_buy_f86_1
-wget http://$1:9000/trans_add_f87_3_200
-wget http://$1:9000/trans_buy_f87_2
-wget http://$1:9000/trans_add_f88_4_50
-wget http://$1:9000/trans_buy_f88_3
-wget http://$1:9000/trans_add_f89_5_100
-wget http://$1:9000/trans_buy_f89_4
-wget http://$1:9000/trans_add_f90_1_150
-wget http://$1:9000/trans_buy_f90_0
-wget http://$1:9000/trans_add_f91_2_200
-wget http://$1:9000/trans_buy_f91_1
-wget http://$1:9000/trans_add_f92_3_50
-wget http://$1:9000/trans_buy_f92_2
-wget http://$1:9000/trans_add_f93_4_100
-wget http://$1:9000/trans_buy_f93_3
-wget http://$1:9000/trans_add_f94_5_150
-wget http://$1:9000/trans_buy_f94_4
-wget http://$1:9000/trans_add_f95_1_200
-wget http://$1:9000/trans_buy_f95_0
-wget http://$1:9000/trans_add_f96_2_50
-wget http://$1:9000/trans_buy_f96_1
-wget http://$1:9000/trans_add_f97_3_100
-wget http://$1:9000/trans_buy_f97_2
-wget http://$1:9000/trans_add_f98_4_150
-wget http://$1:9000/trans_buy_f98_3
-wget http://$1:9000/trans_add_f99_5_200
-wget http://$1:9000/trans_buy_f99_4
-wget http://$1:9000/trans_add_f100_1_50
-wget http://$1:9000/trans_buy_f100_0
-wget http://$1:9000/trans_add_f101_2_100
-wget http://$1:9000/trans_buy_f101_1
-wget http://$1:9000/trans_add_f102_3_150
-wget http://$1:9000/trans_buy_f102_2
-wget http://$1:9000/trans_add_f103_4_200
-wget http://$1:9000/trans_buy_f103_3
-wget http://$1:9000/trans_add_f104_5_50
-wget http://$1:9000/trans_buy_f104_4
-wget http://$1:9000/trans_add_f105_1_100
-wget http://$1:9000/trans_buy_f105_0
-wget http://$1:9000/trans_add_f106_2_150
-wget http://$1:9000/trans_buy_f106_1
-wget http://$1:9000/trans_add_f107_3_200
-wget http://$1:9000/trans_buy_f107_2
-wget http://$1:9000/trans_add_f108_4_50
-wget http://$1:9000/trans_buy_f108_3
-wget http://$1:9000/trans_add_f109_5_100
-wget http://$1:9000/trans_buy_f109_4
-wget http://$1:9000/trans_add_f110_1_150
-wget http://$1:9000/trans_buy_f110_0
-wget http://$1:9000/trans_add_f111_2_200
-wget http://$1:9000/trans_buy_f111_1
-wget http://$1:9000/trans_add_f112_3_50
-wget http://$1:9000/trans_buy_f112_2
-wget http://$1:9000/trans_add_f113_4_100
-wget http://$1:9000/trans_buy_f113_3
-wget http://$1:9000/trans_add_f114_5_150
-wget http://$1:9000/trans_buy_f114_4
-wget http://$1:9000/trans_add_f115_1_200
-wget http://$1:9000/trans_buy_f115_0
-wget http://$1:9000/trans_add_f116_2_50
-wget http://$1:9000/trans_buy_f116_1
-wget http://$1:9000/trans_add_f117_3_100
-wget http://$1:9000/trans_buy_f117_2
-wget http://$1:9000/trans_add_f118_4_150
-wget http://$1:9000/trans_buy_f118_3
-wget http://$1:9000/trans_add_f119_5_200
-wget http://$1:9000/trans_buy_f119_4
-wget http://$1:9000/trans_add_f120_1_50
-wget http://$1:9000/trans_buy_f120_0
-wget http://$1:9000/trans_add_f121_2_100
-wget http://$1:9000/trans_buy_f121_1
-wget http://$1:9000/trans_add_f122_3_150
-wget http://$1:9000/trans_buy_f122_2
-wget http://$1:9000/trans_add_f123_4_200
-wget http://$1:9000/trans_buy_f123_3
-wget http://$1:9000/trans_add_f124_5_50
-wget http://$1:9000/trans_buy_f124_4
-wget http://$1:9000/trans_add_f125_1_100
-wget http://$1:9000/trans_buy_f125_0
-wget http://$1:9000/trans_add_f126_2_150
-wget http://$1:9000/trans_buy_f126_1
-wget http://$1:9000/trans_add_f127_3_200
-wget http://$1:9000/trans_buy_f127_2
-wget http://$1:9000/trans_add_f128_4_50
-wget http://$1:9000/trans_buy_f128_3
-wget http://$1:9000/trans_add_f129_5_100
-wget http://$1:9000/trans_buy_f129_4
-wget http://$1:9000/trans_add_f130_1_150
-wget http://$1:9000/trans_buy_f130_0
-wget http://$1:9000/trans_add_f131_2_200
-wget http://$1:9000/trans_buy_f131_1
-wget http://$1:9000/trans_add_f132_3_50
-wget http://$1:9000/trans_buy_f132_2
-wget http://$1:9000/trans_add_f133_4_100
-wget http://$1:9000/trans_buy_f133_3
-wget http://$1:9000/trans_add_f134_5_150
-wget http://$1:9000/trans_buy_f134_4
-wget http://$1:9000/trans_add_f135_1_200
-wget http://$1:9000/trans_buy_f135_0
-wget http://$1:9000/trans_add_f136_2_50
-wget http://$1:9000/trans_buy_f136_1
-wget http://$1:9000/trans_add_f137_3_100
-wget http://$1:9000/trans_buy_f137_2
-wget http://$1:9000/trans_add_f138_4_150
-wget http://$1:9000/trans_buy_f138_3
-wget http://$1:9000/trans_add_f139_5_200
-wget http://$1:9000/trans_buy_f139_4
-wget http://$1:9000/trans_add_f140_1_50
-wget http://$1:9000/trans_buy_f140_0
-wget http://$1:9000/trans_add_f141_2_100
-wget http://$1:9000/trans_buy_f141_1
-wget http://$1:9000/trans_add_f142_3_150
-wget http://$1:9000/trans_buy_f142_2
-wget http://$1:9000/trans_add_f143_4_200
-wget http://$1:9000/trans_buy_f143_3
-wget http://$1:9000/trans_add_f144_5_50
-wget http://$1:9000/trans_buy_f144_4
-wget http://$1:9000/trans_add_f145_1_100
-wget http://$1:9000/trans_buy_f145_0
-wget http://$1:9000/trans_add_f146_2_150
-wget http://$1:9000/trans_buy_f146_1
-wget http://$1:9000/trans_add_f147_3_200
-wget http://$1:9000/trans_buy_f147_2
-wget http://$1:9000/trans_add_f148_4_50
-wget http://$1:9000/trans_buy_f148_3
-wget http://$1:9000/trans_add_f149_5_100
-wget http://$1:9000/trans_buy_f149_4
-wget http://$1:9000/trans_add_f150_1_150
-wget http://$1:9000/trans_buy_f150_0
-wget http://$1:9000/trans_add_f151_2_200
-wget http://$1:9000/trans_buy_f151_1
-wget http://$1:9000/trans_add_f152_3_50
-wget http://$1:9000/trans_buy_f152_2
-wget http://$1:9000/trans_add_f153_4_100
-wget http://$1:9000/trans_buy_f153_3
-wget http://$1:9000/trans_add_f154_5_150
-wget http://$1:9000/trans_buy_f154_4
-wget http://$1:9000/trans_add_f155_1_200
-wget http://$1:9000/trans_buy_f155_0
-wget http://$1:9000/trans_add_f156_2_50
-wget http://$1:9000/trans_buy_f156_1
-wget http://$1:9000/trans_add_f157_3_100
-wget http://$1:9000/trans_buy_f157_2
-wget http://$1:9000/trans_add_f158_4_150
-wget http://$1:9000/trans_buy_f158_3
-wget http://$1:9000/trans_add_f159_5_200
-wget http://$1:9000/trans_buy_f159_4
-wget http://$1:9000/trans_add_f160_1_50
-wget http://$1:9000/trans_buy_f160_0
-wget http://$1:9000/trans_add_f161_2_100
-wget http://$1:9000/trans_buy_f161_1
-wget http://$1:9000/trans_add_f162_3_150
-wget http://$1:9000/trans_buy_f162_2
-wget http://$1:9000/trans_add_f163_4_200
-wget http://$1:9000/trans_buy_f163_3
-wget http://$1:9000/trans_add_f164_5_50
-wget http://$1:9000/trans_buy_f164_4
-wget http://$1:9000/trans_add_f165_1_100
-wget http://$1:9000/trans_buy_f165_0
-wget http://$1:9000/trans_add_f166_2_150
-wget http://$1:9000/trans_buy_f166_1
-wget http://$1:9000/trans_add_f167_3_200
-wget http://$1:9000/trans_buy_f167_2
-wget http://$1:9000/trans_add_f168_4_50
-wget http://$1:9000/trans_buy_f168_3
-wget http://$1:9000/trans_add_f169_5_100
-wget http://$1:9000/trans_buy_f169_4
-wget http://$1:9000/trans_add_f170_1_150
-wget http://$1:9000/trans_buy_f170_0
-wget http://$1:9000/trans_add_f171_2_200
-wget http://$1:9000/trans_buy_f171_1
-wget http://$1:9000/trans_add_f172_3_50
-wget http://$1:9000/trans_buy_f172_2
-wget http://$1:9000/trans_add_f173_4_100
-wget http://$1:9000/trans_buy_f173_3
-wget http://$1:9000/trans_add_f174_5_150
-wget http://$1:9000/trans_buy_f174_4
-wget http://$1:9000/trans_add_f175_1_200
-wget http://$1:9000/trans_buy_f175_0
-wget http://$1:9000/trans_add_f176_2_50
-wget http://$1:9000/trans_buy_f176_1
-wget http://$1:9000/trans_add_f177_3_100
-wget http://$1:9000/trans_buy_f177_2
-wget http://$1:9000/trans_add_f178_4_150
-wget http://$1:9000/trans_buy_f178_3
-wget http://$1:9000/trans_add_f179_5_200
-wget http://$1:9000/trans_buy_f179_4
-wget http://$1:9000/trans_add_f180_1_50
-wget http://$1:9000/trans_buy_f180_0
-wget http://$1:9000/trans_add_f181_2_100
-wget http://$1:9000/trans_buy_f181_1
-wget http://$1:9000/trans_add_f182_3_150
-wget http://$1:9000/trans_buy_f182_2
-wget http://$1:9000/trans_add_f183_4_200
-wget http://$1:9000/trans_buy_f183_3
-wget http://$1:9000/trans_add_f184_5_50
-wget http://$1:9000/trans_buy_f184_4
-wget http://$1:9000/trans_add_f185_1_100
-wget http://$1:9000/trans_buy_f185_0
-wget http://$1:9000/trans_add_f186_2_150
-wget http://$1:9000/trans_buy_f186_1
-wget http://$1:9000/trans_add_f187_3_200
-wget http://$1:9000/trans_buy_f187_2
-wget http://$1:9000/trans_add_f188_4_50
-wget http://$1:9000/trans_buy_f188_3
-wget http://$1:9000/trans_add_f189_5_100
-wget http://$1:9000/trans_buy_f189_4
-wget http://$1:9000/trans_add_f190_1_150
-wget http://$1:9000/trans_buy_f190_0
-wget http://$1:9000/trans_add_f191_2_200
-wget http://$1:9000/trans_buy_f191_1
-wget http://$1:9000/trans_add_f192_3_50
-wget http://$1:9000/trans_buy_f192_2
-wget http://$1:9000/trans_add_f193_4_100
-wget http://$1:9000/trans_buy_f193_3
-wget http://$1:9000/trans_add_f194_5_150
-wget http://$1:9000/trans_buy_f194_4
-wget http://$1:9000/trans_add_f195_1_200
-wget http://$1:9000/trans_buy_f195_0
-wget http://$1:9000/trans_add_f196_2_50
-wget http://$1:9000/trans_buy_f196_1
-wget http://$1:9000/trans_add_f197_3_100
-wget http://$1:9000/trans_buy_f197_2
-wget http://$1:9000/trans_add_f198_4_150
-wget http://$1:9000/trans_buy_f198_3
-wget http://$1:9000/trans_add_f199_5_200
-wget http://$1:9000/trans_buy_f199_4
-wget http://$1:9000/trans_add_f200_1_50
-wget http://$1:9000/trans_buy_f200_0
-wget http://$1:9000/trans_add_f201_2_100
-wget http://$1:9000/trans_buy_f201_1
-wget http://$1:9000/trans_add_f202_3_150
-wget http://$1:9000/trans_buy_f202_2
-wget http://$1:9000/trans_add_f203_4_200
-wget http://$1:9000/trans_buy_f203_3
-wget http://$1:9000/trans_add_f204_5_50
-wget http://$1:9000/trans_buy_f204_4
-wget http://$1:9000/trans_add_f205_1_100
-wget http://$1:9000/trans_buy_f205_0
-wget http://$1:9000/trans_add_f206_2_150
-wget http://$1:9000/trans_buy_f206_1
-wget http://$1:9000/trans_add_f207_3_200
-wget http://$1:9000/trans_buy_f207_2
-wget http://$1:9000/trans_add_f208_4_50
-wget http://$1:9000/trans_buy_f208_3
-wget http://$1:9000/trans_add_f209_5_100
-wget http://$1:9000/trans_buy_f209_4
-wget http://$1:9000/trans_add_f210_1_150
-wget http://$1:9000/trans_buy_f210_0
-wget http://$1:9000/trans_add_f211_2_200
-wget http://$1:9000/trans_buy_f211_1
-wget http://$1:9000/trans_add_f212_3_50
-wget http://$1:9000/trans_buy_f212_2
-wget http://$1:9000/trans_add_f213_4_100
-wget http://$1:9000/trans_buy_f213_3
-wget http://$1:9000/trans_add_f214_5_150
-wget http://$1:9000/trans_buy_f214_4
-wget http://$1:9000/trans_add_f215_1_200
-wget http://$1:9000/trans_buy_f215_0
-wget http://$1:9000/trans_add_f216_2_50
-wget http://$1:9000/trans_buy_f216_1
-wget http://$1:9000/trans_add_f217_3_100
-wget http://$1:9000/trans_buy_f217_2
-wget http://$1:9000/trans_add_f218_4_150
-wget http://$1:9000/trans_buy_f218_3
-wget http://$1:9000/trans_add_f219_5_200
-wget http://$1:9000/trans_buy_f219_4
-wget http://$1:9000/trans_add_f220_1_50
-wget http://$1:9000/trans_buy_f220_0
-wget http://$1:9000/trans_add_f221_2_100
-wget http://$1:9000/trans_buy_f221_1
-wget http://$1:9000/trans_add_f222_3_150
-wget http://$1:9000/trans_buy_f222_2
-wget http://$1:9000/trans_add_f223_4_200
-wget http://$1:9000/trans_buy_f223_3
-wget http://$1:9000/trans_add_f224_5_50
-wget http://$1:9000/trans_buy_f224_4
-wget http://$1:9000/trans_add_f225_1_100
-wget http://$1:9000/trans_buy_f225_0
-wget http://$1:9000/trans_add_f226_2_150
-wget http://$1:9000/trans_buy_f226_1
-wget http://$1:9000/trans_add_f227_3_200
-wget http://$1:9000/trans_buy_f227_2
-wget http://$1:9000/trans_add_f228_4_50
-wget http://$1:9000/trans_buy_f228_3
-wget http://$1:9000/trans_add_f229_5_100
-wget http://$1:9000/trans_buy_f229_4
-wget http://$1:9000/trans_add_f230_1_150
-wget http://$1:9000/trans_buy_f230_0
-wget http://$1:9000/trans_add_f231_2_200
-wget http://$1:9000/trans_buy_f231_1
-wget http://$1:9000/trans_add_f232_3_50
-wget http://$1:9000/trans_buy_f232_2
-wget http://$1:9000/trans_add_f233_4_100
-wget http://$1:9000/trans_buy_f233_3
-wget http://$1:9000/trans_add_f234_5_150
-wget http://$1:9000/trans_buy_f234_4
-wget http://$1:9000/trans_add_f235_1_200
-wget http://$1:9000/trans_buy_f235_0
-wget http://$1:9000/trans_add_f236_2_50
-wget http://$1:9000/trans_buy_f236_1
-wget http://$1:9000/trans_add_f237_3_100
-wget http://$1:9000/trans_buy_f237_2
-wget http://$1:9000/trans_add_f238_4_150
-wget http://$1:9000/trans_buy_f238_3
-wget http://$1:9000/trans_add_f239_5_200
-wget http://$1:9000/trans_buy_f239_4
-wget http://$1:9000/trans_add_f240_1_50
-wget http://$1:9000/trans_buy_f240_0
-wget http://$1:9000/trans_add_f241_2_100
-wget http://$1:9000/trans_buy_f241_1
-wget http://$1:9000/trans_add_f242_3_150
-wget http://$1:9000/trans_buy_f242_2
-wget http://$1:9000/trans_add_f243_4_200
-wget http://$1:9000/trans_buy_f243_3
-wget http://$1:9000/trans_add_f244_5_50
-wget http://$1:9000/trans_buy_f244_4
-wget http://$1:9000/trans_add_f245_1_100
-wget http://$1:9000/trans_buy_f245_0
-wget http://$1:9000/trans_add_f246_2_150
-wget http://$1:9000/trans_buy_f246_1
-wget http://$1:9000/trans_add_f247_3_200
-wget http://$1:9000/trans_buy_f247_2
-wget http://$1:9000/trans_add_f248_4_50
-wget http://$1:9000/trans_buy_f248_3
-wget http://$1:9000/trans_add_f249_5_100
-wget http://$1:9000/trans_buy_f249_4
-wget http://$1:9000/trans_add_f250_1_150
-wget http://$1:9000/trans_buy_f250_0
-wget http://$1:9000/trans_add_f251_2_200
-wget http://$1:9000/trans_buy_f251_1
-wget http://$1:9000/trans_add_f252_3_50
-wget http://$1:9000/trans_buy_f252_2
-wget http://$1:9000/trans_add_f253_4_100
-wget http://$1:9000/trans_buy_f253_3
-wget http://$1:9000/trans_add_f254_5_150
-wget http://$1:9000/trans_buy_f254_4
-wget http://$1:9000/trans_add_f255_1_200
-wget http://$1:9000/trans_buy_f255_0
-wget http://$1:9000/trans_add_f256_2_50
-wget http://$1:9000/trans_buy_f256_1
-wget http://$1:9000/trans_add_f257_3_100
-wget http://$1:9000/trans_buy_f257_2
-wget http://$1:9000/trans_add_f258_4_150
-wget http://$1:9000/trans_buy_f258_3
-wget http://$1:9000/trans_add_f259_5_200
-wget http://$1:9000/trans_buy_f259_4
-wget http://$1:9000/trans_add_f260_1_50
-wget http://$1:9000/trans_buy_f260_0
-wget http://$1:9000/trans_add_f261_2_100
-wget http://$1:9000/trans_buy_f261_1
-wget http://$1:9000/trans_add_f262_3_150
-wget http://$1:9000/trans_buy_f262_2
-wget http://$1:9000/trans_add_f263_4_200
-wget http://$1:9000/trans_buy_f263_3
-wget http://$1:9000/trans_add_f264_5_50
-wget http://$1:9000/trans_buy_f264_4
-wget http://$1:9000/trans_add_f265_1_100
-wget http://$1:9000/trans_buy_f265_0
-wget http://$1:9000/trans_add_f266_2_150
-wget http://$1:9000/trans_buy_f266_1
-wget http://$1:9000/trans_add_f267_3_200
-wget http://$1:9000/trans_buy_f267_2
-wget http://$1:9000/trans_add_f268_4_50
-wget http://$1:9000/trans_buy_f268_3
-wget http://$1:9000/trans_add_f269_5_100
-wget http://$1:9000/trans_buy_f269_4
-wget http://$1:9000/trans_add_f270_1_150
-wget http://$1:9000/trans_buy_f270_0
-wget http://$1:9000/trans_add_f271_2_200
-wget http://$1:9000/trans_buy_f271_1
-wget http://$1:9000/trans_add_f272_3_50
-wget http://$1:9000/trans_buy_f272_2
-wget http://$1:9000/trans_add_f273_4_100
-wget http://$1:9000/trans_buy_f273_3
-wget http://$1:9000/trans_add_f274_5_150
-wget http://$1:9000/trans_buy_f274_4
-wget http://$1:9000/trans_add_f275_1_200
-wget http://$1:9000/trans_buy_f275_0
-wget http://$1:9000/trans_add_f276_2_50
-wget http://$1:9000/trans_buy_f276_1
-wget http://$1:9000/trans_add_f277_3_100
-wget http://$1:9000/trans_buy_f277_2
-wget http://$1:9000/trans_add_f278_4_150
-wget http://$1:9000/trans_buy_f278_3
-wget http://$1:9000/trans_add_f279_5_200
-wget http://$1:9000/trans_buy_f279_4
-wget http://$1:9000/trans_add_f280_1_50
-wget http://$1:9000/trans_buy_f280_0
-wget http://$1:9000/trans_add_f281_2_100
-wget http://$1:9000/trans_buy_f281_1
-wget http://$1:9000/trans_add_f282_3_150
-wget http://$1:9000/trans_buy_f282_2
-wget http://$1:9000/trans_add_f283_4_200
-wget http://$1:9000/trans_buy_f283_3
-wget http://$1:9000/trans_add_f284_5_50
-wget http://$1:9000/trans_buy_f284_4
-wget http://$1:9000/trans_add_f285_1_100
-wget http://$1:9000/trans_buy_f285_0
-wget http://$1:9000/trans_add_f286_2_150
-wget http://$1:9000/trans_buy_f286_1
-wget http://$1:9000/trans_add_f287_3_200
-wget http://$1:9000/trans_buy_f287_2
-wget http://$1:9000/trans_add_f288_4_50
-wget http://$1:9000/trans_buy_f288_3
-wget http://$1:9000/trans_add_f289_5_100
-wget http://$1:9000/trans_buy_f289_4
-wget http://$1:9000/trans_add_f290_1_150
-wget http://$1:9000/trans_buy_f290_0
-wget http://$1:9000/trans_add_f291_2_200
-wget http://$1:9000/trans_buy_f291_1
-wget http://$1:9000/trans_add_f292_3_50
-wget http://$1:9000/trans_buy_f292_2
-wget http://$1:9000/trans_add_f293_4_100
-wget http://$1:9000/trans_buy_f293_3
-wget http://$1:9000/trans_add_f294_5_150
-wget http://$1:9000/trans_buy_f294_4
-wget http://$1:9000/trans_add_f295_1_200
-wget http://$1:9000/trans_buy_f295_0
-wget http://$1:9000/trans_add_f296_2_50
-wget http://$1:9000/trans_buy_f296_1
-wget http://$1:9000/trans_add_f297_3_100
-wget http://$1:9000/trans_buy_f297_2
-wget http://$1:9000/trans_add_f298_4_150
-wget http://$1:9000/trans_buy_f298_3
-wget http://$1:9000/trans_add_f299_5_200
-wget http://$1:9000/trans_buy_f299_4
-wget http://$1:9000/trans_add_f300_1_50
-wget http://$1:9000/trans_buy_f300_0
-wget http://$1:9000/trans_add_f301_2_100
-wget http://$1:9000/trans_buy_f301_1
-wget http://$1:9000/trans_add_f302_3_150
-wget http://$1:9000/trans_buy_f302_2
-wget http://$1:9000/trans_add_f303_4_200
-wget http://$1:9000/trans_buy_f303_3
-wget http://$1:9000/trans_add_f304_5_50
-wget http://$1:9000/trans_buy_f304_4
-wget http://$1:9000/trans_add_f305_1_100
-wget http://$1:9000/trans_buy_f305_0
-wget http://$1:9000/trans_add_f306_2_150
-wget http://$1:9000/trans_buy_f306_1
-wget http://$1:9000/trans_add_f307_3_200
-wget http://$1:9000/trans_buy_f307_2
-wget http://$1:9000/trans_add_f308_4_50
-wget http://$1:9000/trans_buy_f308_3
-wget http://$1:9000/trans_add_f309_5_100
-wget http://$1:9000/trans_buy_f309_4
-wget http://$1:9000/trans_add_f310_1_150
-wget http://$1:9000/trans_buy_f310_0
-wget http://$1:9000/trans_add_f311_2_200
-wget http://$1:9000/trans_buy_f311_1
-wget http://$1:9000/trans_add_f312_3_50
-wget http://$1:9000/trans_buy_f312_2
-wget http://$1:9000/trans_add_f313_4_100
-wget http://$1:9000/trans_buy_f313_3
-wget http://$1:9000/trans_add_f314_5_150
-wget http://$1:9000/trans_buy_f314_4
-wget http://$1:9000/trans_add_f315_1_200
-wget http://$1:9000/trans_buy_f315_0
-wget http://$1:9000/trans_add_f316_2_50
-wget http://$1:9000/trans_buy_f316_1
-wget http://$1:9000/trans_add_f317_3_100
-wget http://$1:9000/trans_buy_f317_2
-wget http://$1:9000/trans_add_f318_4_150
-wget http://$1:9000/trans_buy_f318_3
-wget http://$1:9000/trans_add_f319_5_200
-wget http://$1:9000/trans_buy_f319_4
-wget http://$1:9000/trans_add_f320_1_50
-wget http://$1:9000/trans_buy_f320_0
-wget http://$1:9000/trans_add_f321_2_100
-wget http://$1:9000/trans_buy_f321_1
-wget http://$1:9000/trans_add_f322_3_150
-wget http://$1:9000/trans_buy_f322_2
-wget http://$1:9000/trans_add_f323_4_200
-wget http://$1:9000/trans_buy_f323_3
-wget http://$1:9000/trans_add_f324_5_50
-wget http://$1:9000/trans_buy_f324_4
-wget http://$1:9000/trans_add_f325_1_100
-wget http://$1:9000/trans_buy_f325_0
-wget http://$1:9000/trans_add_f326_2_150
-wget http://$1:9000/trans_buy_f326_1
-wget http://$1:9000/trans_add_f327_3_200
-wget http://$1:9000/trans_buy_f327_2
-wget http://$1:9000/trans_add_f328_4_50
-wget http://$1:9000/trans_buy_f328_3
-wget http://$1:9000/trans_add_f329_5_100
-wget http://$1:9000/trans_buy_f329_4
-wget http://$1:9000/trans_add_f330_1_150
-wget http://$1:9000/trans_buy_f330_0
-wget http://$1:9000/trans_add_f331_2_200
-wget http://$1:9000/trans_buy_f331_1
-wget http://$1:9000/trans_add_f332_3_50
-wget http://$1:9000/trans_buy_f332_2
-wget http://$1:9000/trans_add_f333_4_100
-wget http://$1:9000/trans_buy_f333_3
-wget http://$1:9000/trans_add_f334_5_150
-wget http://$1:9000/trans_buy_f334_4
-wget http://$1:9000/trans_add_f335_1_200
-wget http://$1:9000/trans_buy_f335_0
-wget http://$1:9000/trans_add_f336_2_50
-wget http://$1:9000/trans_buy_f336_1
-wget http://$1:9000/trans_add_f337_3_100
-wget http://$1:9000/trans_buy_f337_2
-wget http://$1:9000/trans_add_f338_4_150
-wget http://$1:9000/trans_buy_f338_3
-wget http://$1:9000/trans_add_f339_5_200
-wget http://$1:9000/trans_buy_f339_4
-wget http://$1:9000/trans_add_f340_1_50
-wget http://$1:9000/trans_buy_f340_0
-wget http://$1:9000/trans_add_f341_2_100
-wget http://$1:9000/trans_buy_f341_1
-wget http://$1:9000/trans_add_f342_3_150
-wget http://$1:9000/trans_buy_f342_2
-wget http://$1:9000/trans_add_f343_4_200
-wget http://$1:9000/trans_buy_f343_3
-wget http://$1:9000/trans_add_f344_5_50
-wget http://$1:9000/trans_buy_f344_4
-wget http://$1:9000/trans_add_f345_1_100
-wget http://$1:9000/trans_buy_f345_0
-wget http://$1:9000/trans_add_f346_2_150
-wget http://$1:9000/trans_buy_f346_1
-wget http://$1:9000/trans_add_f347_3_200
-wget http://$1:9000/trans_buy_f347_2
-wget http://$1:9000/trans_add_f348_4_50
-wget http://$1:9000/trans_buy_f348_3
-wget http://$1:9000/trans_add_f349_5_100
-wget http://$1:9000/trans_buy_f349_4
-wget http://$1:9000/trans_add_f350_1_150
-wget http://$1:9000/trans_buy_f350_0
-wget http://$1:9000/trans_add_f351_2_200
-wget http://$1:9000/trans_buy_f351_1
-wget http://$1:9000/trans_add_f352_3_50
-wget http://$1:9000/trans_buy_f352_2
-wget http://$1:9000/trans_add_f353_4_100
-wget http://$1:9000/trans_buy_f353_3
-wget http://$1:9000/trans_add_f354_5_150
-wget http://$1:9000/trans_buy_f354_4
-wget http://$1:9000/trans_add_f355_1_200
-wget http://$1:9000/trans_buy_f355_0
-wget http://$1:9000/trans_add_f356_2_50
-wget http://$1:9000/trans_buy_f356_1
-wget http://$1:9000/trans_add_f357_3_100
-wget http://$1:9000/trans_buy_f357_2
-wget http://$1:9000/trans_add_f358_4_150
-wget http://$1:9000/trans_buy_f358_3
-wget http://$1:9000/trans_add_f359_5_200
-wget http://$1:9000/trans_buy_f359_4
-wget http://$1:9000/trans_add_f360_1_50
-wget http://$1:9000/trans_buy_f360_0
-wget http://$1:9000/trans_add_f361_2_100
-wget http://$1:9000/trans_buy_f361_1
-wget http://$1:9000/trans_add_f362_3_150
-wget http://$1:9000/trans_buy_f362_2
-wget http://$1:9000/trans_add_f363_4_200
-wget http://$1:9000/trans_buy_f363_3
-wget http://$1:9000/trans_add_f364_5_50
-wget http://$1:9000/trans_buy_f364_4
-wget http://$1:9000/trans_add_f365_1_100
-wget http://$1:9000/trans_buy_f365_0
-wget http://$1:9000/trans_add_f366_2_150
-wget http://$1:9000/trans_buy_f366_1
-wget http://$1:9000/trans_add_f367_3_200
-wget http://$1:9000/trans_buy_f367_2
-wget http://$1:9000/trans_add_f368_4_50
-wget http://$1:9000/trans_buy_f368_3
-wget http://$1:9000/trans_add_f369_5_100
-wget http://$1:9000/trans_buy_f369_4
-wget http://$1:9000/trans_add_f370_1_150
-wget http://$1:9000/trans_buy_f370_0
-wget http://$1:9000/trans_add_f371_2_200
-wget http://$1:9000/trans_buy_f371_1
-wget http://$1:9000/trans_add_f372_3_50
-wget http://$1:9000/trans_buy_f372_2
-wget http://$1:9000/trans_add_f373_4_100
-wget http://$1:9000/trans_buy_f373_3
-wget http://$1:9000/trans_add_f374_5_150
-wget http://$1:9000/trans_buy_f374_4
-wget http://$1:9000/trans_add_f375_1_200
-wget http://$1:9000/trans_buy_f375_0
-wget http://$1:9000/trans_add_f376_2_50
-wget http://$1:9000/trans_buy_f376_1
-wget http://$1:9000/trans_add_f377_3_100
-wget http://$1:9000/trans_buy_f377_2
-wget http://$1:9000/trans_add_f378_4_150
-wget http://$1:9000/trans_buy_f378_3
-wget http://$1:9000/trans_add_f379_5_200
-wget http://$1:9000/trans_buy_f379_4
-wget http://$1:9000/trans_add_f380_1_50
-wget http://$1:9000/trans_buy_f380_0
-wget http://$1:9000/trans_add_f381_2_100
-wget http://$1:9000/trans_buy_f381_1
-wget http://$1:9000/trans_add_f382_3_150
-wget http://$1:9000/trans_buy_f382_2
-wget http://$1:9000/trans_add_f383_4_200
-wget http://$1:9000/trans_buy_f383_3
-wget http://$1:9000/trans_add_f384_5_50
-wget http://$1:9000/trans_buy_f384_4
-wget http://$1:9000/trans_add_f385_1_100
-wget http://$1:9000/trans_buy_f385_0
-wget http://$1:9000/trans_add_f386_2_150
-wget http://$1:9000/trans_buy_f386_1
-wget http://$1:9000/trans_add_f387_3_200
-wget http://$1:9000/trans_buy_f387_2
-wget http://$1:9000/trans_add_f388_4_50
-wget http://$1:9000/trans_buy_f388_3
-wget http://$1:9000/trans_add_f389_5_100
-wget http://$1:9000/trans_buy_f389_4
-wget http://$1:9000/trans_add_f390_1_150
-wget http://$1:9000/trans_buy_f390_0
-wget http://$1:9000/trans_add_f391_2_200
-wget http://$1:9000/trans_buy_f391_1
-wget http://$1:9000/trans_add_f392_3_50
-wget http://$1:9000/trans_buy_f392_2
-wget http://$1:9000/trans_add_f393_4_100
-wget http://$1:9000/trans_buy_f393_3
-wget http://$1:9000/trans_add_f394_5_150
-wget http://$1:9000/trans_buy_f394_4
-wget http://$1:9000/trans_add_f395_1_200
-wget http://$1:9000/trans_buy_f395_0
-wget http://$1:9000/trans_add_f396_2_50
-wget http://$1:9000/trans_buy_f396_1
-wget http://$1:9000/trans_add_f397_3_100
-wget http://$1:9000/trans_buy_f397_2
-wget http://$1:9000/trans_add_f398_4_150
-wget http://$1:9000/trans_buy_f398_3
-wget http://$1:9000/trans_add_f399_5_200
-wget http://$1:9000/trans_buy_f399_4
-wget http://$1:9000/trans_add_f400_1_50
-wget http://$1:9000/trans_buy_f400_0
-wget http://$1:9000/trans_add_f401_2_100
-wget http://$1:9000/trans_buy_f401_1
-wget http://$1:9000/trans_add_f402_3_150
-wget http://$1:9000/trans_buy_f402_2
-wget http://$1:9000/trans_add_f403_4_200
-wget http://$1:9000/trans_buy_f403_3
-wget http://$1:9000/trans_add_f404_5_50
-wget http://$1:9000/trans_buy_f404_4
-wget http://$1:9000/trans_add_f405_1_100
-wget http://$1:9000/trans_buy_f405_0
-wget http://$1:9000/trans_add_f406_2_150
-wget http://$1:9000/trans_buy_f406_1
-wget http://$1:9000/trans_add_f407_3_200
-wget http://$1:9000/trans_buy_f407_2
-wget http://$1:9000/trans_add_f408_4_50
-wget http://$1:9000/trans_buy_f408_3
-wget http://$1:9000/trans_add_f409_5_100
-wget http://$1:9000/trans_buy_f409_4
-wget http://$1:9000/trans_add_f410_1_150
-wget http://$1:9000/trans_buy_f410_0
-wget http://$1:9000/trans_add_f411_2_200
-wget http://$1:9000/trans_buy_f411_1
-wget http://$1:9000/trans_add_f412_3_50
-wget http://$1:9000/trans_buy_f412_2
-wget http://$1:9000/trans_add_f413_4_100
-wget http://$1:9000/trans_buy_f413_3
-wget http://$1:9000/trans_add_f414_5_150
-wget http://$1:9000/trans_buy_f414_4
-wget http://$1:9000/trans_add_f415_1_200
-wget http://$1:9000/trans_buy_f415_0
-wget http://$1:9000/trans_add_f416_2_50
-wget http://$1:9000/trans_buy_f416_1
-wget http://$1:9000/trans_add_f417_3_100
-wget http://$1:9000/trans_buy_f417_2
-wget http://$1:9000/trans_add_f418_4_150
-wget http://$1:9000/trans_buy_f418_3
-wget http://$1:9000/trans_add_f419_5_200
-wget http://$1:9000/trans_buy_f419_4
-wget http://$1:9000/trans_add_f420_1_50
-wget http://$1:9000/trans_buy_f420_0
-wget http://$1:9000/trans_add_f421_2_100
-wget http://$1:9000/trans_buy_f421_1
-wget http://$1:9000/trans_add_f422_3_150
-wget http://$1:9000/trans_buy_f422_2
-wget http://$1:9000/trans_add_f423_4_200
-wget http://$1:9000/trans_buy_f423_3
-wget http://$1:9000/trans_add_f424_5_50
-wget http://$1:9000/trans_buy_f424_4
-wget http://$1:9000/trans_add_f425_1_100
-wget http://$1:9000/trans_buy_f425_0
-wget http://$1:9000/trans_add_f426_2_150
-wget http://$1:9000/trans_buy_f426_1
-wget http://$1:9000/trans_add_f427_3_200
-wget http://$1:9000/trans_buy_f427_2
-wget http://$1:9000/trans_add_f428_4_50
-wget http://$1:9000/trans_buy_f428_3
-wget http://$1:9000/trans_add_f429_5_100
-wget http://$1:9000/trans_buy_f429_4
-wget http://$1:9000/trans_add_f430_1_150
-wget http://$1:9000/trans_buy_f430_0
-wget http://$1:9000/trans_add_f431_2_200
-wget http://$1:9000/trans_buy_f431_1
-wget http://$1:9000/trans_add_f432_3_50
-wget http://$1:9000/trans_buy_f432_2
-wget http://$1:9000/trans_add_f433_4_100
-wget http://$1:9000/trans_buy_f433_3
-wget http://$1:9000/trans_add_f434_5_150
-wget http://$1:9000/trans_buy_f434_4
-wget http://$1:9000/trans_add_f435_1_200
-wget http://$1:9000/trans_buy_f435_0
-wget http://$1:9000/trans_add_f436_2_50
-wget http://$1:9000/trans_buy_f436_1
-wget http://$1:9000/trans_add_f437_3_100
-wget http://$1:9000/trans_buy_f437_2
-wget http://$1:9000/trans_add_f438_4_150
-wget http://$1:9000/trans_buy_f438_3
-wget http://$1:9000/trans_add_f439_5_200
-wget http://$1:9000/trans_buy_f439_4
-wget http://$1:9000/trans_add_f440_1_50
-wget http://$1:9000/trans_buy_f440_0
-wget http://$1:9000/trans_add_f441_2_100
-wget http://$1:9000/trans_buy_f441_1
-wget http://$1:9000/trans_add_f442_3_150
-wget http://$1:9000/trans_buy_f442_2
-wget http://$1:9000/trans_add_f443_4_200
-wget http://$1:9000/trans_buy_f443_3
-wget http://$1:9000/trans_add_f444_5_50
-wget http://$1:9000/trans_buy_f444_4
-wget http://$1:9000/trans_add_f445_1_100
-wget http://$1:9000/trans_buy_f445_0
-wget http://$1:9000/trans_add_f446_2_150
-wget http://$1:9000/trans_buy_f446_1
-wget http://$1:9000/trans_add_f447_3_200
-wget http://$1:9000/trans_buy_f447_2
-wget http://$1:9000/trans_add_f448_4_50
-wget http://$1:9000/trans_buy_f448_3
-wget http://$1:9000/trans_add_f449_5_100
-wget http://$1:9000/trans_buy_f449_4
-wget http://$1:9000/trans_add_f450_1_150
-wget http://$1:9000/trans_buy_f450_0
-wget http://$1:9000/trans_add_f451_2_200
-wget http://$1:9000/trans_buy_f451_1
-wget http://$1:9000/trans_add_f452_3_50
-wget http://$1:9000/trans_buy_f452_2
-wget http://$1:9000/trans_add_f453_4_100
-wget http://$1:9000/trans_buy_f453_3
-wget http://$1:9000/trans_add_f454_5_150
-wget http://$1:9000/trans_buy_f454_4
-wget http://$1:9000/trans_add_f455_1_200
-wget http://$1:9000/trans_buy_f455_0
-wget http://$1:9000/trans_add_f456_2_50
-wget http://$1:9000/trans_buy_f456_1
-wget http://$1:9000/trans_add_f457_3_100
-wget http://$1:9000/trans_buy_f457_2
-wget http://$1:9000/trans_add_f458_4_150
-wget http://$1:9000/trans_buy_f458_3
-wget http://$1:9000/trans_add_f459_5_200
-wget http://$1:9000/trans_buy_f459_4
-wget http://$1:9000/trans_add_f460_1_50
-wget http://$1:9000/trans_buy_f460_0
-wget http://$1:9000/trans_add_f461_2_100
-wget http://$1:9000/trans_buy_f461_1
-wget http://$1:9000/trans_add_f462_3_150
-wget http://$1:9000/trans_buy_f462_2
-wget http://$1:9000/trans_add_f463_4_200
-wget http://$1:9000/trans_buy_f463_3
-wget http://$1:9000/trans_add_f464_5_50
-wget http://$1:9000/trans_buy_f464_4
-wget http://$1:9000/trans_add_f465_1_100
-wget http://$1:9000/trans_buy_f465_0
-wget http://$1:9000/trans_add_f466_2_150
-wget http://$1:9000/trans_buy_f466_1
-wget http://$1:9000/trans_add_f467_3_200
-wget http://$1:9000/trans_buy_f467_2
-wget http://$1:9000/trans_add_f468_4_50
-wget http://$1:9000/trans_buy_f468_3
-wget http://$1:9000/trans_add_f469_5_100
-wget http://$1:9000/trans_buy_f469_4
-wget http://$1:9000/trans_add_f470_1_150
-wget http://$1:9000/trans_buy_f470_0
-wget http://$1:9000/trans_add_f471_2_200
-wget http://$1:9000/trans_buy_f471_1
-wget http://$1:9000/trans_add_f472_3_50
-wget http://$1:9000/trans_buy_f472_2
-wget http://$1:9000/trans_add_f473_4_100
-wget http://$1:9000/trans_buy_f473_3
-wget http://$1:9000/trans_add_f474_5_150
-wget http://$1:9000/trans_buy_f474_4
-wget http://$1:9000/trans_add_f475_1_200
-wget http://$1:9000/trans_buy_f475_0
-wget http://$1:9000/trans_add_f476_2_50
-wget http://$1:9000/trans_buy_f476_1
-wget http://$1:9000/trans_add_f477_3_100
-wget http://$1:9000/trans_buy_f477_2
-wget http://$1:9000/trans_add_f478_4_150
-wget http://$1:9000/trans_buy_f478_3
-wget http://$1:9000/trans_add_f479_5_200
-wget http://$1:9000/trans_buy_f479_4
-wget http://$1:9000/trans_add_f480_1_50
-wget http://$1:9000/trans_buy_f480_0
-wget http://$1:9000/trans_add_f481_2_100
-wget http://$1:9000/trans_buy_f481_1
-wget http://$1:9000/trans_add_f482_3_150
-wget http://$1:9000/trans_buy_f482_2
-wget http://$1:9000/trans_add_f483_4_200
-wget http://$1:9000/trans_buy_f483_3
-wget http://$1:9000/trans_add_f484_5_50
-wget http://$1:9000/trans_buy_f484_4
-wget http://$1:9000/trans_add_f485_1_100
-wget http://$1:9000/trans_buy_f485_0
-wget http://$1:9000/trans_add_f486_2_150
-wget http://$1:9000/trans_buy_f486_1
-wget http://$1:9000/trans_add_f487_3_200
-wget http://$1:9000/trans_buy_f487_2
-wget http://$1:9000/trans_add_f488_4_50
-wget http://$1:9000/trans_buy_f488_3
-wget http://$1:9000/trans_add_f489_5_100
-wget http://$1:9000/trans_buy_f489_4
-wget http://$1:9000/trans_add_f490_1_150
-wget http://$1:9000/trans_buy_f490_0
-wget http://$1:9000/trans_add_f491_2_200
-wget http://$1:9000/trans_buy_f491_1
-wget http://$1:9000/trans_add_f492_3_50
-wget http://$1:9000/trans_buy_f492_2
-wget http://$1:9000/trans_add_f493_4_100
-wget http://$1:9000/trans_buy_f493_3
-wget http://$1:9000/trans_add_f494_5_150
-wget http://$1:9000/trans_buy_f494_4
-wget http://$1:9000/trans_add_f495_1_200
-wget http://$1:9000/trans_buy_f495_0
-wget http://$1:9000/trans_add_f496_2_50
-wget http://$1:9000/trans_buy_f496_1
-wget http://$1:9000/trans_add_f497_3_100
-wget http://$1:9000/trans_buy_f497_2
-wget http://$1:9000/trans_add_f498_4_150
-wget http://$1:9000/trans_buy_f498_3
-wget http://$1:9000/trans_add_f499_5_200
-wget http://$1:9000/trans_buy_f499_4
-wget http://$1:9000/trans_add_f500_1_50
-wget http://$1:9000/trans_buy_f500_0
-wget http://$1:9000/trans_add_f501_2_100
-wget http://$1:9000/trans_buy_f501_1
-wget http://$1:9000/trans_add_f502_3_150
-wget http://$1:9000/trans_buy_f502_2
-wget http://$1:9000/trans_add_f503_4_200
-wget http://$1:9000/trans_buy_f503_3
-wget http://$1:9000/trans_add_f504_5_50
-wget http://$1:9000/trans_buy_f504_4
-wget http://$1:9000/trans_add_f505_1_100
-wget http://$1:9000/trans_buy_f505_0
-wget http://$1:9000/trans_add_f506_2_150
-wget http://$1:9000/trans_buy_f506_1
-wget http://$1:9000/trans_add_f507_3_200
-wget http://$1:9000/trans_buy_f507_2
-wget http://$1:9000/trans_add_f508_4_50
-wget http://$1:9000/trans_buy_f508_3
-wget http://$1:9000/trans_add_f509_5_100
-wget http://$1:9000/trans_buy_f509_4
-wget http://$1:9000/trans_add_f510_1_150
-wget http://$1:9000/trans_buy_f510_0
-wget http://$1:9000/trans_add_f511_2_200
-wget http://$1:9000/trans_buy_f511_1
-wget http://$1:9000/trans_add_f512_3_50
-wget http://$1:9000/trans_buy_f512_2
-wget http://$1:9000/trans_add_f513_4_100
-wget http://$1:9000/trans_buy_f513_3
-wget http://$1:9000/trans_add_f514_5_150
-wget http://$1:9000/trans_buy_f514_4
-wget http://$1:9000/trans_add_f515_1_200
-wget http://$1:9000/trans_buy_f515_0
-wget http://$1:9000/trans_add_f516_2_50
-wget http://$1:9000/trans_buy_f516_1
-wget http://$1:9000/trans_add_f517_3_100
-wget http://$1:9000/trans_buy_f517_2
-wget http://$1:9000/trans_add_f518_4_150
-wget http://$1:9000/trans_buy_f518_3
-wget http://$1:9000/trans_add_f519_5_200
-wget http://$1:9000/trans_buy_f519_4
-wget http://$1:9000/trans_add_f520_1_50
-wget http://$1:9000/trans_buy_f520_0
-wget http://$1:9000/trans_add_f521_2_100
-wget http://$1:9000/trans_buy_f521_1
-wget http://$1:9000/trans_add_f522_3_150
-wget http://$1:9000/trans_buy_f522_2
-wget http://$1:9000/trans_add_f523_4_200
-wget http://$1:9000/trans_buy_f523_3
-wget http://$1:9000/trans_add_f524_5_50
-wget http://$1:9000/trans_buy_f524_4
-wget http://$1:9000/trans_add_f525_1_100
-wget http://$1:9000/trans_buy_f525_0
-wget http://$1:9000/trans_add_f526_2_150
-wget http://$1:9000/trans_buy_f526_1
-wget http://$1:9000/trans_add_f527_3_200
-wget http://$1:9000/trans_buy_f527_2
-wget http://$1:9000/trans_add_f528_4_50
-wget http://$1:9000/trans_buy_f528_3
-wget http://$1:9000/trans_add_f529_5_100
-wget http://$1:9000/trans_buy_f529_4
-wget http://$1:9000/trans_add_f530_1_150
-wget http://$1:9000/trans_buy_f530_0
-wget http://$1:9000/trans_add_f531_2_200
-wget http://$1:9000/trans_buy_f531_1
-wget http://$1:9000/trans_add_f532_3_50
-wget http://$1:9000/trans_buy_f532_2
-wget http://$1:9000/trans_add_f533_4_100
-wget http://$1:9000/trans_buy_f533_3
-wget http://$1:9000/trans_add_f534_5_150
-wget http://$1:9000/trans_buy_f534_4
-wget http://$1:9000/trans_add_f535_1_200
-wget http://$1:9000/trans_buy_f535_0
-wget http://$1:9000/trans_add_f536_2_50
-wget http://$1:9000/trans_buy_f536_1
-wget http://$1:9000/trans_add_f537_3_100
-wget http://$1:9000/trans_buy_f537_2
-wget http://$1:9000/trans_add_f538_4_150
-wget http://$1:9000/trans_buy_f538_3
-wget http://$1:9000/trans_add_f539_5_200
-wget http://$1:9000/trans_buy_f539_4
-wget http://$1:9000/trans_add_f540_1_50
-wget http://$1:9000/trans_buy_f540_0
-wget http://$1:9000/trans_add_f541_2_100
-wget http://$1:9000/trans_buy_f541_1
-wget http://$1:9000/trans_add_f542_3_150
-wget http://$1:9000/trans_buy_f542_2
-wget http://$1:9000/trans_add_f543_4_200
-wget http://$1:9000/trans_buy_f543_3
-wget http://$1:9000/trans_add_f544_5_50
-wget http://$1:9000/trans_buy_f544_4
-wget http://$1:9000/trans_add_f545_1_100
-wget http://$1:9000/trans_buy_f545_0
-wget http://$1:9000/trans_add_f546_2_150
-wget http://$1:9000/trans_buy_f546_1
-wget http://$1:9000/trans_add_f547_3_200
-wget http://$1:9000/trans_buy_f547_2
-wget http://$1:9000/trans_add_f548_4_50
-wget http://$1:9000/trans_buy_f548_3
-wget http://$1:9000/trans_add_f549_5_100
-wget http://$1:9000/trans_buy_f549_4
-wget http://$1:9000/trans_add_f550_1_150
-wget http://$1:9000/trans_buy_f550_0
-wget http://$1:9000/trans_add_f551_2_200
-wget http://$1:9000/trans_buy_f551_1
-wget http://$1:9000/trans_add_f552_3_50
-wget http://$1:9000/trans_buy_f552_2
-wget http://$1:9000/trans_add_f553_4_100
-wget http://$1:9000/trans_buy_f553_3
-wget http://$1:9000/trans_add_f554_5_150
-wget http://$1:9000/trans_buy_f554_4
-wget http://$1:9000/trans_add_f555_1_200
-wget http://$1:9000/trans_buy_f555_0
-wget http://$1:9000/trans_add_f556_2_50
-wget http://$1:9000/trans_buy_f556_1
-wget http://$1:9000/trans_add_f557_3_100
-wget http://$1:9000/trans_buy_f557_2
-wget http://$1:9000/trans_add_f558_4_150
-wget http://$1:9000/trans_buy_f558_3
-wget http://$1:9000/trans_add_f559_5_200
-wget http://$1:9000/trans_buy_f559_4
-wget http://$1:9000/trans_add_f560_1_50
-wget http://$1:9000/trans_buy_f560_0
-wget http://$1:9000/trans_add_f561_2_100
-wget http://$1:9000/trans_buy_f561_1
-wget http://$1:9000/trans_add_f562_3_150
-wget http://$1:9000/trans_buy_f562_2
-wget http://$1:9000/trans_add_f563_4_200
-wget http://$1:9000/trans_buy_f563_3
-wget http://$1:9000/trans_add_f564_5_50
-wget http://$1:9000/trans_buy_f564_4
-wget http://$1:9000/trans_add_f565_1_100
-wget http://$1:9000/trans_buy_f565_0
-wget http://$1:9000/trans_add_f566_2_150
-wget http://$1:9000/trans_buy_f566_1
-wget http://$1:9000/trans_add_f567_3_200
-wget http://$1:9000/trans_buy_f567_2
-wget http://$1:9000/trans_add_f568_4_50
-wget http://$1:9000/trans_buy_f568_3
-wget http://$1:9000/trans_add_f569_5_100
-wget http://$1:9000/trans_buy_f569_4
-wget http://$1:9000/trans_add_f570_1_150
-wget http://$1:9000/trans_buy_f570_0
-wget http://$1:9000/trans_add_f571_2_200
-wget http://$1:9000/trans_buy_f571_1
-wget http://$1:9000/trans_add_f572_3_50
-wget http://$1:9000/trans_buy_f572_2
-wget http://$1:9000/trans_add_f573_4_100
-wget http://$1:9000/trans_buy_f573_3
-wget http://$1:9000/trans_add_f574_5_150
-wget http://$1:9000/trans_buy_f574_4
-wget http://$1:9000/trans_add_f575_1_200
-wget http://$1:9000/trans_buy_f575_0
-wget http://$1:9000/trans_add_f576_2_50
-wget http://$1:9000/trans_buy_f576_1
-wget http://$1:9000/trans_add_f577_3_100
-wget http://$1:9000/trans_buy_f577_2
-wget http://$1:9000/trans_add_f578_4_150
-wget http://$1:9000/trans_buy_f578_3
-wget http://$1:9000/trans_add_f579_5_200
-wget http://$1:9000/trans_buy_f579_4
-wget http://$1:9000/trans_add_f580_1_50
-wget http://$1:9000/trans_buy_f580_0
-wget http://$1:9000/trans_add_f581_2_100
-wget http://$1:9000/trans_buy_f581_1
-wget http://$1:9000/trans_add_f582_3_150
-wget http://$1:9000/trans_buy_f582_2
-wget http://$1:9000/trans_add_f583_4_200
-wget http://$1:9000/trans_buy_f583_3
-wget http://$1:9000/trans_add_f584_5_50
-wget http://$1:9000/trans_buy_f584_4
-wget http://$1:9000/trans_add_f585_1_100
-wget http://$1:9000/trans_buy_f585_0
-wget http://$1:9000/trans_add_f586_2_150
-wget http://$1:9000/trans_buy_f586_1
-wget http://$1:9000/trans_add_f587_3_200
-wget http://$1:9000/trans_buy_f587_2
-wget http://$1:9000/trans_add_f588_4_50
-wget http://$1:9000/trans_buy_f588_3
-wget http://$1:9000/trans_add_f589_5_100
-wget http://$1:9000/trans_buy_f589_4
-wget http://$1:9000/trans_add_f590_1_150
-wget http://$1:9000/trans_buy_f590_0
-wget http://$1:9000/trans_add_f591_2_200
-wget http://$1:9000/trans_buy_f591_1
-wget http://$1:9000/trans_add_f592_3_50
-wget http://$1:9000/trans_buy_f592_2
-wget http://$1:9000/trans_add_f593_4_100
-wget http://$1:9000/trans_buy_f593_3
-wget http://$1:9000/trans_add_f594_5_150
-wget http://$1:9000/trans_buy_f594_4
-wget http://$1:9000/trans_add_f595_1_200
-wget http://$1:9000/trans_buy_f595_0
-wget http://$1:9000/trans_add_f596_2_50
-wget http://$1:9000/trans_buy_f596_1
-wget http://$1:9000/trans_add_f597_3_100
-wget http://$1:9000/trans_buy_f597_2
-wget http://$1:9000/trans_add_f598_4_150
-wget http://$1:9000/trans_buy_f598_3
-wget http://$1:9000/trans_add_f599_5_200
-wget http://$1:9000/trans_buy_f599_4
-wget http://$1:9000/trans_add_f600_1_50
-wget http://$1:9000/trans_buy_f600_0
-wget http://$1:9000/trans_add_f601_2_100
-wget http://$1:9000/trans_buy_f601_1
-wget http://$1:9000/trans_add_f602_3_150
-wget http://$1:9000/trans_buy_f602_2
-wget http://$1:9000/trans_add_f603_4_200
-wget http://$1:9000/trans_buy_f603_3
-wget http://$1:9000/trans_add_f604_5_50
-wget http://$1:9000/trans_buy_f604_4
-wget http://$1:9000/trans_add_f605_1_100
-wget http://$1:9000/trans_buy_f605_0
-wget http://$1:9000/trans_add_f606_2_150
-wget http://$1:9000/trans_buy_f606_1
-wget http://$1:9000/trans_add_f607_3_200
-wget http://$1:9000/trans_buy_f607_2
-wget http://$1:9000/trans_add_f608_4_50
-wget http://$1:9000/trans_buy_f608_3
-wget http://$1:9000/trans_add_f609_5_100
-wget http://$1:9000/trans_buy_f609_4
-wget http://$1:9000/trans_add_f610_1_150
-wget http://$1:9000/trans_buy_f610_0
-wget http://$1:9000/trans_add_f611_2_200
-wget http://$1:9000/trans_buy_f611_1
-wget http://$1:9000/trans_add_f612_3_50
-wget http://$1:9000/trans_buy_f612_2
-wget http://$1:9000/trans_add_f613_4_100
-wget http://$1:9000/trans_buy_f613_3
-wget http://$1:9000/trans_add_f614_5_150
-wget http://$1:9000/trans_buy_f614_4
-wget http://$1:9000/trans_add_f615_1_200
-wget http://$1:9000/trans_buy_f615_0
-wget http://$1:9000/trans_add_f616_2_50
-wget http://$1:9000/trans_buy_f616_1
-wget http://$1:9000/trans_add_f617_3_100
-wget http://$1:9000/trans_buy_f617_2
-wget http://$1:9000/trans_add_f618_4_150
-wget http://$1:9000/trans_buy_f618_3
-wget http://$1:9000/trans_add_f619_5_200
-wget http://$1:9000/trans_buy_f619_4
-wget http://$1:9000/trans_add_f620_1_50
-wget http://$1:9000/trans_buy_f620_0
-wget http://$1:9000/trans_add_f621_2_100
-wget http://$1:9000/trans_buy_f621_1
-wget http://$1:9000/trans_add_f622_3_150
-wget http://$1:9000/trans_buy_f622_2
-wget http://$1:9000/trans_add_f623_4_200
-wget http://$1:9000/trans_buy_f623_3
-wget http://$1:9000/trans_add_f624_5_50
-wget http://$1:9000/trans_buy_f624_4
-wget http://$1:9000/trans_add_f625_1_100
-wget http://$1:9000/trans_buy_f625_0
-wget http://$1:9000/trans_add_f626_2_150
-wget http://$1:9000/trans_buy_f626_1
-wget http://$1:9000/trans_add_f627_3_200
-wget http://$1:9000/trans_buy_f627_2
-wget http://$1:9000/trans_add_f628_4_50
-wget http://$1:9000/trans_buy_f628_3
-wget http://$1:9000/trans_add_f629_5_100
-wget http://$1:9000/trans_buy_f629_4
-wget http://$1:9000/trans_add_f630_1_150
-wget http://$1:9000/trans_buy_f630_0
-wget http://$1:9000/trans_add_f631_2_200
-wget http://$1:9000/trans_buy_f631_1
-wget http://$1:9000/trans_add_f632_3_50
-wget http://$1:9000/trans_buy_f632_2
-wget http://$1:9000/trans_add_f633_4_100
-wget http://$1:9000/trans_buy_f633_3
-wget http://$1:9000/trans_add_f634_5_150
-wget http://$1:9000/trans_buy_f634_4
-wget http://$1:9000/trans_add_f635_1_200
-wget http://$1:9000/trans_buy_f635_0
-wget http://$1:9000/trans_add_f636_2_50
-wget http://$1:9000/trans_buy_f636_1
-wget http://$1:9000/trans_add_f637_3_100
-wget http://$1:9000/trans_buy_f637_2
-wget http://$1:9000/trans_add_f638_4_150
-wget http://$1:9000/trans_buy_f638_3
-wget http://$1:9000/trans_add_f639_5_200
-wget http://$1:9000/trans_buy_f639_4
-wget http://$1:9000/trans_add_f640_1_50
-wget http://$1:9000/trans_buy_f640_0
-wget http://$1:9000/trans_add_f641_2_100
-wget http://$1:9000/trans_buy_f641_1
-wget http://$1:9000/trans_add_f642_3_150
-wget http://$1:9000/trans_buy_f642_2
-wget http://$1:9000/trans_add_f643_4_200
-wget http://$1:9000/trans_buy_f643_3
-wget http://$1:9000/trans_add_f644_5_50
-wget http://$1:9000/trans_buy_f644_4
-wget http://$1:9000/trans_add_f645_1_100
-wget http://$1:9000/trans_buy_f645_0
-wget http://$1:9000/trans_add_f646_2_150
-wget http://$1:9000/trans_buy_f646_1
-wget http://$1:9000/trans_add_f647_3_200
-wget http://$1:9000/trans_buy_f647_2
-wget http://$1:9000/trans_add_f648_4_50
-wget http://$1:9000/trans_buy_f648_3
-wget http://$1:9000/trans_add_f649_5_100
-wget http://$1:9000/trans_buy_f649_4
-wget http://$1:9000/trans_add_f650_1_150
-wget http://$1:9000/trans_buy_f650_0
-wget http://$1:9000/trans_add_f651_2_200
-wget http://$1:9000/trans_buy_f651_1
-wget http://$1:9000/trans_add_f652_3_50
-wget http://$1:9000/trans_buy_f652_2
-wget http://$1:9000/trans_add_f653_4_100
-wget http://$1:9000/trans_buy_f653_3
-wget http://$1:9000/trans_add_f654_5_150
-wget http://$1:9000/trans_buy_f654_4
-wget http://$1:9000/trans_add_f655_1_200
-wget http://$1:9000/trans_buy_f655_0
-wget http://$1:9000/trans_add_f656_2_50
-wget http://$1:9000/trans_buy_f656_1
-wget http://$1:9000/trans_add_f657_3_100
-wget http://$1:9000/trans_buy_f657_2
-wget http://$1:9000/trans_add_f658_4_150
-wget http://$1:9000/trans_buy_f658_3
-wget http://$1:9000/trans_add_f659_5_200
-wget http://$1:9000/trans_buy_f659_4
-wget http://$1:9000/trans_add_f660_1_50
-wget http://$1:9000/trans_buy_f660_0
-wget http://$1:9000/trans_add_f661_2_100
-wget http://$1:9000/trans_buy_f661_1
-wget http://$1:9000/trans_add_f662_3_150
-wget http://$1:9000/trans_buy_f662_2
-wget http://$1:9000/trans_add_f663_4_200
-wget http://$1:9000/trans_buy_f663_3
-wget http://$1:9000/trans_add_f664_5_50
-wget http://$1:9000/trans_buy_f664_4
-wget http://$1:9000/trans_add_f665_1_100
-wget http://$1:9000/trans_buy_f665_0
-wget http://$1:9000/trans_add_f666_2_150
-wget http://$1:9000/trans_buy_f666_1
-wget http://$1:9000/trans_add_f667_3_200
-wget http://$1:9000/trans_buy_f667_2
-wget http://$1:9000/trans_add_f668_4_50
-wget http://$1:9000/trans_buy_f668_3
-wget http://$1:9000/trans_add_f669_5_100
-wget http://$1:9000/trans_buy_f669_4
-wget http://$1:9000/trans_add_f670_1_150
-wget http://$1:9000/trans_buy_f670_0
-wget http://$1:9000/trans_add_f671_2_200
-wget http://$1:9000/trans_buy_f671_1
-wget http://$1:9000/trans_add_f672_3_50
-wget http://$1:9000/trans_buy_f672_2
-wget http://$1:9000/trans_add_f673_4_100
-wget http://$1:9000/trans_buy_f673_3
-wget http://$1:9000/trans_add_f674_5_150
-wget http://$1:9000/trans_buy_f674_4
-wget http://$1:9000/trans_add_f675_1_200
-wget http://$1:9000/trans_buy_f675_0
-wget http://$1:9000/trans_add_f676_2_50
-wget http://$1:9000/trans_buy_f676_1
-wget http://$1:9000/trans_add_f677_3_100
-wget http://$1:9000/trans_buy_f677_2
-wget http://$1:9000/trans_add_f678_4_150
-wget http://$1:9000/trans_buy_f678_3
-wget http://$1:9000/trans_add_f679_5_200
-wget http://$1:9000/trans_buy_f679_4
-wget http://$1:9000/trans_add_f680_1_50
-wget http://$1:9000/trans_buy_f680_0
-wget http://$1:9000/trans_add_f681_2_100
-wget http://$1:9000/trans_buy_f681_1
-wget http://$1:9000/trans_add_f682_3_150
-wget http://$1:9000/trans_buy_f682_2
-wget http://$1:9000/trans_add_f683_4_200
-wget http://$1:9000/trans_buy_f683_3
-wget http://$1:9000/trans_add_f684_5_50
-wget http://$1:9000/trans_buy_f684_4
-wget http://$1:9000/trans_add_f685_1_100
-wget http://$1:9000/trans_buy_f685_0
-wget http://$1:9000/trans_add_f686_2_150
-wget http://$1:9000/trans_buy_f686_1
-wget http://$1:9000/trans_add_f687_3_200
-wget http://$1:9000/trans_buy_f687_2
-wget http://$1:9000/trans_add_f688_4_50
-wget http://$1:9000/trans_buy_f688_3
-wget http://$1:9000/trans_add_f689_5_100
-wget http://$1:9000/trans_buy_f689_4
-wget http://$1:9000/trans_add_f690_1_150
-wget http://$1:9000/trans_buy_f690_0
-wget http://$1:9000/trans_add_f691_2_200
-wget http://$1:9000/trans_buy_f691_1
-wget http://$1:9000/trans_add_f692_3_50
-wget http://$1:9000/trans_buy_f692_2
-wget http://$1:9000/trans_add_f693_4_100
-wget http://$1:9000/trans_buy_f693_3
-wget http://$1:9000/trans_add_f694_5_150
-wget http://$1:9000/trans_buy_f694_4
-wget http://$1:9000/trans_add_f695_1_200
-wget http://$1:9000/trans_buy_f695_0
-wget http://$1:9000/trans_add_f696_2_50
-wget http://$1:9000/trans_buy_f696_1
-wget http://$1:9000/trans_add_f697_3_100
-wget http://$1:9000/trans_buy_f697_2
-wget http://$1:9000/trans_add_f698_4_150
-wget http://$1:9000/trans_buy_f698_3
-wget http://$1:9000/trans_add_f699_5_200
-wget http://$1:9000/trans_buy_f699_4
-wget http://$1:9000/trans_add_f700_1_50
-wget http://$1:9000/trans_buy_f700_0
-wget http://$1:9000/trans_add_f701_2_100
-wget http://$1:9000/trans_buy_f701_1
-wget http://$1:9000/trans_add_f702_3_150
-wget http://$1:9000/trans_buy_f702_2
-wget http://$1:9000/trans_add_f703_4_200
-wget http://$1:9000/trans_buy_f703_3
-wget http://$1:9000/trans_add_f704_5_50
-wget http://$1:9000/trans_buy_f704_4
-wget http://$1:9000/trans_add_f705_1_100
-wget http://$1:9000/trans_buy_f705_0
-wget http://$1:9000/trans_add_f706_2_150
-wget http://$1:9000/trans_buy_f706_1
-wget http://$1:9000/trans_add_f707_3_200
-wget http://$1:9000/trans_buy_f707_2
-wget http://$1:9000/trans_add_f708_4_50
-wget http://$1:9000/trans_buy_f708_3
-wget http://$1:9000/trans_add_f709_5_100
-wget http://$1:9000/trans_buy_f709_4
-wget http://$1:9000/trans_add_f710_1_150
-wget http://$1:9000/trans_buy_f710_0
-wget http://$1:9000/trans_add_f711_2_200
-wget http://$1:9000/trans_buy_f711_1
-wget http://$1:9000/trans_add_f712_3_50
-wget http://$1:9000/trans_buy_f712_2
-wget http://$1:9000/trans_add_f713_4_100
-wget http://$1:9000/trans_buy_f713_3
-wget http://$1:9000/trans_add_f714_5_150
-wget http://$1:9000/trans_buy_f714_4
-wget http://$1:9000/trans_add_f715_1_200
-wget http://$1:9000/trans_buy_f715_0
-wget http://$1:9000/trans_add_f716_2_50
-wget http://$1:9000/trans_buy_f716_1
-wget http://$1:9000/trans_add_f717_3_100
-wget http://$1:9000/trans_buy_f717_2
-wget http://$1:9000/trans_add_f718_4_150
-wget http://$1:9000/trans_buy_f718_3
-wget http://$1:9000/trans_add_f719_5_200
-wget http://$1:9000/trans_buy_f719_4
-wget http://$1:9000/trans_add_f720_1_50
-wget http://$1:9000/trans_buy_f720_0
-wget http://$1:9000/trans_add_f721_2_100
-wget http://$1:9000/trans_buy_f721_1
-wget http://$1:9000/trans_add_f722_3_150
-wget http://$1:9000/trans_buy_f722_2
-wget http://$1:9000/trans_add_f723_4_200
-wget http://$1:9000/trans_buy_f723_3
-wget http://$1:9000/trans_add_f724_5_50
-wget http://$1:9000/trans_buy_f724_4
-wget http://$1:9000/trans_add_f725_1_100
-wget http://$1:9000/trans_buy_f725_0
-wget http://$1:9000/trans_add_f726_2_150
-wget http://$1:9000/trans_buy_f726_1
-wget http://$1:9000/trans_add_f727_3_200
-wget http://$1:9000/trans_buy_f727_2
-wget http://$1:9000/trans_add_f728_4_50
-wget http://$1:9000/trans_buy_f728_3
-wget http://$1:9000/trans_add_f729_5_100
-wget http://$1:9000/trans_buy_f729_4
-wget http://$1:9000/trans_add_f730_1_150
-wget http://$1:9000/trans_buy_f730_0
-wget http://$1:9000/trans_add_f731_2_200
-wget http://$1:9000/trans_buy_f731_1
-wget http://$1:9000/trans_add_f732_3_50
-wget http://$1:9000/trans_buy_f732_2
-wget http://$1:9000/trans_add_f733_4_100
-wget http://$1:9000/trans_buy_f733_3
-wget http://$1:9000/trans_add_f734_5_150
-wget http://$1:9000/trans_buy_f734_4
-wget http://$1:9000/trans_add_f735_1_200
-wget http://$1:9000/trans_buy_f735_0
-wget http://$1:9000/trans_add_f736_2_50
-wget http://$1:9000/trans_buy_f736_1
-wget http://$1:9000/trans_add_f737_3_100
-wget http://$1:9000/trans_buy_f737_2
-wget http://$1:9000/trans_add_f738_4_150
-wget http://$1:9000/trans_buy_f738_3
-wget http://$1:9000/trans_add_f739_5_200
-wget http://$1:9000/trans_buy_f739_4
-wget http://$1:9000/trans_add_f740_1_50
-wget http://$1:9000/trans_buy_f740_0
-wget http://$1:9000/trans_add_f741_2_100
-wget http://$1:9000/trans_buy_f741_1
-wget http://$1:9000/trans_add_f742_3_150
-wget http://$1:9000/trans_buy_f742_2
-wget http://$1:9000/trans_add_f743_4_200
-wget http://$1:9000/trans_buy_f743_3
-wget http://$1:9000/trans_add_f744_5_50
-wget http://$1:9000/trans_buy_f744_4
-wget http://$1:9000/trans_add_f745_1_100
-wget http://$1:9000/trans_buy_f745_0
-wget http://$1:9000/trans_add_f746_2_150
-wget http://$1:9000/trans_buy_f746_1
-wget http://$1:9000/trans_add_f747_3_200
-wget http://$1:9000/trans_buy_f747_2
-wget http://$1:9000/trans_add_f748_4_50
-wget http://$1:9000/trans_buy_f748_3
-wget http://$1:9000/trans_add_f749_5_100
-wget http://$1:9000/trans_buy_f749_4
-wget http://$1:9000/trans_add_f750_1_150
-wget http://$1:9000/trans_buy_f750_0
-wget http://$1:9000/trans_add_f751_2_200
-wget http://$1:9000/trans_buy_f751_1
-wget http://$1:9000/trans_add_f752_3_50
-wget http://$1:9000/trans_buy_f752_2
-wget http://$1:9000/trans_add_f753_4_100
-wget http://$1:9000/trans_buy_f753_3
-wget http://$1:9000/trans_add_f754_5_150
-wget http://$1:9000/trans_buy_f754_4
-wget http://$1:9000/trans_add_f755_1_200
-wget http://$1:9000/trans_buy_f755_0
-wget http://$1:9000/trans_add_f756_2_50
-wget http://$1:9000/trans_buy_f756_1
-wget http://$1:9000/trans_add_f757_3_100
-wget http://$1:9000/trans_buy_f757_2
-wget http://$1:9000/trans_add_f758_4_150
-wget http://$1:9000/trans_buy_f758_3
-wget http://$1:9000/trans_add_f759_5_200
-wget http://$1:9000/trans_buy_f759_4
-wget http://$1:9000/trans_add_f760_1_50
-wget http://$1:9000/trans_buy_f760_0
-wget http://$1:9000/trans_add_f761_2_100
-wget http://$1:9000/trans_buy_f761_1
-wget http://$1:9000/trans_add_f762_3_150
-wget http://$1:9000/trans_buy_f762_2
-wget http://$1:9000/trans_add_f763_4_200
-wget http://$1:9000/trans_buy_f763_3
-wget http://$1:9000/trans_add_f764_5_50
-wget http://$1:9000/trans_buy_f764_4
-wget http://$1:9000/trans_add_f765_1_100
-wget http://$1:9000/trans_buy_f765_0
-wget http://$1:9000/trans_add_f766_2_150
-wget http://$1:9000/trans_buy_f766_1
-wget http://$1:9000/trans_add_f767_3_200
-wget http://$1:9000/trans_buy_f767_2
-wget http://$1:9000/trans_add_f768_4_50
-wget http://$1:9000/trans_buy_f768_3
-wget http://$1:9000/trans_add_f769_5_100
-wget http://$1:9000/trans_buy_f769_4
-wget http://$1:9000/trans_add_f770_1_150
-wget http://$1:9000/trans_buy_f770_0
-wget http://$1:9000/trans_add_f771_2_200
-wget http://$1:9000/trans_buy_f771_1
-wget http://$1:9000/trans_add_f772_3_50
-wget http://$1:9000/trans_buy_f772_2
-wget http://$1:9000/trans_add_f773_4_100
-wget http://$1:9000/trans_buy_f773_3
-wget http://$1:9000/trans_add_f774_5_150
-wget http://$1:9000/trans_buy_f774_4
-wget http://$1:9000/trans_add_f775_1_200
-wget http://$1:9000/trans_buy_f775_0
-wget http://$1:9000/trans_add_f776_2_50
-wget http://$1:9000/trans_buy_f776_1
-wget http://$1:9000/trans_add_f777_3_100
-wget http://$1:9000/trans_buy_f777_2
-wget http://$1:9000/trans_add_f778_4_150
-wget http://$1:9000/trans_buy_f778_3
-wget http://$1:9000/trans_add_f779_5_200
-wget http://$1:9000/trans_buy_f779_4
-wget http://$1:9000/trans_add_f780_1_50
-wget http://$1:9000/trans_buy_f780_0
-wget http://$1:9000/trans_add_f781_2_100
-wget http://$1:9000/trans_buy_f781_1
-wget http://$1:9000/trans_add_f782_3_150
-wget http://$1:9000/trans_buy_f782_2
-wget http://$1:9000/trans_add_f783_4_200
-wget http://$1:9000/trans_buy_f783_3
-wget http://$1:9000/trans_add_f784_5_50
-wget http://$1:9000/trans_buy_f784_4
-wget http://$1:9000/trans_add_f785_1_100
-wget http://$1:9000/trans_buy_f785_0
-wget http://$1:9000/trans_add_f786_2_150
-wget http://$1:9000/trans_buy_f786_1
-wget http://$1:9000/trans_add_f787_3_200
-wget http://$1:9000/trans_buy_f787_2
-wget http://$1:9000/trans_add_f788_4_50
-wget http://$1:9000/trans_buy_f788_3
-wget http://$1:9000/trans_add_f789_5_100
-wget http://$1:9000/trans_buy_f789_4
-wget http://$1:9000/trans_add_f790_1_150
-wget http://$1:9000/trans_buy_f790_0
-wget http://$1:9000/trans_add_f791_2_200
-wget http://$1:9000/trans_buy_f791_1
-wget http://$1:9000/trans_add_f792_3_50
-wget http://$1:9000/trans_buy_f792_2
-wget http://$1:9000/trans_add_f793_4_100
-wget http://$1:9000/trans_buy_f793_3
-wget http://$1:9000/trans_add_f794_5_150
-wget http://$1:9000/trans_buy_f794_4
-wget http://$1:9000/trans_add_f795_1_200
-wget http://$1:9000/trans_buy_f795_0
-wget http://$1:9000/trans_add_f796_2_50
-wget http://$1:9000/trans_buy_f796_1
-wget http://$1:9000/trans_add_f797_3_100
-wget http://$1:9000/trans_buy_f797_2
-wget http://$1:9000/trans_add_f798_4_150
-wget http://$1:9000/trans_buy_f798_3
-wget http://$1:9000/trans_add_f799_5_200
-wget http://$1:9000/trans_buy_f799_4
-wget http://$1:9000/trans_add_f800_1_50
-wget http://$1:9000/trans_buy_f800_0
-wget http://$1:9000/trans_add_f801_2_100
-wget http://$1:9000/trans_buy_f801_1
-wget http://$1:9000/trans_add_f802_3_150
-wget http://$1:9000/trans_buy_f802_2
-wget http://$1:9000/trans_add_f803_4_200
-wget http://$1:9000/trans_buy_f803_3
-wget http://$1:9000/trans_add_f804_5_50
-wget http://$1:9000/trans_buy_f804_4
-wget http://$1:9000/trans_add_f805_1_100
-wget http://$1:9000/trans_buy_f805_0
-wget http://$1:9000/trans_add_f806_2_150
-wget http://$1:9000/trans_buy_f806_1
-wget http://$1:9000/trans_add_f807_3_200
-wget http://$1:9000/trans_buy_f807_2
-wget http://$1:9000/trans_add_f808_4_50
-wget http://$1:9000/trans_buy_f808_3
-wget http://$1:9000/trans_add_f809_5_100
-wget http://$1:9000/trans_buy_f809_4
-wget http://$1:9000/trans_add_f810_1_150
-wget http://$1:9000/trans_buy_f810_0
-wget http://$1:9000/trans_add_f811_2_200
-wget http://$1:9000/trans_buy_f811_1
-wget http://$1:9000/trans_add_f812_3_50
-wget http://$1:9000/trans_buy_f812_2
-wget http://$1:9000/trans_add_f813_4_100
-wget http://$1:9000/trans_buy_f813_3
-wget http://$1:9000/trans_add_f814_5_150
-wget http://$1:9000/trans_buy_f814_4
-wget http://$1:9000/trans_add_f815_1_200
-wget http://$1:9000/trans_buy_f815_0
-wget http://$1:9000/trans_add_f816_2_50
-wget http://$1:9000/trans_buy_f816_1
-wget http://$1:9000/trans_add_f817_3_100
-wget http://$1:9000/trans_buy_f817_2
-wget http://$1:9000/trans_add_f818_4_150
-wget http://$1:9000/trans_buy_f818_3
-wget http://$1:9000/trans_add_f819_5_200
-wget http://$1:9000/trans_buy_f819_4
-wget http://$1:9000/trans_add_f820_1_50
-wget http://$1:9000/trans_buy_f820_0
-wget http://$1:9000/trans_add_f821_2_100
-wget http://$1:9000/trans_buy_f821_1
-wget http://$1:9000/trans_add_f822_3_150
-wget http://$1:9000/trans_buy_f822_2
-wget http://$1:9000/trans_add_f823_4_200
-wget http://$1:9000/trans_buy_f823_3
-wget http://$1:9000/trans_add_f824_5_50
-wget http://$1:9000/trans_buy_f824_4
-wget http://$1:9000/trans_add_f825_1_100
-wget http://$1:9000/trans_buy_f825_0
-wget http://$1:9000/trans_add_f826_2_150
-wget http://$1:9000/trans_buy_f826_1
-wget http://$1:9000/trans_add_f827_3_200
-wget http://$1:9000/trans_buy_f827_2
-wget http://$1:9000/trans_add_f828_4_50
-wget http://$1:9000/trans_buy_f828_3
-wget http://$1:9000/trans_add_f829_5_100
-wget http://$1:9000/trans_buy_f829_4
-wget http://$1:9000/trans_add_f830_1_150
-wget http://$1:9000/trans_buy_f830_0
-wget http://$1:9000/trans_add_f831_2_200
-wget http://$1:9000/trans_buy_f831_1
-wget http://$1:9000/trans_add_f832_3_50
-wget http://$1:9000/trans_buy_f832_2
-wget http://$1:9000/trans_add_f833_4_100
-wget http://$1:9000/trans_buy_f833_3
-wget http://$1:9000/trans_add_f834_5_150
-wget http://$1:9000/trans_buy_f834_4
-wget http://$1:9000/trans_add_f835_1_200
-wget http://$1:9000/trans_buy_f835_0
-wget http://$1:9000/trans_add_f836_2_50
-wget http://$1:9000/trans_buy_f836_1
-wget http://$1:9000/trans_add_f837_3_100
-wget http://$1:9000/trans_buy_f837_2
-wget http://$1:9000/trans_add_f838_4_150
-wget http://$1:9000/trans_buy_f838_3
-wget http://$1:9000/trans_add_f839_5_200
-wget http://$1:9000/trans_buy_f839_4
-wget http://$1:9000/trans_add_f840_1_50
-wget http://$1:9000/trans_buy_f840_0
-wget http://$1:9000/trans_add_f841_2_100
-wget http://$1:9000/trans_buy_f841_1
-wget http://$1:9000/trans_add_f842_3_150
-wget http://$1:9000/trans_buy_f842_2
-wget http://$1:9000/trans_add_f843_4_200
-wget http://$1:9000/trans_buy_f843_3
-wget http://$1:9000/trans_add_f844_5_50
-wget http://$1:9000/trans_buy_f844_4
-wget http://$1:9000/trans_add_f845_1_100
-wget http://$1:9000/trans_buy_f845_0
-wget http://$1:9000/trans_add_f846_2_150
-wget http://$1:9000/trans_buy_f846_1
-wget http://$1:9000/trans_add_f847_3_200
-wget http://$1:9000/trans_buy_f847_2
-wget http://$1:9000/trans_add_f848_4_50
-wget http://$1:9000/trans_buy_f848_3
-wget http://$1:9000/trans_add_f849_5_100
-wget http://$1:9000/trans_buy_f849_4
-wget http://$1:9000/trans_add_f850_1_150
-wget http://$1:9000/trans_buy_f850_0
-wget http://$1:9000/trans_add_f851_2_200
-wget http://$1:9000/trans_buy_f851_1
-wget http://$1:9000/trans_add_f852_3_50
-wget http://$1:9000/trans_buy_f852_2
-wget http://$1:9000/trans_add_f853_4_100
-wget http://$1:9000/trans_buy_f853_3
-wget http://$1:9000/trans_add_f854_5_150
-wget http://$1:9000/trans_buy_f854_4
-wget http://$1:9000/trans_add_f855_1_200
-wget http://$1:9000/trans_buy_f855_0
-wget http://$1:9000/trans_add_f856_2_50
-wget http://$1:9000/trans_buy_f856_1
-wget http://$1:9000/trans_add_f857_3_100
-wget http://$1:9000/trans_buy_f857_2
-wget http://$1:9000/trans_add_f858_4_150
-wget http://$1:9000/trans_buy_f858_3
-wget http://$1:9000/trans_add_f859_5_200
-wget http://$1:9000/trans_buy_f859_4
-wget http://$1:9000/trans_add_f860_1_50
-wget http://$1:9000/trans_buy_f860_0
-wget http://$1:9000/trans_add_f861_2_100
-wget http://$1:9000/trans_buy_f861_1
-wget http://$1:9000/trans_add_f862_3_150
-wget http://$1:9000/trans_buy_f862_2
-wget http://$1:9000/trans_add_f863_4_200
-wget http://$1:9000/trans_buy_f863_3
-wget http://$1:9000/trans_add_f864_5_50
-wget http://$1:9000/trans_buy_f864_4
-wget http://$1:9000/trans_add_f865_1_100
-wget http://$1:9000/trans_buy_f865_0
-wget http://$1:9000/trans_add_f866_2_150
-wget http://$1:9000/trans_buy_f866_1
-wget http://$1:9000/trans_add_f867_3_200
-wget http://$1:9000/trans_buy_f867_2
-wget http://$1:9000/trans_add_f868_4_50
-wget http://$1:9000/trans_buy_f868_3
-wget http://$1:9000/trans_add_f869_5_100
-wget http://$1:9000/trans_buy_f869_4
-wget http://$1:9000/trans_add_f870_1_150
-wget http://$1:9000/trans_buy_f870_0
-wget http://$1:9000/trans_add_f871_2_200
-wget http://$1:9000/trans_buy_f871_1
-wget http://$1:9000/trans_add_f872_3_50
-wget http://$1:9000/trans_buy_f872_2
-wget http://$1:9000/trans_add_f873_4_100
-wget http://$1:9000/trans_buy_f873_3
-wget http://$1:9000/trans_add_f874_5_150
-wget http://$1:9000/trans_buy_f874_4
-wget http://$1:9000/trans_add_f875_1_200
-wget http://$1:9000/trans_buy_f875_0
-wget http://$1:9000/trans_add_f876_2_50
-wget http://$1:9000/trans_buy_f876_1
-wget http://$1:9000/trans_add_f877_3_100
-wget http://$1:9000/trans_buy_f877_2
-wget http://$1:9000/trans_add_f878_4_150
-wget http://$1:9000/trans_buy_f878_3
-wget http://$1:9000/trans_add_f879_5_200
-wget http://$1:9000/trans_buy_f879_4
-wget http://$1:9000/trans_add_f880_1_50
-wget http://$1:9000/trans_buy_f880_0
-wget http://$1:9000/trans_add_f881_2_100
-wget http://$1:9000/trans_buy_f881_1
-wget http://$1:9000/trans_add_f882_3_150
-wget http://$1:9000/trans_buy_f882_2
-wget http://$1:9000/trans_add_f883_4_200
-wget http://$1:9000/trans_buy_f883_3
-wget http://$1:9000/trans_add_f884_5_50
-wget http://$1:9000/trans_buy_f884_4
-wget http://$1:9000/trans_add_f885_1_100
-wget http://$1:9000/trans_buy_f885_0
-wget http://$1:9000/trans_add_f886_2_150
-wget http://$1:9000/trans_buy_f886_1
-wget http://$1:9000/trans_add_f887_3_200
-wget http://$1:9000/trans_buy_f887_2
-wget http://$1:9000/trans_add_f888_4_50
-wget http://$1:9000/trans_buy_f888_3
-wget http://$1:9000/trans_add_f889_5_100
-wget http://$1:9000/trans_buy_f889_4
-wget http://$1:9000/trans_add_f890_1_150
-wget http://$1:9000/trans_buy_f890_0
-wget http://$1:9000/trans_add_f891_2_200
-wget http://$1:9000/trans_buy_f891_1
-wget http://$1:9000/trans_add_f892_3_50
-wget http://$1:9000/trans_buy_f892_2
-wget http://$1:9000/trans_add_f893_4_100
-wget http://$1:9000/trans_buy_f893_3
-wget http://$1:9000/trans_add_f894_5_150
-wget http://$1:9000/trans_buy_f894_4
-wget http://$1:9000/trans_add_f895_1_200
-wget http://$1:9000/trans_buy_f895_0
-wget http://$1:9000/trans_add_f896_2_50
-wget http://$1:9000/trans_buy_f896_1
-wget http://$1:9000/trans_add_f897_3_100
-wget http://$1:9000/trans_buy_f897_2
-wget http://$1:9000/trans_add_f898_4_150
-wget http://$1:9000/trans_buy_f898_3
-wget http://$1:9000/trans_add_f899_5_200
-wget http://$1:9000/trans_buy_f899_4
-wget http://$1:9000/trans_add_f900_1_50
-wget http://$1:9000/trans_buy_f900_0
-wget http://$1:9000/trans_add_f901_2_100
-wget http://$1:9000/trans_buy_f901_1
-wget http://$1:9000/trans_add_f902_3_150
-wget http://$1:9000/trans_buy_f902_2
-wget http://$1:9000/trans_add_f903_4_200
-wget http://$1:9000/trans_buy_f903_3
-wget http://$1:9000/trans_add_f904_5_50
-wget http://$1:9000/trans_buy_f904_4
-wget http://$1:9000/trans_add_f905_1_100
-wget http://$1:9000/trans_buy_f905_0
-wget http://$1:9000/trans_add_f906_2_150
-wget http://$1:9000/trans_buy_f906_1
-wget http://$1:9000/trans_add_f907_3_200
-wget http://$1:9000/trans_buy_f907_2
-wget http://$1:9000/trans_add_f908_4_50
-wget http://$1:9000/trans_buy_f908_3
-wget http://$1:9000/trans_add_f909_5_100
-wget http://$1:9000/trans_buy_f909_4
-wget http://$1:9000/trans_add_f910_1_150
-wget http://$1:9000/trans_buy_f910_0
-wget http://$1:9000/trans_add_f911_2_200
-wget http://$1:9000/trans_buy_f911_1
-wget http://$1:9000/trans_add_f912_3_50
-wget http://$1:9000/trans_buy_f912_2
-wget http://$1:9000/trans_add_f913_4_100
-wget http://$1:9000/trans_buy_f913_3
-wget http://$1:9000/trans_add_f914_5_150
-wget http://$1:9000/trans_buy_f914_4
-wget http://$1:9000/trans_add_f915_1_200
-wget http://$1:9000/trans_buy_f915_0
-wget http://$1:9000/trans_add_f916_2_50
-wget http://$1:9000/trans_buy_f916_1
-wget http://$1:9000/trans_add_f917_3_100
-wget http://$1:9000/trans_buy_f917_2
-wget http://$1:9000/trans_add_f918_4_150
-wget http://$1:9000/trans_buy_f918_3
-wget http://$1:9000/trans_add_f919_5_200
-wget http://$1:9000/trans_buy_f919_4
-wget http://$1:9000/trans_add_f920_1_50
-wget http://$1:9000/trans_buy_f920_0
-wget http://$1:9000/trans_add_f921_2_100
-wget http://$1:9000/trans_buy_f921_1
-wget http://$1:9000/trans_add_f922_3_150
-wget http://$1:9000/trans_buy_f922_2
-wget http://$1:9000/trans_add_f923_4_200
-wget http://$1:9000/trans_buy_f923_3
-wget http://$1:9000/trans_add_f924_5_50
-wget http://$1:9000/trans_buy_f924_4
-wget http://$1:9000/trans_add_f925_1_100
-wget http://$1:9000/trans_buy_f925_0
-wget http://$1:9000/trans_add_f926_2_150
-wget http://$1:9000/trans_buy_f926_1
-wget http://$1:9000/trans_add_f927_3_200
-wget http://$1:9000/trans_buy_f927_2
-wget http://$1:9000/trans_add_f928_4_50
-wget http://$1:9000/trans_buy_f928_3
-wget http://$1:9000/trans_add_f929_5_100
-wget http://$1:9000/trans_buy_f929_4
-wget http://$1:9000/trans_add_f930_1_150
-wget http://$1:9000/trans_buy_f930_0
-wget http://$1:9000/trans_add_f931_2_200
-wget http://$1:9000/trans_buy_f931_1
-wget http://$1:9000/trans_add_f932_3_50
-wget http://$1:9000/trans_buy_f932_2
-wget http://$1:9000/trans_add_f933_4_100
-wget http://$1:9000/trans_buy_f933_3
-wget http://$1:9000/trans_add_f934_5_150
-wget http://$1:9000/trans_buy_f934_4
-wget http://$1:9000/trans_add_f935_1_200
-wget http://$1:9000/trans_buy_f935_0
-wget http://$1:9000/trans_add_f936_2_50
-wget http://$1:9000/trans_buy_f936_1
-wget http://$1:9000/trans_add_f937_3_100
-wget http://$1:9000/trans_buy_f937_2
-wget http://$1:9000/trans_add_f938_4_150
-wget http://$1:9000/trans_buy_f938_3
-wget http://$1:9000/trans_add_f939_5_200
-wget http://$1:9000/trans_buy_f939_4
-wget http://$1:9000/trans_add_f940_1_50
-wget http://$1:9000/trans_buy_f940_0
-wget http://$1:9000/trans_add_f941_2_100
-wget http://$1:9000/trans_buy_f941_1
-wget http://$1:9000/trans_add_f942_3_150
-wget http://$1:9000/trans_buy_f942_2
-wget http://$1:9000/trans_add_f943_4_200
-wget http://$1:9000/trans_buy_f943_3
-wget http://$1:9000/trans_add_f944_5_50
-wget http://$1:9000/trans_buy_f944_4
-wget http://$1:9000/trans_add_f945_1_100
-wget http://$1:9000/trans_buy_f945_0
-wget http://$1:9000/trans_add_f946_2_150
-wget http://$1:9000/trans_buy_f946_1
-wget http://$1:9000/trans_add_f947_3_200
-wget http://$1:9000/trans_buy_f947_2
-wget http://$1:9000/trans_add_f948_4_50
-wget http://$1:9000/trans_buy_f948_3
-wget http://$1:9000/trans_add_f949_5_100
-wget http://$1:9000/trans_buy_f949_4
-wget http://$1:9000/trans_add_f950_1_150
-wget http://$1:9000/trans_buy_f950_0
-wget http://$1:9000/trans_add_f951_2_200
-wget http://$1:9000/trans_buy_f951_1
-wget http://$1:9000/trans_add_f952_3_50
-wget http://$1:9000/trans_buy_f952_2
-wget http://$1:9000/trans_add_f953_4_100
-wget http://$1:9000/trans_buy_f953_3
-wget http://$1:9000/trans_add_f954_5_150
-wget http://$1:9000/trans_buy_f954_4
-wget http://$1:9000/trans_add_f955_1_200
-wget http://$1:9000/trans_buy_f955_0
-wget http://$1:9000/trans_add_f956_2_50
-wget http://$1:9000/trans_buy_f956_1
-wget http://$1:9000/trans_add_f957_3_100
-wget http://$1:9000/trans_buy_f957_2
-wget http://$1:9000/trans_add_f958_4_150
-wget http://$1:9000/trans_buy_f958_3
-wget http://$1:9000/trans_add_f959_5_200
-wget http://$1:9000/trans_buy_f959_4
-wget http://$1:9000/trans_add_f960_1_50
-wget http://$1:9000/trans_buy_f960_0
-wget http://$1:9000/trans_add_f961_2_100
-wget http://$1:9000/trans_buy_f961_1
-wget http://$1:9000/trans_add_f962_3_150
-wget http://$1:9000/trans_buy_f962_2
-wget http://$1:9000/trans_add_f963_4_200
-wget http://$1:9000/trans_buy_f963_3
-wget http://$1:9000/trans_add_f964_5_50
-wget http://$1:9000/trans_buy_f964_4
-wget http://$1:9000/trans_add_f965_1_100
-wget http://$1:9000/trans_buy_f965_0
-wget http://$1:9000/trans_add_f966_2_150
-wget http://$1:9000/trans_buy_f966_1
-wget http://$1:9000/trans_add_f967_3_200
-wget http://$1:9000/trans_buy_f967_2
-wget http://$1:9000/trans_add_f968_4_50
-wget http://$1:9000/trans_buy_f968_3
-wget http://$1:9000/trans_add_f969_5_100
-wget http://$1:9000/trans_buy_f969_4
-wget http://$1:9000/trans_add_f970_1_150
-wget http://$1:9000/trans_buy_f970_0
-wget http://$1:9000/trans_add_f971_2_200
-wget http://$1:9000/trans_buy_f971_1
-wget http://$1:9000/trans_add_f972_3_50
-wget http://$1:9000/trans_buy_f972_2
-wget http://$1:9000/trans_add_f973_4_100
-wget http://$1:9000/trans_buy_f973_3
-wget http://$1:9000/trans_add_f974_5_150
-wget http://$1:9000/trans_buy_f974_4
-wget http://$1:9000/trans_add_f975_1_200
-wget http://$1:9000/trans_buy_f975_0
-wget http://$1:9000/trans_add_f976_2_50
-wget http://$1:9000/trans_buy_f976_1
-wget http://$1:9000/trans_add_f977_3_100
-wget http://$1:9000/trans_buy_f977_2
-wget http://$1:9000/trans_add_f978_4_150
-wget http://$1:9000/trans_buy_f978_3
-wget http://$1:9000/trans_add_f979_5_200
-wget http://$1:9000/trans_buy_f979_4
-wget http://$1:9000/trans_add_f980_1_50
-wget http://$1:9000/trans_buy_f980_0
-wget http://$1:9000/trans_add_f981_2_100
-wget http://$1:9000/trans_buy_f981_1
-wget http://$1:9000/trans_add_f982_3_150
-wget http://$1:9000/trans_buy_f982_2
-wget http://$1:9000/trans_add_f983_4_200
-wget http://$1:9000/trans_buy_f983_3
-wget http://$1:9000/trans_add_f984_5_50
-wget http://$1:9000/trans_buy_f984_4
-wget http://$1:9000/trans_add_f985_1_100
-wget http://$1:9000/trans_buy_f985_0
-wget http://$1:9000/trans_add_f986_2_150
-wget http://$1:9000/trans_buy_f986_1
-wget http://$1:9000/trans_add_f987_3_200
-wget http://$1:9000/trans_buy_f987_2
-wget http://$1:9000/trans_add_f988_4_50
-wget http://$1:9000/trans_buy_f988_3
-wget http://$1:9000/trans_add_f989_5_100
-wget http://$1:9000/trans_buy_f989_4
-wget http://$1:9000/trans_add_f990_1_150
-wget http://$1:9000/trans_buy_f990_0
-wget http://$1:9000/trans_add_f991_2_200
-wget http://$1:9000/trans_buy_f991_1
-wget http://$1:9000/trans_add_f992_3_50
-wget http://$1:9000/trans_buy_f992_2
-wget http://$1:9000/trans_add_f993_4_100
-wget http://$1:9000/trans_buy_f993_3
-wget http://$1:9000/trans_add_f994_5_150
-wget http://$1:9000/trans_buy_f994_4
-wget http://$1:9000/trans_add_f995_1_200
-wget http://$1:9000/trans_buy_f995_0
-wget http://$1:9000/trans_add_f996_2_50
-wget http://$1:9000/trans_buy_f996_1
-wget http://$1:9000/trans_add_f997_3_100
-wget http://$1:9000/trans_buy_f997_2
-wget http://$1:9000/trans_add_f998_4_150
-wget http://$1:9000/trans_buy_f998_3
-wget http://$1:9000/trans_add_f999_5_200
-wget http://$1:9000/trans_buy_f999_4
-wget http://$1:9000/trans_add_f1000_1_50
-wget http://$1:9000/trans_buy_f1000_0
-wget http://$1:9000/trans_add_f1001_2_100
-wget http://$1:9000/trans_buy_f1001_1
-wget http://$1:9000/trans_add_f1002_3_150
-wget http://$1:9000/trans_buy_f1002_2
-wget http://$1:9000/trans_add_f1003_4_200
-wget http://$1:9000/trans_buy_f1003_3
-wget http://$1:9000/trans_add_f1004_5_50
-wget http://$1:9000/trans_buy_f1004_4
-wget http://$1:9000/trans_add_f1005_1_100
-wget http://$1:9000/trans_buy_f1005_0
-wget http://$1:9000/trans_add_f1006_2_150
-wget http://$1:9000/trans_buy_f1006_1
-wget http://$1:9000/trans_add_f1007_3_200
-wget http://$1:9000/trans_buy_f1007_2
-wget http://$1:9000/trans_add_f1008_4_50
-wget http://$1:9000/trans_buy_f1008_3
-wget http://$1:9000/trans_add_f1009_5_100
-wget http://$1:9000/trans_buy_f1009_4
-wget http://$1:9000/trans_add_f1010_1_150
-wget http://$1:9000/trans_buy_f1010_0
-wget http://$1:9000/trans_add_f1011_2_200
-wget http://$1:9000/trans_buy_f1011_1
-wget http://$1:9000/trans_add_f1012_3_50
-wget http://$1:9000/trans_buy_f1012_2
-wget http://$1:9000/trans_add_f1013_4_100
-wget http://$1:9000/trans_buy_f1013_3
-wget http://$1:9000/trans_add_f1014_5_150
-wget http://$1:9000/trans_buy_f1014_4
-wget http://$1:9000/trans_add_f1015_1_200
-wget http://$1:9000/trans_buy_f1015_0
-wget http://$1:9000/trans_add_f1016_2_50
-wget http://$1:9000/trans_buy_f1016_1
-wget http://$1:9000/trans_add_f1017_3_100
-wget http://$1:9000/trans_buy_f1017_2
-wget http://$1:9000/trans_add_f1018_4_150
-wget http://$1:9000/trans_buy_f1018_3
-wget http://$1:9000/trans_add_f1019_5_200
-wget http://$1:9000/trans_buy_f1019_4
-wget http://$1:9000/trans_add_f1020_1_50
-wget http://$1:9000/trans_buy_f1020_0
-wget http://$1:9000/trans_add_f1021_2_100
-wget http://$1:9000/trans_buy_f1021_1
-wget http://$1:9000/trans_add_f1022_3_150
-wget http://$1:9000/trans_buy_f1022_2
-wget http://$1:9000/trans_add_f1023_4_200
-wget http://$1:9000/trans_buy_f1023_3
-wget http://$1:9000/trans_add_f1024_5_50
-wget http://$1:9000/trans_buy_f1024_4
-wget http://$1:9000/trans_add_f1025_1_100
-wget http://$1:9000/trans_buy_f1025_0
-wget http://$1:9000/trans_add_f1026_2_150
-wget http://$1:9000/trans_buy_f1026_1
-wget http://$1:9000/trans_add_f1027_3_200
-wget http://$1:9000/trans_buy_f1027_2
-wget http://$1:9000/trans_add_f1028_4_50
-wget http://$1:9000/trans_buy_f1028_3
-wget http://$1:9000/trans_add_f1029_5_100
-wget http://$1:9000/trans_buy_f1029_4
-wget http://$1:9000/trans_add_f1030_1_150
-wget http://$1:9000/trans_buy_f1030_0
-wget http://$1:9000/trans_add_f1031_2_200
-wget http://$1:9000/trans_buy_f1031_1
-wget http://$1:9000/trans_add_f1032_3_50
-wget http://$1:9000/trans_buy_f1032_2
-wget http://$1:9000/trans_add_f1033_4_100
-wget http://$1:9000/trans_buy_f1033_3
-wget http://$1:9000/trans_add_f1034_5_150
-wget http://$1:9000/trans_buy_f1034_4
-wget http://$1:9000/trans_add_f1035_1_200
-wget http://$1:9000/trans_buy_f1035_0
-wget http://$1:9000/trans_add_f1036_2_50
-wget http://$1:9000/trans_buy_f1036_1
-wget http://$1:9000/trans_add_f1037_3_100
-wget http://$1:9000/trans_buy_f1037_2
-wget http://$1:9000/trans_add_f1038_4_150
-wget http://$1:9000/trans_buy_f1038_3
-wget http://$1:9000/trans_add_f1039_5_200
-wget http://$1:9000/trans_buy_f1039_4
-wget http://$1:9000/trans_add_f1040_1_50
-wget http://$1:9000/trans_buy_f1040_0
-wget http://$1:9000/trans_add_f1041_2_100
-wget http://$1:9000/trans_buy_f1041_1
-wget http://$1:9000/trans_add_f1042_3_150
-wget http://$1:9000/trans_buy_f1042_2
-wget http://$1:9000/trans_add_f1043_4_200
-wget http://$1:9000/trans_buy_f1043_3
-wget http://$1:9000/trans_add_f1044_5_50
-wget http://$1:9000/trans_buy_f1044_4
-wget http://$1:9000/trans_add_f1045_1_100
-wget http://$1:9000/trans_buy_f1045_0
-wget http://$1:9000/trans_add_f1046_2_150
-wget http://$1:9000/trans_buy_f1046_1
-wget http://$1:9000/trans_add_f1047_3_200
-wget http://$1:9000/trans_buy_f1047_2
-wget http://$1:9000/trans_add_f1048_4_50
-wget http://$1:9000/trans_buy_f1048_3
-wget http://$1:9000/trans_add_f1049_5_100
-wget http://$1:9000/trans_buy_f1049_4
-wget http://$1:9000/trans_add_f1050_1_150
-wget http://$1:9000/trans_buy_f1050_0
-wget http://$1:9000/trans_add_f1051_2_200
-wget http://$1:9000/trans_buy_f1051_1
-wget http://$1:9000/trans_add_f1052_3_50
-wget http://$1:9000/trans_buy_f1052_2
-wget http://$1:9000/trans_add_f1053_4_100
-wget http://$1:9000/trans_buy_f1053_3
-wget http://$1:9000/trans_add_f1054_5_150
-wget http://$1:9000/trans_buy_f1054_4
-wget http://$1:9000/trans_add_f1055_1_200
-wget http://$1:9000/trans_buy_f1055_0
-wget http://$1:9000/trans_add_f1056_2_50
-wget http://$1:9000/trans_buy_f1056_1
-wget http://$1:9000/trans_add_f1057_3_100
-wget http://$1:9000/trans_buy_f1057_2
-wget http://$1:9000/trans_add_f1058_4_150
-wget http://$1:9000/trans_buy_f1058_3
-wget http://$1:9000/trans_add_f1059_5_200
-wget http://$1:9000/trans_buy_f1059_4
-wget http://$1:9000/trans_add_f1060_1_50
-wget http://$1:9000/trans_buy_f1060_0
-wget http://$1:9000/trans_add_f1061_2_100
-wget http://$1:9000/trans_buy_f1061_1
-wget http://$1:9000/trans_add_f1062_3_150
-wget http://$1:9000/trans_buy_f1062_2
-wget http://$1:9000/trans_add_f1063_4_200
-wget http://$1:9000/trans_buy_f1063_3
-wget http://$1:9000/trans_add_f1064_5_50
-wget http://$1:9000/trans_buy_f1064_4
-wget http://$1:9000/trans_add_f1065_1_100
-wget http://$1:9000/trans_buy_f1065_0
-wget http://$1:9000/trans_add_f1066_2_150
-wget http://$1:9000/trans_buy_f1066_1
-wget http://$1:9000/trans_add_f1067_3_200
-wget http://$1:9000/trans_buy_f1067_2
-wget http://$1:9000/trans_add_f1068_4_50
-wget http://$1:9000/trans_buy_f1068_3
-wget http://$1:9000/trans_add_f1069_5_100
-wget http://$1:9000/trans_buy_f1069_4
-wget http://$1:9000/trans_add_f1070_1_150
-wget http://$1:9000/trans_buy_f1070_0
-wget http://$1:9000/trans_add_f1071_2_200
-wget http://$1:9000/trans_buy_f1071_1
-wget http://$1:9000/trans_add_f1072_3_50
-wget http://$1:9000/trans_buy_f1072_2
-wget http://$1:9000/trans_add_f1073_4_100
-wget http://$1:9000/trans_buy_f1073_3
-wget http://$1:9000/trans_add_f1074_5_150
-wget http://$1:9000/trans_buy_f1074_4
-wget http://$1:9000/trans_add_f1075_1_200
-wget http://$1:9000/trans_buy_f1075_0
-wget http://$1:9000/trans_add_f1076_2_50
-wget http://$1:9000/trans_buy_f1076_1
-wget http://$1:9000/trans_add_f1077_3_100
-wget http://$1:9000/trans_buy_f1077_2
-wget http://$1:9000/trans_add_f1078_4_150
-wget http://$1:9000/trans_buy_f1078_3
-wget http://$1:9000/trans_add_f1079_5_200
-wget http://$1:9000/trans_buy_f1079_4
-wget http://$1:9000/trans_add_f1080_1_50
-wget http://$1:9000/trans_buy_f1080_0
-wget http://$1:9000/trans_add_f1081_2_100
-wget http://$1:9000/trans_buy_f1081_1
-wget http://$1:9000/trans_add_f1082_3_150
-wget http://$1:9000/trans_buy_f1082_2
-wget http://$1:9000/trans_add_f1083_4_200
-wget http://$1:9000/trans_buy_f1083_3
-wget http://$1:9000/trans_add_f1084_5_50
-wget http://$1:9000/trans_buy_f1084_4
-wget http://$1:9000/trans_add_f1085_1_100
-wget http://$1:9000/trans_buy_f1085_0
-wget http://$1:9000/trans_add_f1086_2_150
-wget http://$1:9000/trans_buy_f1086_1
-wget http://$1:9000/trans_add_f1087_3_200
-wget http://$1:9000/trans_buy_f1087_2
-wget http://$1:9000/trans_add_f1088_4_50
-wget http://$1:9000/trans_buy_f1088_3
-wget http://$1:9000/trans_add_f1089_5_100
-wget http://$1:9000/trans_buy_f1089_4
-wget http://$1:9000/trans_add_f1090_1_150
-wget http://$1:9000/trans_buy_f1090_0
-wget http://$1:9000/trans_add_f1091_2_200
-wget http://$1:9000/trans_buy_f1091_1
-wget http://$1:9000/trans_add_f1092_3_50
-wget http://$1:9000/trans_buy_f1092_2
-wget http://$1:9000/trans_add_f1093_4_100
-wget http://$1:9000/trans_buy_f1093_3
-wget http://$1:9000/trans_add_f1094_5_150
-wget http://$1:9000/trans_buy_f1094_4
-wget http://$1:9000/trans_add_f1095_1_200
-wget http://$1:9000/trans_buy_f1095_0
-wget http://$1:9000/trans_add_f1096_2_50
-wget http://$1:9000/trans_buy_f1096_1
-wget http://$1:9000/trans_add_f1097_3_100
-wget http://$1:9000/trans_buy_f1097_2
-wget http://$1:9000/trans_add_f1098_4_150
-wget http://$1:9000/trans_buy_f1098_3
-wget http://$1:9000/trans_add_f1099_5_200
-wget http://$1:9000/trans_buy_f1099_4
-wget http://$1:9000/trans_add_f1100_1_50
-wget http://$1:9000/trans_buy_f1100_0
-wget http://$1:9000/trans_add_f1101_2_100
-wget http://$1:9000/trans_buy_f1101_1
-wget http://$1:9000/trans_add_f1102_3_150
-wget http://$1:9000/trans_buy_f1102_2
-wget http://$1:9000/trans_add_f1103_4_200
-wget http://$1:9000/trans_buy_f1103_3
-wget http://$1:9000/trans_add_f1104_5_50
-wget http://$1:9000/trans_buy_f1104_4
-wget http://$1:9000/trans_add_f1105_1_100
-wget http://$1:9000/trans_buy_f1105_0
-wget http://$1:9000/trans_add_f1106_2_150
-wget http://$1:9000/trans_buy_f1106_1
-wget http://$1:9000/trans_add_f1107_3_200
-wget http://$1:9000/trans_buy_f1107_2
-wget http://$1:9000/trans_add_f1108_4_50
-wget http://$1:9000/trans_buy_f1108_3
-wget http://$1:9000/trans_add_f1109_5_100
-wget http://$1:9000/trans_buy_f1109_4
-wget http://$1:9000/trans_add_f1110_1_150
-wget http://$1:9000/trans_buy_f1110_0
-wget http://$1:9000/trans_add_f1111_2_200
-wget http://$1:9000/trans_buy_f1111_1
-wget http://$1:9000/trans_add_f1112_3_50
-wget http://$1:9000/trans_buy_f1112_2
-wget http://$1:9000/trans_add_f1113_4_100
-wget http://$1:9000/trans_buy_f1113_3
-wget http://$1:9000/trans_add_f1114_5_150
-wget http://$1:9000/trans_buy_f1114_4
-wget http://$1:9000/trans_add_f1115_1_200
-wget http://$1:9000/trans_buy_f1115_0
-wget http://$1:9000/trans_add_f1116_2_50
-wget http://$1:9000/trans_buy_f1116_1
-wget http://$1:9000/trans_add_f1117_3_100
-wget http://$1:9000/trans_buy_f1117_2
-wget http://$1:9000/trans_add_f1118_4_150
-wget http://$1:9000/trans_buy_f1118_3
-wget http://$1:9000/trans_add_f1119_5_200
-wget http://$1:9000/trans_buy_f1119_4
-wget http://$1:9000/trans_add_f1120_1_50
-wget http://$1:9000/trans_buy_f1120_0
-wget http://$1:9000/trans_add_f1121_2_100
-wget http://$1:9000/trans_buy_f1121_1
-wget http://$1:9000/trans_add_f1122_3_150
-wget http://$1:9000/trans_buy_f1122_2
-wget http://$1:9000/trans_add_f1123_4_200
-wget http://$1:9000/trans_buy_f1123_3
-wget http://$1:9000/trans_add_f1124_5_50
-wget http://$1:9000/trans_buy_f1124_4
-wget http://$1:9000/trans_add_f1125_1_100
-wget http://$1:9000/trans_buy_f1125_0
-wget http://$1:9000/trans_add_f1126_2_150
-wget http://$1:9000/trans_buy_f1126_1
-wget http://$1:9000/trans_add_f1127_3_200
-wget http://$1:9000/trans_buy_f1127_2
-wget http://$1:9000/trans_add_f1128_4_50
-wget http://$1:9000/trans_buy_f1128_3
-wget http://$1:9000/trans_add_f1129_5_100
-wget http://$1:9000/trans_buy_f1129_4
-wget http://$1:9000/trans_add_f1130_1_150
-wget http://$1:9000/trans_buy_f1130_0
-wget http://$1:9000/trans_add_f1131_2_200
-wget http://$1:9000/trans_buy_f1131_1
-wget http://$1:9000/trans_add_f1132_3_50
-wget http://$1:9000/trans_buy_f1132_2
-wget http://$1:9000/trans_add_f1133_4_100
-wget http://$1:9000/trans_buy_f1133_3
-wget http://$1:9000/trans_add_f1134_5_150
-wget http://$1:9000/trans_buy_f1134_4
-wget http://$1:9000/trans_add_f1135_1_200
-wget http://$1:9000/trans_buy_f1135_0
-wget http://$1:9000/trans_add_f1136_2_50
-wget http://$1:9000/trans_buy_f1136_1
-wget http://$1:9000/trans_add_f1137_3_100
-wget http://$1:9000/trans_buy_f1137_2
-wget http://$1:9000/trans_add_f1138_4_150
-wget http://$1:9000/trans_buy_f1138_3
-wget http://$1:9000/trans_add_f1139_5_200
-wget http://$1:9000/trans_buy_f1139_4
-wget http://$1:9000/trans_add_f1140_1_50
-wget http://$1:9000/trans_buy_f1140_0
-wget http://$1:9000/trans_add_f1141_2_100
-wget http://$1:9000/trans_buy_f1141_1
-wget http://$1:9000/trans_add_f1142_3_150
-wget http://$1:9000/trans_buy_f1142_2
-wget http://$1:9000/trans_add_f1143_4_200
-wget http://$1:9000/trans_buy_f1143_3
-wget http://$1:9000/trans_add_f1144_5_50
-wget http://$1:9000/trans_buy_f1144_4
-wget http://$1:9000/trans_add_f1145_1_100
-wget http://$1:9000/trans_buy_f1145_0
-wget http://$1:9000/trans_add_f1146_2_150
-wget http://$1:9000/trans_buy_f1146_1
-wget http://$1:9000/trans_add_f1147_3_200
-wget http://$1:9000/trans_buy_f1147_2
-wget http://$1:9000/trans_add_f1148_4_50
-wget http://$1:9000/trans_buy_f1148_3
-wget http://$1:9000/trans_add_f1149_5_100
-wget http://$1:9000/trans_buy_f1149_4
-wget http://$1:9000/trans_add_f1150_1_150
-wget http://$1:9000/trans_buy_f1150_0
-wget http://$1:9000/trans_add_f1151_2_200
-wget http://$1:9000/trans_buy_f1151_1
-wget http://$1:9000/trans_add_f1152_3_50
-wget http://$1:9000/trans_buy_f1152_2
-wget http://$1:9000/trans_add_f1153_4_100
-wget http://$1:9000/trans_buy_f1153_3
-wget http://$1:9000/trans_add_f1154_5_150
-wget http://$1:9000/trans_buy_f1154_4
-wget http://$1:9000/trans_add_f1155_1_200
-wget http://$1:9000/trans_buy_f1155_0
-wget http://$1:9000/trans_add_f1156_2_50
-wget http://$1:9000/trans_buy_f1156_1
-wget http://$1:9000/trans_add_f1157_3_100
-wget http://$1:9000/trans_buy_f1157_2
-wget http://$1:9000/trans_add_f1158_4_150
-wget http://$1:9000/trans_buy_f1158_3
-wget http://$1:9000/trans_add_f1159_5_200
-wget http://$1:9000/trans_buy_f1159_4
-wget http://$1:9000/trans_add_f1160_1_50
-wget http://$1:9000/trans_buy_f1160_0
-wget http://$1:9000/trans_add_f1161_2_100
-wget http://$1:9000/trans_buy_f1161_1
-wget http://$1:9000/trans_add_f1162_3_150
-wget http://$1:9000/trans_buy_f1162_2
-wget http://$1:9000/trans_add_f1163_4_200
-wget http://$1:9000/trans_buy_f1163_3
-wget http://$1:9000/trans_add_f1164_5_50
-wget http://$1:9000/trans_buy_f1164_4
-wget http://$1:9000/trans_add_f1165_1_100
-wget http://$1:9000/trans_buy_f1165_0
-wget http://$1:9000/trans_add_f1166_2_150
-wget http://$1:9000/trans_buy_f1166_1
-wget http://$1:9000/trans_add_f1167_3_200
-wget http://$1:9000/trans_buy_f1167_2
-wget http://$1:9000/trans_add_f1168_4_50
-wget http://$1:9000/trans_buy_f1168_3
-wget http://$1:9000/trans_add_f1169_5_100
-wget http://$1:9000/trans_buy_f1169_4
-wget http://$1:9000/trans_add_f1170_1_150
-wget http://$1:9000/trans_buy_f1170_0
-wget http://$1:9000/trans_add_f1171_2_200
-wget http://$1:9000/trans_buy_f1171_1
-wget http://$1:9000/trans_add_f1172_3_50
-wget http://$1:9000/trans_buy_f1172_2
-wget http://$1:9000/trans_add_f1173_4_100
-wget http://$1:9000/trans_buy_f1173_3
-wget http://$1:9000/trans_add_f1174_5_150
-wget http://$1:9000/trans_buy_f1174_4
-wget http://$1:9000/trans_add_f1175_1_200
-wget http://$1:9000/trans_buy_f1175_0
-wget http://$1:9000/trans_add_f1176_2_50
-wget http://$1:9000/trans_buy_f1176_1
-wget http://$1:9000/trans_add_f1177_3_100
-wget http://$1:9000/trans_buy_f1177_2
-wget http://$1:9000/trans_add_f1178_4_150
-wget http://$1:9000/trans_buy_f1178_3
-wget http://$1:9000/trans_add_f1179_5_200
-wget http://$1:9000/trans_buy_f1179_4
-wget http://$1:9000/trans_add_f1180_1_50
-wget http://$1:9000/trans_buy_f1180_0
-wget http://$1:9000/trans_add_f1181_2_100
-wget http://$1:9000/trans_buy_f1181_1
-wget http://$1:9000/trans_add_f1182_3_150
-wget http://$1:9000/trans_buy_f1182_2
-wget http://$1:9000/trans_add_f1183_4_200
-wget http://$1:9000/trans_buy_f1183_3
-wget http://$1:9000/trans_add_f1184_5_50
-wget http://$1:9000/trans_buy_f1184_4
-wget http://$1:9000/trans_add_f1185_1_100
-wget http://$1:9000/trans_buy_f1185_0
-wget http://$1:9000/trans_add_f1186_2_150
-wget http://$1:9000/trans_buy_f1186_1
-wget http://$1:9000/trans_add_f1187_3_200
-wget http://$1:9000/trans_buy_f1187_2
-wget http://$1:9000/trans_add_f1188_4_50
-wget http://$1:9000/trans_buy_f1188_3
-wget http://$1:9000/trans_add_f1189_5_100
-wget http://$1:9000/trans_buy_f1189_4
-wget http://$1:9000/trans_add_f1190_1_150
-wget http://$1:9000/trans_buy_f1190_0
-wget http://$1:9000/trans_add_f1191_2_200
-wget http://$1:9000/trans_buy_f1191_1
-wget http://$1:9000/trans_add_f1192_3_50
-wget http://$1:9000/trans_buy_f1192_2
-wget http://$1:9000/trans_add_f1193_4_100
-wget http://$1:9000/trans_buy_f1193_3
-wget http://$1:9000/trans_add_f1194_5_150
-wget http://$1:9000/trans_buy_f1194_4
-wget http://$1:9000/trans_add_f1195_1_200
-wget http://$1:9000/trans_buy_f1195_0
-wget http://$1:9000/trans_add_f1196_2_50
-wget http://$1:9000/trans_buy_f1196_1
-wget http://$1:9000/trans_add_f1197_3_100
-wget http://$1:9000/trans_buy_f1197_2
-wget http://$1:9000/trans_add_f1198_4_150
-wget http://$1:9000/trans_buy_f1198_3
-wget http://$1:9000/trans_add_f1199_5_200
-wget http://$1:9000/trans_buy_f1199_4
-wget http://$1:9000/trans_add_f1200_1_50
-wget http://$1:9000/trans_buy_f1200_0
-wget http://$1:9000/trans_add_f1201_2_100
-wget http://$1:9000/trans_buy_f1201_1
-wget http://$1:9000/trans_add_f1202_3_150
-wget http://$1:9000/trans_buy_f1202_2
-wget http://$1:9000/trans_add_f1203_4_200
-wget http://$1:9000/trans_buy_f1203_3
-wget http://$1:9000/trans_add_f1204_5_50
-wget http://$1:9000/trans_buy_f1204_4
-wget http://$1:9000/trans_add_f1205_1_100
-wget http://$1:9000/trans_buy_f1205_0
-wget http://$1:9000/trans_add_f1206_2_150
-wget http://$1:9000/trans_buy_f1206_1
-wget http://$1:9000/trans_add_f1207_3_200
-wget http://$1:9000/trans_buy_f1207_2
-wget http://$1:9000/trans_add_f1208_4_50
-wget http://$1:9000/trans_buy_f1208_3
-wget http://$1:9000/trans_add_f1209_5_100
-wget http://$1:9000/trans_buy_f1209_4
-wget http://$1:9000/trans_add_f1210_1_150
-wget http://$1:9000/trans_buy_f1210_0
-wget http://$1:9000/trans_add_f1211_2_200
-wget http://$1:9000/trans_buy_f1211_1
-wget http://$1:9000/trans_add_f1212_3_50
-wget http://$1:9000/trans_buy_f1212_2
-wget http://$1:9000/trans_add_f1213_4_100
-wget http://$1:9000/trans_buy_f1213_3
-wget http://$1:9000/trans_add_f1214_5_150
-wget http://$1:9000/trans_buy_f1214_4
-wget http://$1:9000/trans_add_f1215_1_200
-wget http://$1:9000/trans_buy_f1215_0
-wget http://$1:9000/trans_add_f1216_2_50
-wget http://$1:9000/trans_buy_f1216_1
-wget http://$1:9000/trans_add_f1217_3_100
-wget http://$1:9000/trans_buy_f1217_2
-wget http://$1:9000/trans_add_f1218_4_150
-wget http://$1:9000/trans_buy_f1218_3
-wget http://$1:9000/trans_add_f1219_5_200
-wget http://$1:9000/trans_buy_f1219_4
-wget http://$1:9000/trans_add_f1220_1_50
-wget http://$1:9000/trans_buy_f1220_0
-wget http://$1:9000/trans_add_f1221_2_100
-wget http://$1:9000/trans_buy_f1221_1
-wget http://$1:9000/trans_add_f1222_3_150
-wget http://$1:9000/trans_buy_f1222_2
-wget http://$1:9000/trans_add_f1223_4_200
-wget http://$1:9000/trans_buy_f1223_3
-wget http://$1:9000/trans_add_f1224_5_50
-wget http://$1:9000/trans_buy_f1224_4
-wget http://$1:9000/trans_add_f1225_1_100
-wget http://$1:9000/trans_buy_f1225_0
-wget http://$1:9000/trans_add_f1226_2_150
-wget http://$1:9000/trans_buy_f1226_1
-wget http://$1:9000/trans_add_f1227_3_200
-wget http://$1:9000/trans_buy_f1227_2
-wget http://$1:9000/trans_add_f1228_4_50
-wget http://$1:9000/trans_buy_f1228_3
-wget http://$1:9000/trans_add_f1229_5_100
-wget http://$1:9000/trans_buy_f1229_4
-wget http://$1:9000/trans_add_f1230_1_150
-wget http://$1:9000/trans_buy_f1230_0
-wget http://$1:9000/trans_add_f1231_2_200
-wget http://$1:9000/trans_buy_f1231_1
-wget http://$1:9000/trans_add_f1232_3_50
-wget http://$1:9000/trans_buy_f1232_2
-wget http://$1:9000/trans_add_f1233_4_100
-wget http://$1:9000/trans_buy_f1233_3
-wget http://$1:9000/trans_add_f1234_5_150
-wget http://$1:9000/trans_buy_f1234_4
-wget http://$1:9000/trans_add_f1235_1_200
-wget http://$1:9000/trans_buy_f1235_0
-wget http://$1:9000/trans_add_f1236_2_50
-wget http://$1:9000/trans_buy_f1236_1
-wget http://$1:9000/trans_add_f1237_3_100
-wget http://$1:9000/trans_buy_f1237_2
-wget http://$1:9000/trans_add_f1238_4_150
-wget http://$1:9000/trans_buy_f1238_3
-wget http://$1:9000/trans_add_f1239_5_200
-wget http://$1:9000/trans_buy_f1239_4
-wget http://$1:9000/trans_add_f1240_1_50
-wget http://$1:9000/trans_buy_f1240_0
-wget http://$1:9000/trans_add_f1241_2_100
-wget http://$1:9000/trans_buy_f1241_1
-wget http://$1:9000/trans_add_f1242_3_150
-wget http://$1:9000/trans_buy_f1242_2
-wget http://$1:9000/trans_add_f1243_4_200
-wget http://$1:9000/trans_buy_f1243_3
-wget http://$1:9000/trans_add_f1244_5_50
-wget http://$1:9000/trans_buy_f1244_4
-wget http://$1:9000/trans_add_f1245_1_100
-wget http://$1:9000/trans_buy_f1245_0
-wget http://$1:9000/trans_add_f1246_2_150
-wget http://$1:9000/trans_buy_f1246_1
-wget http://$1:9000/trans_add_f1247_3_200
-wget http://$1:9000/trans_buy_f1247_2
-wget http://$1:9000/trans_add_f1248_4_50
-wget http://$1:9000/trans_buy_f1248_3
-wget http://$1:9000/trans_add_f1249_5_100
-wget http://$1:9000/trans_buy_f1249_4
-wget http://$1:9000/trans_add_f1250_1_150
-wget http://$1:9000/trans_buy_f1250_0
-wget http://$1:9000/trans_add_f1251_2_200
-wget http://$1:9000/trans_buy_f1251_1
-wget http://$1:9000/trans_add_f1252_3_50
-wget http://$1:9000/trans_buy_f1252_2
-wget http://$1:9000/trans_add_f1253_4_100
-wget http://$1:9000/trans_buy_f1253_3
-wget http://$1:9000/trans_add_f1254_5_150
-wget http://$1:9000/trans_buy_f1254_4
-wget http://$1:9000/trans_add_f1255_1_200
-wget http://$1:9000/trans_buy_f1255_0
-wget http://$1:9000/trans_add_f1256_2_50
-wget http://$1:9000/trans_buy_f1256_1
-wget http://$1:9000/trans_add_f1257_3_100
-wget http://$1:9000/trans_buy_f1257_2
-wget http://$1:9000/trans_add_f1258_4_150
-wget http://$1:9000/trans_buy_f1258_3
-wget http://$1:9000/trans_add_f1259_5_200
-wget http://$1:9000/trans_buy_f1259_4
-wget http://$1:9000/trans_add_f1260_1_50
-wget http://$1:9000/trans_buy_f1260_0
-wget http://$1:9000/trans_add_f1261_2_100
-wget http://$1:9000/trans_buy_f1261_1
-wget http://$1:9000/trans_add_f1262_3_150
-wget http://$1:9000/trans_buy_f1262_2
-wget http://$1:9000/trans_add_f1263_4_200
-wget http://$1:9000/trans_buy_f1263_3
-wget http://$1:9000/trans_add_f1264_5_50
-wget http://$1:9000/trans_buy_f1264_4
-wget http://$1:9000/trans_add_f1265_1_100
-wget http://$1:9000/trans_buy_f1265_0
-wget http://$1:9000/trans_add_f1266_2_150
-wget http://$1:9000/trans_buy_f1266_1
-wget http://$1:9000/trans_add_f1267_3_200
-wget http://$1:9000/trans_buy_f1267_2
-wget http://$1:9000/trans_add_f1268_4_50
-wget http://$1:9000/trans_buy_f1268_3
-wget http://$1:9000/trans_add_f1269_5_100
-wget http://$1:9000/trans_buy_f1269_4
-wget http://$1:9000/trans_add_f1270_1_150
-wget http://$1:9000/trans_buy_f1270_0
-wget http://$1:9000/trans_add_f1271_2_200
-wget http://$1:9000/trans_buy_f1271_1
-wget http://$1:9000/trans_add_f1272_3_50
-wget http://$1:9000/trans_buy_f1272_2
-wget http://$1:9000/trans_add_f1273_4_100
-wget http://$1:9000/trans_buy_f1273_3
-wget http://$1:9000/trans_add_f1274_5_150
-wget http://$1:9000/trans_buy_f1274_4
-wget http://$1:9000/trans_add_f1275_1_200
-wget http://$1:9000/trans_buy_f1275_0
-wget http://$1:9000/trans_add_f1276_2_50
-wget http://$1:9000/trans_buy_f1276_1
-wget http://$1:9000/trans_add_f1277_3_100
-wget http://$1:9000/trans_buy_f1277_2
-wget http://$1:9000/trans_add_f1278_4_150
-wget http://$1:9000/trans_buy_f1278_3
-wget http://$1:9000/trans_add_f1279_5_200
-wget http://$1:9000/trans_buy_f1279_4
-wget http://$1:9000/trans_add_f1280_1_50
-wget http://$1:9000/trans_buy_f1280_0
-wget http://$1:9000/trans_add_f1281_2_100
-wget http://$1:9000/trans_buy_f1281_1
-wget http://$1:9000/trans_add_f1282_3_150
-wget http://$1:9000/trans_buy_f1282_2
-wget http://$1:9000/trans_add_f1283_4_200
-wget http://$1:9000/trans_buy_f1283_3
-wget http://$1:9000/trans_add_f1284_5_50
-wget http://$1:9000/trans_buy_f1284_4
-wget http://$1:9000/trans_add_f1285_1_100
-wget http://$1:9000/trans_buy_f1285_0
-wget http://$1:9000/trans_add_f1286_2_150
-wget http://$1:9000/trans_buy_f1286_1
-wget http://$1:9000/trans_add_f1287_3_200
-wget http://$1:9000/trans_buy_f1287_2
-wget http://$1:9000/trans_add_f1288_4_50
-wget http://$1:9000/trans_buy_f1288_3
-wget http://$1:9000/trans_add_f1289_5_100
-wget http://$1:9000/trans_buy_f1289_4
-wget http://$1:9000/trans_add_f1290_1_150
-wget http://$1:9000/trans_buy_f1290_0
-wget http://$1:9000/trans_add_f1291_2_200
-wget http://$1:9000/trans_buy_f1291_1
-wget http://$1:9000/trans_add_f1292_3_50
-wget http://$1:9000/trans_buy_f1292_2
-wget http://$1:9000/trans_add_f1293_4_100
-wget http://$1:9000/trans_buy_f1293_3
-wget http://$1:9000/trans_add_f1294_5_150
-wget http://$1:9000/trans_buy_f1294_4
-wget http://$1:9000/trans_add_f1295_1_200
-wget http://$1:9000/trans_buy_f1295_0
-wget http://$1:9000/trans_add_f1296_2_50
-wget http://$1:9000/trans_buy_f1296_1
-wget http://$1:9000/trans_add_f1297_3_100
-wget http://$1:9000/trans_buy_f1297_2
-wget http://$1:9000/trans_add_f1298_4_150
-wget http://$1:9000/trans_buy_f1298_3
-wget http://$1:9000/trans_add_f1299_5_200
-wget http://$1:9000/trans_buy_f1299_4
-wget http://$1:9000/trans_add_f1300_1_50
-wget http://$1:9000/trans_buy_f1300_0
-wget http://$1:9000/trans_add_f1301_2_100
-wget http://$1:9000/trans_buy_f1301_1
-wget http://$1:9000/trans_add_f1302_3_150
-wget http://$1:9000/trans_buy_f1302_2
-wget http://$1:9000/trans_add_f1303_4_200
-wget http://$1:9000/trans_buy_f1303_3
-wget http://$1:9000/trans_add_f1304_5_50
-wget http://$1:9000/trans_buy_f1304_4
-wget http://$1:9000/trans_add_f1305_1_100
-wget http://$1:9000/trans_buy_f1305_0
-wget http://$1:9000/trans_add_f1306_2_150
-wget http://$1:9000/trans_buy_f1306_1
-wget http://$1:9000/trans_add_f1307_3_200
-wget http://$1:9000/trans_buy_f1307_2
-wget http://$1:9000/trans_add_f1308_4_50
-wget http://$1:9000/trans_buy_f1308_3
-wget http://$1:9000/trans_add_f1309_5_100
-wget http://$1:9000/trans_buy_f1309_4
-wget http://$1:9000/trans_add_f1310_1_150
-wget http://$1:9000/trans_buy_f1310_0
-wget http://$1:9000/trans_add_f1311_2_200
-wget http://$1:9000/trans_buy_f1311_1
-wget http://$1:9000/trans_add_f1312_3_50
-wget http://$1:9000/trans_buy_f1312_2
-wget http://$1:9000/trans_add_f1313_4_100
-wget http://$1:9000/trans_buy_f1313_3
-wget http://$1:9000/trans_add_f1314_5_150
-wget http://$1:9000/trans_buy_f1314_4
-wget http://$1:9000/trans_add_f1315_1_200
-wget http://$1:9000/trans_buy_f1315_0
-wget http://$1:9000/trans_add_f1316_2_50
-wget http://$1:9000/trans_buy_f1316_1
-wget http://$1:9000/trans_add_f1317_3_100
-wget http://$1:9000/trans_buy_f1317_2
-wget http://$1:9000/trans_add_f1318_4_150
-wget http://$1:9000/trans_buy_f1318_3
-wget http://$1:9000/trans_add_f1319_5_200
-wget http://$1:9000/trans_buy_f1319_4
-wget http://$1:9000/trans_add_f1320_1_50
-wget http://$1:9000/trans_buy_f1320_0
-wget http://$1:9000/trans_add_f1321_2_100
-wget http://$1:9000/trans_buy_f1321_1
-wget http://$1:9000/trans_add_f1322_3_150
-wget http://$1:9000/trans_buy_f1322_2
-wget http://$1:9000/trans_add_f1323_4_200
-wget http://$1:9000/trans_buy_f1323_3
-wget http://$1:9000/trans_add_f1324_5_50
-wget http://$1:9000/trans_buy_f1324_4
-wget http://$1:9000/trans_add_f1325_1_100
-wget http://$1:9000/trans_buy_f1325_0
-wget http://$1:9000/trans_add_f1326_2_150
-wget http://$1:9000/trans_buy_f1326_1
-wget http://$1:9000/trans_add_f1327_3_200
-wget http://$1:9000/trans_buy_f1327_2
-wget http://$1:9000/trans_add_f1328_4_50
-wget http://$1:9000/trans_buy_f1328_3
-wget http://$1:9000/trans_add_f1329_5_100
-wget http://$1:9000/trans_buy_f1329_4
-wget http://$1:9000/trans_add_f1330_1_150
-wget http://$1:9000/trans_buy_f1330_0
-wget http://$1:9000/trans_add_f1331_2_200
-wget http://$1:9000/trans_buy_f1331_1
-wget http://$1:9000/trans_add_f1332_3_50
-wget http://$1:9000/trans_buy_f1332_2
-wget http://$1:9000/trans_add_f1333_4_100
-wget http://$1:9000/trans_buy_f1333_3
-wget http://$1:9000/trans_add_f1334_5_150
-wget http://$1:9000/trans_buy_f1334_4
-wget http://$1:9000/trans_add_f1335_1_200
-wget http://$1:9000/trans_buy_f1335_0
-wget http://$1:9000/trans_add_f1336_2_50
-wget http://$1:9000/trans_buy_f1336_1
-wget http://$1:9000/trans_add_f1337_3_100
-wget http://$1:9000/trans_buy_f1337_2
-wget http://$1:9000/trans_add_f1338_4_150
-wget http://$1:9000/trans_buy_f1338_3
-wget http://$1:9000/trans_add_f1339_5_200
-wget http://$1:9000/trans_buy_f1339_4
-wget http://$1:9000/trans_add_f1340_1_50
-wget http://$1:9000/trans_buy_f1340_0
-wget http://$1:9000/trans_add_f1341_2_100
-wget http://$1:9000/trans_buy_f1341_1
-wget http://$1:9000/trans_add_f1342_3_150
-wget http://$1:9000/trans_buy_f1342_2
-wget http://$1:9000/trans_add_f1343_4_200
-wget http://$1:9000/trans_buy_f1343_3
-wget http://$1:9000/trans_add_f1344_5_50
-wget http://$1:9000/trans_buy_f1344_4
-wget http://$1:9000/trans_add_f1345_1_100
-wget http://$1:9000/trans_buy_f1345_0
-wget http://$1:9000/trans_add_f1346_2_150
-wget http://$1:9000/trans_buy_f1346_1
-wget http://$1:9000/trans_add_f1347_3_200
-wget http://$1:9000/trans_buy_f1347_2
-wget http://$1:9000/trans_add_f1348_4_50
-wget http://$1:9000/trans_buy_f1348_3
-wget http://$1:9000/trans_add_f1349_5_100
-wget http://$1:9000/trans_buy_f1349_4
-wget http://$1:9000/trans_add_f1350_1_150
-wget http://$1:9000/trans_buy_f1350_0
-wget http://$1:9000/trans_add_f1351_2_200
-wget http://$1:9000/trans_buy_f1351_1
-wget http://$1:9000/trans_add_f1352_3_50
-wget http://$1:9000/trans_buy_f1352_2
-wget http://$1:9000/trans_add_f1353_4_100
-wget http://$1:9000/trans_buy_f1353_3
-wget http://$1:9000/trans_add_f1354_5_150
-wget http://$1:9000/trans_buy_f1354_4
-wget http://$1:9000/trans_add_f1355_1_200
-wget http://$1:9000/trans_buy_f1355_0
-wget http://$1:9000/trans_add_f1356_2_50
-wget http://$1:9000/trans_buy_f1356_1
-wget http://$1:9000/trans_add_f1357_3_100
-wget http://$1:9000/trans_buy_f1357_2
-wget http://$1:9000/trans_add_f1358_4_150
-wget http://$1:9000/trans_buy_f1358_3
-wget http://$1:9000/trans_add_f1359_5_200
-wget http://$1:9000/trans_buy_f1359_4
-wget http://$1:9000/trans_add_f1360_1_50
-wget http://$1:9000/trans_buy_f1360_0
-wget http://$1:9000/trans_add_f1361_2_100
-wget http://$1:9000/trans_buy_f1361_1
-wget http://$1:9000/trans_add_f1362_3_150
-wget http://$1:9000/trans_buy_f1362_2
-wget http://$1:9000/trans_add_f1363_4_200
-wget http://$1:9000/trans_buy_f1363_3
-wget http://$1:9000/trans_add_f1364_5_50
-wget http://$1:9000/trans_buy_f1364_4
-wget http://$1:9000/trans_add_f1365_1_100
-wget http://$1:9000/trans_buy_f1365_0
-wget http://$1:9000/trans_add_f1366_2_150
-wget http://$1:9000/trans_buy_f1366_1
-wget http://$1:9000/trans_add_f1367_3_200
-wget http://$1:9000/trans_buy_f1367_2
-wget http://$1:9000/trans_add_f1368_4_50
-wget http://$1:9000/trans_buy_f1368_3
-wget http://$1:9000/trans_add_f1369_5_100
-wget http://$1:9000/trans_buy_f1369_4
-wget http://$1:9000/trans_add_f1370_1_150
-wget http://$1:9000/trans_buy_f1370_0
-wget http://$1:9000/trans_add_f1371_2_200
-wget http://$1:9000/trans_buy_f1371_1
-wget http://$1:9000/trans_add_f1372_3_50
-wget http://$1:9000/trans_buy_f1372_2
-wget http://$1:9000/trans_add_f1373_4_100
-wget http://$1:9000/trans_buy_f1373_3
-wget http://$1:9000/trans_add_f1374_5_150
-wget http://$1:9000/trans_buy_f1374_4
-wget http://$1:9000/trans_add_f1375_1_200
-wget http://$1:9000/trans_buy_f1375_0
-wget http://$1:9000/trans_add_f1376_2_50
-wget http://$1:9000/trans_buy_f1376_1
-wget http://$1:9000/trans_add_f1377_3_100
-wget http://$1:9000/trans_buy_f1377_2
-wget http://$1:9000/trans_add_f1378_4_150
-wget http://$1:9000/trans_buy_f1378_3
-wget http://$1:9000/trans_add_f1379_5_200
-wget http://$1:9000/trans_buy_f1379_4
-wget http://$1:9000/trans_add_f1380_1_50
-wget http://$1:9000/trans_buy_f1380_0
-wget http://$1:9000/trans_add_f1381_2_100
-wget http://$1:9000/trans_buy_f1381_1
-wget http://$1:9000/trans_add_f1382_3_150
-wget http://$1:9000/trans_buy_f1382_2
-wget http://$1:9000/trans_add_f1383_4_200
-wget http://$1:9000/trans_buy_f1383_3
-wget http://$1:9000/trans_add_f1384_5_50
-wget http://$1:9000/trans_buy_f1384_4
-wget http://$1:9000/trans_add_f1385_1_100
-wget http://$1:9000/trans_buy_f1385_0
-wget http://$1:9000/trans_add_f1386_2_150
-wget http://$1:9000/trans_buy_f1386_1
-wget http://$1:9000/trans_add_f1387_3_200
-wget http://$1:9000/trans_buy_f1387_2
-wget http://$1:9000/trans_add_f1388_4_50
-wget http://$1:9000/trans_buy_f1388_3
-wget http://$1:9000/trans_add_f1389_5_100
-wget http://$1:9000/trans_buy_f1389_4
-wget http://$1:9000/trans_add_f1390_1_150
-wget http://$1:9000/trans_buy_f1390_0
-wget http://$1:9000/trans_add_f1391_2_200
-wget http://$1:9000/trans_buy_f1391_1
-wget http://$1:9000/trans_add_f1392_3_50
-wget http://$1:9000/trans_buy_f1392_2
-wget http://$1:9000/trans_add_f1393_4_100
-wget http://$1:9000/trans_buy_f1393_3
-wget http://$1:9000/trans_add_f1394_5_150
-wget http://$1:9000/trans_buy_f1394_4
-wget http://$1:9000/trans_add_f1395_1_200
-wget http://$1:9000/trans_buy_f1395_0
-wget http://$1:9000/trans_add_f1396_2_50
-wget http://$1:9000/trans_buy_f1396_1
-wget http://$1:9000/trans_add_f1397_3_100
-wget http://$1:9000/trans_buy_f1397_2
-wget http://$1:9000/trans_add_f1398_4_150
-wget http://$1:9000/trans_buy_f1398_3
-wget http://$1:9000/trans_add_f1399_5_200
-wget http://$1:9000/trans_buy_f1399_4
-wget http://$1:9000/trans_add_f1400_1_50
-wget http://$1:9000/trans_buy_f1400_0
-wget http://$1:9000/trans_add_f1401_2_100
-wget http://$1:9000/trans_buy_f1401_1
-wget http://$1:9000/trans_add_f1402_3_150
-wget http://$1:9000/trans_buy_f1402_2
-wget http://$1:9000/trans_add_f1403_4_200
-wget http://$1:9000/trans_buy_f1403_3
-wget http://$1:9000/trans_add_f1404_5_50
-wget http://$1:9000/trans_buy_f1404_4
-wget http://$1:9000/trans_add_f1405_1_100
-wget http://$1:9000/trans_buy_f1405_0
-wget http://$1:9000/trans_add_f1406_2_150
-wget http://$1:9000/trans_buy_f1406_1
-wget http://$1:9000/trans_add_f1407_3_200
-wget http://$1:9000/trans_buy_f1407_2
-wget http://$1:9000/trans_add_f1408_4_50
-wget http://$1:9000/trans_buy_f1408_3
-wget http://$1:9000/trans_add_f1409_5_100
-wget http://$1:9000/trans_buy_f1409_4
-wget http://$1:9000/trans_add_f1410_1_150
-wget http://$1:9000/trans_buy_f1410_0
-wget http://$1:9000/trans_add_f1411_2_200
-wget http://$1:9000/trans_buy_f1411_1
-wget http://$1:9000/trans_add_f1412_3_50
-wget http://$1:9000/trans_buy_f1412_2
-wget http://$1:9000/trans_add_f1413_4_100
-wget http://$1:9000/trans_buy_f1413_3
-wget http://$1:9000/trans_add_f1414_5_150
-wget http://$1:9000/trans_buy_f1414_4
-wget http://$1:9000/trans_add_f1415_1_200
-wget http://$1:9000/trans_buy_f1415_0
-wget http://$1:9000/trans_add_f1416_2_50
-wget http://$1:9000/trans_buy_f1416_1
-wget http://$1:9000/trans_add_f1417_3_100
-wget http://$1:9000/trans_buy_f1417_2
-wget http://$1:9000/trans_add_f1418_4_150
-wget http://$1:9000/trans_buy_f1418_3
-wget http://$1:9000/trans_add_f1419_5_200
-wget http://$1:9000/trans_buy_f1419_4
-wget http://$1:9000/trans_add_f1420_1_50
-wget http://$1:9000/trans_buy_f1420_0
-wget http://$1:9000/trans_add_f1421_2_100
-wget http://$1:9000/trans_buy_f1421_1
-wget http://$1:9000/trans_add_f1422_3_150
-wget http://$1:9000/trans_buy_f1422_2
-wget http://$1:9000/trans_add_f1423_4_200
-wget http://$1:9000/trans_buy_f1423_3
-wget http://$1:9000/trans_add_f1424_5_50
-wget http://$1:9000/trans_buy_f1424_4
-wget http://$1:9000/trans_add_f1425_1_100
-wget http://$1:9000/trans_buy_f1425_0
-wget http://$1:9000/trans_add_f1426_2_150
-wget http://$1:9000/trans_buy_f1426_1
-wget http://$1:9000/trans_add_f1427_3_200
-wget http://$1:9000/trans_buy_f1427_2
-wget http://$1:9000/trans_add_f1428_4_50
-wget http://$1:9000/trans_buy_f1428_3
-wget http://$1:9000/trans_add_f1429_5_100
-wget http://$1:9000/trans_buy_f1429_4
-wget http://$1:9000/trans_add_f1430_1_150
-wget http://$1:9000/trans_buy_f1430_0
-wget http://$1:9000/trans_add_f1431_2_200
-wget http://$1:9000/trans_buy_f1431_1
-wget http://$1:9000/trans_add_f1432_3_50
-wget http://$1:9000/trans_buy_f1432_2
-wget http://$1:9000/trans_add_f1433_4_100
-wget http://$1:9000/trans_buy_f1433_3
-wget http://$1:9000/trans_add_f1434_5_150
-wget http://$1:9000/trans_buy_f1434_4
-wget http://$1:9000/trans_add_f1435_1_200
-wget http://$1:9000/trans_buy_f1435_0
-wget http://$1:9000/trans_add_f1436_2_50
-wget http://$1:9000/trans_buy_f1436_1
-wget http://$1:9000/trans_add_f1437_3_100
-wget http://$1:9000/trans_buy_f1437_2
-wget http://$1:9000/trans_add_f1438_4_150
-wget http://$1:9000/trans_buy_f1438_3
-wget http://$1:9000/trans_add_f1439_5_200
-wget http://$1:9000/trans_buy_f1439_4
-wget http://$1:9000/trans_add_f1440_1_50
-wget http://$1:9000/trans_buy_f1440_0
-wget http://$1:9000/trans_add_f1441_2_100
-wget http://$1:9000/trans_buy_f1441_1
-wget http://$1:9000/trans_add_f1442_3_150
-wget http://$1:9000/trans_buy_f1442_2
-wget http://$1:9000/trans_add_f1443_4_200
-wget http://$1:9000/trans_buy_f1443_3
-wget http://$1:9000/trans_add_f1444_5_50
-wget http://$1:9000/trans_buy_f1444_4
-wget http://$1:9000/trans_add_f1445_1_100
-wget http://$1:9000/trans_buy_f1445_0
-wget http://$1:9000/trans_add_f1446_2_150
-wget http://$1:9000/trans_buy_f1446_1
-wget http://$1:9000/trans_add_f1447_3_200
-wget http://$1:9000/trans_buy_f1447_2
-wget http://$1:9000/trans_add_f1448_4_50
-wget http://$1:9000/trans_buy_f1448_3
-wget http://$1:9000/trans_add_f1449_5_100
-wget http://$1:9000/trans_buy_f1449_4
-wget http://$1:9000/trans_add_f1450_1_150
-wget http://$1:9000/trans_buy_f1450_0
-wget http://$1:9000/trans_add_f1451_2_200
-wget http://$1:9000/trans_buy_f1451_1
-wget http://$1:9000/trans_add_f1452_3_50
-wget http://$1:9000/trans_buy_f1452_2
-wget http://$1:9000/trans_add_f1453_4_100
-wget http://$1:9000/trans_buy_f1453_3
-wget http://$1:9000/trans_add_f1454_5_150
-wget http://$1:9000/trans_buy_f1454_4
-wget http://$1:9000/trans_add_f1455_1_200
-wget http://$1:9000/trans_buy_f1455_0
-wget http://$1:9000/trans_add_f1456_2_50
-wget http://$1:9000/trans_buy_f1456_1
-wget http://$1:9000/trans_add_f1457_3_100
-wget http://$1:9000/trans_buy_f1457_2
-wget http://$1:9000/trans_add_f1458_4_150
-wget http://$1:9000/trans_buy_f1458_3
-wget http://$1:9000/trans_add_f1459_5_200
-wget http://$1:9000/trans_buy_f1459_4
-wget http://$1:9000/trans_add_f1460_1_50
-wget http://$1:9000/trans_buy_f1460_0
-wget http://$1:9000/trans_add_f1461_2_100
-wget http://$1:9000/trans_buy_f1461_1
-wget http://$1:9000/trans_add_f1462_3_150
-wget http://$1:9000/trans_buy_f1462_2
-wget http://$1:9000/trans_add_f1463_4_200
-wget http://$1:9000/trans_buy_f1463_3
-wget http://$1:9000/trans_add_f1464_5_50
-wget http://$1:9000/trans_buy_f1464_4
-wget http://$1:9000/trans_add_f1465_1_100
-wget http://$1:9000/trans_buy_f1465_0
-wget http://$1:9000/trans_add_f1466_2_150
-wget http://$1:9000/trans_buy_f1466_1
-wget http://$1:9000/trans_add_f1467_3_200
-wget http://$1:9000/trans_buy_f1467_2
-wget http://$1:9000/trans_add_f1468_4_50
-wget http://$1:9000/trans_buy_f1468_3
-wget http://$1:9000/trans_add_f1469_5_100
-wget http://$1:9000/trans_buy_f1469_4
-wget http://$1:9000/trans_add_f1470_1_150
-wget http://$1:9000/trans_buy_f1470_0
-wget http://$1:9000/trans_add_f1471_2_200
-wget http://$1:9000/trans_buy_f1471_1
-wget http://$1:9000/trans_add_f1472_3_50
-wget http://$1:9000/trans_buy_f1472_2
-wget http://$1:9000/trans_add_f1473_4_100
-wget http://$1:9000/trans_buy_f1473_3
-wget http://$1:9000/trans_add_f1474_5_150
-wget http://$1:9000/trans_buy_f1474_4
-wget http://$1:9000/trans_add_f1475_1_200
-wget http://$1:9000/trans_buy_f1475_0
-wget http://$1:9000/trans_add_f1476_2_50
-wget http://$1:9000/trans_buy_f1476_1
-wget http://$1:9000/trans_add_f1477_3_100
-wget http://$1:9000/trans_buy_f1477_2
-wget http://$1:9000/trans_add_f1478_4_150
-wget http://$1:9000/trans_buy_f1478_3
-wget http://$1:9000/trans_add_f1479_5_200
-wget http://$1:9000/trans_buy_f1479_4
-wget http://$1:9000/trans_add_f1480_1_50
-wget http://$1:9000/trans_buy_f1480_0
-wget http://$1:9000/trans_add_f1481_2_100
-wget http://$1:9000/trans_buy_f1481_1
-wget http://$1:9000/trans_add_f1482_3_150
-wget http://$1:9000/trans_buy_f1482_2
-wget http://$1:9000/trans_add_f1483_4_200
-wget http://$1:9000/trans_buy_f1483_3
-wget http://$1:9000/trans_add_f1484_5_50
-wget http://$1:9000/trans_buy_f1484_4
-wget http://$1:9000/trans_add_f1485_1_100
-wget http://$1:9000/trans_buy_f1485_0
-wget http://$1:9000/trans_add_f1486_2_150
-wget http://$1:9000/trans_buy_f1486_1
-wget http://$1:9000/trans_add_f1487_3_200
-wget http://$1:9000/trans_buy_f1487_2
-wget http://$1:9000/trans_add_f1488_4_50
-wget http://$1:9000/trans_buy_f1488_3
-wget http://$1:9000/trans_add_f1489_5_100
-wget http://$1:9000/trans_buy_f1489_4
-wget http://$1:9000/trans_add_f1490_1_150
-wget http://$1:9000/trans_buy_f1490_0
-wget http://$1:9000/trans_add_f1491_2_200
-wget http://$1:9000/trans_buy_f1491_1
-wget http://$1:9000/trans_add_f1492_3_50
-wget http://$1:9000/trans_buy_f1492_2
-wget http://$1:9000/trans_add_f1493_4_100
-wget http://$1:9000/trans_buy_f1493_3
-wget http://$1:9000/trans_add_f1494_5_150
-wget http://$1:9000/trans_buy_f1494_4
-wget http://$1:9000/trans_add_f1495_1_200
-wget http://$1:9000/trans_buy_f1495_0
-wget http://$1:9000/trans_add_f1496_2_50
-wget http://$1:9000/trans_buy_f1496_1
-wget http://$1:9000/trans_add_f1497_3_100
-wget http://$1:9000/trans_buy_f1497_2
-wget http://$1:9000/trans_add_f1498_4_150
-wget http://$1:9000/trans_buy_f1498_3
-wget http://$1:9000/trans_add_f1499_5_200
-wget http://$1:9000/trans_buy_f1499_4
-wget http://$1:9000/trans_add_f1500_1_50
-wget http://$1:9000/trans_buy_f1500_0
-wget http://$1:9000/trans_add_f1501_2_100
-wget http://$1:9000/trans_buy_f1501_1
-wget http://$1:9000/trans_add_f1502_3_150
-wget http://$1:9000/trans_buy_f1502_2
-wget http://$1:9000/trans_add_f1503_4_200
-wget http://$1:9000/trans_buy_f1503_3
-wget http://$1:9000/trans_add_f1504_5_50
-wget http://$1:9000/trans_buy_f1504_4
-wget http://$1:9000/trans_add_f1505_1_100
-wget http://$1:9000/trans_buy_f1505_0
-wget http://$1:9000/trans_add_f1506_2_150
-wget http://$1:9000/trans_buy_f1506_1
-wget http://$1:9000/trans_add_f1507_3_200
-wget http://$1:9000/trans_buy_f1507_2
-wget http://$1:9000/trans_add_f1508_4_50
-wget http://$1:9000/trans_buy_f1508_3
-wget http://$1:9000/trans_add_f1509_5_100
-wget http://$1:9000/trans_buy_f1509_4
-wget http://$1:9000/trans_add_f1510_1_150
-wget http://$1:9000/trans_buy_f1510_0
-wget http://$1:9000/trans_add_f1511_2_200
-wget http://$1:9000/trans_buy_f1511_1
-wget http://$1:9000/trans_add_f1512_3_50
-wget http://$1:9000/trans_buy_f1512_2
-wget http://$1:9000/trans_add_f1513_4_100
-wget http://$1:9000/trans_buy_f1513_3
-wget http://$1:9000/trans_add_f1514_5_150
-wget http://$1:9000/trans_buy_f1514_4
-wget http://$1:9000/trans_add_f1515_1_200
-wget http://$1:9000/trans_buy_f1515_0
-wget http://$1:9000/trans_add_f1516_2_50
-wget http://$1:9000/trans_buy_f1516_1
-wget http://$1:9000/trans_add_f1517_3_100
-wget http://$1:9000/trans_buy_f1517_2
-wget http://$1:9000/trans_add_f1518_4_150
-wget http://$1:9000/trans_buy_f1518_3
-wget http://$1:9000/trans_add_f1519_5_200
-wget http://$1:9000/trans_buy_f1519_4
-wget http://$1:9000/trans_add_f1520_1_50
-wget http://$1:9000/trans_buy_f1520_0
-wget http://$1:9000/trans_add_f1521_2_100
-wget http://$1:9000/trans_buy_f1521_1
-wget http://$1:9000/trans_add_f1522_3_150
-wget http://$1:9000/trans_buy_f1522_2
-wget http://$1:9000/trans_add_f1523_4_200
-wget http://$1:9000/trans_buy_f1523_3
-wget http://$1:9000/trans_add_f1524_5_50
-wget http://$1:9000/trans_buy_f1524_4
-wget http://$1:9000/trans_add_f1525_1_100
-wget http://$1:9000/trans_buy_f1525_0
-wget http://$1:9000/trans_add_f1526_2_150
-wget http://$1:9000/trans_buy_f1526_1
-wget http://$1:9000/trans_add_f1527_3_200
-wget http://$1:9000/trans_buy_f1527_2
-wget http://$1:9000/trans_add_f1528_4_50
-wget http://$1:9000/trans_buy_f1528_3
-wget http://$1:9000/trans_add_f1529_5_100
-wget http://$1:9000/trans_buy_f1529_4
-wget http://$1:9000/trans_add_f1530_1_150
-wget http://$1:9000/trans_buy_f1530_0
-wget http://$1:9000/trans_add_f1531_2_200
-wget http://$1:9000/trans_buy_f1531_1
-wget http://$1:9000/trans_add_f1532_3_50
-wget http://$1:9000/trans_buy_f1532_2
-wget http://$1:9000/trans_add_f1533_4_100
-wget http://$1:9000/trans_buy_f1533_3
-wget http://$1:9000/trans_add_f1534_5_150
-wget http://$1:9000/trans_buy_f1534_4
-wget http://$1:9000/trans_add_f1535_1_200
-wget http://$1:9000/trans_buy_f1535_0
-wget http://$1:9000/trans_add_f1536_2_50
-wget http://$1:9000/trans_buy_f1536_1
-wget http://$1:9000/trans_add_f1537_3_100
-wget http://$1:9000/trans_buy_f1537_2
-wget http://$1:9000/trans_add_f1538_4_150
-wget http://$1:9000/trans_buy_f1538_3
-wget http://$1:9000/trans_add_f1539_5_200
-wget http://$1:9000/trans_buy_f1539_4
-wget http://$1:9000/trans_add_f1540_1_50
-wget http://$1:9000/trans_buy_f1540_0
-wget http://$1:9000/trans_add_f1541_2_100
-wget http://$1:9000/trans_buy_f1541_1
-wget http://$1:9000/trans_add_f1542_3_150
-wget http://$1:9000/trans_buy_f1542_2
-wget http://$1:9000/trans_add_f1543_4_200
-wget http://$1:9000/trans_buy_f1543_3
-wget http://$1:9000/trans_add_f1544_5_50
-wget http://$1:9000/trans_buy_f1544_4
-wget http://$1:9000/trans_add_f1545_1_100
-wget http://$1:9000/trans_buy_f1545_0
-wget http://$1:9000/trans_add_f1546_2_150
-wget http://$1:9000/trans_buy_f1546_1
-wget http://$1:9000/trans_add_f1547_3_200
-wget http://$1:9000/trans_buy_f1547_2
-wget http://$1:9000/trans_add_f1548_4_50
-wget http://$1:9000/trans_buy_f1548_3
-wget http://$1:9000/trans_add_f1549_5_100
-wget http://$1:9000/trans_buy_f1549_4
-wget http://$1:9000/trans_add_f1550_1_150
-wget http://$1:9000/trans_buy_f1550_0
-wget http://$1:9000/trans_add_f1551_2_200
-wget http://$1:9000/trans_buy_f1551_1
-wget http://$1:9000/trans_add_f1552_3_50
-wget http://$1:9000/trans_buy_f1552_2
-wget http://$1:9000/trans_add_f1553_4_100
-wget http://$1:9000/trans_buy_f1553_3
-wget http://$1:9000/trans_add_f1554_5_150
-wget http://$1:9000/trans_buy_f1554_4
-wget http://$1:9000/trans_add_f1555_1_200
-wget http://$1:9000/trans_buy_f1555_0
-wget http://$1:9000/trans_add_f1556_2_50
-wget http://$1:9000/trans_buy_f1556_1
-wget http://$1:9000/trans_add_f1557_3_100
-wget http://$1:9000/trans_buy_f1557_2
-wget http://$1:9000/trans_add_f1558_4_150
-wget http://$1:9000/trans_buy_f1558_3
-wget http://$1:9000/trans_add_f1559_5_200
-wget http://$1:9000/trans_buy_f1559_4
-wget http://$1:9000/trans_add_f1560_1_50
-wget http://$1:9000/trans_buy_f1560_0
-wget http://$1:9000/trans_add_f1561_2_100
-wget http://$1:9000/trans_buy_f1561_1
-wget http://$1:9000/trans_add_f1562_3_150
-wget http://$1:9000/trans_buy_f1562_2
-wget http://$1:9000/trans_add_f1563_4_200
-wget http://$1:9000/trans_buy_f1563_3
-wget http://$1:9000/trans_add_f1564_5_50
-wget http://$1:9000/trans_buy_f1564_4
-wget http://$1:9000/trans_add_f1565_1_100
-wget http://$1:9000/trans_buy_f1565_0
-wget http://$1:9000/trans_add_f1566_2_150
-wget http://$1:9000/trans_buy_f1566_1
-wget http://$1:9000/trans_add_f1567_3_200
-wget http://$1:9000/trans_buy_f1567_2
-wget http://$1:9000/trans_add_f1568_4_50
-wget http://$1:9000/trans_buy_f1568_3
-wget http://$1:9000/trans_add_f1569_5_100
-wget http://$1:9000/trans_buy_f1569_4
-wget http://$1:9000/trans_add_f1570_1_150
-wget http://$1:9000/trans_buy_f1570_0
-wget http://$1:9000/trans_add_f1571_2_200
-wget http://$1:9000/trans_buy_f1571_1
-wget http://$1:9000/trans_add_f1572_3_50
-wget http://$1:9000/trans_buy_f1572_2
-wget http://$1:9000/trans_add_f1573_4_100
-wget http://$1:9000/trans_buy_f1573_3
-wget http://$1:9000/trans_add_f1574_5_150
-wget http://$1:9000/trans_buy_f1574_4
-wget http://$1:9000/trans_add_f1575_1_200
-wget http://$1:9000/trans_buy_f1575_0
-wget http://$1:9000/trans_add_f1576_2_50
-wget http://$1:9000/trans_buy_f1576_1
-wget http://$1:9000/trans_add_f1577_3_100
-wget http://$1:9000/trans_buy_f1577_2
-wget http://$1:9000/trans_add_f1578_4_150
-wget http://$1:9000/trans_buy_f1578_3
-wget http://$1:9000/trans_add_f1579_5_200
-wget http://$1:9000/trans_buy_f1579_4
-wget http://$1:9000/trans_add_f1580_1_50
-wget http://$1:9000/trans_buy_f1580_0
-wget http://$1:9000/trans_add_f1581_2_100
-wget http://$1:9000/trans_buy_f1581_1
-wget http://$1:9000/trans_add_f1582_3_150
-wget http://$1:9000/trans_buy_f1582_2
-wget http://$1:9000/trans_add_f1583_4_200
-wget http://$1:9000/trans_buy_f1583_3
-wget http://$1:9000/trans_add_f1584_5_50
-wget http://$1:9000/trans_buy_f1584_4
-wget http://$1:9000/trans_add_f1585_1_100
-wget http://$1:9000/trans_buy_f1585_0
-wget http://$1:9000/trans_add_f1586_2_150
-wget http://$1:9000/trans_buy_f1586_1
-wget http://$1:9000/trans_add_f1587_3_200
-wget http://$1:9000/trans_buy_f1587_2
-wget http://$1:9000/trans_add_f1588_4_50
-wget http://$1:9000/trans_buy_f1588_3
-wget http://$1:9000/trans_add_f1589_5_100
-wget http://$1:9000/trans_buy_f1589_4
-wget http://$1:9000/trans_add_f1590_1_150
-wget http://$1:9000/trans_buy_f1590_0
-wget http://$1:9000/trans_add_f1591_2_200
-wget http://$1:9000/trans_buy_f1591_1
-wget http://$1:9000/trans_add_f1592_3_50
-wget http://$1:9000/trans_buy_f1592_2
-wget http://$1:9000/trans_add_f1593_4_100
-wget http://$1:9000/trans_buy_f1593_3
-wget http://$1:9000/trans_add_f1594_5_150
-wget http://$1:9000/trans_buy_f1594_4
-wget http://$1:9000/trans_add_f1595_1_200
-wget http://$1:9000/trans_buy_f1595_0
-wget http://$1:9000/trans_add_f1596_2_50
-wget http://$1:9000/trans_buy_f1596_1
-wget http://$1:9000/trans_add_f1597_3_100
-wget http://$1:9000/trans_buy_f1597_2
-wget http://$1:9000/trans_add_f1598_4_150
-wget http://$1:9000/trans_buy_f1598_3
-wget http://$1:9000/trans_add_f1599_5_200
-wget http://$1:9000/trans_buy_f1599_4
-wget http://$1:9000/trans_add_f1600_1_50
-wget http://$1:9000/trans_buy_f1600_0
-wget http://$1:9000/trans_add_f1601_2_100
-wget http://$1:9000/trans_buy_f1601_1
-wget http://$1:9000/trans_add_f1602_3_150
-wget http://$1:9000/trans_buy_f1602_2
-wget http://$1:9000/trans_add_f1603_4_200
-wget http://$1:9000/trans_buy_f1603_3
-wget http://$1:9000/trans_add_f1604_5_50
-wget http://$1:9000/trans_buy_f1604_4
-wget http://$1:9000/trans_add_f1605_1_100
-wget http://$1:9000/trans_buy_f1605_0
-wget http://$1:9000/trans_add_f1606_2_150
-wget http://$1:9000/trans_buy_f1606_1
-wget http://$1:9000/trans_add_f1607_3_200
-wget http://$1:9000/trans_buy_f1607_2
-wget http://$1:9000/trans_add_f1608_4_50
-wget http://$1:9000/trans_buy_f1608_3
-wget http://$1:9000/trans_add_f1609_5_100
-wget http://$1:9000/trans_buy_f1609_4
-wget http://$1:9000/trans_add_f1610_1_150
-wget http://$1:9000/trans_buy_f1610_0
-wget http://$1:9000/trans_add_f1611_2_200
-wget http://$1:9000/trans_buy_f1611_1
-wget http://$1:9000/trans_add_f1612_3_50
-wget http://$1:9000/trans_buy_f1612_2
-wget http://$1:9000/trans_add_f1613_4_100
-wget http://$1:9000/trans_buy_f1613_3
-wget http://$1:9000/trans_add_f1614_5_150
-wget http://$1:9000/trans_buy_f1614_4
-wget http://$1:9000/trans_add_f1615_1_200
-wget http://$1:9000/trans_buy_f1615_0
-wget http://$1:9000/trans_add_f1616_2_50
-wget http://$1:9000/trans_buy_f1616_1
-wget http://$1:9000/trans_add_f1617_3_100
-wget http://$1:9000/trans_buy_f1617_2
-wget http://$1:9000/trans_add_f1618_4_150
-wget http://$1:9000/trans_buy_f1618_3
-wget http://$1:9000/trans_add_f1619_5_200
-wget http://$1:9000/trans_buy_f1619_4
-wget http://$1:9000/trans_add_f1620_1_50
-wget http://$1:9000/trans_buy_f1620_0
-wget http://$1:9000/trans_add_f1621_2_100
-wget http://$1:9000/trans_buy_f1621_1
-wget http://$1:9000/trans_add_f1622_3_150
-wget http://$1:9000/trans_buy_f1622_2
-wget http://$1:9000/trans_add_f1623_4_200
-wget http://$1:9000/trans_buy_f1623_3
-wget http://$1:9000/trans_add_f1624_5_50
-wget http://$1:9000/trans_buy_f1624_4
-wget http://$1:9000/trans_add_f1625_1_100
-wget http://$1:9000/trans_buy_f1625_0
-wget http://$1:9000/trans_add_f1626_2_150
-wget http://$1:9000/trans_buy_f1626_1
-wget http://$1:9000/trans_add_f1627_3_200
-wget http://$1:9000/trans_buy_f1627_2
-wget http://$1:9000/trans_add_f1628_4_50
-wget http://$1:9000/trans_buy_f1628_3
-wget http://$1:9000/trans_add_f1629_5_100
-wget http://$1:9000/trans_buy_f1629_4
-wget http://$1:9000/trans_add_f1630_1_150
-wget http://$1:9000/trans_buy_f1630_0
-wget http://$1:9000/trans_add_f1631_2_200
-wget http://$1:9000/trans_buy_f1631_1
-wget http://$1:9000/trans_add_f1632_3_50
-wget http://$1:9000/trans_buy_f1632_2
-wget http://$1:9000/trans_add_f1633_4_100
-wget http://$1:9000/trans_buy_f1633_3
-wget http://$1:9000/trans_add_f1634_5_150
-wget http://$1:9000/trans_buy_f1634_4
-wget http://$1:9000/trans_add_f1635_1_200
-wget http://$1:9000/trans_buy_f1635_0
-wget http://$1:9000/trans_add_f1636_2_50
-wget http://$1:9000/trans_buy_f1636_1
-wget http://$1:9000/trans_add_f1637_3_100
-wget http://$1:9000/trans_buy_f1637_2
-wget http://$1:9000/trans_add_f1638_4_150
-wget http://$1:9000/trans_buy_f1638_3
-wget http://$1:9000/trans_add_f1639_5_200
-wget http://$1:9000/trans_buy_f1639_4
-wget http://$1:9000/trans_add_f1640_1_50
-wget http://$1:9000/trans_buy_f1640_0
-wget http://$1:9000/trans_add_f1641_2_100
-wget http://$1:9000/trans_buy_f1641_1
-wget http://$1:9000/trans_add_f1642_3_150
-wget http://$1:9000/trans_buy_f1642_2
-wget http://$1:9000/trans_add_f1643_4_200
-wget http://$1:9000/trans_buy_f1643_3
-wget http://$1:9000/trans_add_f1644_5_50
-wget http://$1:9000/trans_buy_f1644_4
-wget http://$1:9000/trans_add_f1645_1_100
-wget http://$1:9000/trans_buy_f1645_0
-wget http://$1:9000/trans_add_f1646_2_150
-wget http://$1:9000/trans_buy_f1646_1
-wget http://$1:9000/trans_add_f1647_3_200
-wget http://$1:9000/trans_buy_f1647_2
-wget http://$1:9000/trans_add_f1648_4_50
-wget http://$1:9000/trans_buy_f1648_3
-wget http://$1:9000/trans_add_f1649_5_100
-wget http://$1:9000/trans_buy_f1649_4
-wget http://$1:9000/trans_add_f1650_1_150
-wget http://$1:9000/trans_buy_f1650_0
-wget http://$1:9000/trans_add_f1651_2_200
-wget http://$1:9000/trans_buy_f1651_1
-wget http://$1:9000/trans_add_f1652_3_50
-wget http://$1:9000/trans_buy_f1652_2
-wget http://$1:9000/trans_add_f1653_4_100
-wget http://$1:9000/trans_buy_f1653_3
-wget http://$1:9000/trans_add_f1654_5_150
-wget http://$1:9000/trans_buy_f1654_4
-wget http://$1:9000/trans_add_f1655_1_200
-wget http://$1:9000/trans_buy_f1655_0
-wget http://$1:9000/trans_add_f1656_2_50
-wget http://$1:9000/trans_buy_f1656_1
-wget http://$1:9000/trans_add_f1657_3_100
-wget http://$1:9000/trans_buy_f1657_2
-wget http://$1:9000/trans_add_f1658_4_150
-wget http://$1:9000/trans_buy_f1658_3
-wget http://$1:9000/trans_add_f1659_5_200
-wget http://$1:9000/trans_buy_f1659_4
-wget http://$1:9000/trans_add_f1660_1_50
-wget http://$1:9000/trans_buy_f1660_0
-wget http://$1:9000/trans_add_f1661_2_100
-wget http://$1:9000/trans_buy_f1661_1
-wget http://$1:9000/trans_add_f1662_3_150
-wget http://$1:9000/trans_buy_f1662_2
-wget http://$1:9000/trans_add_f1663_4_200
-wget http://$1:9000/trans_buy_f1663_3
-wget http://$1:9000/trans_add_f1664_5_50
-wget http://$1:9000/trans_buy_f1664_4
-wget http://$1:9000/trans_add_f1665_1_100
-wget http://$1:9000/trans_buy_f1665_0
-wget http://$1:9000/trans_add_f1666_2_150
-wget http://$1:9000/trans_buy_f1666_1
-wget http://$1:9000/trans_add_f1667_3_200
-wget http://$1:9000/trans_buy_f1667_2
-wget http://$1:9000/trans_add_f1668_4_50
-wget http://$1:9000/trans_buy_f1668_3
-wget http://$1:9000/trans_add_f1669_5_100
-wget http://$1:9000/trans_buy_f1669_4
-wget http://$1:9000/trans_add_f1670_1_150
-wget http://$1:9000/trans_buy_f1670_0
-wget http://$1:9000/trans_add_f1671_2_200
-wget http://$1:9000/trans_buy_f1671_1
-wget http://$1:9000/trans_add_f1672_3_50
-wget http://$1:9000/trans_buy_f1672_2
-wget http://$1:9000/trans_add_f1673_4_100
-wget http://$1:9000/trans_buy_f1673_3
-wget http://$1:9000/trans_add_f1674_5_150
-wget http://$1:9000/trans_buy_f1674_4
-wget http://$1:9000/trans_add_f1675_1_200
-wget http://$1:9000/trans_buy_f1675_0
-wget http://$1:9000/trans_add_f1676_2_50
-wget http://$1:9000/trans_buy_f1676_1
-wget http://$1:9000/trans_add_f1677_3_100
-wget http://$1:9000/trans_buy_f1677_2
-wget http://$1:9000/trans_add_f1678_4_150
-wget http://$1:9000/trans_buy_f1678_3
-wget http://$1:9000/trans_add_f1679_5_200
-wget http://$1:9000/trans_buy_f1679_4
-wget http://$1:9000/trans_add_f1680_1_50
-wget http://$1:9000/trans_buy_f1680_0
-wget http://$1:9000/trans_add_f1681_2_100
-wget http://$1:9000/trans_buy_f1681_1
-wget http://$1:9000/trans_add_f1682_3_150
-wget http://$1:9000/trans_buy_f1682_2
-wget http://$1:9000/trans_add_f1683_4_200
-wget http://$1:9000/trans_buy_f1683_3
-wget http://$1:9000/trans_add_f1684_5_50
-wget http://$1:9000/trans_buy_f1684_4
-wget http://$1:9000/trans_add_f1685_1_100
-wget http://$1:9000/trans_buy_f1685_0
-wget http://$1:9000/trans_add_f1686_2_150
-wget http://$1:9000/trans_buy_f1686_1
-wget http://$1:9000/trans_add_f1687_3_200
-wget http://$1:9000/trans_buy_f1687_2
-wget http://$1:9000/trans_add_f1688_4_50
-wget http://$1:9000/trans_buy_f1688_3
-wget http://$1:9000/trans_add_f1689_5_100
-wget http://$1:9000/trans_buy_f1689_4
-wget http://$1:9000/trans_add_f1690_1_150
-wget http://$1:9000/trans_buy_f1690_0
-wget http://$1:9000/trans_add_f1691_2_200
-wget http://$1:9000/trans_buy_f1691_1
-wget http://$1:9000/trans_add_f1692_3_50
-wget http://$1:9000/trans_buy_f1692_2
-wget http://$1:9000/trans_add_f1693_4_100
-wget http://$1:9000/trans_buy_f1693_3
-wget http://$1:9000/trans_add_f1694_5_150
-wget http://$1:9000/trans_buy_f1694_4
-wget http://$1:9000/trans_add_f1695_1_200
-wget http://$1:9000/trans_buy_f1695_0
-wget http://$1:9000/trans_add_f1696_2_50
-wget http://$1:9000/trans_buy_f1696_1
-wget http://$1:9000/trans_add_f1697_3_100
-wget http://$1:9000/trans_buy_f1697_2
-wget http://$1:9000/trans_add_f1698_4_150
-wget http://$1:9000/trans_buy_f1698_3
-wget http://$1:9000/trans_add_f1699_5_200
-wget http://$1:9000/trans_buy_f1699_4
-wget http://$1:9000/trans_add_f1700_1_50
-wget http://$1:9000/trans_buy_f1700_0
-wget http://$1:9000/trans_add_f1701_2_100
-wget http://$1:9000/trans_buy_f1701_1
-wget http://$1:9000/trans_add_f1702_3_150
-wget http://$1:9000/trans_buy_f1702_2
-wget http://$1:9000/trans_add_f1703_4_200
-wget http://$1:9000/trans_buy_f1703_3
-wget http://$1:9000/trans_add_f1704_5_50
-wget http://$1:9000/trans_buy_f1704_4
-wget http://$1:9000/trans_add_f1705_1_100
-wget http://$1:9000/trans_buy_f1705_0
-wget http://$1:9000/trans_add_f1706_2_150
-wget http://$1:9000/trans_buy_f1706_1
-wget http://$1:9000/trans_add_f1707_3_200
-wget http://$1:9000/trans_buy_f1707_2
-wget http://$1:9000/trans_add_f1708_4_50
-wget http://$1:9000/trans_buy_f1708_3
-wget http://$1:9000/trans_add_f1709_5_100
-wget http://$1:9000/trans_buy_f1709_4
-wget http://$1:9000/trans_add_f1710_1_150
-wget http://$1:9000/trans_buy_f1710_0
-wget http://$1:9000/trans_add_f1711_2_200
-wget http://$1:9000/trans_buy_f1711_1
-wget http://$1:9000/trans_add_f1712_3_50
-wget http://$1:9000/trans_buy_f1712_2
-wget http://$1:9000/trans_add_f1713_4_100
-wget http://$1:9000/trans_buy_f1713_3
-wget http://$1:9000/trans_add_f1714_5_150
-wget http://$1:9000/trans_buy_f1714_4
-wget http://$1:9000/trans_add_f1715_1_200
-wget http://$1:9000/trans_buy_f1715_0
-wget http://$1:9000/trans_add_f1716_2_50
-wget http://$1:9000/trans_buy_f1716_1
-wget http://$1:9000/trans_add_f1717_3_100
-wget http://$1:9000/trans_buy_f1717_2
-wget http://$1:9000/trans_add_f1718_4_150
-wget http://$1:9000/trans_buy_f1718_3
-wget http://$1:9000/trans_add_f1719_5_200
-wget http://$1:9000/trans_buy_f1719_4
-wget http://$1:9000/trans_add_f1720_1_50
-wget http://$1:9000/trans_buy_f1720_0
-wget http://$1:9000/trans_add_f1721_2_100
-wget http://$1:9000/trans_buy_f1721_1
-wget http://$1:9000/trans_add_f1722_3_150
-wget http://$1:9000/trans_buy_f1722_2
-wget http://$1:9000/trans_add_f1723_4_200
-wget http://$1:9000/trans_buy_f1723_3
-wget http://$1:9000/trans_add_f1724_5_50
-wget http://$1:9000/trans_buy_f1724_4
-wget http://$1:9000/trans_add_f1725_1_100
-wget http://$1:9000/trans_buy_f1725_0
-wget http://$1:9000/trans_add_f1726_2_150
-wget http://$1:9000/trans_buy_f1726_1
-wget http://$1:9000/trans_add_f1727_3_200
-wget http://$1:9000/trans_buy_f1727_2
-wget http://$1:9000/trans_add_f1728_4_50
-wget http://$1:9000/trans_buy_f1728_3
-wget http://$1:9000/trans_add_f1729_5_100
-wget http://$1:9000/trans_buy_f1729_4
-wget http://$1:9000/trans_add_f1730_1_150
-wget http://$1:9000/trans_buy_f1730_0
-wget http://$1:9000/trans_add_f1731_2_200
-wget http://$1:9000/trans_buy_f1731_1
-wget http://$1:9000/trans_add_f1732_3_50
-wget http://$1:9000/trans_buy_f1732_2
-wget http://$1:9000/trans_add_f1733_4_100
-wget http://$1:9000/trans_buy_f1733_3
-wget http://$1:9000/trans_add_f1734_5_150
-wget http://$1:9000/trans_buy_f1734_4
-wget http://$1:9000/trans_add_f1735_1_200
-wget http://$1:9000/trans_buy_f1735_0
-wget http://$1:9000/trans_add_f1736_2_50
-wget http://$1:9000/trans_buy_f1736_1
-wget http://$1:9000/trans_add_f1737_3_100
-wget http://$1:9000/trans_buy_f1737_2
-wget http://$1:9000/trans_add_f1738_4_150
-wget http://$1:9000/trans_buy_f1738_3
-wget http://$1:9000/trans_add_f1739_5_200
-wget http://$1:9000/trans_buy_f1739_4
-wget http://$1:9000/trans_add_f1740_1_50
-wget http://$1:9000/trans_buy_f1740_0
-wget http://$1:9000/trans_add_f1741_2_100
-wget http://$1:9000/trans_buy_f1741_1
-wget http://$1:9000/trans_add_f1742_3_150
-wget http://$1:9000/trans_buy_f1742_2
-wget http://$1:9000/trans_add_f1743_4_200
-wget http://$1:9000/trans_buy_f1743_3
-wget http://$1:9000/trans_add_f1744_5_50
-wget http://$1:9000/trans_buy_f1744_4
-wget http://$1:9000/trans_add_f1745_1_100
-wget http://$1:9000/trans_buy_f1745_0
-wget http://$1:9000/trans_add_f1746_2_150
-wget http://$1:9000/trans_buy_f1746_1
-wget http://$1:9000/trans_add_f1747_3_200
-wget http://$1:9000/trans_buy_f1747_2
-wget http://$1:9000/trans_add_f1748_4_50
-wget http://$1:9000/trans_buy_f1748_3
-wget http://$1:9000/trans_add_f1749_5_100
-wget http://$1:9000/trans_buy_f1749_4
-wget http://$1:9000/trans_add_f1750_1_150
-wget http://$1:9000/trans_buy_f1750_0
-wget http://$1:9000/trans_add_f1751_2_200
-wget http://$1:9000/trans_buy_f1751_1
-wget http://$1:9000/trans_add_f1752_3_50
-wget http://$1:9000/trans_buy_f1752_2
-wget http://$1:9000/trans_add_f1753_4_100
-wget http://$1:9000/trans_buy_f1753_3
-wget http://$1:9000/trans_add_f1754_5_150
-wget http://$1:9000/trans_buy_f1754_4
-wget http://$1:9000/trans_add_f1755_1_200
-wget http://$1:9000/trans_buy_f1755_0
-wget http://$1:9000/trans_add_f1756_2_50
-wget http://$1:9000/trans_buy_f1756_1
-wget http://$1:9000/trans_add_f1757_3_100
-wget http://$1:9000/trans_buy_f1757_2
-wget http://$1:9000/trans_add_f1758_4_150
-wget http://$1:9000/trans_buy_f1758_3
-wget http://$1:9000/trans_add_f1759_5_200
-wget http://$1:9000/trans_buy_f1759_4
-wget http://$1:9000/trans_add_f1760_1_50
-wget http://$1:9000/trans_buy_f1760_0
-wget http://$1:9000/trans_add_f1761_2_100
-wget http://$1:9000/trans_buy_f1761_1
-wget http://$1:9000/trans_add_f1762_3_150
-wget http://$1:9000/trans_buy_f1762_2
-wget http://$1:9000/trans_add_f1763_4_200
-wget http://$1:9000/trans_buy_f1763_3
-wget http://$1:9000/trans_add_f1764_5_50
-wget http://$1:9000/trans_buy_f1764_4
-wget http://$1:9000/trans_add_f1765_1_100
-wget http://$1:9000/trans_buy_f1765_0
-wget http://$1:9000/trans_add_f1766_2_150
-wget http://$1:9000/trans_buy_f1766_1
-wget http://$1:9000/trans_add_f1767_3_200
-wget http://$1:9000/trans_buy_f1767_2
-wget http://$1:9000/trans_add_f1768_4_50
-wget http://$1:9000/trans_buy_f1768_3
-wget http://$1:9000/trans_add_f1769_5_100
-wget http://$1:9000/trans_buy_f1769_4
-wget http://$1:9000/trans_add_f1770_1_150
-wget http://$1:9000/trans_buy_f1770_0
-wget http://$1:9000/trans_add_f1771_2_200
-wget http://$1:9000/trans_buy_f1771_1
-wget http://$1:9000/trans_add_f1772_3_50
-wget http://$1:9000/trans_buy_f1772_2
-wget http://$1:9000/trans_add_f1773_4_100
-wget http://$1:9000/trans_buy_f1773_3
-wget http://$1:9000/trans_add_f1774_5_150
-wget http://$1:9000/trans_buy_f1774_4
-wget http://$1:9000/trans_add_f1775_1_200
-wget http://$1:9000/trans_buy_f1775_0
-wget http://$1:9000/trans_add_f1776_2_50
-wget http://$1:9000/trans_buy_f1776_1
-wget http://$1:9000/trans_add_f1777_3_100
-wget http://$1:9000/trans_buy_f1777_2
-wget http://$1:9000/trans_add_f1778_4_150
-wget http://$1:9000/trans_buy_f1778_3
-wget http://$1:9000/trans_add_f1779_5_200
-wget http://$1:9000/trans_buy_f1779_4
-wget http://$1:9000/trans_add_f1780_1_50
-wget http://$1:9000/trans_buy_f1780_0
-wget http://$1:9000/trans_add_f1781_2_100
-wget http://$1:9000/trans_buy_f1781_1
-wget http://$1:9000/trans_add_f1782_3_150
-wget http://$1:9000/trans_buy_f1782_2
-wget http://$1:9000/trans_add_f1783_4_200
-wget http://$1:9000/trans_buy_f1783_3
-wget http://$1:9000/trans_add_f1784_5_50
-wget http://$1:9000/trans_buy_f1784_4
-wget http://$1:9000/trans_add_f1785_1_100
-wget http://$1:9000/trans_buy_f1785_0
-wget http://$1:9000/trans_add_f1786_2_150
-wget http://$1:9000/trans_buy_f1786_1
-wget http://$1:9000/trans_add_f1787_3_200
-wget http://$1:9000/trans_buy_f1787_2
-wget http://$1:9000/trans_add_f1788_4_50
-wget http://$1:9000/trans_buy_f1788_3
-wget http://$1:9000/trans_add_f1789_5_100
-wget http://$1:9000/trans_buy_f1789_4
-wget http://$1:9000/trans_add_f1790_1_150
-wget http://$1:9000/trans_buy_f1790_0
-wget http://$1:9000/trans_add_f1791_2_200
-wget http://$1:9000/trans_buy_f1791_1
-wget http://$1:9000/trans_add_f1792_3_50
-wget http://$1:9000/trans_buy_f1792_2
-wget http://$1:9000/trans_add_f1793_4_100
-wget http://$1:9000/trans_buy_f1793_3
-wget http://$1:9000/trans_add_f1794_5_150
-wget http://$1:9000/trans_buy_f1794_4
-wget http://$1:9000/trans_add_f1795_1_200
-wget http://$1:9000/trans_buy_f1795_0
-wget http://$1:9000/trans_add_f1796_2_50
-wget http://$1:9000/trans_buy_f1796_1
-wget http://$1:9000/trans_add_f1797_3_100
-wget http://$1:9000/trans_buy_f1797_2
-wget http://$1:9000/trans_add_f1798_4_150
-wget http://$1:9000/trans_buy_f1798_3
-wget http://$1:9000/trans_add_f1799_5_200
-wget http://$1:9000/trans_buy_f1799_4
-wget http://$1:9000/trans_add_f1800_1_50
-wget http://$1:9000/trans_buy_f1800_0
-wget http://$1:9000/trans_add_f1801_2_100
-wget http://$1:9000/trans_buy_f1801_1
-wget http://$1:9000/trans_add_f1802_3_150
-wget http://$1:9000/trans_buy_f1802_2
-wget http://$1:9000/trans_add_f1803_4_200
-wget http://$1:9000/trans_buy_f1803_3
-wget http://$1:9000/trans_add_f1804_5_50
-wget http://$1:9000/trans_buy_f1804_4
-wget http://$1:9000/trans_add_f1805_1_100
-wget http://$1:9000/trans_buy_f1805_0
-wget http://$1:9000/trans_add_f1806_2_150
-wget http://$1:9000/trans_buy_f1806_1
-wget http://$1:9000/trans_add_f1807_3_200
-wget http://$1:9000/trans_buy_f1807_2
-wget http://$1:9000/trans_add_f1808_4_50
-wget http://$1:9000/trans_buy_f1808_3
-wget http://$1:9000/trans_add_f1809_5_100
-wget http://$1:9000/trans_buy_f1809_4
-wget http://$1:9000/trans_add_f1810_1_150
-wget http://$1:9000/trans_buy_f1810_0
-wget http://$1:9000/trans_add_f1811_2_200
-wget http://$1:9000/trans_buy_f1811_1
-wget http://$1:9000/trans_add_f1812_3_50
-wget http://$1:9000/trans_buy_f1812_2
-wget http://$1:9000/trans_add_f1813_4_100
-wget http://$1:9000/trans_buy_f1813_3
-wget http://$1:9000/trans_add_f1814_5_150
-wget http://$1:9000/trans_buy_f1814_4
-wget http://$1:9000/trans_add_f1815_1_200
-wget http://$1:9000/trans_buy_f1815_0
-wget http://$1:9000/trans_add_f1816_2_50
-wget http://$1:9000/trans_buy_f1816_1
-wget http://$1:9000/trans_add_f1817_3_100
-wget http://$1:9000/trans_buy_f1817_2
-wget http://$1:9000/trans_add_f1818_4_150
-wget http://$1:9000/trans_buy_f1818_3
-wget http://$1:9000/trans_add_f1819_5_200
-wget http://$1:9000/trans_buy_f1819_4
-wget http://$1:9000/trans_add_f1820_1_50
-wget http://$1:9000/trans_buy_f1820_0
-wget http://$1:9000/trans_add_f1821_2_100
-wget http://$1:9000/trans_buy_f1821_1
-wget http://$1:9000/trans_add_f1822_3_150
-wget http://$1:9000/trans_buy_f1822_2
-wget http://$1:9000/trans_add_f1823_4_200
-wget http://$1:9000/trans_buy_f1823_3
-wget http://$1:9000/trans_add_f1824_5_50
-wget http://$1:9000/trans_buy_f1824_4
-wget http://$1:9000/trans_add_f1825_1_100
-wget http://$1:9000/trans_buy_f1825_0
-wget http://$1:9000/trans_add_f1826_2_150
-wget http://$1:9000/trans_buy_f1826_1
-wget http://$1:9000/trans_add_f1827_3_200
-wget http://$1:9000/trans_buy_f1827_2
-wget http://$1:9000/trans_add_f1828_4_50
-wget http://$1:9000/trans_buy_f1828_3
-wget http://$1:9000/trans_add_f1829_5_100
-wget http://$1:9000/trans_buy_f1829_4
-wget http://$1:9000/trans_add_f1830_1_150
-wget http://$1:9000/trans_buy_f1830_0
-wget http://$1:9000/trans_add_f1831_2_200
-wget http://$1:9000/trans_buy_f1831_1
-wget http://$1:9000/trans_add_f1832_3_50
-wget http://$1:9000/trans_buy_f1832_2
-wget http://$1:9000/trans_add_f1833_4_100
-wget http://$1:9000/trans_buy_f1833_3
-wget http://$1:9000/trans_add_f1834_5_150
-wget http://$1:9000/trans_buy_f1834_4
-wget http://$1:9000/trans_add_f1835_1_200
-wget http://$1:9000/trans_buy_f1835_0
-wget http://$1:9000/trans_add_f1836_2_50
-wget http://$1:9000/trans_buy_f1836_1
-wget http://$1:9000/trans_add_f1837_3_100
-wget http://$1:9000/trans_buy_f1837_2
-wget http://$1:9000/trans_add_f1838_4_150
-wget http://$1:9000/trans_buy_f1838_3
-wget http://$1:9000/trans_add_f1839_5_200
-wget http://$1:9000/trans_buy_f1839_4
-wget http://$1:9000/trans_add_f1840_1_50
-wget http://$1:9000/trans_buy_f1840_0
-wget http://$1:9000/trans_add_f1841_2_100
-wget http://$1:9000/trans_buy_f1841_1
-wget http://$1:9000/trans_add_f1842_3_150
-wget http://$1:9000/trans_buy_f1842_2
-wget http://$1:9000/trans_add_f1843_4_200
-wget http://$1:9000/trans_buy_f1843_3
-wget http://$1:9000/trans_add_f1844_5_50
-wget http://$1:9000/trans_buy_f1844_4
-wget http://$1:9000/trans_add_f1845_1_100
-wget http://$1:9000/trans_buy_f1845_0
-wget http://$1:9000/trans_add_f1846_2_150
-wget http://$1:9000/trans_buy_f1846_1
-wget http://$1:9000/trans_add_f1847_3_200
-wget http://$1:9000/trans_buy_f1847_2
-wget http://$1:9000/trans_add_f1848_4_50
-wget http://$1:9000/trans_buy_f1848_3
-wget http://$1:9000/trans_add_f1849_5_100
-wget http://$1:9000/trans_buy_f1849_4
-wget http://$1:9000/trans_add_f1850_1_150
-wget http://$1:9000/trans_buy_f1850_0
-wget http://$1:9000/trans_add_f1851_2_200
-wget http://$1:9000/trans_buy_f1851_1
-wget http://$1:9000/trans_add_f1852_3_50
-wget http://$1:9000/trans_buy_f1852_2
-wget http://$1:9000/trans_add_f1853_4_100
-wget http://$1:9000/trans_buy_f1853_3
-wget http://$1:9000/trans_add_f1854_5_150
-wget http://$1:9000/trans_buy_f1854_4
-wget http://$1:9000/trans_add_f1855_1_200
-wget http://$1:9000/trans_buy_f1855_0
-wget http://$1:9000/trans_add_f1856_2_50
-wget http://$1:9000/trans_buy_f1856_1
-wget http://$1:9000/trans_add_f1857_3_100
-wget http://$1:9000/trans_buy_f1857_2
-wget http://$1:9000/trans_add_f1858_4_150
-wget http://$1:9000/trans_buy_f1858_3
-wget http://$1:9000/trans_add_f1859_5_200
-wget http://$1:9000/trans_buy_f1859_4
-wget http://$1:9000/trans_add_f1860_1_50
-wget http://$1:9000/trans_buy_f1860_0
-wget http://$1:9000/trans_add_f1861_2_100
-wget http://$1:9000/trans_buy_f1861_1
-wget http://$1:9000/trans_add_f1862_3_150
-wget http://$1:9000/trans_buy_f1862_2
-wget http://$1:9000/trans_add_f1863_4_200
-wget http://$1:9000/trans_buy_f1863_3
-wget http://$1:9000/trans_add_f1864_5_50
-wget http://$1:9000/trans_buy_f1864_4
-wget http://$1:9000/trans_add_f1865_1_100
-wget http://$1:9000/trans_buy_f1865_0
-wget http://$1:9000/trans_add_f1866_2_150
-wget http://$1:9000/trans_buy_f1866_1
-wget http://$1:9000/trans_add_f1867_3_200
-wget http://$1:9000/trans_buy_f1867_2
-wget http://$1:9000/trans_add_f1868_4_50
-wget http://$1:9000/trans_buy_f1868_3
-wget http://$1:9000/trans_add_f1869_5_100
-wget http://$1:9000/trans_buy_f1869_4
-wget http://$1:9000/trans_add_f1870_1_150
-wget http://$1:9000/trans_buy_f1870_0
-wget http://$1:9000/trans_add_f1871_2_200
-wget http://$1:9000/trans_buy_f1871_1
-wget http://$1:9000/trans_add_f1872_3_50
-wget http://$1:9000/trans_buy_f1872_2
-wget http://$1:9000/trans_add_f1873_4_100
-wget http://$1:9000/trans_buy_f1873_3
-wget http://$1:9000/trans_add_f1874_5_150
-wget http://$1:9000/trans_buy_f1874_4
-wget http://$1:9000/trans_add_f1875_1_200
-wget http://$1:9000/trans_buy_f1875_0
-wget http://$1:9000/trans_add_f1876_2_50
-wget http://$1:9000/trans_buy_f1876_1
-wget http://$1:9000/trans_add_f1877_3_100
-wget http://$1:9000/trans_buy_f1877_2
-wget http://$1:9000/trans_add_f1878_4_150
-wget http://$1:9000/trans_buy_f1878_3
-wget http://$1:9000/trans_add_f1879_5_200
-wget http://$1:9000/trans_buy_f1879_4
-wget http://$1:9000/trans_add_f1880_1_50
-wget http://$1:9000/trans_buy_f1880_0
-wget http://$1:9000/trans_add_f1881_2_100
-wget http://$1:9000/trans_buy_f1881_1
-wget http://$1:9000/trans_add_f1882_3_150
-wget http://$1:9000/trans_buy_f1882_2
-wget http://$1:9000/trans_add_f1883_4_200
-wget http://$1:9000/trans_buy_f1883_3
-wget http://$1:9000/trans_add_f1884_5_50
-wget http://$1:9000/trans_buy_f1884_4
-wget http://$1:9000/trans_add_f1885_1_100
-wget http://$1:9000/trans_buy_f1885_0
-wget http://$1:9000/trans_add_f1886_2_150
-wget http://$1:9000/trans_buy_f1886_1
-wget http://$1:9000/trans_add_f1887_3_200
-wget http://$1:9000/trans_buy_f1887_2
-wget http://$1:9000/trans_add_f1888_4_50
-wget http://$1:9000/trans_buy_f1888_3
-wget http://$1:9000/trans_add_f1889_5_100
-wget http://$1:9000/trans_buy_f1889_4
-wget http://$1:9000/trans_add_f1890_1_150
-wget http://$1:9000/trans_buy_f1890_0
-wget http://$1:9000/trans_add_f1891_2_200
-wget http://$1:9000/trans_buy_f1891_1
-wget http://$1:9000/trans_add_f1892_3_50
-wget http://$1:9000/trans_buy_f1892_2
-wget http://$1:9000/trans_add_f1893_4_100
-wget http://$1:9000/trans_buy_f1893_3
-wget http://$1:9000/trans_add_f1894_5_150
-wget http://$1:9000/trans_buy_f1894_4
-wget http://$1:9000/trans_add_f1895_1_200
-wget http://$1:9000/trans_buy_f1895_0
-wget http://$1:9000/trans_add_f1896_2_50
-wget http://$1:9000/trans_buy_f1896_1
-wget http://$1:9000/trans_add_f1897_3_100
-wget http://$1:9000/trans_buy_f1897_2
-wget http://$1:9000/trans_add_f1898_4_150
-wget http://$1:9000/trans_buy_f1898_3
-wget http://$1:9000/trans_add_f1899_5_200
-wget http://$1:9000/trans_buy_f1899_4
-wget http://$1:9000/trans_add_f1900_1_50
-wget http://$1:9000/trans_buy_f1900_0
-wget http://$1:9000/trans_add_f1901_2_100
-wget http://$1:9000/trans_buy_f1901_1
-wget http://$1:9000/trans_add_f1902_3_150
-wget http://$1:9000/trans_buy_f1902_2
-wget http://$1:9000/trans_add_f1903_4_200
-wget http://$1:9000/trans_buy_f1903_3
-wget http://$1:9000/trans_add_f1904_5_50
-wget http://$1:9000/trans_buy_f1904_4
-wget http://$1:9000/trans_add_f1905_1_100
-wget http://$1:9000/trans_buy_f1905_0
-wget http://$1:9000/trans_add_f1906_2_150
-wget http://$1:9000/trans_buy_f1906_1
-wget http://$1:9000/trans_add_f1907_3_200
-wget http://$1:9000/trans_buy_f1907_2
-wget http://$1:9000/trans_add_f1908_4_50
-wget http://$1:9000/trans_buy_f1908_3
-wget http://$1:9000/trans_add_f1909_5_100
-wget http://$1:9000/trans_buy_f1909_4
-wget http://$1:9000/trans_add_f1910_1_150
-wget http://$1:9000/trans_buy_f1910_0
-wget http://$1:9000/trans_add_f1911_2_200
-wget http://$1:9000/trans_buy_f1911_1
-wget http://$1:9000/trans_add_f1912_3_50
-wget http://$1:9000/trans_buy_f1912_2
-wget http://$1:9000/trans_add_f1913_4_100
-wget http://$1:9000/trans_buy_f1913_3
-wget http://$1:9000/trans_add_f1914_5_150
-wget http://$1:9000/trans_buy_f1914_4
-wget http://$1:9000/trans_add_f1915_1_200
-wget http://$1:9000/trans_buy_f1915_0
-wget http://$1:9000/trans_add_f1916_2_50
-wget http://$1:9000/trans_buy_f1916_1
-wget http://$1:9000/trans_add_f1917_3_100
-wget http://$1:9000/trans_buy_f1917_2
-wget http://$1:9000/trans_add_f1918_4_150
-wget http://$1:9000/trans_buy_f1918_3
-wget http://$1:9000/trans_add_f1919_5_200
-wget http://$1:9000/trans_buy_f1919_4
-wget http://$1:9000/trans_add_f1920_1_50
-wget http://$1:9000/trans_buy_f1920_0
-wget http://$1:9000/trans_add_f1921_2_100
-wget http://$1:9000/trans_buy_f1921_1
-wget http://$1:9000/trans_add_f1922_3_150
-wget http://$1:9000/trans_buy_f1922_2
-wget http://$1:9000/trans_add_f1923_4_200
-wget http://$1:9000/trans_buy_f1923_3
-wget http://$1:9000/trans_add_f1924_5_50
-wget http://$1:9000/trans_buy_f1924_4
-wget http://$1:9000/trans_add_f1925_1_100
-wget http://$1:9000/trans_buy_f1925_0
-wget http://$1:9000/trans_add_f1926_2_150
-wget http://$1:9000/trans_buy_f1926_1
-wget http://$1:9000/trans_add_f1927_3_200
-wget http://$1:9000/trans_buy_f1927_2
-wget http://$1:9000/trans_add_f1928_4_50
-wget http://$1:9000/trans_buy_f1928_3
-wget http://$1:9000/trans_add_f1929_5_100
-wget http://$1:9000/trans_buy_f1929_4
-wget http://$1:9000/trans_add_f1930_1_150
-wget http://$1:9000/trans_buy_f1930_0
-wget http://$1:9000/trans_add_f1931_2_200
-wget http://$1:9000/trans_buy_f1931_1
-wget http://$1:9000/trans_add_f1932_3_50
-wget http://$1:9000/trans_buy_f1932_2
-wget http://$1:9000/trans_add_f1933_4_100
-wget http://$1:9000/trans_buy_f1933_3
-wget http://$1:9000/trans_add_f1934_5_150
-wget http://$1:9000/trans_buy_f1934_4
-wget http://$1:9000/trans_add_f1935_1_200
-wget http://$1:9000/trans_buy_f1935_0
-wget http://$1:9000/trans_add_f1936_2_50
-wget http://$1:9000/trans_buy_f1936_1
-wget http://$1:9000/trans_add_f1937_3_100
-wget http://$1:9000/trans_buy_f1937_2
-wget http://$1:9000/trans_add_f1938_4_150
-wget http://$1:9000/trans_buy_f1938_3
-wget http://$1:9000/trans_add_f1939_5_200
-wget http://$1:9000/trans_buy_f1939_4
-wget http://$1:9000/trans_add_f1940_1_50
-wget http://$1:9000/trans_buy_f1940_0
-wget http://$1:9000/trans_add_f1941_2_100
-wget http://$1:9000/trans_buy_f1941_1
-wget http://$1:9000/trans_add_f1942_3_150
-wget http://$1:9000/trans_buy_f1942_2
-wget http://$1:9000/trans_add_f1943_4_200
-wget http://$1:9000/trans_buy_f1943_3
-wget http://$1:9000/trans_add_f1944_5_50
-wget http://$1:9000/trans_buy_f1944_4
-wget http://$1:9000/trans_add_f1945_1_100
-wget http://$1:9000/trans_buy_f1945_0
-wget http://$1:9000/trans_add_f1946_2_150
-wget http://$1:9000/trans_buy_f1946_1
-wget http://$1:9000/trans_add_f1947_3_200
-wget http://$1:9000/trans_buy_f1947_2
-wget http://$1:9000/trans_add_f1948_4_50
-wget http://$1:9000/trans_buy_f1948_3
-wget http://$1:9000/trans_add_f1949_5_100
-wget http://$1:9000/trans_buy_f1949_4
-wget http://$1:9000/trans_add_f1950_1_150
-wget http://$1:9000/trans_buy_f1950_0
-wget http://$1:9000/trans_add_f1951_2_200
-wget http://$1:9000/trans_buy_f1951_1
-wget http://$1:9000/trans_add_f1952_3_50
-wget http://$1:9000/trans_buy_f1952_2
-wget http://$1:9000/trans_add_f1953_4_100
-wget http://$1:9000/trans_buy_f1953_3
-wget http://$1:9000/trans_add_f1954_5_150
-wget http://$1:9000/trans_buy_f1954_4
-wget http://$1:9000/trans_add_f1955_1_200
-wget http://$1:9000/trans_buy_f1955_0
-wget http://$1:9000/trans_add_f1956_2_50
-wget http://$1:9000/trans_buy_f1956_1
-wget http://$1:9000/trans_add_f1957_3_100
-wget http://$1:9000/trans_buy_f1957_2
-wget http://$1:9000/trans_add_f1958_4_150
-wget http://$1:9000/trans_buy_f1958_3
-wget http://$1:9000/trans_add_f1959_5_200
-wget http://$1:9000/trans_buy_f1959_4
-wget http://$1:9000/trans_add_f1960_1_50
-wget http://$1:9000/trans_buy_f1960_0
-wget http://$1:9000/trans_add_f1961_2_100
-wget http://$1:9000/trans_buy_f1961_1
-wget http://$1:9000/trans_add_f1962_3_150
-wget http://$1:9000/trans_buy_f1962_2
-wget http://$1:9000/trans_add_f1963_4_200
-wget http://$1:9000/trans_buy_f1963_3
-wget http://$1:9000/trans_add_f1964_5_50
-wget http://$1:9000/trans_buy_f1964_4
-wget http://$1:9000/trans_add_f1965_1_100
-wget http://$1:9000/trans_buy_f1965_0
-wget http://$1:9000/trans_add_f1966_2_150
-wget http://$1:9000/trans_buy_f1966_1
-wget http://$1:9000/trans_add_f1967_3_200
-wget http://$1:9000/trans_buy_f1967_2
-wget http://$1:9000/trans_add_f1968_4_50
-wget http://$1:9000/trans_buy_f1968_3
-wget http://$1:9000/trans_add_f1969_5_100
-wget http://$1:9000/trans_buy_f1969_4
-wget http://$1:9000/trans_add_f1970_1_150
-wget http://$1:9000/trans_buy_f1970_0
-wget http://$1:9000/trans_add_f1971_2_200
-wget http://$1:9000/trans_buy_f1971_1
-wget http://$1:9000/trans_add_f1972_3_50
-wget http://$1:9000/trans_buy_f1972_2
-wget http://$1:9000/trans_add_f1973_4_100
-wget http://$1:9000/trans_buy_f1973_3
-wget http://$1:9000/trans_add_f1974_5_150
-wget http://$1:9000/trans_buy_f1974_4
-wget http://$1:9000/trans_add_f1975_1_200
-wget http://$1:9000/trans_buy_f1975_0
-wget http://$1:9000/trans_add_f1976_2_50
-wget http://$1:9000/trans_buy_f1976_1
-wget http://$1:9000/trans_add_f1977_3_100
-wget http://$1:9000/trans_buy_f1977_2
-wget http://$1:9000/trans_add_f1978_4_150
-wget http://$1:9000/trans_buy_f1978_3
-wget http://$1:9000/trans_add_f1979_5_200
-wget http://$1:9000/trans_buy_f1979_4
-wget http://$1:9000/trans_add_f1980_1_50
-wget http://$1:9000/trans_buy_f1980_0
-wget http://$1:9000/trans_add_f1981_2_100
-wget http://$1:9000/trans_buy_f1981_1
-wget http://$1:9000/trans_add_f1982_3_150
-wget http://$1:9000/trans_buy_f1982_2
-wget http://$1:9000/trans_add_f1983_4_200
-wget http://$1:9000/trans_buy_f1983_3
-wget http://$1:9000/trans_add_f1984_5_50
-wget http://$1:9000/trans_buy_f1984_4
-wget http://$1:9000/trans_add_f1985_1_100
-wget http://$1:9000/trans_buy_f1985_0
-wget http://$1:9000/trans_add_f1986_2_150
-wget http://$1:9000/trans_buy_f1986_1
-wget http://$1:9000/trans_add_f1987_3_200
-wget http://$1:9000/trans_buy_f1987_2
-wget http://$1:9000/trans_add_f1988_4_50
-wget http://$1:9000/trans_buy_f1988_3
-wget http://$1:9000/trans_add_f1989_5_100
-wget http://$1:9000/trans_buy_f1989_4
-wget http://$1:9000/trans_add_f1990_1_150
-wget http://$1:9000/trans_buy_f1990_0
-wget http://$1:9000/trans_add_f1991_2_200
-wget http://$1:9000/trans_buy_f1991_1
-wget http://$1:9000/trans_add_f1992_3_50
-wget http://$1:9000/trans_buy_f1992_2
-wget http://$1:9000/trans_add_f1993_4_100
-wget http://$1:9000/trans_buy_f1993_3
-wget http://$1:9000/trans_add_f1994_5_150
-wget http://$1:9000/trans_buy_f1994_4
-wget http://$1:9000/trans_add_f1995_1_200
-wget http://$1:9000/trans_buy_f1995_0
-wget http://$1:9000/trans_add_f1996_2_50
-wget http://$1:9000/trans_buy_f1996_1
-wget http://$1:9000/trans_add_f1997_3_100
-wget http://$1:9000/trans_buy_f1997_2
-wget http://$1:9000/trans_add_f1998_4_150
-wget http://$1:9000/trans_buy_f1998_3
-wget http://$1:9000/trans_add_f1999_5_200
-wget http://$1:9000/trans_buy_f1999_4
-wget http://$1:9000/trans_add_f2000_1_50
-wget http://$1:9000/trans_buy_f2000_0
-wget http://$1:9000/trans_add_f2001_2_100
-wget http://$1:9000/trans_buy_f2001_1
-wget http://$1:9000/trans_add_f2002_3_150
-wget http://$1:9000/trans_buy_f2002_2
-wget http://$1:9000/trans_add_f2003_4_200
-wget http://$1:9000/trans_buy_f2003_3
-wget http://$1:9000/trans_add_f2004_5_50
-wget http://$1:9000/trans_buy_f2004_4
-wget http://$1:9000/trans_add_f2005_1_100
-wget http://$1:9000/trans_buy_f2005_0
-wget http://$1:9000/trans_add_f2006_2_150
-wget http://$1:9000/trans_buy_f2006_1
-wget http://$1:9000/trans_add_f2007_3_200
-wget http://$1:9000/trans_buy_f2007_2
-wget http://$1:9000/trans_add_f2008_4_50
-wget http://$1:9000/trans_buy_f2008_3
-wget http://$1:9000/trans_add_f2009_5_100
-wget http://$1:9000/trans_buy_f2009_4
-wget http://$1:9000/trans_add_f2010_1_150
-wget http://$1:9000/trans_buy_f2010_0
-wget http://$1:9000/trans_add_f2011_2_200
-wget http://$1:9000/trans_buy_f2011_1
-wget http://$1:9000/trans_add_f2012_3_50
-wget http://$1:9000/trans_buy_f2012_2
-wget http://$1:9000/trans_add_f2013_4_100
-wget http://$1:9000/trans_buy_f2013_3
-wget http://$1:9000/trans_add_f2014_5_150
-wget http://$1:9000/trans_buy_f2014_4
-wget http://$1:9000/trans_add_f2015_1_200
-wget http://$1:9000/trans_buy_f2015_0
-wget http://$1:9000/trans_add_f2016_2_50
-wget http://$1:9000/trans_buy_f2016_1
-wget http://$1:9000/trans_add_f2017_3_100
-wget http://$1:9000/trans_buy_f2017_2
-wget http://$1:9000/trans_add_f2018_4_150
-wget http://$1:9000/trans_buy_f2018_3
-wget http://$1:9000/trans_add_f2019_5_200
-wget http://$1:9000/trans_buy_f2019_4
-wget http://$1:9000/trans_add_f2020_1_50
-wget http://$1:9000/trans_buy_f2020_0
-wget http://$1:9000/trans_add_f2021_2_100
-wget http://$1:9000/trans_buy_f2021_1
-wget http://$1:9000/trans_add_f2022_3_150
-wget http://$1:9000/trans_buy_f2022_2
-wget http://$1:9000/trans_add_f2023_4_200
-wget http://$1:9000/trans_buy_f2023_3
-wget http://$1:9000/trans_add_f2024_5_50
-wget http://$1:9000/trans_buy_f2024_4
-wget http://$1:9000/trans_add_f2025_1_100
-wget http://$1:9000/trans_buy_f2025_0
-wget http://$1:9000/trans_add_f2026_2_150
-wget http://$1:9000/trans_buy_f2026_1
-wget http://$1:9000/trans_add_f2027_3_200
-wget http://$1:9000/trans_buy_f2027_2
-wget http://$1:9000/trans_add_f2028_4_50
-wget http://$1:9000/trans_buy_f2028_3
-wget http://$1:9000/trans_add_f2029_5_100
-wget http://$1:9000/trans_buy_f2029_4
-wget http://$1:9000/trans_add_f2030_1_150
-wget http://$1:9000/trans_buy_f2030_0
-wget http://$1:9000/trans_add_f2031_2_200
-wget http://$1:9000/trans_buy_f2031_1
-wget http://$1:9000/trans_add_f2032_3_50
-wget http://$1:9000/trans_buy_f2032_2
-wget http://$1:9000/trans_add_f2033_4_100
-wget http://$1:9000/trans_buy_f2033_3
-wget http://$1:9000/trans_add_f2034_5_150
-wget http://$1:9000/trans_buy_f2034_4
-wget http://$1:9000/trans_add_f2035_1_200
-wget http://$1:9000/trans_buy_f2035_0
-wget http://$1:9000/trans_add_f2036_2_50
-wget http://$1:9000/trans_buy_f2036_1
-wget http://$1:9000/trans_add_f2037_3_100
-wget http://$1:9000/trans_buy_f2037_2
-wget http://$1:9000/trans_add_f2038_4_150
-wget http://$1:9000/trans_buy_f2038_3
-wget http://$1:9000/trans_add_f2039_5_200
-wget http://$1:9000/trans_buy_f2039_4
-wget http://$1:9000/trans_add_f2040_1_50
-wget http://$1:9000/trans_buy_f2040_0
-wget http://$1:9000/trans_add_f2041_2_100
-wget http://$1:9000/trans_buy_f2041_1
-wget http://$1:9000/trans_add_f2042_3_150
-wget http://$1:9000/trans_buy_f2042_2
-wget http://$1:9000/trans_add_f2043_4_200
-wget http://$1:9000/trans_buy_f2043_3
-wget http://$1:9000/trans_add_f2044_5_50
-wget http://$1:9000/trans_buy_f2044_4
-wget http://$1:9000/trans_add_f2045_1_100
-wget http://$1:9000/trans_buy_f2045_0
-wget http://$1:9000/trans_add_f2046_2_150
-wget http://$1:9000/trans_buy_f2046_1
-wget http://$1:9000/trans_add_f2047_3_200
-wget http://$1:9000/trans_buy_f2047_2
-wget http://$1:9000/trans_add_f2048_4_50
-wget http://$1:9000/trans_buy_f2048_3
-wget http://$1:9000/trans_add_f2049_5_100
-wget http://$1:9000/trans_buy_f2049_4
-wget http://$1:9000/trans_add_f2050_1_150
-wget http://$1:9000/trans_buy_f2050_0
-wget http://$1:9000/trans_add_f2051_2_200
-wget http://$1:9000/trans_buy_f2051_1
-wget http://$1:9000/trans_add_f2052_3_50
-wget http://$1:9000/trans_buy_f2052_2
-wget http://$1:9000/trans_add_f2053_4_100
-wget http://$1:9000/trans_buy_f2053_3
-wget http://$1:9000/trans_add_f2054_5_150
-wget http://$1:9000/trans_buy_f2054_4
-wget http://$1:9000/trans_add_f2055_1_200
-wget http://$1:9000/trans_buy_f2055_0
-wget http://$1:9000/trans_add_f2056_2_50
-wget http://$1:9000/trans_buy_f2056_1
-wget http://$1:9000/trans_add_f2057_3_100
-wget http://$1:9000/trans_buy_f2057_2
-wget http://$1:9000/trans_add_f2058_4_150
-wget http://$1:9000/trans_buy_f2058_3
-wget http://$1:9000/trans_add_f2059_5_200
-wget http://$1:9000/trans_buy_f2059_4
-wget http://$1:9000/trans_add_f2060_1_50
-wget http://$1:9000/trans_buy_f2060_0
-wget http://$1:9000/trans_add_f2061_2_100
-wget http://$1:9000/trans_buy_f2061_1
-wget http://$1:9000/trans_add_f2062_3_150
-wget http://$1:9000/trans_buy_f2062_2
-wget http://$1:9000/trans_add_f2063_4_200
-wget http://$1:9000/trans_buy_f2063_3
-wget http://$1:9000/trans_add_f2064_5_50
-wget http://$1:9000/trans_buy_f2064_4
-wget http://$1:9000/trans_add_f2065_1_100
-wget http://$1:9000/trans_buy_f2065_0
-wget http://$1:9000/trans_add_f2066_2_150
-wget http://$1:9000/trans_buy_f2066_1
-wget http://$1:9000/trans_add_f2067_3_200
-wget http://$1:9000/trans_buy_f2067_2
-wget http://$1:9000/trans_add_f2068_4_50
-wget http://$1:9000/trans_buy_f2068_3
-wget http://$1:9000/trans_add_f2069_5_100
-wget http://$1:9000/trans_buy_f2069_4
-wget http://$1:9000/trans_add_f2070_1_150
-wget http://$1:9000/trans_buy_f2070_0
-wget http://$1:9000/trans_add_f2071_2_200
-wget http://$1:9000/trans_buy_f2071_1
-wget http://$1:9000/trans_add_f2072_3_50
-wget http://$1:9000/trans_buy_f2072_2
-wget http://$1:9000/trans_add_f2073_4_100
-wget http://$1:9000/trans_buy_f2073_3
-wget http://$1:9000/trans_add_f2074_5_150
-wget http://$1:9000/trans_buy_f2074_4
-wget http://$1:9000/trans_add_f2075_1_200
-wget http://$1:9000/trans_buy_f2075_0
-wget http://$1:9000/trans_add_f2076_2_50
-wget http://$1:9000/trans_buy_f2076_1
-wget http://$1:9000/trans_add_f2077_3_100
-wget http://$1:9000/trans_buy_f2077_2
-wget http://$1:9000/trans_add_f2078_4_150
-wget http://$1:9000/trans_buy_f2078_3
-wget http://$1:9000/trans_add_f2079_5_200
-wget http://$1:9000/trans_buy_f2079_4
-wget http://$1:9000/trans_add_f2080_1_50
-wget http://$1:9000/trans_buy_f2080_0
-wget http://$1:9000/trans_add_f2081_2_100
-wget http://$1:9000/trans_buy_f2081_1
-wget http://$1:9000/trans_add_f2082_3_150
-wget http://$1:9000/trans_buy_f2082_2
-wget http://$1:9000/trans_add_f2083_4_200
-wget http://$1:9000/trans_buy_f2083_3
-wget http://$1:9000/trans_add_f2084_5_50
-wget http://$1:9000/trans_buy_f2084_4
-wget http://$1:9000/trans_add_f2085_1_100
-wget http://$1:9000/trans_buy_f2085_0
-wget http://$1:9000/trans_add_f2086_2_150
-wget http://$1:9000/trans_buy_f2086_1
-wget http://$1:9000/trans_add_f2087_3_200
-wget http://$1:9000/trans_buy_f2087_2
-wget http://$1:9000/trans_add_f2088_4_50
-wget http://$1:9000/trans_buy_f2088_3
-wget http://$1:9000/trans_add_f2089_5_100
-wget http://$1:9000/trans_buy_f2089_4
-wget http://$1:9000/trans_add_f2090_1_150
-wget http://$1:9000/trans_buy_f2090_0
-wget http://$1:9000/trans_add_f2091_2_200
-wget http://$1:9000/trans_buy_f2091_1
-wget http://$1:9000/trans_add_f2092_3_50
-wget http://$1:9000/trans_buy_f2092_2
-wget http://$1:9000/trans_add_f2093_4_100
-wget http://$1:9000/trans_buy_f2093_3
-wget http://$1:9000/trans_add_f2094_5_150
-wget http://$1:9000/trans_buy_f2094_4
-wget http://$1:9000/trans_add_f2095_1_200
-wget http://$1:9000/trans_buy_f2095_0
-wget http://$1:9000/trans_add_f2096_2_50
-wget http://$1:9000/trans_buy_f2096_1
-wget http://$1:9000/trans_add_f2097_3_100
-wget http://$1:9000/trans_buy_f2097_2
-wget http://$1:9000/trans_add_f2098_4_150
-wget http://$1:9000/trans_buy_f2098_3
-wget http://$1:9000/trans_add_f2099_5_200
-wget http://$1:9000/trans_buy_f2099_4
-wget http://$1:9000/trans_add_f2100_1_50
-wget http://$1:9000/trans_buy_f2100_0
-wget http://$1:9000/trans_add_f2101_2_100
-wget http://$1:9000/trans_buy_f2101_1
-wget http://$1:9000/trans_add_f2102_3_150
-wget http://$1:9000/trans_buy_f2102_2
-wget http://$1:9000/trans_add_f2103_4_200
-wget http://$1:9000/trans_buy_f2103_3
-wget http://$1:9000/trans_add_f2104_5_50
-wget http://$1:9000/trans_buy_f2104_4
-wget http://$1:9000/trans_add_f2105_1_100
-wget http://$1:9000/trans_buy_f2105_0
-wget http://$1:9000/trans_add_f2106_2_150
-wget http://$1:9000/trans_buy_f2106_1
-wget http://$1:9000/trans_add_f2107_3_200
-wget http://$1:9000/trans_buy_f2107_2
-wget http://$1:9000/trans_add_f2108_4_50
-wget http://$1:9000/trans_buy_f2108_3
-wget http://$1:9000/trans_add_f2109_5_100
-wget http://$1:9000/trans_buy_f2109_4
-wget http://$1:9000/trans_add_f2110_1_150
-wget http://$1:9000/trans_buy_f2110_0
-wget http://$1:9000/trans_add_f2111_2_200
-wget http://$1:9000/trans_buy_f2111_1
-wget http://$1:9000/trans_add_f2112_3_50
-wget http://$1:9000/trans_buy_f2112_2
-wget http://$1:9000/trans_add_f2113_4_100
-wget http://$1:9000/trans_buy_f2113_3
-wget http://$1:9000/trans_add_f2114_5_150
-wget http://$1:9000/trans_buy_f2114_4
-wget http://$1:9000/trans_add_f2115_1_200
-wget http://$1:9000/trans_buy_f2115_0
-wget http://$1:9000/trans_add_f2116_2_50
-wget http://$1:9000/trans_buy_f2116_1
-wget http://$1:9000/trans_add_f2117_3_100
-wget http://$1:9000/trans_buy_f2117_2
-wget http://$1:9000/trans_add_f2118_4_150
-wget http://$1:9000/trans_buy_f2118_3
-wget http://$1:9000/trans_add_f2119_5_200
-wget http://$1:9000/trans_buy_f2119_4
-wget http://$1:9000/trans_add_f2120_1_50
-wget http://$1:9000/trans_buy_f2120_0
-wget http://$1:9000/trans_add_f2121_2_100
-wget http://$1:9000/trans_buy_f2121_1
-wget http://$1:9000/trans_add_f2122_3_150
-wget http://$1:9000/trans_buy_f2122_2
-wget http://$1:9000/trans_add_f2123_4_200
-wget http://$1:9000/trans_buy_f2123_3
-wget http://$1:9000/trans_add_f2124_5_50
-wget http://$1:9000/trans_buy_f2124_4
-wget http://$1:9000/trans_add_f2125_1_100
-wget http://$1:9000/trans_buy_f2125_0
-wget http://$1:9000/trans_add_f2126_2_150
-wget http://$1:9000/trans_buy_f2126_1
-wget http://$1:9000/trans_add_f2127_3_200
-wget http://$1:9000/trans_buy_f2127_2
-wget http://$1:9000/trans_add_f2128_4_50
-wget http://$1:9000/trans_buy_f2128_3
-wget http://$1:9000/trans_add_f2129_5_100
-wget http://$1:9000/trans_buy_f2129_4
-wget http://$1:9000/trans_add_f2130_1_150
-wget http://$1:9000/trans_buy_f2130_0
-wget http://$1:9000/trans_add_f2131_2_200
-wget http://$1:9000/trans_buy_f2131_1
-wget http://$1:9000/trans_add_f2132_3_50
-wget http://$1:9000/trans_buy_f2132_2
-wget http://$1:9000/trans_add_f2133_4_100
-wget http://$1:9000/trans_buy_f2133_3
-wget http://$1:9000/trans_add_f2134_5_150
-wget http://$1:9000/trans_buy_f2134_4
-wget http://$1:9000/trans_add_f2135_1_200
-wget http://$1:9000/trans_buy_f2135_0
-wget http://$1:9000/trans_add_f2136_2_50
-wget http://$1:9000/trans_buy_f2136_1
-wget http://$1:9000/trans_add_f2137_3_100
-wget http://$1:9000/trans_buy_f2137_2
-wget http://$1:9000/trans_add_f2138_4_150
-wget http://$1:9000/trans_buy_f2138_3
-wget http://$1:9000/trans_add_f2139_5_200
-wget http://$1:9000/trans_buy_f2139_4
-wget http://$1:9000/trans_add_f2140_1_50
-wget http://$1:9000/trans_buy_f2140_0
-wget http://$1:9000/trans_add_f2141_2_100
-wget http://$1:9000/trans_buy_f2141_1
-wget http://$1:9000/trans_add_f2142_3_150
-wget http://$1:9000/trans_buy_f2142_2
-wget http://$1:9000/trans_add_f2143_4_200
-wget http://$1:9000/trans_buy_f2143_3
-wget http://$1:9000/trans_add_f2144_5_50
-wget http://$1:9000/trans_buy_f2144_4
-wget http://$1:9000/trans_add_f2145_1_100
-wget http://$1:9000/trans_buy_f2145_0
-wget http://$1:9000/trans_add_f2146_2_150
-wget http://$1:9000/trans_buy_f2146_1
-wget http://$1:9000/trans_add_f2147_3_200
-wget http://$1:9000/trans_buy_f2147_2
-wget http://$1:9000/trans_add_f2148_4_50
-wget http://$1:9000/trans_buy_f2148_3
-wget http://$1:9000/trans_add_f2149_5_100
-wget http://$1:9000/trans_buy_f2149_4
-wget http://$1:9000/trans_add_f2150_1_150
-wget http://$1:9000/trans_buy_f2150_0
-wget http://$1:9000/trans_add_f2151_2_200
-wget http://$1:9000/trans_buy_f2151_1
-wget http://$1:9000/trans_add_f2152_3_50
-wget http://$1:9000/trans_buy_f2152_2
-wget http://$1:9000/trans_add_f2153_4_100
-wget http://$1:9000/trans_buy_f2153_3
-wget http://$1:9000/trans_add_f2154_5_150
-wget http://$1:9000/trans_buy_f2154_4
-wget http://$1:9000/trans_add_f2155_1_200
-wget http://$1:9000/trans_buy_f2155_0
-wget http://$1:9000/trans_add_f2156_2_50
-wget http://$1:9000/trans_buy_f2156_1
-wget http://$1:9000/trans_add_f2157_3_100
-wget http://$1:9000/trans_buy_f2157_2
-wget http://$1:9000/trans_add_f2158_4_150
-wget http://$1:9000/trans_buy_f2158_3
-wget http://$1:9000/trans_add_f2159_5_200
-wget http://$1:9000/trans_buy_f2159_4
-wget http://$1:9000/trans_add_f2160_1_50
-wget http://$1:9000/trans_buy_f2160_0
-wget http://$1:9000/trans_add_f2161_2_100
-wget http://$1:9000/trans_buy_f2161_1
-wget http://$1:9000/trans_add_f2162_3_150
-wget http://$1:9000/trans_buy_f2162_2
-wget http://$1:9000/trans_add_f2163_4_200
-wget http://$1:9000/trans_buy_f2163_3
-wget http://$1:9000/trans_add_f2164_5_50
-wget http://$1:9000/trans_buy_f2164_4
-wget http://$1:9000/trans_add_f2165_1_100
-wget http://$1:9000/trans_buy_f2165_0
-wget http://$1:9000/trans_add_f2166_2_150
-wget http://$1:9000/trans_buy_f2166_1
-wget http://$1:9000/trans_add_f2167_3_200
-wget http://$1:9000/trans_buy_f2167_2
-wget http://$1:9000/trans_add_f2168_4_50
-wget http://$1:9000/trans_buy_f2168_3
-wget http://$1:9000/trans_add_f2169_5_100
-wget http://$1:9000/trans_buy_f2169_4
-wget http://$1:9000/trans_add_f2170_1_150
-wget http://$1:9000/trans_buy_f2170_0
-wget http://$1:9000/trans_add_f2171_2_200
-wget http://$1:9000/trans_buy_f2171_1
-wget http://$1:9000/trans_add_f2172_3_50
-wget http://$1:9000/trans_buy_f2172_2
-wget http://$1:9000/trans_add_f2173_4_100
-wget http://$1:9000/trans_buy_f2173_3
-wget http://$1:9000/trans_add_f2174_5_150
-wget http://$1:9000/trans_buy_f2174_4
-wget http://$1:9000/trans_add_f2175_1_200
-wget http://$1:9000/trans_buy_f2175_0
-wget http://$1:9000/trans_add_f2176_2_50
-wget http://$1:9000/trans_buy_f2176_1
-wget http://$1:9000/trans_add_f2177_3_100
-wget http://$1:9000/trans_buy_f2177_2
-wget http://$1:9000/trans_add_f2178_4_150
-wget http://$1:9000/trans_buy_f2178_3
-wget http://$1:9000/trans_add_f2179_5_200
-wget http://$1:9000/trans_buy_f2179_4
-wget http://$1:9000/trans_add_f2180_1_50
-wget http://$1:9000/trans_buy_f2180_0
-wget http://$1:9000/trans_add_f2181_2_100
-wget http://$1:9000/trans_buy_f2181_1
-wget http://$1:9000/trans_add_f2182_3_150
-wget http://$1:9000/trans_buy_f2182_2
-wget http://$1:9000/trans_add_f2183_4_200
-wget http://$1:9000/trans_buy_f2183_3
-wget http://$1:9000/trans_add_f2184_5_50
-wget http://$1:9000/trans_buy_f2184_4
-wget http://$1:9000/trans_add_f2185_1_100
-wget http://$1:9000/trans_buy_f2185_0
-wget http://$1:9000/trans_add_f2186_2_150
-wget http://$1:9000/trans_buy_f2186_1
-wget http://$1:9000/trans_add_f2187_3_200
-wget http://$1:9000/trans_buy_f2187_2
-wget http://$1:9000/trans_add_f2188_4_50
-wget http://$1:9000/trans_buy_f2188_3
-wget http://$1:9000/trans_add_f2189_5_100
-wget http://$1:9000/trans_buy_f2189_4
-wget http://$1:9000/trans_add_f2190_1_150
-wget http://$1:9000/trans_buy_f2190_0
-wget http://$1:9000/trans_add_f2191_2_200
-wget http://$1:9000/trans_buy_f2191_1
-wget http://$1:9000/trans_add_f2192_3_50
-wget http://$1:9000/trans_buy_f2192_2
-wget http://$1:9000/trans_add_f2193_4_100
-wget http://$1:9000/trans_buy_f2193_3
-wget http://$1:9000/trans_add_f2194_5_150
-wget http://$1:9000/trans_buy_f2194_4
-wget http://$1:9000/trans_add_f2195_1_200
-wget http://$1:9000/trans_buy_f2195_0
-wget http://$1:9000/trans_add_f2196_2_50
-wget http://$1:9000/trans_buy_f2196_1
-wget http://$1:9000/trans_add_f2197_3_100
-wget http://$1:9000/trans_buy_f2197_2
-wget http://$1:9000/trans_add_f2198_4_150
-wget http://$1:9000/trans_buy_f2198_3
-wget http://$1:9000/trans_add_f2199_5_200
-wget http://$1:9000/trans_buy_f2199_4
-wget http://$1:9000/trans_inventory
+++ /dev/null
-#!/bin/bash
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preperfume_39_50
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
-wget http://$1:9000/trans_buy_predvd_15_19
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_preroses_15_4
-wget http://$1:9000/trans_add_predvd_78_19
-wget http://$1:9000/trans_buy_preperfume_9_50
+++ /dev/null
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
+++ /dev/null
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_book_2
-wget http://$1:9000/trans_buy_soap_2
-wget http://$1:9000/trans_buy_pen_22
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_1
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_20_3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_bread_10000_4
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_book_2
-wget http://$1:9000/trans_buy_soap_2
-wget http://$1:9000/trans_buy_pen_22
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_1
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_20_3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_bread_10000_4
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.1
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.2
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_book_2
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_soap_2
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_pen_22
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_1
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_20_3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_bread_10000_4
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.1
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.2
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.3
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/index.html
-wget http://$1:9000/index1.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index2.html
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/index1.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index3.html
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.2
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/index1.html
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/index2.html
-wget http://$1:9000/index.html.1
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/index.html.2
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/index3.html
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/index2.html
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/index.html.2
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
+++ /dev/null
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_book_2
-wget http://$1:9000/trans_buy_soap_2
-wget http://$1:9000/trans_buy_pen_22
-wget http://$1:9000/trans_buy_car_1
-wget http://$1:9000/trans_add_coke_20_3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_bread_10000_4
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_add_soap_42_7
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
+++ /dev/null
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_book_2
-wget http://$1:9000/trans_buy_soap_2
-wget http://$1:9000/trans_buy_pen_22
-wget http://$1:9000/trans_buy_car_1
-wget http://$1:9000/trans_add_coke_20_3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_bread_10000_4
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_add_soap_42_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_soap_72_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_book_2
-wget http://$1:9000/trans_buy_soap_2
-wget http://$1:9000/trans_buy_pen_22
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_1
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_20_3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_bread_10000_4
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_add_soap_42_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_soap_72_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_book_2
-wget http://$1:9000/trans_buy_soap_2
-wget http://$1:9000/trans_buy_pen_22
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_1
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_20_3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_bread_10000_4
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_add_soap_42_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_soap_72_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_book_2
-wget http://$1:9000/trans_buy_soap_2
-wget http://$1:9000/trans_buy_pen_22
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_1
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_20_3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_bread_10000_4
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_add_soap_42_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_soap_72_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_book_2
-wget http://$1:9000/trans_buy_soap_2
-wget http://$1:9000/trans_buy_pen_22
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_1
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_20_3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_bread_10000_4
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_add_soap_42_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_soap_72_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_book_2
-wget http://$1:9000/trans_buy_soap_2
-wget http://$1:9000/trans_buy_pen_22
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_1
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_20_3
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_bread_10000_4
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_add_car_20_15000
-wget http://$1:9000/trans_add_book_100_50
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_add_soap_42_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_soap_72_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_buy_soap_2000_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_buy_car_15_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_buy_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_buy_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_buy_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_buy_car_15_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_15_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_car_1_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_add_car_15_10000
-wget http://$1:9000/trans_add_car_1_10000
-wget http://$1:9000/trans_add_car_1_10000
-wget http://$1:9000/trans_add_car_1_10000
-wget http://$1:9000/trans_add_car_1_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_add_soap_42_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_soap_72_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_buy_soap_2000_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_5_5
-wget http://$1:9000/trans_add_pen_0_5
-wget http://$1:9000/trans_add_pen_300_5
-wget http://$1:9000/trans_add_pen_45_5
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_add_soap_42_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_soap_72_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_155_7
-wget http://$1:9000/trans_buy_soap_200_7
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_add_bread_10_4
-wget http://$1:9000/trans_add_bread_1340_4
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_bread_220
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_buy_soap_8
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_add_book_10_50
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_soap_72_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_add_soap_2_7
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_add_car_2_10000
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_car_2_10000
-wget http://$1:9000/trans_add_pen_50_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_add_coke_100_5
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_add_soap_20_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_soap_888
-wget http://$1:9000/trans_add_soap_72_7
-wget http://$1:9000/trans_inventory
-wget http://$1:9000/trans_buy_pen_11
+++ /dev/null
-#!/bin/bash
-./buildscripttaskerror trans WebServerSocket.java WebServerExample.java Logger.java ItemInfo.java Inventory.java
+++ /dev/null
-<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>Google</title><style><!--
-body,td,a,p,.h{font-family:arial,sans-serif}
-.h{font-size:20px}
-.q{color:#00c}
---></style>
-<script>
-<!--
-function sf(){document.f.q.focus();}
-function rwt(el,oi,cad,ct,cd,sg_url,sg){var e = window.encodeURIComponent ? encodeURIComponent : escape;var oi_param="";var cad_param="";var p = el.href.split("#");var sig_url="";if (oi) oi_param="&oi="+e(oi);if (cad) cad_param="&cad="+e(cad);if (sg_url) sig_url="&sig="+sg_url;el.href="/url?sa=t"+oi_param+cad_param+"&ct="+e(ct)+"&cd="+e(cd)+"&url="+e(p[0]).replace(/\+/g,"%2B")+"&ei=DpMpRaeJPKSC4AHOvaWSDQ"+sig_url+sg+(p[1]?"#"+p[1]:"");el.onmousedown="";return true;}
-// -->
-</script>
-</head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onLoad=sf() topmargin=3 marginheight=3><center><div align=right nowrap style="padding-bottom:4px" width=100%><font size=-1><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den&sig=__yvmOvIrk79QYmDkrJAeuYO8jTmo=" onmousedown="return rwt(this,'promos','hppphou:en_us','pro','1','__pYXj21XO9PZsXL6jB7U30u5HZlE=','')">Personalized Home</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/webhp&hl=en">Sign in</a></font></div><img src="/intl/en/images/logo.gif" width=276 height=110 alt="Google"><br><br>
-<form action=/search name=f><script><!--
-function qs(el) {if (window.RegExp && window.encodeURIComponent) {var ue=el.href;var qe=encodeURIComponent(document.f.q.value);if(ue.indexOf("q=")!=-1){el.href=ue.replace(new RegExp("q=[^&$]*"),"q="+qe);}else{el.href=ue+"&q="+qe;}}return 1;}
-// -->
-</script><table border=0 cellspacing=0 cellpadding=4><tr><td nowrap><font size=-1><b>Web</b> <a class=q href="/imghp?hl=en&tab=wi" onClick="return qs(this);">Images</a> <a class=q href="http://video.google.com/?hl=en&tab=wv" onClick="return qs(this);">Video<a style="text-decoration:none"><sup><font color=red>New!</font></sup></a></a> <a class=q href="http://news.google.com/nwshp?hl=en&tab=wn" onClick="return qs(this);">News</a> <a class=q href="/maps?hl=en&tab=wl" onClick="return qs(this);">Maps</a> <b><a href="/intl/en/options/" class=q onclick="this.blur();return togDisp(event);">more »</a></b><script><!--
-function togDisp(e){stopB(e);var elems=document.getElementsByName('more');for(var i=0;i<elems.length;i++){var obj=elems[i];var dp="";if(obj.style.display==""){dp="none";}obj.style.display=dp;}return false;}
-function stopB(e){if(!e)e=window.event;e.cancelBubble=true;}
-document.onclick=function(event){var elems=document.getElementsByName('more');if(elems[0].style.display == ""){togDisp(event);}}
-//-->
-
-</script><style><!--
-.cb{margin:.5ex}
---></style>
-<span name=more id=more style="display:none;position:absolute;background:#fff;border:1px solid #369;margin:-.5ex 1.5ex;padding:0 0 .5ex .8ex;width:16ex;line-height:1.9;z-index:1000" onclick="stopB(event);"><a href=# onclick="return togDisp(event);"><img border=0 src=/images/x2.gif width=12 height=12 alt="Close menu" align=right class=cb></a><a class=q href="http://books.google.com/bkshp?hl=en&tab=wp" onClick="return qs(this);">Books</a><br><a class=q href="http://froogle.google.com/frghp?hl=en&tab=wf" onClick="return qs(this);">Froogle</a><br><a class=q href="http://groups.google.com/grphp?hl=en&tab=wg" onClick="return qs(this);">Groups</a><br><a class=q href="http://scholar.google.com/schhp?hl=en&tab=ws" onClick="return qs(this);">Scholar</a><br><a href="/intl/en/options/" class=q><b>even more »</b></a></span></font></td></tr></table><table cellspacing=0 cellpadding=0><tr><td width=25%> </td><td align=center><input type=hidden name=hl value=en><input maxlength=2048 size=55 name=q value="" title="Google Search"><br><input type=submit value="Google Search" name=btnG><input type=submit value="I'm Feeling Lucky" name=btnI></td><td valign=top nowrap width=25%><font size=-2> <a href=/advanced_search?hl=en>Advanced Search</a><br> <a href=/preferences?hl=en>Preferences</a><br> <a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><br><font size=-1><a href="/intl/en/ads/">Advertising Programs</a> - <a href=/services/>Business Solutions</a> - <a href=/intl/en/about.html>About Google</a></font><p><font size=-2>©2006 Google</font></p></center></body></html>
+++ /dev/null
-<HTML>
- <HEAD>
- <TITLE>Test HTML Document</TITLE>
- </HEAD>
- <BODY>
- <h1>Testing html file for display on web browser.</h1>
- </BODY>
-</HTML>
+++ /dev/null
-
-New Request received: index2.html
-New Request received: favicon.ico
-New Request received: index2.html
-New Request received: favicon.ico
-New Request received: index2.html
-New Request received: favicon.ico
-New Request received: index2.html
-New Request received: favicon.ico
-New Request received: index2.html
-New Request received: favicon.ico
-New Request received: index2.html
-New Request received: favicon.ico
-New Request received: index2.html
-New Request received: favicon.ico
-New Request received: index2.html
\ No newline at end of file
+++ /dev/null
-import java.util.*;
-import java.net.*;
-import java.io.*;
-
-public class Inventory {
- // Transaction variables
- int numitems;
- HashMap map;
- int balance;
-
- // Constructor
- public Inventory(){
- map = new HashMap();
- balance=100000;
- }
-
- public Inventory(int howmany) {
- numitems = howmany;// howmany keeps track of the number of items
- // in the inventory
- map = new HashMap();
- }
-
- // Add item to a list of inventory
- public synchronized void additem(String name, int quantity, int price){
- ItemInfo newitem = new ItemInfo(quantity, price);
- balance-=quantity*price;
-
- // Get the item from hash
- if (map.containsKey(name) == false) {
- map.put(name, newitem);
- } else {
- ItemInfo i = (ItemInfo) map.get(name);
- i.quantity += quantity;
- i.price = price;
- map.put(name, i);
- }
- }
-
- // Buy item from a given list of inventory
- public synchronized int buyitem(String name, int quantity){
- if (map.containsKey(name) == false) {
- // System.printString("Error - Item does not exist");
- return -1;
- } else {
- ItemInfo i = (ItemInfo) map.get(name);
- if (i.quantity == 0) {
- // System.printString("Error - Item unavailable");
- return -1;
- }
- if ((i.quantity-quantity) < 0 ) {
- // System.printString("Error - Available qty is less: Cannot Buy\n");
- return -1;
- } else {
- i.quantity -= quantity;
- map.put(name, i);
- balance+=quantity*i.price;
- return i.price;
- }
- }
- }
-
- //Display the inventory list
- public synchronized void inventory(Socket s){
- try {
- OutputStream sockout=s.getOutputStream();
- Iterator i = map.keySet().iterator();// Gets key from the hashmap= name of item
- Iterator j = map.values().iterator();//Gets the value from hashmap
- int totalvalue=balance;
- while (i.hasNext() == true) {
- StringBuffer sb = new StringBuffer("");
- Object o = i.next();
- String name = o.toString();
- ItemInfo oo = (ItemInfo) j.next();
- sb.append(name);
- sb.append(" ");
- Integer q = new Integer(oo.quantity);
- sb.append(q.toString());
- sb.append(" ");
- Integer p = new Integer(oo.price);
- sb.append(p.toString());
- sb.append("\n");
- totalvalue+=oo.quantity*oo.price;
- sockout.write(sb.toString().getBytes());
- }
- StringBuffer sb=new StringBuffer("");
- sb.append("Total value: ");
- sb.append((new Integer(totalvalue)).toString());
- sb.append("\n");
- sockout.write(sb.toString().getBytes());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
+++ /dev/null
-class ItemInfo {
- int quantity;
- int price;
- ItemInfo(int x, int y) {
- quantity = x;
- price = y;
- }
-}
+++ /dev/null
-import java.io.*;
-
-public class Logger {
- //Logger flag
- FileOutputStream fos;
-
-
- //Constructor
- public Logger(){
- try {
- fos=new FileOutputStream("request.log");//Open request.log file
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- //Logs filename as per client requests
- public void logrequest(String filename){
- try {
- String request = new String("\nNew Request received: ");
- fos.write(request.getBytes());
- fos.write(filename.getBytes());
- fos.flush();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public void logrequest(){
- try {
- String request = new String("\nNew Request received: ");
- fos.write(request.getBytes());
- fos.flush();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public void closerequest() {
- try {
- fos.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
+++ /dev/null
-import java.net.*;
-
-public class WebServerExample {
-
- public static void main(String arg[]) {
- // Create New ServerSocket
- // System.printString("W> Starting\n");
- ServerSocket ss=null;
- try {
- ss= new ServerSocket(9000);
- } catch (Exception e){}
- // System.printString("W> Creating ServerSocket\n");
- Logger log = new Logger();
- Inventory inventorylist = new Inventory();
- acceptConnection(ss, log, inventorylist);
- }
-
- //Listen for a request and accept request
- public static void acceptConnection(ServerSocket ss, Logger log, Inventory inventorylist) {
- // System.printString("W> Waiting for connection...\n");
- while(true) {
- Socket s=null;
- try {
- s=ss.accept();
- } catch (Exception e) {}
- WebServerThread web = new WebServerThread(s, log, inventorylist);
- web.start();
- // System.printString("W> Connected... \n");
- }
- }
-}
+++ /dev/null
-import java.io.*;
-import java.net.*;
-
-public class WebServerThread extends Thread {
- //Filename requested by the client
- String filename;
- String[] parsed;
- String prefix;
- Logger log;
- Inventory inventorylist;
- Socket sock;
- InputStream sockin;
- OutputStream sockout;
-
- //Constructor
- public WebServerThread(Socket s, Logger log, Inventory inventory){
- parsed = new String[4];
- this.log=log;
- this.sock=s;
- try {
- sockin=s.getInputStream();
- sockout=s.getOutputStream();
- } catch (Exception e) {
- e.printStackTrace();
- }
- this.inventorylist=inventory;
- }
-
- public void run() {
- // Process the incoming http request
- while (!clientrequest()) {
- }
- if(checktrans()==false) {
- // Not special transaction , do normal filesending
- SendFile();
- LogRequest();
- } else {
- // Invoke special inventory transaction
- Transaction();
- LogRequest();
- }
- }
-
- //Do the WriteIO on server socket and send the requested file to Client
- public void SendFile() {
- sendfile();
- try {
- sock.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- // Log the Client request
- public void LogRequest() {
- log.logrequest(filename);
- }
-
- //Transaction on Inventory
- public void Transaction() {
- // Parse
- int op = parseTransaction();
- // Check for the kind of operation
- if (op == 0 ) { /* Add */
- // System.printString("DEBUG > Calling add transaction\n");
- Integer qty = new Integer(parsed[2]);
- Integer price = new Integer(parsed[3]);
- inventorylist.additem(parsed[1], qty.intValue(), price.intValue());
- httpresponse();
- StringBuffer s = new StringBuffer("Added Item ");
- s.append(parsed[1]);
- s.append(" Quantity ");
- s.append(parsed[2]);
- s.append(" Price ");
- s.append(parsed[3]);
- s.append("\n");
- String towrite = new String(s);
- try {
- sockout.write(towrite.getBytes());
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else if (op == 1) { /* Buy */
- // System.printString("DEBUG > Calling buy transaction\n");
- Integer qty = new Integer(parsed[2]);
- int ret = inventorylist.buyitem(parsed[1], qty.intValue());
- if (ret >= 0) {
- httpresponse();
- StringBuffer s = new StringBuffer("Bought item ");
- s.append(parsed[1]);
- s.append(" Quantity ");
- s.append(parsed[2]);
- s.append(" Cost ");
- Integer cost = new Integer(ret*qty.intValue());
- String c = cost.toString();
- s.append(c);
- String towrite = new String(s);
- try {
- sockout.write(towrite.getBytes());
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- httpresponse();
- String s = new String("Error encountered");
- try {
- sockout.write(s.getBytes());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- } else if (op == 2) { /* Inventory */
- // System.printString("DEBUG > Calling inventory transaction\n");
- httpresponse();
- inventorylist.inventory(sock);
- } else { /* Error */
- // System.printString("T > Error - Unknown transaction\n");
- }
- //Invoke close operations
- try {
- sock.close();
- } catch (Exception e) {e.printStackTrace();}
- }
-
-
- //Send the http header for web browser display
- public void httpresponse(){
- StringBuffer header = new StringBuffer("HTTP/1.0 200 OK\n");
- header.append("Content-type: text/html\n");
- header.append("\n\n");
- String temp_str = new String(header);
- try {
- sockout.write(temp_str.getBytes());
- } catch (Exception e) {
- e.printStackTrace();
- }
- return;
-
- }
-
- // Send the html file , read from file one byte at a time
- public void sendfile() {
- StringBuffer req_file = new StringBuffer("./htmlfiles/");
- req_file.append(filename);
- String filepath = new String(req_file);
- FileInputStream def_file = null;
- try {
- def_file=new FileInputStream(filepath);
- } catch (FileNotFoundException e) {
- }
- // int status = def_file.getfd();//Checks if the file is present in
- //current directory
- httpresponse();
- if (def_file == null){
- StringBuffer response = new StringBuffer("404: not found: ");//Send 404 error if
- // file not found
- response.append(filename);
- String buffer = new String(response);
- try {
- sockout.write(buffer.getBytes());
- } catch (Exception e) {
- e.printStackTrace();
- }
- try {
- def_file.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return;
- }
- byte buf[] = new byte[16];
- int ret;
-
- try {
- while ((ret = def_file.read(buf)) > 0) {// Read from file and write
- // one byte at a time into the socket
- byte tosend[] = new byte[ret];
- for (int i = 0; i < ret; i++) {
- tosend[i] = buf[i];
- }
- sockout.write(tosend);
- //String str = new String(tosend);
- }
- def_file.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- //Read the client request and extract the filename from it
- public boolean clientrequest(){
- byte b1[] = new byte[1024];
- int numbytes=0;
- try {
- numbytes=sockin.read(b1);//Read client request from web server socket
- } catch (Exception e) {
- e.printStackTrace();
- }
- String curr=(new String(b1)).substring(0, numbytes);
- if (prefix!=null) {
- StringBuffer sb=new StringBuffer(prefix);
- sb.append(curr);
- curr=sb.toString();
- }
- prefix=curr;
- if(prefix.indexOf("\r\n\r\n")>=0) {
-
- int index = prefix.indexOf('/');//Parse the GET client request to find filename
- int end = prefix.indexOf('H');
- filename = prefix.substring((index+1), (end-1));
- // System.printString("\n");
- return true;
- }
- return false;
- }
-
- // Parse for the prefix in the client request
- // This is helpful to find if the prefix is a special transaction
- public boolean checktrans(){
- if (filename.startsWith("trans") == true) {
- return true;
- } else {
- return false;
- }
- }
-
- //Parse for the substrings in the filename and use it to obtain the
- //kind of operation, name of item, quantity of item, price of item
- //e.g. trans_add_car_2_10000 is the filename
- //store in the parsed[] string , add,car,2,1000
- public int parseTransaction(){
- int start = filename.indexOf('_');
- String s = filename.substring(start+1);
-
- if (s.startsWith("add")==true){
- // System.printString("DEBUG > ADD\n");
- int i1 = s.indexOf('_');
- parsed[0] = new String(s.substring(0,i1));
-
- int i2 = s.indexOf('_',i1+1);
- parsed[1] = new String(s.substring(i1+1,i2));
-
- int i3 = s.indexOf('_',i2+1);
- parsed[2] = new String(s.substring(i2+1,i3));
-
- String s3 = s.substring(i3+1);
- parsed[3] = s3;
-
- return 0;
-
- }
- if (s.startsWith("buy")==true){
- // System.printString("DEBUG > BUY\n");
- int i1 = s.indexOf('_');
- parsed[0] = s.substring(0,i1);
-
- int i2 = s.indexOf('_', i1+1);
- parsed[1] = s.substring(i1+1,i2);
-
- String s2 = s.substring(i2+1);
- parsed[2] = s2;
-
- parsed[3] = "";
-
- return 1;
- }
- if (s.startsWith("inventory")==true){
- // System.printString("DEBUG > INVENTORY\n");
- return 2;
-
- }
- // Error transaction
- return -1;
- }
-}
+++ /dev/null
-public class Inventory {
- // Transaction variables
- int numitems;
- HashMap map;
- int balance;
-
- // Constructor
- public Inventory(){
- map = new HashMap();
- balance=100000;
- }
-
- public Inventory(int howmany) {
- numitems = howmany;// howmany keeps track of the number of items
- // in the inventory
- map = new HashMap();
- }
-
- // Add item to a list of inventory
- public synchronized int additem(String name, int quantity, int price){
- ItemInfo newitem = new ItemInfo(quantity, price);
- balance-=quantity*price;
-
- // Get the item from hash
- if (map.containsKey(name) == false) {
- map.put(name, newitem);
- } else {
- ItemInfo i = (ItemInfo) map.get(name);
- i.quantity += quantity;
- i.price = price;
- map.put(name, i);
- }
- return 0;
- }
-
- // Buy item from a given list of inventory
- public synchronized int buyitem(String name, int quantity){
- if (map.containsKey(name) == false) {
- // System.printString("Error - Item does not exist");
- return -1;
- } else {
- ItemInfo i = (ItemInfo) map.get(name);
- if (i.quantity == 0) {
- // System.printString("Error - Item unavailable");
- return -1;
- }
- if ((i.quantity-quantity) < 0 ) {
- // System.printString("Error - Available qty is less: Cannot Buy\n");
- return -1;
- } else {
- i.quantity -= quantity;
- map.put(name, i);
- balance+=quantity*i.price;
- return i.price;
- }
- }
- return 0;
- }
-
- //Display the inventory list
- public synchronized void inventory(Socket s){
- HashMapIterator i = new HashMapIterator(map, 0);// Gets key from the hashmap= name of item
- HashMapIterator j = new HashMapIterator(map, 1);//Gets the value from hashmap
- int totalvalue=balance;
- while (i.hasNext() == true) {
- StringBuffer sb = new StringBuffer("");
- Object o = i.next();
- String name = o.toString();
- ItemInfo oo = (ItemInfo) j.next();
- sb.append(name);
- sb.append(" ");
- Integer q = new Integer(oo.quantity);
- sb.append(q.toString());
- sb.append(" ");
- Integer p = new Integer(oo.price);
- sb.append(p.toString());
- sb.append("\n");
- totalvalue+=oo.quantity*oo.price;
- s.write(sb.toString().getBytes());
- }
- StringBuffer sb=new StringBuffer("");
- sb.append("Total value: ");
- sb.append((new Integer(totalvalue)).toString());
- sb.append("\n");
- s.write(sb.toString().getBytes());
- }
-}
+++ /dev/null
-class ItemInfo {
- int quantity;
- int price;
- ItemInfo(int x, int y) {
- quantity = x;
- price = y;
- }
-}
+++ /dev/null
-public class Logger {
- FileOutputStream fos;
-
-
- //Constructor
- public Logger(){
- fos=new FileOutputStream("request.log");//Open request.log file
- }
-
- //Logs filename as per client requests
- public synchronized void logrequest(String filename){
- String request = new String("\nNew Request received: ");
- fos.write(request.getBytes());
- fos.write(filename.getBytes());
- fos.flush();
- }
-
- public synchronized void logrequest(){
- String request = new String("\nNew Request received: ");
- fos.write(request.getBytes());
- fos.flush();
- }
-
- public void closerequest() {
- fos.close();
- }
-}
+++ /dev/null
-public class WebServerExample {
-
- public static int main(String arg[]) {
- // Create New ServerSocket
- // System.printString("W> Starting\n");
- ServerSocket ss = new ServerSocket(9000);
- // System.printString("W> Creating ServerSocket\n");
- Logger log = new Logger();
- Inventory inventorylist = new Inventory();
- acceptConnection(ss, log, inventorylist);
- }
-
- //Listen for a request and accept request
- public static void acceptConnection(ServerSocket ss, Logger log, Inventory inventorylist) {
- // System.printString("W> Waiting for connection...\n");
- while(true) {
- Socket s=ss.accept();
- WebServerThread web = new WebServerThread(s, log, inventorylist);
- web.start();
- // System.printString("W> Connected... \n");
- }
- }
-}
+++ /dev/null
-public class WebServerThread extends Thread {
- //Filename requested by the client
- String filename;
- String[] parsed;
- String prefix;
- Logger log;
- Inventory inventorylist;
- Socket sock;
-
- //Constructor
- public WebServerThread(Socket s, Logger log, Inventory inventory){
- parsed = new String[4];
- this.log=log;
- this.sock=s;
- this.inventorylist=inventory;
- }
-
- public void run() {
- // Process the incoming http request
- while (!clientrequest()) {
- }
- if(checktrans()==false) {
- // Not special transaction , do normal filesending
- SendFile();
- LogRequest();
- } else {
- // Invoke special inventory transaction
- Transaction();
- LogRequest();
- }
- }
-
- //Do the WriteIO on server socket and send the requested file to Client
- public void SendFile() {
- sendfile();
- sock.close();
- }
-
- // Log the Client request
- public void LogRequest() {
- log.logrequest(filename);
- }
-
- //Transaction on Inventory
- public void Transaction() {
- // Parse
- int op = parseTransaction();
- // Check for the kind of operation
- if (op == 0 ) { /* Add */
- // System.printString("DEBUG > Calling add transaction\n");
- Integer qty = new Integer(parsed[2]);
- Integer price = new Integer(parsed[3]);
- int ret = inventorylist.additem(parsed[1], qty.intValue(), price.intValue());
- if (ret == 0) {
- httpresponse();
- StringBuffer s = new StringBuffer("Added Item ");
- s.append(parsed[1]);
- s.append(" Quantity ");
- s.append(parsed[2]);
- s.append(" Price ");
- s.append(parsed[3]);
- s.append("\n");
- String towrite = new String(s);
- sock.write(towrite.getBytes());
- } else {
- httpresponse();
- String s = new String("Error encountered");
- sock.write(s.getBytes());
- }
- } else if (op == 1) { /* Buy */
- // System.printString("DEBUG > Calling buy transaction\n");
- Integer qty = new Integer(parsed[2]);
- int ret = inventorylist.buyitem(parsed[1], qty.intValue());
- if (ret >= 0) {
- httpresponse();
- StringBuffer s = new StringBuffer("Bought item ");
- s.append(parsed[1]);
- s.append(" Quantity ");
- s.append(parsed[2]);
- s.append(" Cost ");
- Integer cost = new Integer(ret*qty.intValue());
- String c = cost.toString();
- s.append(c);
- String towrite = new String(s);
- sock.write(towrite.getBytes());
- } else {
- httpresponse();
- String s = new String("Error encountered");
- sock.write(s.getBytes());
- }
- } else if (op == 2) { /* Inventory */
- // System.printString("DEBUG > Calling inventory transaction\n");
- httpresponse();
- inventorylist.inventory(sock);
- } else { /* Error */
- // System.printString("T > Error - Unknown transaction\n");
- }
- //Invoke close operations
- sock.close();
- }
-
-
- //Send the http header for web browser display
- public void httpresponse(){
- StringBuffer header = new StringBuffer("HTTP/1.0 200 OK\n");
- header.append("Content-type: text/html\n");
- header.append("\n\n");
- String temp_str = new String(header);
- sock.write(temp_str.getBytes());
- return;
-
- }
-
- // Send the html file , read from file one byte at a time
- public void sendfile() {
- StringBuffer req_file = new StringBuffer("./htmlfiles/");
- req_file.append(filename);
- String filepath = new String(req_file);
- FileInputStream def_file = new FileInputStream(filepath);
- int status = def_file.getfd();//Checks if the file is present in
- //current directory
- httpresponse();
- if (status == -1){
- StringBuffer response = new StringBuffer("404: not found: ");//Send 404 error if
- // file not found
- response.append(filename);
- String buffer = new String(response);
- sock.write(buffer.getBytes());
- def_file.close();
- return;
- }
- byte buf[] = new byte[16];
- int ret;
-
- while ((ret = def_file.read(buf)) > 0) {// Read from file and write
- // one byte at a time into the socket
- byte tosend[] = new byte[ret];
- for (int i = 0; i < ret; i++) {
- tosend[i] = buf[i];
- }
- sock.write(tosend);
- //String str = new String(tosend);
- }
- def_file.close();
- }
-
- //Read the client request and extract the filename from it
- public boolean clientrequest(){
- byte b1[] = new byte[1024];
- int numbytes=sock.read(b1);//Read client request from web server socket
- String curr=(new String(b1)).subString(0, numbytes);
- if (prefix!=null) {
- StringBuffer sb=new StringBuffer(prefix);
- sb.append(curr);
- curr=sb.toString();
- }
- prefix=curr;
- if(prefix.indexOf("\r\n\r\n")>=0) {
-
- int index = prefix.indexOf('/');//Parse the GET client request to find filename
- int end = prefix.indexOf('H');
- filename = prefix.subString((index+1), (end-1));
- // System.printString("\n");
- return true;
- }
- return false;
- }
-
- // Parse for the prefix in the client request
- // This is helpful to find if the prefix is a special transaction
- public boolean checktrans(){
- if (filename.startsWith("trans") == true) {
- return true;
- } else {
- return false;
- }
- }
-
- //Parse for the substrings in the filename and use it to obtain the
- //kind of operation, name of item, quantity of item, price of item
- //e.g. trans_add_car_2_10000 is the filename
- //store in the parsed[] string , add,car,2,1000
- public int parseTransaction(){
- int start = filename.indexOf('_');
- String s = filename.subString(start+1);
-
- if (s.startsWith("add")==true){
- // System.printString("DEBUG > ADD\n");
- int i1 = s.indexOf('_');
- parsed[0] = new String(s.subString(0,i1));
-
- int i2 = s.indexOf('_',i1+1);
- parsed[1] = new String(s.subString(i1+1,i2));
-
- int i3 = s.indexOf('_',i2+1);
- parsed[2] = new String(s.subString(i2+1,i3));
-
- String s3 = s.subString(i3+1);
- parsed[3] = s3;
-
- return 0;
-
- }
- if (s.startsWith("buy")==true){
- // System.printString("DEBUG > BUY\n");
- int i1 = s.indexOf('_');
- parsed[0] = s.subString(0,i1);
-
- int i2 = s.indexOf('_', i1+1);
- parsed[1] = s.subString(i1+1,i2);
-
- String s2 = s.subString(i2+1);
- parsed[2] = s2;
-
- parsed[3] = "";
-
- return 1;
- }
- if (s.startsWith("inventory")==true){
- // System.printString("DEBUG > INVENTORY\n");
- return 2;
-
- }
- // Error transaction
- return -1;
- }
-}
+++ /dev/null
-public class Inventory {
- // Inventory flags
- flag TransInitialize;
-
- // Transaction variables
- int numitems;
- HashMap map;
- int balance;
-
- // Constructor
- public Inventory(){
- map = new HashMap();
- balance=100000;
- }
-
- public Inventory(int howmany) {
- numitems = howmany;// howmany keeps track of the number of items
- // in the inventory
- map = new HashMap();
- }
-
- // Add item to a list of inventory
- public int additem(String name, int quantity, int price){
- ItemInfo newitem = new ItemInfo(quantity, price);
- balance-=quantity*price;
-
- // Get the item from hash
- if (map.containsKey(name) == false) {
- map.put(name, newitem);
- } else {
- ItemInfo i = (ItemInfo) map.get(name);
- i.quantity += quantity;
- i.price = price;
- map.put(name, i);
- }
- return 0;
- }
-
- // Buy item from a given list of inventory
- public int buyitem(String name, int quantity){
- if (map.containsKey(name) == false) {
- // System.printString("Error - Item does not exist");
- return -1;
- } else {
- ItemInfo i = (ItemInfo) map.get(name);
- if (i.quantity == 0) {
- // System.printString("Error - Item unavailable");
- return -1;
- }
- if ((i.quantity-quantity) < 0 ) {
- // System.printString("Error - Available qty is less: Cannot Buy\n");
- return -1;
- } else {
- i.quantity -= quantity;
- map.put(name, i);
- balance+=quantity*i.price;
- return i.price;
- }
- }
- return 0;
- }
-
- //Display the inventory list
- //Display the inventory list
- public synchronized void inventory(Socket s){
- HashMapIterator i = new HashMapIterator(map, 0);// Gets key from the hashmap= name of item
- HashMapIterator j = new HashMapIterator(map, 1);//Gets the value from hashmap
- int totalvalue=balance;
- while (i.hasNext() == true) {
- StringBuffer sb = new StringBuffer("");
- Object o = i.next();
- String name = o.toString();
- ItemInfo oo = (ItemInfo) j.next();
- sb.append(name);
- sb.append(" ");
- Integer q = new Integer(oo.quantity);
- sb.append(q.toString());
- sb.append(" ");
- Integer p = new Integer(oo.price);
- sb.append(p.toString());
- sb.append("\n");
- totalvalue+=oo.quantity*oo.price;
- s.write(sb.toString().getBytes());
- }
- StringBuffer sb=new StringBuffer("");
- sb.append("Total value: ");
- sb.append((new Integer(totalvalue)).toString());
- sb.append("\n");
- s.write(sb.toString().getBytes());
- }
-}
+++ /dev/null
-class ItemInfo {
- int quantity;
- int price;
- ItemInfo(int x, int y) {
- quantity = x;
- price = y;
- }
-}
+++ /dev/null
-public class Logger {
- //Logger flag
- flag Initialize;
- FileOutputStream fos;
-
-
- //Constructor
- public Logger(){
- fos=new FileOutputStream("request.log");//Open request.log file
- }
-
- //Logs filename as per client requests
- public void logrequest(String filename){
- String request = new String("\nNew Request received: ");
- fos.write(request.getBytes());
- fos.write(filename.getBytes());
- fos.flush();
- }
-
- public void logrequest(){
- String request = new String("\nNew Request received: ");
- fos.write(request.getBytes());
- fos.flush();
- }
-
- public void closerequest() {
- fos.close();
- }
-}
+++ /dev/null
-/* Startup object is generated with the initialstate flag set by the
- * system to start the computation up */
-
-// Create New ServerSocket
-task Startup(StartupObject s {initialstate}) {
-// System.printString("W> Starting\n");
- ServerSocket ss = new ServerSocket(9000);
-// System.printString("W> Creating ServerSocket\n");
- Logger log = new Logger() {Initialize};
- Inventory inventorylist = new Inventory(){TransInitialize};
- taskexit(s {!initialstate}); /* Turns initial state flag off, so this task won't refire */
-}
-
-//Listen for a request and accept request
-task AcceptConnection(ServerSocket ss{SocketPending}) {
- // System.printString("W> Waiting for connection...\n");
- tag t=new tag(link);
- WebServerSocket web = new WebServerSocket() {!WritePending, !TransPending, WebInitialize}{t};
- ss.accept(t);
-// System.printString("W> Connected... \n");
-}
-
-// Process the incoming http request
-task ProcessRequest(WebServerSocket web{WebInitialize}{link l}, Socket s{IOPending}{link l}) {
- if (web.clientrequest(s)) {
- if(web.checktrans()==false)
- // Not special transaction , do normal filesending
- taskexit(web {WritePending, LogPending,!WebInitialize}); //Sets the WritePending and LogPending flag true
- else
- // Invoke special inventory transaction
- taskexit(web {TransPending, LogPending,!WebInitialize});
- }
-}
-
-//Do the WriteIO on server socket and send the requested file to Client
-task SendFile(WebServerSocket web{WritePending}{link l}, Socket s{}{link l}) {
-// System.printString("W> Inside SendFile ... \n");
- web.sendfile(s);
- s.close();
- taskexit(web {!WritePending});
-}
-
-// Log the Client request
-task LogRequest(WebServerSocket web{LogPending}, Logger log{Initialize}) {
-//Task fired when both
-// LogPending and Initialize flags are true
-// System.printString("L > Inside logrequest\n");
- log.logrequest(web.filename);
- taskexit(web {!LogPending});
-}
-
-//Transaction on Inventory
-task Transaction(WebServerSocket web{TransPending}{link l}, Inventory inventorylist{TransInitialize},Socket s{}{link l}){ //Task for WebServerTransactions
-// System.printString("T > Inside Transaction\n");
- // Parse
- int op = web.parseTransaction();
- // Check for the kind of operation
- if (op == 0 ) { /* Add */
-// System.printString("DEBUG > Calling add transaction\n");
- Integer qty = new Integer(web.parsed[2]);
- Integer price = new Integer(web.parsed[3]);
- int ret = inventorylist.additem(web.parsed[1], qty.intValue(), price.intValue());
- if (ret == 0) {
- web.httpresponse(s);
- StringBuffer st = new StringBuffer("Added Item ");
- st.append(web.parsed[1]);
- st.append(" Quantity ");
- st.append(web.parsed[2]);
- st.append(" Price ");
- st.append(web.parsed[3]);
- st.append("\n");
- String towrite = new String(st);
- s.write(towrite.getBytes());
- } else {
- web.httpresponse(s);
- String st = new String("Error encountered");
- s.write(st.getBytes());
- }
- } else if (op == 1) { /* Buy */
-// System.printString("DEBUG > Calling buy transaction\n");
- Integer qty = new Integer(web.parsed[2]);
- int ret = inventorylist.buyitem(web.parsed[1], qty.intValue());
- if (ret >= 0) {
- web.httpresponse(s);
- StringBuffer st = new StringBuffer("Bought item ");
- st.append(web.parsed[1]);
- st.append(" Quantity ");
- st.append(web.parsed[2]);
- st.append(" Cost ");
- Integer cost = new Integer(ret*qty.intValue());
- String c = cost.toString();
- st.append(c);
- String towrite = new String(st);
- s.write(towrite.getBytes());
- } else {
- web.httpresponse(s);
- String st = new String("Error encountered");
- s.write(st.getBytes());
- }
- } else if (op == 2) { /* Inventory */
-// System.printString("DEBUG > Calling inventory transaction\n");
- web.httpresponse(s);
- inventorylist.inventory(s);
- } else { /* Error */
-// System.printString("T > Error - Unknown transaction\n");
- }
- //Invoke close operations
- s.close();
- taskexit(web {!TransPending});
-}
+++ /dev/null
-public class WebServerSocket {
- // Websocket flag
- flag LogPending;
- flag WritePending;
- flag TransPending;
- flag WebInitialize;
-
- //Filename requested by the client
- String filename;
- String[] parsed;
- String prefix;
-
- //Constructor
- public WebServerSocket(){
- parsed = new String[4];
- }
-
- //Send the http header for web browser display
- public void httpresponse(Socket s){
- StringBuffer header = new StringBuffer("HTTP/1.0 200 OK\n");
- header.append("Content-type: text/html\n");
- header.append("\n\n");
- String temp_str = new String(header);
- s.write(temp_str.getBytes());
- return;
-
- }
-
- // Send the html file , read from file one byte at a time
- public void sendfile(Socket s) {
- StringBuffer req_file = new StringBuffer("./htmlfiles/");
- req_file.append(filename);
- String filepath = new String(req_file);
- FileInputStream def_file = new FileInputStream(filepath);
- int status = def_file.getfd();//Checks if the file is present in
- //current directory
- httpresponse(s);
- if (status == -1){
- StringBuffer response = new StringBuffer("404: not found: ");//Send 404 error if
- // file not found
- response.append(filename);
- String buffer = new String(response);
- s.write(buffer.getBytes());
- def_file.close();
- return;
- }
- byte buf[] = new byte[16];
- int ret;
-
- while ((ret = def_file.read(buf)) > 0) {// Read from file and write
- // one byte at a time into the socket
- byte tosend[] = new byte[ret];
- for (int i = 0; i < ret; i++) {
- tosend[i] = buf[i];
- }
- s.write(tosend);
- //String str = new String(tosend);
- }
- def_file.close();
- }
-
- //Read the client request and extract the filename from it
- public boolean clientrequest(Socket s){
- byte b1[] = new byte[1024];
- int numbytes=s.read(b1);//Read client request from web server socket
- String curr=(new String(b1)).subString(0, numbytes);
- if (prefix!=null) {
- StringBuffer sb=new StringBuffer(prefix);
- sb.append(curr);
- curr=sb.toString();
- }
- prefix=curr;
- if(prefix.indexOf("\r\n\r\n")>=0) {
-
- int index = prefix.indexOf('/');//Parse the GET client request to find filename
- int end = prefix.indexOf('H');
- filename = prefix.subString((index+1), (end-1));
- return true;
- }
- return false;
- }
-
- // Parse for the prefix in the client request
- // This is helpful to find if the prefix is a special transaction
- public boolean checktrans(){
- if (filename.startsWith("trans") == true) {
- return true;
- } else {
- return false;
- }
- }
-
- //Parse for the substrings in the filename and use it to obtain the
- //kind of operation, name of item, quantity of item, price of item
- //e.g. trans_add_car_2_10000 is the filename
- //store in the parsed[] string , add,car,2,1000
- public int parseTransaction(){
- int start = filename.indexOf('_');
- String s = filename.subString(start+1);
-
- if (s.startsWith("add")==true){
- // System.printString("DEBUG > ADD\n");
- int i1 = s.indexOf('_');
- parsed[0] = new String(s.subString(0,i1));
-
- int i2 = s.indexOf('_',i1+1);
- parsed[1] = new String(s.subString(i1+1,i2));
-
- int i3 = s.indexOf('_',i2+1);
- parsed[2] = new String(s.subString(i2+1,i3));
-
- String s3 = s.subString(i3+1);
- parsed[3] = s3;
-
- return 0;
-
- }
- if (s.startsWith("buy")==true){
- // System.printString("DEBUG > BUY\n");
- int i1 = s.indexOf('_');
- parsed[0] = s.subString(0,i1);
-
- int i2 = s.indexOf('_', i1+1);
- parsed[1] = s.subString(i1+1,i2);
-
- String s2 = s.subString(i2+1);
- parsed[2] = s2;
-
- parsed[3] = "";
-
- return 1;
- }
- if (s.startsWith("inventory")==true){
- // System.printString("DEBUG > INVENTORY\n");
- return 2;
-
- }
- // Error transaction
- return -1;
- }
-}
+++ /dev/null
-public class File {
- String path;
-
- public File(String path) {
- this.path=path;
- }
-
- String getPath() {
- return path;
- }
-
- long length() {
- return nativeLength(path.getBytes());
- }
-
- private static native long nativeLength(byte[] pathname);
-}
+++ /dev/null
-public class FileInputStream {
- private int fd;
-
- public FileInputStream(String pathname) {
- fd=nativeOpen(pathname.getBytes());
- }
-
- public FileInputStream(File path) {
- fd=nativeOpen(path.getPath().getBytes());
- }
- public int getfd() {
- return fd;
- }
-
- private static native int nativeOpen(byte[] filename);
- private static native int nativeRead(int fd, byte[] array, int numBytes);
- private static native void nativeClose(int fd);
-
- public int read() {
- byte b[]=new byte[1];
- int retval=read(b);
- if (retval==-1)
- return -1;
- return b[0];
- }
-
- public int read(byte[] b) {
- return nativeRead(fd, b, b.length);
- }
-
- public void close() {
- nativeClose(fd);
- }
-}
+++ /dev/null
-public class FileOutputStream {
- private int fd;
-
- public FileOutputStream(String pathname) {
- fd=nativeOpen(pathname.getBytes());
- }
-
- public FileOutputStream(String pathname, int mode) {
- if(mode==0)
- fd=nativeAppend(pathname.getBytes());
- if(mode==1)
- fd=nativeOpen(pathname.getBytes());
- }
-
-
- public FileOutputStream(File path) {
- fd=nativeOpen(path.getPath().getBytes());
- }
-
- private static native int nativeOpen(byte[] filename);
- private static native int nativeAppend(byte[] filename);
- private static native void nativeWrite(int fd, byte[] array);
- private static native void nativeClose(int fd);
- private static native void nativeFlush(int fd);
-
- public void write(int ch) {
- byte b[]=new byte[1];
- b[0]=(byte)ch;
- write(b);
- }
-
- public void write(byte[] b) {
- nativeWrite(fd, b);
- }
-
- public void flush() {
- nativeFlush(fd);
- }
-
- public void close() {
- nativeClose(fd);
- }
-}
+++ /dev/null
-class HashEntry {
- public HashEntry() {}
- Object key;
- Object value;
- HashEntry next;
-}
+++ /dev/null
-public class HashMap {
- HashEntry[] table;
- float loadFactor;
- int numItems;
-
- public HashMap() {
- init(16, 0.75f);
- }
-
- public HashMap(int initialCapacity) {
- init(initialCapacity, 0.75f);
- }
-
- public HashMap(int initialCapacity, float loadFactor) {
- init(initialCapacity, loadFactor);
- }
-
- private void init(int initialCapacity, float loadFactor) {
- table=new HashEntry[initialCapacity];
- this.loadFactor=loadFactor;
- this.numItems=0;
- }
-
- private int hash(Object o) {
- if (o==null)
- return 0;
- int value=o.hashCode()%table.length;
- if (value<0)
- return -value;
- return value;
- }
-
- void resize() {
- int newCapacity=2*table.length+1;
- HashEntry[] oldtable=table;
- this.table=new HashEntry[newCapacity];
-
- for(int i=0;i<oldtable.length;i++) {
- HashEntry e=oldtable[i];
- while(e!=null) {
- HashEntry next=e.next;
- int bin=hash(e.key);
- e.next=table[bin];
- table[bin]=e;
- e=next;
- }
- }
- }
-
- public boolean isEmpty() {
- return numItems==0;
- }
-
- public int size() {
- return numItems;
- }
-
- /* 0=keys, 1=values */
- public HashMapIterator iterator(int type) {
- return new HashMapIterator(this, type);
- }
-
- Object remove(Object key) {
- int bin=hash(key);
- HashEntry ptr=table[bin];
- if (ptr!=null) {
- if (ptr.key.equals(key)) {
- table[bin]=ptr.next;
- numItems--;
- return ptr.value;
- }
- while(ptr.next!=null) {
- if (ptr.next.key.equals(key)) {
- Object oldvalue=ptr.value;
- ptr.next=ptr.next.next;
- numItems--;
- return oldvalue;
- }
- ptr=ptr.next;
- }
- }
- return null;
- }
-
- Object get(Object key) {
- int bin=hash(key);
- HashEntry ptr=table[bin];
- while(ptr!=null) {
- if (ptr.key.equals(key)) {
- return ptr.value;
- }
- ptr=ptr.next;
- }
- return null;
- }
-
- boolean containsKey(Object key) {
- int bin=hash(key);
- HashEntry ptr=table[bin];
- while(ptr!=null) {
- if (ptr.key.equals(key)) {
- return true;
- }
- ptr=ptr.next;
- }
- return false;
- }
-
- Object put(Object key, Object value) {
- numItems++;
- if (numItems>(loadFactor*table.length)) {
- //Resize the table
- resize();
- }
- int bin=hash(key);
- HashEntry ptr=table[bin];
- while(ptr!=null) {
- if (ptr.key.equals(key)) {
- Object oldvalue=ptr.value;
- ptr.value=value;
- return oldvalue;
- }
- ptr=ptr.next;
- }
- HashEntry he=new HashEntry();
- he.value=value;
- he.key=key;
- he.next=table[bin];
- table[bin]=he;
- return null;
- }
-}
+++ /dev/null
-class HashMapIterator {
- HashMap map;
- int type;
- int bin;
- HashEntry he;
-
- public HashMapIterator(HashMap map, int type) {
- this.map=map;
- this.type=type;
- this.bin=0;
- this.he=null;
- }
-
- public boolean hasNext() {
- if (he!=null&&he.next!=null)
- return true;
- int i=bin;
- while((i<map.table.length)&&map.table[i]==null)
- i++;
- return (i<map.table.length);
- }
-
- public Object next() {
- if (he!=null&&he.next!=null) {
- he=he.next;
- Object o;
- if (type==0)
- o=he.key;
- else
- o=he.value;
- return o;
- }
- while((bin<map.table.length)&&
- (map.table[bin]==null))
- bin++;
- if (bin<map.table.length) {
- he=map.table[bin++];
- Object o;
- if (type==0)
- o=he.key;
- else
- o=he.value;
- return o;
- } else System.error();
- }
-}
+++ /dev/null
-public class HashSet {
- HashMap map;
- HashSet() {
- map=new HashMap();
- }
- HashSet(int initialCapacity) {
- map=new HashMap(initialCapacity);
- }
- HashSet(int initialCapacity, float loadFactor) {
- map=new HashMap(initialCapacity, loadFactor);
- }
- public boolean add(Object o) {
- return (map.put(o, this)==null);
- }
- public boolean remove(Object o) {
- return (map.remove(o)!=null);
- }
- public boolean isEmpty() {
- return map.isEmpty();
- }
- public boolean contains(Object o) {
- return map.containsKey(o);
- }
- public int size() {
- return map.size();
- }
- public HashMapIterator iterator() {
- return map.iterator(0);
- }
-}
+++ /dev/null
-public class InetAddress {
- String hostname;
- byte[] address;
-
- public InetAddress(byte[] addr, String hostname) {
- this.hostname=hostname;
- this.address=addr;
- }
-
- public static InetAddress getByAddress(String host, byte[] addr) {
- return new InetAddress(addr, host);
- }
-
- public static InetAddress getByName(String hostname) {
- InetAddress[] addresses=getAllByName(hostname);
- return addresses[0];
- }
-
- public byte[] getAddress() {
- return address;
- }
-
- public static InetAddress[] getAllByName(String hostname) {
- InetAddress[] addresses;
-
- byte[][] iplist = InetAddress.getHostByName(hostname.getBytes());
-
- addresses = new InetAddress[iplist.length];
-
- for (int i = 0; i < iplist.length; i++) {
- addresses[i] = new InetAddress(iplist[i], hostname);
- }
- return addresses;
- }
-
- public static native byte[][] getHostByName(byte[] hostname);
-}
+++ /dev/null
-public class Integer {
- private int value;
-
- public Integer(int value) {
- this.value=value;
- }
-
- public Integer(String str) {
- value=Integer.parseInt(str, 10);
- }
-
- public int intValue() {
- return value;
- }
-
- public static int parseInt(String str) {
- return Integer.parseInt(str, 10);
- }
-
- public static int parseInt(String str, int radix) {
- int value=0;
- boolean isNeg=false;
- int start=0;
- byte[] chars=str.getBytes();
-
- while(chars[start]==' '||chars[start]=='\t')
- start++;
-
- if (chars[start]=='-') {
- isNeg=true;
- start++;
- }
- boolean cont=true;
- for(int i=start;cont&&i<str.length();i++) {
- byte b=chars[i];
- int val;
- if (b>='0'&&b<='9')
- val=b-'0';
- else if (b>='a'&&b<='z')
- val=10+b-'a';
- else if (b>='A'&&b<='Z')
- val=10+b-'A';
- else cont=false;
- if (cont) {
- if (val>=radix)
- System.error();
- value=value*radix+val;
- }
- }
- if (isNeg)
- value=-value;
- return value;
- }
-
- public String toString() {
- return String.valueOf(value);
- }
-}
+++ /dev/null
-public class Object {
- public native int nativehashCode();
- private int cachedCode;//first field has to be a primitive
- private boolean cachedHash;
-
- /* DO NOT USE ANY OF THESE - THEY ARE FOR IMPLEMENTING TAGS */
- private Object tags;
-
- public int hashCode() {
- if (!cachedHash) {
- cachedCode=nativehashCode();
- cachedHash=true;
- }
- return cachedCode;
- }
-
- /* DON'T USE THIS METHOD UNLESS NECESSARY */
- /* WE WILL DEPRECATE IT AS SOON AS INSTANCEOF WORKS */
- public native int getType();
-
- public String toString() {
- return String.valueOf(this);
- }
-
- public boolean equals(Object o) {
- if (o==this)
- return true;
- return false;
- }
-}
+++ /dev/null
-public class Object {
- public int cachedCode; //first field has to be a primitive
- public boolean cachedHash;
-
- public native int nativehashCode();
- private Object nextlockobject;
- private Object prevlockobject;
-
- public int hashCode() {
- if (!cachedHash) {
- cachedCode=nativehashCode();
- cachedHash=true;
- }
- return cachedCode;
- }
-
- /* DON'T USE THIS METHOD UNLESS NECESSARY */
- /* WE WILL DEPRECATE IT AS SOON AS INSTANCEOF WORKS */
- public native int getType();
-
- public native int MonitorEnter();
- public native int MonitorExit();
-
- public String toString() {
- return String.valueOf(this);
- }
-
- public boolean equals(Object o) {
- if (o==this)
- return true;
- return false;
- }
-}
+++ /dev/null
-public class Object {
- public int cachedCode; //first field has to be a primitive
- public boolean cachedHash;
-
- public native int nativehashCode();
- public Object foo;
-
- public int hashCode() {
- if (!cachedHash) {
- cachedCode=nativehashCode();
- cachedHash=true;
- }
- return cachedCode;
- }
-
- /* DON'T USE THIS METHOD UNLESS NECESSARY */
- /* WE WILL DEPRECATE IT AS SOON AS INSTANCEOF WORKS */
- public native int getType();
-
- public String toString() {
- return String.valueOf(this);
- }
-
- public boolean equals(Object o) {
- if (o==this)
- return true;
- return false;
- }
-}
+++ /dev/null
-public class ServerSocket {
- /* Socket pending flag */
- external flag SocketPending;
- /* File Descriptor */
- int fd;
-
- private native int createSocket(int port);
-
- public ServerSocket(int port) {
- this.fd=createSocket(port);
- }
-
- public Socket accept() {
- Socket s=new Socket();
- int newfd=nativeaccept(s);
- s.setFD(newfd);
- return s;
- }
-
- public Socket accept(tag td) {
- Socket s=new Socket(){}{td};
- int newfd=nativeaccept(s);
- s.setFD(newfd);
- return s;
- }
-
- /* Lets caller pass in their own Socket object. */
- public void accept(Socket s) {
- int newfd=nativeaccept(s);
- s.setFD(newfd);
- }
-
- private native int nativeaccept(Socket s);
-
- public void close();
-
-}
+++ /dev/null
-public class ServerSocket {
- /* File Descriptor */
- int fd;
-
- private native int createSocket(int port);
-
- public ServerSocket(int port) {
- this.fd=createSocket(port);
- }
-
- public Socket accept() {
- Socket s=new Socket();
- int newfd=nativeaccept(s);
- s.setFD(newfd);
- return s;
- }
-
- /* Lets caller pass in their own Socket object. */
- public void accept(Socket s) {
- int newfd=nativeaccept(s);
- s.setFD(newfd);
- }
-
- private native int nativeaccept(Socket s);
-
- public void close();
-
-}
+++ /dev/null
-public class Socket {
- /* Data pending flag */
- external flag IOPending;
- /* File Descriptor */
- int fd;
-
- public Socket() {
- }
-
- public Socket(String host, int port) {
- InetAddress address=InetAddress.getByName(host);
- fd=nativeBind(address.getAddress(), port);
- nativeConnect(fd, address.getAddress(), port);
- }
-
- public Socket(InetAddress address, int port) {
- fd=nativeBind(address.getAddress(), port);
- nativeConnect(fd, address.getAddress(), port);
- }
-
- public static native int nativeBind(byte[] address, int port);
-
- public native int nativeConnect(int fd, byte[] address, int port);
-
- int setFD(int filed) {
- fd=filed;
- }
-
- public int read(byte[] b) {
- return nativeRead(b);
- }
- public void write(byte[] b) {
- nativeWrite(b);
- }
-
- private native int nativeRead(byte[] b);
- private native void nativeWrite(byte[] b);
- private native void nativeClose();
-
- public void close() {
- nativeClose();
- }
-}
+++ /dev/null
-public class Socket {
- /* File Descriptor */
- int fd;
-
- public Socket() {
- }
-
- public Socket(String host, int port) {
- InetAddress address=InetAddress.getByName(host);
- fd=nativeBind(address.getAddress(), port);
- nativeConnect(fd, address.getAddress(), port);
- }
-
- public Socket(InetAddress address, int port) {
- fd=nativeBind(address.getAddress(), port);
- nativeConnect(fd, address.getAddress(), port);
- }
-
- public static native int nativeBind(byte[] address, int port);
-
- public static native int nativeConnect(int fd, byte[] address, int port);
-
- int setFD(int filed) {
- fd=filed;
- }
-
- public int read(byte[] b) {
- return nativeRead(b);
- }
- public void write(byte[] b) {
- nativeWrite(b);
- }
-
- private native int nativeRead(byte[] b);
- private native void nativeWrite(byte[] b);
- private native void nativeClose();
-
- public void close() {
- nativeClose();
- }
-}
+++ /dev/null
-public class StartupObject {
- flag initialstate;
-
- String [] parameters;
-}
+++ /dev/null
-public class String {
- char value[];
- int count;
- int offset;
- private int cachedHashcode;
-
- private String() {
- }
-
- public String(char str[]) {
- char charstr[]=new char[str.length];
- for(int i=0;i<str.length;i++)
- charstr[i]=str[i];
- this.value=charstr;
- this.count=str.length;
- this.offset=0;
- }
-
- public String(byte str[]) {
- char charstr[]=new char[str.length];
- for(int i=0;i<str.length;i++)
- charstr[i]=(char)str[i];
- this.value=charstr;
- this.count=str.length;
- this.offset=0;
- }
-
- public String(String str) {
- this.value=str.value;
- this.count=str.count;
- this.offset=str.offset;
- }
-
- public String(StringBuffer strbuf) {
- value=new char[strbuf.length()];
- count=strbuf.length();
- offset=0;
- for(int i=0;i<count;i++)
- value[i]=strbuf.value[i];
- }
-
- public String subString(int beginIndex, int endIndex) {
- String str=new String();
- if (beginIndex>this.count||endIndex>this.count||beginIndex>endIndex) {
- // FIXME
- }
- str.value=this.value;
- str.count=endIndex-beginIndex;
- str.offset=this.offset+beginIndex;
- return str;
- }
-
- public String subString(int beginIndex) {
- return this.subString(beginIndex, this.count);
- }
-
- public int lastindexOf(int ch) {
- return this.lastindexOf(ch, count - 1);
- }
-
- public int lastindexOf(int ch, int fromIndex) {
- for(int i=fromIndex;i>0;i--)
- if (this.charAt(i)==ch)
- return i;
- return -1;
- }
-
- public String replace(char oldch, char newch) {
- char[] buffer=new char[count];
- for(int i=0;i<count;i++) {
- char x=charAt(i);
- if (x==oldch)
- x=newch;
- buffer[i]=x;
- }
- return new String(buffer);
- }
-
- public int indexOf(int ch) {
- return this.indexOf(ch, 0);
- }
-
- public int indexOf(int ch, int fromIndex) {
- for(int i=fromIndex;i<count;i++)
- if (this.charAt(i)==ch)
- return i;
- return -1;
- }
-
- public int indexOf(String str) {
- return this.indexOf(str, 0);
- }
-
- public int indexOf(String str, int fromIndex) {
- if (fromIndex<0)
- fromIndex=0;
- for(int i=fromIndex;i<=(count-str.count);i++)
- if (regionMatches(i, str, 0, str.count))
- return i;
- return -1;
- }
-
- public boolean startsWith(String str) {
- return regionMatches(0, str, 0, str.count);
- }
-
- public boolean regionMatches(int toffset, String other, int ooffset, int len) {
- if (toffset<0 || ooffset <0 || (toffset+len)>count || (ooffset+len)>other.count)
- return false;
- for(int i=0;i<len;i++)
- if (other.value[i+other.offset+ooffset]!=
- this.value[i+this.offset+toffset])
- return false;
- return true;
- }
-
- public char[] toCharArray() {
- char str[]=new char[count];
- for(int i=0;i<count;i++)
- str[i]=value[i+offset];
- return str;
- }
-
- public byte[] getBytes() {
- byte str[]=new byte[count];
- for(int i=0;i<count;i++)
- str[i]=(byte)value[i+offset];
- return str;
- }
-
- public int length() {
- return count;
- }
-
- public char charAt(int i) {
- return value[i+offset];
- }
-
- public String toString() {
- return this;
- }
-
- public static String valueOf(Object o) {
- return o.toString();
- }
-
- public static String valueOf(int x) {
- int length=0;
- int tmp;
- if (x<0)
- tmp=-x;
- else
- tmp=x;
- do {
- tmp=tmp/10;
- length=length+1;
- } while(tmp!=0);
-
- char chararray[];
- if (x<0)
- chararray=new char[length+1];
- else
- chararray=new char[length];
- int voffset;
- if (x<0) {
- chararray[0]='-';
- voffset=1;
- x=-x;
- } else
- voffset=0;
-
- do {
- chararray[--length+voffset]=(char)(x%10+'0');
- x=x/10;
- } while (length!=0);
- return new String(chararray);
- }
-
- public int hashCode() {
- if (cachedHashcode!=0)
- return cachedHashcode;
- int hashcode=0;
- for(int i=0;i<count;i++)
- hashcode=hashcode*31+value[i+offset];
- cachedHashcode=hashcode;
- return hashcode;
- }
-
- public boolean equals(Object o) {
- if (o.getType()!=getType())
- return false;
- String s=(String)o;
- if (s.count!=count)
- return false;
- for(int i=0;i<count;i++) {
- if (s.value[i+s.offset]!=value[i+offset])
- return false;
- }
- return true;
- }
-}
+++ /dev/null
-public class StringBuffer {
- char value[];
- int count;
- // private static final int DEFAULTSIZE=16;
-
- public StringBuffer(String str) {
- value=new char[str.count+16];//16 is DEFAULTSIZE
- count=str.count;
- for(int i=0;i<count;i++)
- value[i]=str.value[i+str.offset];
- }
-
- public StringBuffer() {
- value=new char[16];//16 is DEFAULTSIZE
- count=0;
- }
-
- public int length() {
- return count;
- }
-
- public int capacity() {
- return value.length;
- }
-
- public char charAt(int x) {
- return value[x];
- }
-
- public void append(String s) {
- if ((s.count+count)>value.length) {
- // Need to allocate
- char newvalue[]=new char[s.count+count+16]; //16 is DEFAULTSIZE
- for(int i=0;i<count;i++)
- newvalue[i]=value[i];
- for(int i=0;i<s.count;i++)
- newvalue[i+count]=s.value[i+s.offset];
- value=newvalue;
- count+=s.count;
- } else {
- for(int i=0;i<s.count;i++) {
- value[i+count]=s.value[i+s.offset];
- }
- count+=s.count;
- }
- }
-
- public void append(StringBuffer s) {
- if ((s.count+count)>value.length) {
- // Need to allocate
- char newvalue[]=new char[s.count+count+16]; //16 is DEFAULTSIZE
- for(int i=0;i<count;i++)
- newvalue[i]=value[i];
- for(int i=0;i<s.count;i++)
- newvalue[i+count]=s.value[i];
- value=newvalue;
- count+=s.count;
- } else {
- for(int i=0;i<s.count;i++) {
- value[i+count]=s.value[i];
- }
- count+=s.count;
- }
- }
-
- public String toString() {
- return new String(this);
- }
-}
+++ /dev/null
-public class System {
- public static void printInt(int x) {
- String s=String.valueOf(x);
- printString(s);
- }
-
- public static native void printString(String s);
-
- public static void error() {
- System.printString("Error (Use Breakpoint on ___System______error method for more information!)\n");
- }
-}
+++ /dev/null
-/** This class is not to be used by the end user. It's intended for
- * internal use to keep track of tags. */
-
-private class TagDescriptor {
-}
+++ /dev/null
-public class Thread {
- public void start() {
- nativeCreate();
- }
-
- private static void staticStart(Thread t) {
- t.run();
- }
-
- public native static void sleep(long millis);
-
- public void run() {}
-
- private native void nativeCreate();
-}
+++ /dev/null
-package IR;
-
-public class AssignOperation {
- public static final int EQ=1;
- public static final int MULTEQ=2;
- public static final int DIVEQ=3;
- public static final int MODEQ=4;
- public static final int PLUSEQ=5;
- public static final int MINUSEQ=6;
- public static final int LSHIFTEQ=7;
- public static final int RSHIFTEQ=8;
- public static final int URSHIFTEQ=9;
- public static final int ANDEQ=10;
- public static final int XOREQ=11;
- public static final int OREQ=12;
- public static final int POSTINC=13;
- public static final int POSTDEC=14;
-
- private int operation;
- public AssignOperation(int op) {
- this.operation=op;
- }
-
- public AssignOperation(String op) {
- this.operation=parseOp(op);
- }
-
- public Operation getBaseOp() {
- switch(operation) {
- case EQ:
- return null;
- case MULTEQ:
- return new Operation(Operation.MULT);
- case DIVEQ:
- return new Operation(Operation.DIV);
- case MODEQ:
- return new Operation(Operation.MOD);
- case PLUSEQ:
- return new Operation(Operation.ADD);
- case MINUSEQ:
- return new Operation(Operation.SUB);
- case LSHIFTEQ:
- return new Operation(Operation.LEFTSHIFT);
- case RSHIFTEQ:
- return new Operation(Operation.RIGHTSHIFT);
- case ANDEQ:
- return new Operation(Operation.BIT_AND);
- case XOREQ:
- return new Operation(Operation.BIT_XOR);
- case OREQ:
- return new Operation(Operation.BIT_OR);
- case POSTINC:
- return new Operation(Operation.POSTINC);
- case POSTDEC:
- return new Operation(Operation.POSTDEC);
- }
- throw new Error();
- }
-
- public static int parseOp(String st) {
- if (st.equals("eq"))
- return EQ;
- else if (st.equals("multeq"))
- return MULTEQ;
- else if (st.equals("diveq"))
- return DIVEQ;
- else if (st.equals("modeq"))
- return MODEQ;
- else if (st.equals("pluseq"))
- return PLUSEQ;
- else if (st.equals("minuseq"))
- return MINUSEQ;
- else if (st.equals("lshifteq"))
- return LSHIFTEQ;
- else if (st.equals("rshifteq"))
- return RSHIFTEQ;
- else if (st.equals("andeq"))
- return ANDEQ;
- else if (st.equals("xoreq"))
- return XOREQ;
- else if (st.equals("oreq"))
- return OREQ;
- else if (st.equals("postinc"))
- return POSTINC;
- else if (st.equals("postdec"))
- return POSTDEC;
- else throw new Error();
- }
-
- public String toString() {
- if (operation==EQ)
- return "=";
- else if (operation==MULTEQ)
- return "*=";
- else if (operation==DIVEQ)
- return "/=";
- else if (operation==MODEQ)
- return "%=";
- else if (operation==PLUSEQ)
- return "+=";
- else if (operation==MINUSEQ)
- return "-=";
- else if (operation==LSHIFTEQ)
- return "<=";
- else if (operation==RSHIFTEQ)
- return ">=";
- else if (operation==ANDEQ)
- return "&=";
- else if (operation==XOREQ)
- return "^=";
- else if (operation==OREQ)
- return "|=";
- else if (operation==POSTINC)
- return "postinc";
- else if (operation==POSTDEC)
- return "postdec";
- else throw new Error();
- }
-
-
-}
+++ /dev/null
-package IR;
-import java.util.*;
-import IR.Tree.*;
-
-public class ClassDescriptor extends Descriptor {
- private static int UIDCount=0;
- private final int classid;
- String superclass;
- ClassDescriptor superdesc;
- boolean hasFlags=false;
- String packagename;
-
- Modifiers modifiers;
-
- SymbolTable fields;
- SymbolTable flags;
- SymbolTable methods;
-
- public ClassDescriptor(String classname) {
- this("", classname);
- }
-
- public ClassDescriptor(String packagename, String classname) {
- super(classname);
- superclass=null;
- flags=new SymbolTable();
- fields=new SymbolTable();
- methods=new SymbolTable();
- classid=UIDCount++;
- this.packagename=packagename;
- }
-
- public int getId() {
- return classid;
- }
-
- public Iterator getMethods() {
- return methods.getDescriptorsIterator();
- }
-
- public Iterator getFields() {
- return fields.getDescriptorsIterator();
- }
-
- public Iterator getFlags() {
- return flags.getDescriptorsIterator();
- }
-
- public SymbolTable getFieldTable() {
- return fields;
- }
-
- public SymbolTable getFlagTable() {
- return flags;
- }
-
- public SymbolTable getMethodTable() {
- return methods;
- }
-
- public String getSafeDescriptor() {
- return "L"+safename.replace('.','/');
- }
-
- public String printTree(State state) {
- int indent;
- String st=modifiers.toString()+"class "+getSymbol();
- if (superclass!=null)
- st+="extends "+superclass.toString();
- st+=" {\n";
- indent=TreeNode.INDENT;
- boolean printcr=false;
-
- for(Iterator it=getFlags();it.hasNext();) {
- FlagDescriptor fd=(FlagDescriptor)it.next();
- st+=TreeNode.printSpace(indent)+fd.toString()+"\n";
- printcr=true;
- }
- if (printcr)
- st+="\n";
-
- printcr=false;
-
- for(Iterator it=getFields();it.hasNext();) {
- FieldDescriptor fd=(FieldDescriptor)it.next();
- st+=TreeNode.printSpace(indent)+fd.toString()+"\n";
- printcr=true;
- }
- if (printcr)
- st+="\n";
-
- for(Iterator it=getMethods();it.hasNext();) {
- MethodDescriptor md=(MethodDescriptor)it.next();
- st+=TreeNode.printSpace(indent)+md.toString()+" ";
- BlockNode bn=state.getMethodBody(md);
- st+=bn.printNode(indent)+"\n\n";
- }
- st+="}\n";
- return st;
- }
-
- public void addFlag(FlagDescriptor fd) {
- if (flags.contains(fd.getSymbol()))
- throw new Error(fd.getSymbol()+" already defined");
- hasFlags=true;
- flags.add(fd);
- }
-
- public boolean hasFlags() {
- return hasFlags;
- }
-
- public void addField(FieldDescriptor fd) {
- if (fields.contains(fd.getSymbol()))
- throw new Error(fd.getSymbol()+" already defined");
- fields.add(fd);
- }
-
- public void addMethod(MethodDescriptor md) {
- methods.add(md);
- }
-
- public void setModifiers(Modifiers modifiers) {
- this.modifiers=modifiers;
- }
-
- public void setSuper(String superclass) {
- this.superclass=superclass;
- }
-
- public ClassDescriptor getSuperDesc() {
- return superdesc;
- }
-
- public void setSuper(ClassDescriptor scd) {
- this.superdesc=scd;
- }
-
- public String getSuper() {
- return superclass;
- }
-}
+++ /dev/null
-package IR;
-
-/**
- * Descriptor
- *
- * represents a symbol in the language (var name, function name, etc).
- */
-
-public abstract class Descriptor {
-
- protected String name;
- protected String safename;
- static int count=0;
- int uniqueid;
-
- public Descriptor(String name) {
- this.name = name;
- this.safename = "___" + name + "___";
- this.uniqueid=count++;
- }
-
- protected Descriptor(String name, String safename) {
- this.name = name;
- this.safename = safename;
- this.uniqueid=count++;
- }
-
- public String toString() {
- return name;
- }
-
- public String getSymbol() {
- return name;
- }
-
- public String getSafeSymbol() {
- return safename;
- }
- public int getNum() {
- return uniqueid;
- }
-}
+++ /dev/null
-package IR;
-import IR.Tree.Modifiers;
-import IR.Tree.ExpressionNode;
-
-/**
- * Descriptor
- *
- * represents a symbol in the language (var name, function name, etc).
- */
-
-public class FieldDescriptor extends Descriptor {
-
- public static FieldDescriptor arrayLength=new FieldDescriptor(new Modifiers(Modifiers.PUBLIC|Modifiers.FINAL), new TypeDescriptor(TypeDescriptor.INT), "length", null, false);
-
- protected Modifiers modifier;
- protected TypeDescriptor td;
- protected String identifier;
- protected ExpressionNode en;
- private boolean isglobal;
-
- public FieldDescriptor(Modifiers m, TypeDescriptor t, String identifier, ExpressionNode e, boolean isglobal) {
- super(identifier);
- this.modifier=m;
- this.td=t;
- this.en=e;
- this.safename = "___" + name + "___";
- this.uniqueid=count++;
- this.isglobal=isglobal;
- if (en!=null) throw new Error("Field initializers not implemented");
- }
-
- public boolean isGlobal() {
- return isglobal;
- }
-
- public TypeDescriptor getType() {
- return td;
- }
-
- public String toString() {
- if (en==null)
- return modifier.toString()+td.toString()+" "+getSymbol()+";";
- else
- return modifier.toString()+td.toString()+" "+getSymbol()+"="+en.printNode(0)+";";
- }
-}
+++ /dev/null
-package IR;
-
-/**
- * Descriptor
- *
- * represents a symbol in the language (var name, function name, etc).
- */
-
-public class FlagDescriptor extends Descriptor {
-
- public FlagDescriptor(String identifier) {
- super(identifier);
- }
-
- private boolean isExternal=false;
- public void makeExternal() {
- isExternal=true;
- }
-
- public boolean getExternal() {
- return isExternal;
- }
-
- public String toString() {
- return "Flag "+getSymbol();
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.*;
-import IR.Tree.*;
-import java.util.*;
-
-public class BuildFlat {
- State state;
- Hashtable temptovar;
- MethodDescriptor currmd;
- TypeUtil typeutil;
-
- public BuildFlat(State st, TypeUtil typeutil) {
- state=st;
- temptovar=new Hashtable();
- this.typeutil=typeutil;
- }
-
- public Hashtable getMap() {
- return temptovar;
- }
-
- public void buildFlat() {
- Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
- while(it.hasNext()) {
- ClassDescriptor cn=(ClassDescriptor)it.next();
- flattenClass(cn);
- }
-
- Iterator task_it=state.getTaskSymbolTable().getDescriptorsIterator();
- while(task_it.hasNext()) {
- TaskDescriptor td=(TaskDescriptor)task_it.next();
- flattenTask(td);
- }
- }
-
- private void flattenTask(TaskDescriptor td) {
- BlockNode bn=state.getMethodBody(td);
- NodePair np=flattenBlockNode(bn);
- FlatNode fn=np.getBegin();
- if (np.getEnd().kind()!=FKind.FlatReturnNode) {
- FlatReturnNode rnflat=new FlatReturnNode(null);
- np.getEnd().addNext(rnflat);
- }
-
- FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.PRE);
- ffan.addNext(fn);
-
- FlatMethod fm=new FlatMethod(td);
- fm.addNext(ffan);
-
- Hashtable visitedset=new Hashtable();
-
- for(int i=0;i<td.numParameters();i++) {
- VarDescriptor paramvd=td.getParameter(i);
- fm.addParameterTemp(getTempforVar(paramvd));
- TagExpressionList tel=td.getTag(paramvd);
- //BUG added next line to fix...to test feed in any task program
- if (tel!=null)
- for(int j=0;j<tel.numTags();j++) {
- TagVarDescriptor tvd=(TagVarDescriptor) td.getParameterTable().getFromSameScope(tel.getName(j));
- TempDescriptor tagtmp=getTempforVar(tvd);
- if (!visitedset.containsKey(tvd.getName())) {
- visitedset.put(tvd.getName(),tvd.getTag());
- fm.addTagTemp(tagtmp);
- } else {
- TagDescriptor tmptd=(TagDescriptor) visitedset.get(tvd.getName());
- if (!tmptd.equals(tvd.getTag()))
- throw new Error("Two different tag types with same name as parameters to:"+td);
- }
- tel.setTemp(j, tagtmp);
- }
- }
-
- /* Flatten Vector of Flag Effects */
- Vector flags=td.getFlagEffects();
- updateFlagActionNode(ffan,flags);
-
- state.addFlatCode(td,fm);
- }
-
-
- /* This method transforms a vector of FlagEffects into the FlatFlagActionNode */
- private void updateFlagActionNode(FlatFlagActionNode ffan, Vector flags) {
- if (flags==null) // Do nothing if the flag effects vector is empty
- return;
-
- for(int i=0;i<flags.size();i++) {
- FlagEffects fes=(FlagEffects)flags.get(i);
- TempDescriptor flagtemp=getTempforVar(fes.getVar());
- // Process the flags
- for(int j=0;j<fes.numEffects();j++) {
- FlagEffect fe=fes.getEffect(j);
- ffan.addFlagAction(flagtemp, fe.getFlag(), fe.getStatus());
- }
- // Process the tags
- for(int j=0;j<fes.numTagEffects();j++) {
- TagEffect te=fes.getTagEffect(j);
- TempDescriptor tagtemp=getTempforVar(te.getTag());
-
- ffan.addTagAction(flagtemp, te.getTag().getTag(), tagtemp, te.getStatus());
- }
- }
- }
-
- private void flattenClass(ClassDescriptor cn) {
- Iterator methodit=cn.getMethods();
- while(methodit.hasNext()) {
- currmd=(MethodDescriptor)methodit.next();
- BlockNode bn=state.getMethodBody(currmd);
- NodePair np=flattenBlockNode(bn);
- FlatNode fn=np.getBegin();
- if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
- MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
- TempDescriptor thistd=getTempforVar(currmd.getThis());
- FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
- fc.addNext(fn);
- fn=fc;
- if (np.getEnd().kind()!=FKind.FlatReturnNode) {
- MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
- FlatCall fcunlock=new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
- np.getEnd().addNext(fcunlock);
- FlatReturnNode rnflat=new FlatReturnNode(null);
- fcunlock.addNext(rnflat);
- }
- } else if (state.DSM&&currmd.getModifiers().isAtomic()) {
- FlatAtomicEnterNode an=new FlatAtomicEnterNode();
- an.addNext(fn);
- fn=an;
- if (np.getEnd().kind()!=FKind.FlatReturnNode) {
- FlatAtomicExitNode aen=new FlatAtomicExitNode();
- np.getEnd().addNext(aen);
- FlatReturnNode rnflat=new FlatReturnNode(null);
- aen.addNext(rnflat);
- }
- } else if (np.getEnd().kind()!=FKind.FlatReturnNode) {
- FlatReturnNode rnflat=new FlatReturnNode(null);
- np.getEnd().addNext(rnflat);
- }
-
- FlatMethod fm=new FlatMethod(currmd);
- fm.addNext(fn);
- if (!currmd.isStatic())
- fm.addParameterTemp(getTempforParam(currmd.getThis()));
- for(int i=0;i<currmd.numParameters();i++) {
- fm.addParameterTemp(getTempforParam(currmd.getParameter(i)));
- }
- state.addFlatCode(currmd,fm);
- }
- }
-
- private NodePair flattenBlockNode(BlockNode bn) {
- FlatNode begin=null;
- FlatNode end=null;
- for(int i=0;i<bn.size();i++) {
- NodePair np=flattenBlockStatementNode(bn.get(i));
- FlatNode np_begin=np.getBegin();
- FlatNode np_end=np.getEnd();
- if (begin==null) {
- begin=np_begin;
- }
- if (end==null) {
- end=np_end;
- } else {
- end.addNext(np_begin);
- end=np_end;
- }
- }
- if (begin==null) {
- end=begin=new FlatNop();
- }
- return new NodePair(begin,end);
- }
-
- private NodePair flattenBlockExpressionNode(BlockExpressionNode en) {
- TempDescriptor tmp=TempDescriptor.tempFactory("neverused",en.getExpression().getType());
- return flattenExpressionNode(en.getExpression(),tmp);
- }
-
- private NodePair flattenCastNode(CastNode cn,TempDescriptor out_temp) {
- TempDescriptor tmp=TempDescriptor.tempFactory("tocast",cn.getExpression().getType());
- NodePair np=flattenExpressionNode(cn.getExpression(), tmp);
- FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp);
- np.getEnd().addNext(fcn);
- return new NodePair(np.getBegin(),fcn);
- }
-
- private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
- FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp);
- return new NodePair(fln,fln);
- }
-
- private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
- TypeDescriptor td=con.getType();
- if (!td.isArray()) {
- FlatNew fn=new FlatNew(td, out_temp, con.isGlobal());
- TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
- FlatNode last=fn;
- if (td.getClassDesc().hasFlags()) {
- // if (con.getFlagEffects()!=null) {
- FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.NEWOBJECT);
- FlagEffects fes=con.getFlagEffects();
- TempDescriptor flagtemp=out_temp;
- if (fes!=null) {
- for(int j=0;j<fes.numEffects();j++) {
- FlagEffect fe=fes.getEffect(j);
- ffan.addFlagAction(flagtemp, fe.getFlag(), fe.getStatus());
- }
- for(int j=0;j<fes.numTagEffects();j++) {
- TagEffect te=fes.getTagEffect(j);
- TempDescriptor tagtemp=getTempforVar(te.getTag());
-
- ffan.addTagAction(flagtemp, te.getTag().getTag(), tagtemp, te.getStatus());
- }
- } else {
- ffan.addFlagAction(flagtemp, null, false);
- }
- last.addNext(ffan);
- last=ffan;
- }
- //Build arguments
- for(int i=0;i<con.numArgs();i++) {
- ExpressionNode en=con.getArg(i);
- TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
- temps[i]=tmp;
- NodePair np=flattenExpressionNode(en, tmp);
- last.addNext(np.getBegin());
- last=np.getEnd();
- }
- MethodDescriptor md=con.getConstructor();
- //Call to constructor
- FlatCall fc=new FlatCall(md, null, out_temp, temps);
- last.addNext(fc);
- last=fc;
- return new NodePair(fn,last);
- } else {
- FlatNode first=null;
- FlatNode last=null;
- TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
- for (int i=0;i<con.numArgs();i++) {
- ExpressionNode en=con.getArg(i);
- TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
- temps[i]=tmp;
- NodePair np=flattenExpressionNode(en, tmp);
- if (first==null)
- first=np.getBegin();
- else
- last.addNext(np.getBegin());
- last=np.getEnd();
-
- TempDescriptor tmp2=(i==0)?
- out_temp:
- TempDescriptor.tempFactory("arg",en.getType());
- }
- FlatNew fn=new FlatNew(td, out_temp, temps[0], con.isGlobal());
- last.addNext(fn);
- if (temps.length>1) {
- NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0, con.isGlobal());
- fn.addNext(np.getBegin());
- return new NodePair(first,np.getEnd());
- } else
- return new NodePair(first, fn);
- }
- }
-
- private NodePair generateNewArrayLoop(TempDescriptor[] temparray, TypeDescriptor td, TempDescriptor tmp, int i, boolean isglobal) {
- TempDescriptor index=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
- TempDescriptor tmpone=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
- FlatNop fnop=new FlatNop();//last node
-
- //index=0
- FlatLiteralNode fln=new FlatLiteralNode(index.getType(),new Integer(0),index);
- //tmpone=1
- FlatLiteralNode fln2=new FlatLiteralNode(tmpone.getType(),new Integer(1),tmpone);
-
- TempDescriptor tmpbool=TempDescriptor.tempFactory("comp",new TypeDescriptor(TypeDescriptor.BOOLEAN));
-
- FlatOpNode fcomp=new FlatOpNode(tmpbool,index,temparray[i],new Operation(Operation.LT));
- FlatCondBranch fcb=new FlatCondBranch(tmpbool);
- //is index<temp[i]
- TempDescriptor new_tmp=TempDescriptor.tempFactory("tmp",td);
- FlatNew fn=new FlatNew(td, new_tmp, temparray[i+1], isglobal);
- FlatSetElementNode fsen=new FlatSetElementNode(tmp,index,new_tmp);
- // index=index+1
- FlatOpNode fon=new FlatOpNode(index,index,tmpone,new Operation(Operation.ADD));
- //jump out
- fln.addNext(fln2);
- fln2.addNext(fcomp);
- fcomp.addNext(fcb);
- fcb.addTrueNext(fn);
- fcb.addFalseNext(fnop);
- fn.addNext(fsen);
- //Recursive call here
- if ((i+2)<temparray.length) {
- NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1, isglobal);
- fsen.addNext(np2.getBegin());
- np2.getEnd().addNext(fon);
- } else {
- fsen.addNext(fon);
- }
- fon.addNext(fcomp);
- return new NodePair(fln, fnop);
- }
-
- private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
- TempDescriptor[] temps=new TempDescriptor[min.numArgs()];
- FlatNode first=null;
- FlatNode last=null;
- TempDescriptor thisarg=null;
-
- if (min.getExpression()!=null) {
- thisarg=TempDescriptor.tempFactory("thisarg",min.getExpression().getType());
- NodePair np=flattenExpressionNode(min.getExpression(),thisarg);
- first=np.getBegin();
- last=np.getEnd();
- }
-
- //Build arguments
- for(int i=0;i<min.numArgs();i++) {
- ExpressionNode en=min.getArg(i);
- TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
- temps[i]=td;
- NodePair np=flattenExpressionNode(en, td);
- if (first==null)
- first=np.getBegin();
- else
- last.addNext(np.getBegin());
- last=np.getEnd();
- }
-
- MethodDescriptor md=min.getMethod();
-
- //Call to constructor
-
- FlatCall fc;
- if(md.getReturnType()==null||md.getReturnType().isVoid())
- fc=new FlatCall(md, null, thisarg, temps);
- else
- fc=new FlatCall(md, out_temp, thisarg, temps);
- if (first==null) {
- first=fc;
- } else
- last.addNext(fc);
- return new NodePair(first,fc);
- }
-
- private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
- TempDescriptor tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType());
- NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
- FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
- npe.getEnd().addNext(fn);
- return new NodePair(npe.getBegin(),fn);
- }
-
- private NodePair flattenArrayAccessNode(ArrayAccessNode aan,TempDescriptor out_temp) {
- TempDescriptor tmp=TempDescriptor.tempFactory("temp",aan.getExpression().getType());
- TempDescriptor tmpindex=TempDescriptor.tempFactory("temp",aan.getIndex().getType());
- NodePair npe=flattenExpressionNode(aan.getExpression(),tmp);
- NodePair npi=flattenExpressionNode(aan.getIndex(),tmpindex);
- FlatElementNode fn=new FlatElementNode(tmp,tmpindex,out_temp);
- npe.getEnd().addNext(npi.getBegin());
- npi.getEnd().addNext(fn);
- return new NodePair(npe.getBegin(),fn);
- }
-
- private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
- // Three cases:
- // left side is variable
- // left side is field
- // left side is array
-
- Operation base=an.getOperation().getBaseOp();
- boolean pre=base==null||(base.getOp()!=Operation.POSTINC&&base.getOp()!=Operation.POSTDEC);
-
- if (!pre) {
- //rewrite the base operation
- base=base.getOp()==Operation.POSTINC?new Operation(Operation.ADD):new Operation(Operation.SUB);
- }
- FlatNode first=null;
- FlatNode last=null;
- TempDescriptor src_tmp=an.getSrc()==null?TempDescriptor.tempFactory("srctmp",an.getDest().getType()):TempDescriptor.tempFactory("srctmp",an.getSrc().getType());
-
- //Get src value
- if (an.getSrc()!=null) {
- NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
- first=np_src.getBegin();
- last=np_src.getEnd();
- } else if (!pre) {
- FlatLiteralNode fln=new FlatLiteralNode(new TypeDescriptor(TypeDescriptor.INT) ,new Integer(1),src_tmp);
- first=fln;
- last=fln;
- }
-
- if (an.getDest().kind()==Kind.FieldAccessNode) {
- //We are assigning an object field
-
- FieldAccessNode fan=(FieldAccessNode)an.getDest();
- ExpressionNode en=fan.getExpression();
- TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
- NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
- if (first==null)
- first=np_baseexp.getBegin();
- else
- last.addNext(np_baseexp.getBegin());
- last=np_baseexp.getEnd();
-
- //See if we need to perform an operation
- if (base!=null) {
- //If it is a preinc we need to store the initial value
- TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
- TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType());
-
- FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
- last.addNext(ffn);
- last=ffn;
- FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
- src_tmp=tmp;
- last.addNext(fon);
- last=fon;
- }
-
- FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
- last.addNext(fsfn);
- last=fsfn;
- if (pre) {
- FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
- fsfn.addNext(fon2);
- last=fon2;
- }
- return new NodePair(first, last);
- } else if (an.getDest().kind()==Kind.ArrayAccessNode) {
- //We are assigning an array element
-
-
- ArrayAccessNode aan=(ArrayAccessNode)an.getDest();
- ExpressionNode en=aan.getExpression();
- ExpressionNode enindex=aan.getIndex();
- TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
- TempDescriptor index_tmp=TempDescriptor.tempFactory("index",enindex.getType());
- NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
- NodePair np_indexexp=flattenExpressionNode(enindex, index_tmp);
- if (first==null)
- first=np_baseexp.getBegin();
- else
- last.addNext(np_baseexp.getBegin());
- np_baseexp.getEnd().addNext(np_indexexp.getBegin());
- last=np_indexexp.getEnd();
-
- //See if we need to perform an operation
- if (base!=null) {
- //If it is a preinc we need to store the initial value
- TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
- TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType());
-
- FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp2);
- last.addNext(fen);
- last=fen;
- FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
- src_tmp=tmp;
- last.addNext(fon);
- last=fon;
- }
-
-
- FlatSetElementNode fsen=new FlatSetElementNode(dst_tmp, index_tmp, src_tmp);
- last.addNext(fsen);
- last=fsen;
- if (pre) {
- FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
- fsen.addNext(fon2);
- last=fon2;
- }
- return new NodePair(first, last);
- } else if (an.getDest().kind()==Kind.NameNode) {
- //We could be assigning a field or variable
- NameNode nn=(NameNode)an.getDest();
- if (nn.getExpression()!=null) {
- //It is a field
- FieldAccessNode fan=(FieldAccessNode)nn.getExpression();
- ExpressionNode en=fan.getExpression();
- TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
- NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
- if (first==null)
- first=np_baseexp.getBegin();
- else
- last.addNext(np_baseexp.getBegin());
- last=np_baseexp.getEnd();
-
- //See if we need to perform an operation
- if (base!=null) {
- //If it is a preinc we need to store the initial value
- TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
- TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType());
-
- FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
- last.addNext(ffn);
- last=ffn;
- FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
- src_tmp=tmp;
- last.addNext(fon);
- last=fon;
- }
-
-
- FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
- last.addNext(fsfn);
- last=fsfn;
- if (pre) {
- FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
- fsfn.addNext(fon2);
- last=fon2;
- }
- return new NodePair(first, last);
- } else {
- if (nn.getField()!=null) {
- //It is a field
- //Get src value
-
- //See if we need to perform an operation
- if (base!=null) {
- //If it is a preinc we need to store the initial value
- TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
- TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType());
-
- FlatFieldNode ffn=new FlatFieldNode(nn.getField(), getTempforVar(nn.getVar()), src_tmp2);
- if (first==null)
- first=ffn;
- else {
- last.addNext(ffn);
- }
- last=ffn;
- FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
- src_tmp=tmp;
- last.addNext(fon);
- last=fon;
- }
-
- FlatSetFieldNode fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
- if (first==null) {
- first=fsfn;
- } else {
- last.addNext(fsfn);
- }
- last=fsfn;
- if (pre) {
- FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
- fsfn.addNext(fon2);
- last=fon2;
- }
- return new NodePair(first, last);
- } else {
- //It is a variable
- //See if we need to perform an operation
-
- if (base!=null) {
- //If it is a preinc we need to store the initial value
- TempDescriptor src_tmp2=getTempforVar(nn.getVar());
- TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType());
- if (!pre) {
- FlatOpNode fon=new FlatOpNode(out_temp, src_tmp2, null, new Operation(Operation.ASSIGN));
- if (first==null)
- first=fon;
- else
- last.addNext(fon);
- last=fon;
- }
-
- FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
- if (first==null)
- first=fon;
- else
- last.addNext(fon);
- src_tmp=tmp;
- last=fon;
- }
-
- FlatOpNode fon=new FlatOpNode(getTempforVar(nn.getVar()), src_tmp, null, new Operation(Operation.ASSIGN));
- last.addNext(fon);
- last=fon;
- if (pre) {
- FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
- fon.addNext(fon2);
- last=fon2;
- }
- return new NodePair(first, last);
- }
- }
- }
- throw new Error();
- }
-
- private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
- if (nn.getExpression()!=null) {
- /* Hack - use subtree instead */
- return flattenExpressionNode(nn.getExpression(),out_temp);
- } else if (nn.getField()!=null) {
- TempDescriptor tmp=getTempforVar(nn.getVar());
- FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp);
- return new NodePair(ffn,ffn);
- } else {
- TempDescriptor tmp=getTempforVar(nn.isTag()?nn.getTagVar():nn.getVar());
- if (nn.isTag()) {
- //propagate tag
- out_temp.setTag(tmp.getTag());
- }
- FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
- return new NodePair(fon,fon);
- }
- }
-
- private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
- TempDescriptor temp_left=TempDescriptor.tempFactory("leftop",on.getLeft().getType());
- TempDescriptor temp_right=null;
-
- Operation op=on.getOp();
- /* We've moved this to assignment nodes
-
- if (op.getOp()==Operation.POSTINC||
- op.getOp()==Operation.POSTDEC||
- op.getOp()==Operation.PREINC||
- op.getOp()==Operation.PREDEC) {
- LiteralNode ln=new LiteralNode("int",new Integer(1));
- ln.setType(new TypeDescriptor(TypeDescriptor.INT));
-
- AssignmentNode an=new AssignmentNode(on.getLeft(),
- new OpNode(on.getLeft(),ln,
- new Operation((op.getOp()==Operation.POSTINC||op.getOp()==Operation.PREINC)?Operation.PLUS:Operation.MINUS))
- );
- if (op.getOp()==Operation.POSTINC||
- op.getOp()==Operation.POSTDEC) {
- //Can't do, this could have side effects
- NodePair left=flattenExpressionNode(on.getLeft(),out_temp);
- NodePair assign=flattenAssignmentNode(an,temp_left);
- left.getEnd().addNext(assign.getBegin());
- return new NodePair(left.getBegin(),assign.getEnd());
- } else {
- NodePair assign=flattenAssignmentNode(an,out_temp);
- return assign;
- }
- } */
-
- NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
- NodePair right;
- if (on.getRight()!=null) {
- temp_right=TempDescriptor.tempFactory("rightop",on.getRight().getType());
- right=flattenExpressionNode(on.getRight(),temp_right);
- } else {
- FlatNop nop=new FlatNop();
- right=new NodePair(nop,nop);
- }
-
- if (op.getOp()==Operation.LOGIC_OR) {
- /* Need to do shortcircuiting */
- FlatCondBranch fcb=new FlatCondBranch(temp_left);
- FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
- FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
- FlatNop fnop=new FlatNop();
- left.getEnd().addNext(fcb);
- fcb.addFalseNext(right.getBegin());
- right.getEnd().addNext(fon2);
- fon2.addNext(fnop);
- fcb.addTrueNext(fon1);
- fon1.addNext(fnop);
- return new NodePair(left.getBegin(), fnop);
- } else if (op.getOp()==Operation.LOGIC_AND) {
- /* Need to do shortcircuiting */
- FlatCondBranch fcb=new FlatCondBranch(temp_left);
- FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
- FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
- FlatNop fnop=new FlatNop();
- left.getEnd().addNext(fcb);
- fcb.addTrueNext(right.getBegin());
- right.getEnd().addNext(fon2);
- fon2.addNext(fnop);
- fcb.addFalseNext(fon1);
- fon1.addNext(fnop);
- return new NodePair(left.getBegin(), fnop);
- }
-
- FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
- left.getEnd().addNext(right.getBegin());
- right.getEnd().addNext(fon);
- return new NodePair(left.getBegin(),fon);
- }
-
- private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
- switch(en.kind()) {
- case Kind.AssignmentNode:
- return flattenAssignmentNode((AssignmentNode)en,out_temp);
- case Kind.CastNode:
- return flattenCastNode((CastNode)en,out_temp);
- case Kind.CreateObjectNode:
- return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
- case Kind.FieldAccessNode:
- return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
- case Kind.ArrayAccessNode:
- return flattenArrayAccessNode((ArrayAccessNode)en,out_temp);
- case Kind.LiteralNode:
- return flattenLiteralNode((LiteralNode)en,out_temp);
- case Kind.MethodInvokeNode:
- return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
- case Kind.NameNode:
- return flattenNameNode((NameNode)en,out_temp);
- case Kind.OpNode:
- return flattenOpNode((OpNode)en,out_temp);
- }
- throw new Error();
- }
-
- private NodePair flattenDeclarationNode(DeclarationNode dn) {
- VarDescriptor vd=dn.getVarDescriptor();
- TempDescriptor td=getTempforVar(vd);
- if (dn.getExpression()!=null)
- return flattenExpressionNode(dn.getExpression(),td);
- else {
- FlatNop fn=new FlatNop();
- return new NodePair(fn,fn);
- }
- }
-
- private NodePair flattenTagDeclarationNode(TagDeclarationNode dn) {
- TagVarDescriptor tvd=dn.getTagVarDescriptor();
- TagDescriptor tag=tvd.getTag();
- TempDescriptor tmp=getTempforVar(tvd);
- FlatTagDeclaration ftd=new FlatTagDeclaration(tag, tmp);
- return new NodePair(ftd,ftd);
- }
-
- private TempDescriptor getTempforParam(Descriptor d) {
- if (temptovar.containsKey(d))
- return (TempDescriptor)temptovar.get(d);
- else {
- if (d instanceof VarDescriptor) {
- VarDescriptor vd=(VarDescriptor)d;
- TempDescriptor td=TempDescriptor.paramtempFactory(vd.getName(),vd.getType());
- temptovar.put(vd,td);
- return td;
- } else if (d instanceof TagVarDescriptor) {
- TagVarDescriptor tvd=(TagVarDescriptor)d;
- TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
- TempDescriptor td=TempDescriptor.paramtempFactory(tvd.getName(), tagtype, tvd.getTag());
- temptovar.put(tvd,td);
- return td;
- } else throw new Error("Unreconized Descriptor");
- }
- }
-
- private TempDescriptor getTempforVar(Descriptor d) {
- if (temptovar.containsKey(d))
- return (TempDescriptor)temptovar.get(d);
- else {
- if (d instanceof VarDescriptor) {
- VarDescriptor vd=(VarDescriptor)d;
- TempDescriptor td=TempDescriptor.tempFactory(vd.getName(), vd.getType());
- temptovar.put(vd,td);
- return td;
- } else if (d instanceof TagVarDescriptor) {
- TagVarDescriptor tvd=(TagVarDescriptor)d;
- //BUGFIX TAGTYPE - add next line, modify following
- //line to tag this new type descriptor, modify
- //TempDescriptor constructor & factory to set type
- //using this Type To test, use any program with tags
- TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
- TempDescriptor td=TempDescriptor.tempFactory(tvd.getName(),tagtype, tvd.getTag());
- temptovar.put(tvd,td);
- return td;
- } else throw new Error("Unrecognized Descriptor");
- }
- }
-
- private NodePair flattenIfStatementNode(IfStatementNode isn) {
- TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.BOOLEAN));
- NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
- FlatCondBranch fcb=new FlatCondBranch(cond_temp);
- NodePair true_np=flattenBlockNode(isn.getTrueBlock());
- NodePair false_np;
- FlatNop nopend=new FlatNop();
-
- if (isn.getFalseBlock()!=null)
- false_np=flattenBlockNode(isn.getFalseBlock());
- else {
- FlatNop nop=new FlatNop();
- false_np=new NodePair(nop,nop);
- }
-
- cond.getEnd().addNext(fcb);
- fcb.addTrueNext(true_np.getBegin());
- fcb.addFalseNext(false_np.getBegin());
- true_np.getEnd().addNext(nopend);
- false_np.getEnd().addNext(nopend);
- return new NodePair(cond.getBegin(), nopend);
- }
-
- private NodePair flattenLoopNode(LoopNode ln) {
- if (ln.getType()==LoopNode.FORLOOP) {
- NodePair initializer=flattenBlockNode(ln.getInitializer());
- TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
- NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
- NodePair update=flattenBlockNode(ln.getUpdate());
- NodePair body=flattenBlockNode(ln.getBody());
- FlatNode begin=initializer.getBegin();
- FlatCondBranch fcb=new FlatCondBranch(cond_temp);
- FlatNop nopend=new FlatNop();
- FlatBackEdge backedge=new FlatBackEdge();
-
- initializer.getEnd().addNext(condition.getBegin());
- body.getEnd().addNext(update.getBegin());
- update.getEnd().addNext(backedge);
- backedge.addNext(condition.getBegin());
- condition.getEnd().addNext(fcb);
- fcb.addFalseNext(nopend);
- fcb.addTrueNext(body.getBegin());
- return new NodePair(begin,nopend);
- } else if (ln.getType()==LoopNode.WHILELOOP) {
- TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
- NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
- NodePair body=flattenBlockNode(ln.getBody());
- FlatNode begin=condition.getBegin();
- FlatCondBranch fcb=new FlatCondBranch(cond_temp);
- FlatNop nopend=new FlatNop();
- FlatBackEdge backedge=new FlatBackEdge();
-
- body.getEnd().addNext(backedge);
- backedge.addNext(condition.getBegin());
-
- condition.getEnd().addNext(fcb);
- fcb.addFalseNext(nopend);
- fcb.addTrueNext(body.getBegin());
- return new NodePair(begin,nopend);
- } else if (ln.getType()==LoopNode.DOWHILELOOP) {
- TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
- NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
- NodePair body=flattenBlockNode(ln.getBody());
- FlatNode begin=body.getBegin();
- FlatCondBranch fcb=new FlatCondBranch(cond_temp);
- FlatNop nopend=new FlatNop();
- FlatBackEdge backedge=new FlatBackEdge();
-
- body.getEnd().addNext(condition.getBegin());
- condition.getEnd().addNext(fcb);
- fcb.addFalseNext(nopend);
- fcb.addTrueNext(backedge);
- backedge.addNext(body.getBegin());
- return new NodePair(begin,nopend);
- } else throw new Error();
- }
-
- private NodePair flattenReturnNode(ReturnNode rntree) {
- TempDescriptor retval=null;
- NodePair cond=null;
- if (rntree.getReturnExpression()!=null) {
- retval=TempDescriptor.tempFactory("ret_value", rntree.getReturnExpression().getType());
- cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
- }
-
- FlatReturnNode rnflat=new FlatReturnNode(retval);
- FlatNode ln=rnflat;
- if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
- MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
- TempDescriptor thistd=getTempforVar(currmd.getThis());
- FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
- fc.addNext(rnflat);
- ln=fc;
- }
-
- if (cond!=null) {
- cond.getEnd().addNext(ln);
- return new NodePair(cond.getBegin(),rnflat);
- } else
- return new NodePair(ln,rnflat);
- }
-
- private NodePair flattenTaskExitNode(TaskExitNode ten) {
- FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.TASKEXIT);
- updateFlagActionNode(ffan, ten.getFlagEffects());
- NodePair fcn=flattenConstraintCheck(ten.getChecks());
- ffan.addNext(fcn.getBegin());
- FlatReturnNode rnflat=new FlatReturnNode(null);
- fcn.getEnd().addNext(rnflat);
- return new NodePair(ffan, rnflat);
- }
-
- private NodePair flattenConstraintCheck(Vector ccs) {
- FlatNode begin=new FlatNop();
- if (ccs==null)
- return new NodePair(begin,begin);
- FlatNode last=begin;
- for(int i=0;i<ccs.size();i++) {
- ConstraintCheck cc=(ConstraintCheck) ccs.get(i);
- /* Flatten the arguments */
- TempDescriptor[] temps=new TempDescriptor[cc.numArgs()];
- String[] vars=new String[cc.numArgs()];
- for(int j=0;j<cc.numArgs();j++) {
- ExpressionNode en=cc.getArg(j);
- TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
- temps[j]=td;
- vars[j]=cc.getVar(j);
- NodePair np=flattenExpressionNode(en, td);
- last.addNext(np.getBegin());
- last=np.getEnd();
- }
-
- FlatCheckNode fcn=new FlatCheckNode(cc.getSpec(), vars, temps);
- last.addNext(fcn);
- last=fcn;
- }
- return new NodePair(begin,last);
- }
-
- private NodePair flattenSubBlockNode(SubBlockNode sbn) {
- return flattenBlockNode(sbn.getBlockNode());
- }
-
- private NodePair flattenAtomicNode(AtomicNode sbn) {
- NodePair np=flattenBlockNode(sbn.getBlockNode());
- FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
- FlatAtomicExitNode faexn=new FlatAtomicExitNode();
- faen.addNext(np.getBegin());
- np.getEnd().addNext(faexn);
- return new NodePair(faen, faexn);
- }
-
- private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
- switch(bsn.kind()) {
- case Kind.BlockExpressionNode:
- return flattenBlockExpressionNode((BlockExpressionNode)bsn);
-
- case Kind.DeclarationNode:
- return flattenDeclarationNode((DeclarationNode)bsn);
-
- case Kind.TagDeclarationNode:
- return flattenTagDeclarationNode((TagDeclarationNode)bsn);
-
- case Kind.IfStatementNode:
- return flattenIfStatementNode((IfStatementNode)bsn);
-
- case Kind.LoopNode:
- return flattenLoopNode((LoopNode)bsn);
-
- case Kind.ReturnNode:
- return flattenReturnNode((IR.Tree.ReturnNode)bsn);
-
- case Kind.TaskExitNode:
- return flattenTaskExitNode((IR.Tree.TaskExitNode)bsn);
-
- case Kind.SubBlockNode:
- return flattenSubBlockNode((SubBlockNode)bsn);
-
- case Kind.AtomicNode:
- return flattenAtomicNode((AtomicNode)bsn);
-
- }
- throw new Error();
- }
-}
+++ /dev/null
-package IR.Flat;
-
-public class FKind {
- public static final int FlatCall=1;
- public static final int FlatFieldNode=2;
- public static final int FlatSetFieldNode=3;
- public static final int FlatNew=4;
- public static final int FlatOpNode=5;
- public static final int FlatCastNode=6;
- public static final int FlatLiteralNode=7;
- public static final int FlatReturnNode=8;
- public static final int FlatCondBranch=9;
- public static final int FlatNop=10;
- public static final int FlatSetElementNode=11;
- public static final int FlatElementNode=12;
- public static final int FlatFlagActionNode=13;
- public static final int FlatCheckNode=14;
- public static final int FlatBackEdge=15;
- public static final int FlatTagDeclaration=16;
- public static final int FlatMethod=17;
- public static final int FlatAtomicEnterNode=18;
- public static final int FlatAtomicExitNode=19;
- public static final int FlatGlobalConvNode=20;
-}
+++ /dev/null
-package IR.Flat;
-import java.util.Vector;
-
-public class FlatAtomicEnterNode extends FlatNode {
- public FlatAtomicEnterNode() {
- }
-
- public String toString() {
- return "atomicenter";
- }
-
- public int kind() {
- return FKind.FlatAtomicEnterNode;
- }
-}
+++ /dev/null
-package IR.Flat;
-import java.util.Vector;
-
-public class FlatAtomicExitNode extends FlatNode {
- public FlatAtomicExitNode() {
- }
-
- public String toString() {
- return "atomicexit";
- }
-
- public int kind() {
- return FKind.FlatAtomicExitNode;
- }
-}
+++ /dev/null
-package IR.Flat;
-import java.util.Vector;
-
-public class FlatBackEdge extends FlatNode {
- public FlatBackEdge() {
- }
-
- public String toString() {
- return "backedge";
- }
-
- public int kind() {
- return FKind.FlatBackEdge;
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.MethodDescriptor;
-
-public class FlatCall extends FlatNode {
- TempDescriptor args[];
- TempDescriptor this_temp;
- TempDescriptor dst;
- MethodDescriptor method;
-
- public FlatCall(MethodDescriptor md, TempDescriptor dst, TempDescriptor this_temp, TempDescriptor[] args) {
- this.method=md;
- this.dst=dst;
- this.this_temp=this_temp;
- this.args=args;
- }
-
- public MethodDescriptor getMethod() {
- return method;
- }
-
- public TempDescriptor getThis() {
- return this_temp;
- }
-
- public TempDescriptor getReturnTemp() {
- return dst;
- }
-
- public int numArgs() {
- return args.length;
- }
-
- public TempDescriptor getArg(int i) {
- return args[i];
- }
-
- public String toString() {
- String st="";
- if (dst==null)
- st+=method.getSymbol()+"(";
- else
- st+=dst+"="+method.getSymbol()+"(";
- if (this_temp!=null) {
- st+=this_temp;
- if (args.length!=0)
- st+=", ";
- }
-
- for(int i=0;i<args.length;i++) {
- st+=args[i].toString();
- if ((i+1)<args.length)
- st+=", ";
- }
- return st+")";
- }
-
- public int kind() {
- return FKind.FlatCall;
- }
-
- public TempDescriptor [] readsTemps() {
- int size=args.length;
- if (this_temp!=null)
- size++;
- TempDescriptor [] t=new TempDescriptor[size];
- int offset=0;
- if (this_temp!=null)
- t[offset++]=this_temp;
- for(int i=0;i<args.length;i++)
- t[offset++]=args[i];
- return t;
- }
-
- public TempDescriptor [] writesTemps() {
- if (dst!=null)
- return new TempDescriptor[] {dst};
- else
- return new TempDescriptor[0];
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.TypeDescriptor;
-
-public class FlatCastNode extends FlatNode {
- TempDescriptor src;
- TempDescriptor dst;
- TypeDescriptor type;
-
- public FlatCastNode(TypeDescriptor type, TempDescriptor src, TempDescriptor dst) {
- this.type=type;
- this.src=src;
- this.dst=dst;
- }
-
- public String toString() {
- return dst.toString()+"=("+type.toString()+")"+src.toString();
- }
-
- public int kind() {
- return FKind.FlatCastNode;
- }
-
- public TypeDescriptor getType() {
- return type;
- }
-
- public TempDescriptor getSrc() {
- return src;
- }
-
- public TempDescriptor getDst() {
- return dst;
- }
-
- public TempDescriptor [] writesTemps() {
- return new TempDescriptor[] {dst};
- }
-
- public TempDescriptor [] readsTemps() {
- return new TempDescriptor[] {src};
- }
-
-}
+++ /dev/null
-package IR.Flat;
-
-public class FlatCheckNode extends FlatNode {
- TempDescriptor [] temps;
- String [] vars;
- String spec;
-
- public FlatCheckNode(String spec, String[] vars, TempDescriptor[] temps) {
- this.spec=spec;
- this.vars=vars;
- this.temps=temps;
- }
-
- public int kind() {
- return FKind.FlatCheckNode;
- }
-
- public String getSpec() {
- return spec;
- }
-
- public String[] getVars() {
- return vars;
- }
-
- public TempDescriptor [] getTemps() {
- return temps;
- }
-
- public TempDescriptor [] readsTemps() {
- return temps;
- }
-}
+++ /dev/null
-package IR.Flat;
-import java.util.Vector;
-
-public class FlatCondBranch extends FlatNode {
- TempDescriptor test_cond;
-
- public FlatCondBranch(TempDescriptor td) {
- test_cond=td;
- }
-
- public void addTrueNext(FlatNode n) {
- if (next.size()==0)
- next.setSize(1);
- next.setElementAt(n,0);
- n.addPrev(this);
- }
-
- public void addFalseNext(FlatNode n) {
- next.setSize(2);
- next.setElementAt(n,1);
- n.addPrev(this);
- }
-
- public TempDescriptor getTest() {
- return test_cond;
- }
-
- public String toString() {
- return "conditional branch";
- }
-
- public String toString(String negjump) {
- return "if (!"+test_cond.toString()+") goto "+negjump;
- }
-
- public void addNext(FlatNode n) {
- throw new Error();
- }
-
- public int kind() {
- return FKind.FlatCondBranch;
- }
-
- public TempDescriptor [] readsTemps() {
- return new TempDescriptor[] {test_cond};
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.FieldDescriptor;
-
-public class FlatElementNode extends FlatNode {
- TempDescriptor src;
- TempDescriptor dst;
- TempDescriptor index;
-
- public FlatElementNode(TempDescriptor src, TempDescriptor index, TempDescriptor dst) {
- this.index=index;
- this.src=src;
- this.dst=dst;
- }
-
- public boolean needsBoundsCheck() {
- return true;
- }
-
- public TempDescriptor getIndex() {
- return index;
- }
-
- public TempDescriptor getSrc() {
- return src;
- }
-
- public TempDescriptor getDst() {
- return dst;
- }
-
- public String toString() {
- return dst.toString()+"="+src.toString()+"["+index.toString()+"]";
- }
-
- public int kind() {
- return FKind.FlatElementNode;
- }
-
- public TempDescriptor [] writesTemps() {
- return new TempDescriptor[] {dst};
- }
-
- public TempDescriptor [] readsTemps() {
- return new TempDescriptor[] {src,index};
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.FieldDescriptor;
-
-public class FlatFieldNode extends FlatNode {
- TempDescriptor src;
- TempDescriptor dst;
- FieldDescriptor field;
-
- public FlatFieldNode(FieldDescriptor field, TempDescriptor src, TempDescriptor dst) {
- this.field=field;
- this.src=src;
- this.dst=dst;
- }
-
- public FieldDescriptor getField() {
- return field;
- }
-
- public TempDescriptor getSrc() {
- return src;
- }
-
- public TempDescriptor getDst() {
- return dst;
- }
-
- public String toString() {
- return dst.toString()+"="+src.toString()+"."+field.getSymbol();
- }
-
- public int kind() {
- return FKind.FlatFieldNode;
- }
-
- public TempDescriptor [] writesTemps() {
- return new TempDescriptor[] {dst};
- }
-
- public TempDescriptor [] readsTemps() {
- return new TempDescriptor[] {src};
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.FlagDescriptor;
-import IR.TagDescriptor;
-import java.util.Hashtable;
-import java.util.HashSet;
-import java.util.Iterator;
-
-public class FlatFlagActionNode extends FlatNode {
- Hashtable tempflagpairs;
- Hashtable temptagpairs;
-
- int taskexit;
- public static final int NEWOBJECT=0;
- public static final int PRE=1;
- public static final int TASKEXIT=2;
-
-
- public FlatFlagActionNode(int taskexit) {
- tempflagpairs=new Hashtable();
- temptagpairs=new Hashtable();
- this.taskexit=taskexit;
- }
-
- public int getTaskType() {
- return taskexit;
- }
-
- public void addFlagAction(TempDescriptor td, FlagDescriptor fd, boolean status) {
- TempFlagPair tfp=new TempFlagPair(td,fd);
- if (tempflagpairs.containsKey(tfp)) {
- throw new Error("Temp/Flag combination used twice: "+tfp);
- }
- tempflagpairs.put(tfp, new Boolean(status));
- }
-
- public void addTagAction(TempDescriptor td, TagDescriptor tagd, TempDescriptor tagt, boolean status) {
- TempTagPair ttp=new TempTagPair(td,tagd, tagt);
- if (temptagpairs.containsKey(ttp)) {
- throw new Error("Temp/Tag combination used twice: "+ttp);
- }
- temptagpairs.put(ttp, new Boolean(status));
- }
-
- public int kind() {
- return FKind.FlatFlagActionNode;
- }
-
- /** This method returns an iterator over the Temp/Flag pairs. */
-
- public Iterator getTempFlagPairs() {
- return tempflagpairs.keySet().iterator();
- }
-
- public Iterator getTempTagPairs() {
- return temptagpairs.keySet().iterator();
- }
-
- public boolean getFlagChange(TempFlagPair tfp) {
- return ((Boolean)tempflagpairs.get(tfp)).booleanValue();
- }
-
- public boolean getTagChange(TempTagPair ttp) {
- return ((Boolean)temptagpairs.get(ttp)).booleanValue();
- }
-
- public TempDescriptor [] readsTemps() {
- if (tempflagpairs.size()==0)
- return new TempDescriptor [0];
- else {
- HashSet temps=new HashSet();
- for(Iterator it=tempflagpairs.keySet().iterator();it.hasNext();) {
- TempFlagPair tfp=(TempFlagPair)it.next();
- temps.add(tfp.getTemp());
- }
- for(Iterator it=temptagpairs.keySet().iterator();it.hasNext();) {
- TempTagPair ttp=(TempTagPair)it.next();
- temps.add(ttp.getTemp());
- temps.add(ttp.getTagTemp());
- }
- return (TempDescriptor[]) temps.toArray(new TempDescriptor [temps.size()]);
- }
- }
-
- public int getFFANType()
- {
- throw new Error("Use getTaskType() instead and remove this method");
- }
-
- public String toString() {
- String st="FlatFlagActionNode";
- for(Iterator it=tempflagpairs.keySet().iterator();it.hasNext();) {
- TempFlagPair tfp=(TempFlagPair)it.next();
- st+=getFlagChange(tfp)?"":"!";
- st+=tfp.getTemp()+" "+tfp.getFlag()+",";
- }
- for(Iterator it=temptagpairs.keySet().iterator();it.hasNext();) {
- TempTagPair ttp=(TempTagPair)it.next();
- st+=getTagChange(ttp)?"":"!";
- st+=ttp.getTemp()+" "+ttp.getTag()+"("+ttp.getTagTemp()+"),";
- }
-
- return st;
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.TypeDescriptor;
-import Analysis.Locality.LocalityBinding;
-
-public class FlatGlobalConvNode extends FlatNode {
- TempDescriptor src;
- LocalityBinding lb;
- boolean makePtr;
-
- public FlatGlobalConvNode(TempDescriptor src, LocalityBinding lb, boolean makePtr) {
- this.src=src;
- this.lb=lb;
- this.makePtr=makePtr;
- }
-
- public String toString() {
- if (makePtr)
- return src.toString()+"=(PTR)"+src.toString()+" "+lb;
- else
- return src.toString()+"=(OID)"+src.toString()+" "+lb;
- }
-
- public int kind() {
- return FKind.FlatGlobalConvNode;
- }
-
- public LocalityBinding getLocality() {
- return lb;
- }
-
- public boolean getMakePtr() {
- return makePtr;
- }
-
- public TempDescriptor getSrc() {
- return src;
- }
-
- public TempDescriptor [] writesTemps() {
- return new TempDescriptor[] {src};
- }
-
- public TempDescriptor [] readsTemps() {
- return new TempDescriptor[] {src};
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.TypeDescriptor;
-
-public class FlatLiteralNode extends FlatNode {
- Object value;
- TypeDescriptor type;
- TempDescriptor dst;
-
- public FlatLiteralNode(TypeDescriptor type, Object o, TempDescriptor dst) {
- this.type=type;
- value=o;
- this.dst=dst;
- }
-
- public TypeDescriptor getType() {
- return type;
- }
-
- public TempDescriptor getDst() {
- return dst;
- }
-
- public Object getValue() {
- return value;
- }
-
- public String toString() {
- if (value==null)
- return dst+"=null";
- else
- return dst+"="+escapeString(value.toString());
- }
- protected static String escapeString(String st) {
- String new_st="";
- for(int i=0;i<st.length();i++) {
- char x=st.charAt(i);
- if (x=='\n')
- new_st+="\\n";
- else if (x=='\r')
- new_st+="\\r";
- else if (x=='"')
- new_st+="\\\"";
- else new_st+=x;
- }
- return new_st;
- }
-
- public int kind() {
- return FKind.FlatLiteralNode;
- }
-
- public TempDescriptor [] writesTemps() {
- return new TempDescriptor[] {dst};
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.MethodDescriptor;
-import IR.TaskDescriptor;
-import java.util.*;
-
-public class FlatMethod extends FlatNode {
- MethodDescriptor method;
- TaskDescriptor task;
- Vector parameterTemps;
- Vector tagTemps;
- Hashtable tagtointmap;
-
- FlatMethod(MethodDescriptor md) {
- method=md;
- task=null;
- parameterTemps=new Vector();
- tagTemps=new Vector();
- tagtointmap=new Hashtable();
- }
-
- FlatMethod(TaskDescriptor td) {
- task=td;
- method=null;
- parameterTemps=new Vector();
- tagTemps=new Vector();
- tagtointmap=new Hashtable();
- }
-
- public String toString() {
- return method.toString();
- }
-
- public MethodDescriptor getMethod() {
- return method;
- }
-
- public TaskDescriptor getTask() {
- return task;
- }
-
- public int kind() {
- return FKind.FlatMethod;
- }
-
- public void addParameterTemp(TempDescriptor t) {
- parameterTemps.add(t);
- }
-
- public int numParameters() {
- return parameterTemps.size();
- }
-
- public void addTagTemp(TempDescriptor t) {
- tagtointmap.put(t, new Integer(tagTemps.size()));
- tagTemps.add(t);
- }
-
- public int getTagInt(TempDescriptor t) {
- return ((Integer)tagtointmap.get(t)).intValue();
- }
-
- public int numTags() {
- return tagTemps.size();
- }
-
- public TempDescriptor getTag(int i) {
- return (TempDescriptor) tagTemps.get(i);
- }
-
- public TempDescriptor getParameter(int i) {
- return (TempDescriptor) parameterTemps.get(i);
- }
-
- /** This method returns a set of the nodes in this flat representation */
-
- public Set<FlatNode> getNodeSet() {
- HashSet<FlatNode> tovisit=new HashSet<FlatNode>();
- HashSet<FlatNode> visited=new HashSet<FlatNode>();
- tovisit.add(this);
- while(!tovisit.isEmpty()) {
- FlatNode fn=tovisit.iterator().next();
- tovisit.remove(fn);
- visited.add(fn);
- for(int i=0;i<fn.numNext();i++) {
- FlatNode nn=fn.getNext(i);
- if (!visited.contains(nn))
- tovisit.add(nn);
- }
- }
- return visited;
- }
-
- /** This method returns a string that is a human readable
- * representation of this method. */
-
- public String printMethod() {
- String st=method+" {\n";
- HashSet tovisit=new HashSet();
- HashSet visited=new HashSet();
- int labelindex=0;
- Hashtable nodetolabel=new Hashtable();
- tovisit.add(this);
- FlatNode current_node=null;
- //Assign labels 1st
- //Node needs a label if it is
- while(!tovisit.isEmpty()) {
- FlatNode fn=(FlatNode)tovisit.iterator().next();
- tovisit.remove(fn);
- visited.add(fn);
-
-// System.out.println("Next : "+fn.numNext());
-
- for(int i=0;i<fn.numNext();i++) {
- FlatNode nn=fn.getNext(i);
- if(i>0) {
- //1) Edge >1 of node
- nodetolabel.put(nn,new Integer(labelindex++));
- }
- if (!visited.contains(nn)&&!tovisit.contains(nn)) {
- tovisit.add(nn);
- } else {
- //2) Join point
- nodetolabel.put(nn,new Integer(labelindex++));
- }
- }
- }
-
- //Do the actual printing
- tovisit=new HashSet();
- visited=new HashSet();
- tovisit.add(this);
- while(current_node!=null||!tovisit.isEmpty()) {
- if (current_node==null) {
- current_node=(FlatNode)tovisit.iterator().next();
- tovisit.remove(current_node);
- }
- visited.add(current_node);
- if (nodetolabel.containsKey(current_node))
- st+="L"+nodetolabel.get(current_node)+":\n";
- if (current_node.numNext()==0) {
- st+=" "+current_node.toString()+"\n";
- current_node=null;
- } else if(current_node.numNext()==1) {
- st+=" "+current_node.toString()+"\n";
- FlatNode nextnode=current_node.getNext(0);
- if (visited.contains(nextnode)) {
- st+="goto L"+nodetolabel.get(nextnode)+"\n";
- current_node=null;
- } else
- current_node=nextnode;
- } else if (current_node.numNext()==2) {
- /* Branch */
- st+=" "+((FlatCondBranch)current_node).toString("L"+nodetolabel.get(current_node.getNext(1)))+"\n";
- if (!visited.contains(current_node.getNext(1)))
- tovisit.add(current_node.getNext(1));
- if (visited.contains(current_node.getNext(0))) {
- st+="goto L"+nodetolabel.get(current_node.getNext(0))+"\n";
- current_node=null;
- } else
- current_node=current_node.getNext(0);
- } else throw new Error();
- }
- return st+"}\n";
- }
-
- public TempDescriptor [] writesTemps() {
- return (TempDescriptor[]) parameterTemps.toArray(new TempDescriptor[ parameterTemps.size()]);
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.TypeDescriptor;
-
-public class FlatNew extends FlatNode {
- TempDescriptor dst;
- TypeDescriptor type;
- TempDescriptor size;
- boolean isglobal;
-
- public FlatNew(TypeDescriptor type, TempDescriptor dst, boolean isglobal) {
- this.type=type;
- this.dst=dst;
- this.size=null;
- this.isglobal=isglobal;
- }
-
- public FlatNew(TypeDescriptor type, TempDescriptor dst, TempDescriptor size, boolean isglobal) {
- this.type=type;
- this.dst=dst;
- this.size=size;
- this.isglobal=isglobal;
- }
-
- public boolean isGlobal() {
- return isglobal;
- }
-
- public String toString() {
- if (size==null)
- return dst.toString()+"= NEW "+type.toString();
- else
- return dst.toString()+"= NEW "+type.toString()+"["+size.toString()+"]";
- }
-
- public int kind() {
- return FKind.FlatNew;
- }
-
- public TempDescriptor [] writesTemps() {
- return new TempDescriptor[] {dst};
- }
-
- public TempDescriptor [] readsTemps() {
- if (size!=null)
- return new TempDescriptor[] {size};
- else
- return new TempDescriptor[0];
- }
-
- public TempDescriptor getDst() {
- return dst;
- }
-
- public TempDescriptor getSize() {
- return size;
- }
-
- public TypeDescriptor getType() {
- return type;
- }
-}
+++ /dev/null
-package IR.Flat;
-import java.util.Vector;
-
-public class FlatNode {
- protected Vector next;
- protected Vector prev;
-
- public FlatNode() {
- next=new Vector();
- prev=new Vector();
- }
-
- public String toString() {
- throw new Error(this.getClass().getName() + "does not implement toString!");
- }
- public int numNext() {
- return next.size();
- }
- public FlatNode getNext(int i) {
- return (FlatNode) next.get(i);
- }
-
- public int numPrev() {
- return prev.size();
- }
- public FlatNode getPrev(int i) {
- return (FlatNode) prev.get(i);
- }
-
- public void addNext(FlatNode n) {
- next.add(n);
- n.addPrev(this);
- }
-
- /** This function modifies the graph */
- public void setNext(int i, FlatNode n) {
- FlatNode old=getNext(i);
- next.set(i, n);
- old.prev.remove(this);
- }
-
- protected void addPrev(FlatNode p) {
- prev.add(p);
- }
- public int kind() {
- throw new Error();
- }
-
- public TempDescriptor [] readsTemps() {
- return new TempDescriptor[0];
- }
-
- public TempDescriptor [] writesTemps() {
- return new TempDescriptor[0];
- }
-}
+++ /dev/null
-package IR.Flat;
-import java.util.Vector;
-
-public class FlatNop extends FlatNode {
- public FlatNop() {
- }
-
- public String toString() {
- return "nop";
- }
-
- public int kind() {
- return FKind.FlatNop;
- }
-}
+++ /dev/null
-package IR.Flat;
-import java.util.Vector;
-import IR.*;
-
-public class FlatOpNode extends FlatNode {
- TempDescriptor dest;
- TempDescriptor left;
- TempDescriptor right;
- Operation op;
-
- public FlatOpNode(TempDescriptor dest, TempDescriptor left, TempDescriptor right, Operation op) {
- this.dest=dest;
- this.left=left;
- this.right=right;
- this.op=op;
- }
-
- public TempDescriptor getDest() {
- return dest;
- }
-
- public TempDescriptor getLeft() {
- return left;
- }
-
- public TempDescriptor getRight() {
- return right;
- }
-
- public Operation getOp() {
- return op;
- }
-
- public String toString() {
- if (right!=null)
- return dest.toString()+"="+left.toString()+op.toString()+right.toString();
- else if (op.getOp()==Operation.ASSIGN)
- return dest.toString()+" = "+left.toString();
- else
- return dest.toString()+" "+op.toString() +" "+left.toString();
- }
-
- public int kind() {
- return FKind.FlatOpNode;
- }
-
- public TempDescriptor [] readsTemps() {
- if (right!=null)
- return new TempDescriptor [] {left,right};
- else
- return new TempDescriptor [] {left};
- }
-
- public TempDescriptor [] writesTemps() {
- return new TempDescriptor [] {dest};
- }
-}
+++ /dev/null
-package IR.Flat;
-
-public class FlatReturnNode extends FlatNode {
- TempDescriptor tempdesc;
-
- public FlatReturnNode(TempDescriptor td) {
- this.tempdesc=td;
- }
-
- public String toString() {
- return "return "+tempdesc;
- }
-
- public int kind() {
- return FKind.FlatReturnNode;
- }
-
- public TempDescriptor [] readsTemps() {
- if (tempdesc==null)
- return new TempDescriptor [0];
- else
- return new TempDescriptor [] {tempdesc};
- }
-
- public TempDescriptor getReturnTemp() {
- return tempdesc;
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.FieldDescriptor;
-
-public class FlatSetElementNode extends FlatNode {
- TempDescriptor src;
- TempDescriptor dst;
- TempDescriptor index;
-
- public FlatSetElementNode(TempDescriptor dst, TempDescriptor index, TempDescriptor src) {
- this.index=index;
- this.src=src;
- this.dst=dst;
- }
-
- public boolean needsBoundsCheck() {
- return true;
- }
-
- public TempDescriptor getSrc() {
- return src;
- }
-
- public TempDescriptor getIndex() {
- return index;
- }
-
- public TempDescriptor getDst() {
- return dst;
- }
-
- public String toString() {
- return dst.toString()+"["+index.toString()+"]="+src.toString();
- }
-
- public int kind() {
- return FKind.FlatSetElementNode;
- }
-
- public TempDescriptor [] readsTemps() {
- return new TempDescriptor [] {src,dst,index};
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.FieldDescriptor;
-
-public class FlatSetFieldNode extends FlatNode {
- TempDescriptor src;
- TempDescriptor dst;
- FieldDescriptor field;
-
- public FlatSetFieldNode(TempDescriptor dst, FieldDescriptor field, TempDescriptor src) {
- this.field=field;
- this.src=src;
- this.dst=dst;
- }
-
- public TempDescriptor getSrc() {
- return src;
- }
-
- public TempDescriptor getDst() {
- return dst;
- }
-
- public FieldDescriptor getField() {
- return field;
- }
-
- public String toString() {
- return dst.toString()+"."+field.getSymbol()+"="+src.toString();
- }
-
- public int kind() {
- return FKind.FlatSetFieldNode;
- }
-
- public TempDescriptor [] readsTemps() {
- return new TempDescriptor [] {src,dst};
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.TagDescriptor;
-
-public class FlatTagDeclaration extends FlatNode {
- TempDescriptor dst;
- TagDescriptor type;
-
- public FlatTagDeclaration(TagDescriptor type, TempDescriptor dst) {
- this.type=type;
- this.dst=dst;
- }
-
- public String toString() {
- return dst.toString()+"= new Tag("+type.toString()+")";
- }
-
- public int kind() {
- return FKind.FlatTagDeclaration;
- }
-
- public TempDescriptor [] writesTemps() {
- return new TempDescriptor[] {dst};
- }
-
- public TempDescriptor [] readsTemps() {
- return new TempDescriptor[0];
- }
-
- public TempDescriptor getDst() {
- return dst;
- }
-
- public TagDescriptor getType() {
- return type;
- }
-}
+++ /dev/null
-package IR.Flat;
-
-public class NodePair {
- FlatNode begin;
- FlatNode end;
-
- public NodePair(FlatNode begin, FlatNode end) {
- this.begin=begin;
- this.end=end;
- }
-
- public FlatNode getBegin() {
- return begin;
- }
-
- public FlatNode getEnd() {
- return end;
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.*;
-import java.util.*;
-
-public class ParamsObject {
- private Vector pointerparams;
- private Vector primitiveparams;
- private MethodDescriptor method;
- private TaskDescriptor task;
- private int tag;
- private Hashtable paramtotemp;
- private Hashtable temptostore;
- private int count;
-
- public ParamsObject(MethodDescriptor md, int tag) {
- pointerparams=new Vector();
- primitiveparams=new Vector();
- paramtotemp=new Hashtable();
- temptostore=new Hashtable();
- this.method=md;
- this.tag=tag;
- count=0;
- }
-
- public ParamsObject(TaskDescriptor task, int tag) {
- pointerparams=new Vector();
- primitiveparams=new Vector();
- paramtotemp=new Hashtable();
- temptostore=new Hashtable();
- this.task=task;
- this.tag=tag;
- count=0;
- }
-
- public int getUID() {
- return tag;
- }
-
- public void addPtr(TempDescriptor t) {
- Position p=new Position(true, pointerparams.size());
- pointerparams.add(t);
- paramtotemp.put(new Integer(count++), t);
- temptostore.put(t,p);
- }
-
- public boolean isParamPtr(TempDescriptor t) {
- if (containsTemp(t)) {
- ParamsObject.Position p=(ParamsObject.Position)temptostore.get(t);
- return p.inStruct;
- }
- return false;
- }
-
- public boolean isParamPrim(TempDescriptor t) {
- if (containsTemp(t)) {
- ParamsObject.Position p=(ParamsObject.Position)temptostore.get(t);
- return !p.inStruct;
- }
- return false;
- }
-
- public boolean containsTemp(TempDescriptor t) {
- return temptostore.containsKey(t);
- }
-
- public void addPrim(TempDescriptor t) {
- Position p=new Position(false, primitiveparams.size());
- primitiveparams.add(t);
- paramtotemp.put(new Integer(count++), t);
- temptostore.put(t,p);
- }
-
- int numPointers() {
- return pointerparams.size();
- }
-
- TempDescriptor getPointer(int i) {
- return (TempDescriptor) pointerparams.get(i);
- }
- int numPrimitives() {
- return primitiveparams.size();
- }
-
- TempDescriptor getPrimitive(int i) {
- return (TempDescriptor) primitiveparams.get(i);
- }
- static class Position {
- boolean inStruct;
- int position;
- Position(boolean inStruct, int position) {
- this.inStruct=inStruct;
- this.position=position;
- }
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.*;
-
-public class TempDescriptor extends Descriptor {
- static int currentid=0;
- int id;
- // String safename;
- TypeDescriptor type;
- TagDescriptor tag;
-
- public TempDescriptor(String name) {
- super(name);
- id=currentid++;
- }
-
- public TempDescriptor(String name, TypeDescriptor td) {
- this(name);
- type=td;
- }
-
- public TempDescriptor(String name, TypeDescriptor type, TagDescriptor td) {
- this(name);
- this.type=type;
- tag=td;
- }
-
- public static TempDescriptor tempFactory() {
- return new TempDescriptor("temp_"+currentid);
- }
-
- public static TempDescriptor tempFactory(String name) {
- return new TempDescriptor(name+currentid);
- }
-
- public static TempDescriptor tempFactory(String name, TypeDescriptor td) {
- return new TempDescriptor(name+currentid,td);
- }
-
- public static TempDescriptor tempFactory(String name, TypeDescriptor type, TagDescriptor tag) {
- return new TempDescriptor(name+currentid,type,tag);
- }
-
- public static TempDescriptor paramtempFactory(String name, TypeDescriptor td) {
- return new TempDescriptor(name,td);
- }
-
- public static TempDescriptor paramtempFactory(String name, TypeDescriptor tagtype, TagDescriptor tag) {
- return new TempDescriptor(name, tagtype, tag);
- }
-
- public String toString() {
- return safename;
- }
-
- public void setType(TypeDescriptor td) {
- type=td;
- }
-
- public TypeDescriptor getType() {
- return type;
- }
-
- public TagDescriptor getTag() {
- return tag;
- }
-
- public void setTag(TagDescriptor tag) {
- this.tag=tag;
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.FlagDescriptor;
-
-public class TempFlagPair {
- FlagDescriptor fd;
- TempDescriptor td;
-
- public TempFlagPair(TempDescriptor td, FlagDescriptor fd) {
- this.fd=fd;
- this.td=td;
- }
- public int hashCode() {
- if (fd!=null)
- return fd.hashCode()^td.hashCode();
- else
- return td.hashCode();
- }
-
- public TempDescriptor getTemp() {
- return td;
- }
-
- public FlagDescriptor getFlag() {
- return fd;
- }
-
- public boolean equals(Object o) {
- if (!(o instanceof TempFlagPair))
- return false;
- TempFlagPair tfp=(TempFlagPair)o;
- return (tfp.fd==fd)&&(tfp.td==td);
- }
-
- public String toString() {
- return "<"+fd+","+td+">";
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.*;
-import java.util.*;
-
-public class TempObject {
- ParamsObject params;
- private Vector pointerparams;
- private Vector primitiveparams;
- private MethodDescriptor method;
- private TaskDescriptor task;
- private int tag;
- private Hashtable paramtotemp;
- private Hashtable temptostore;
- private int count;
-
- public TempObject(ParamsObject p, MethodDescriptor md, int tag) {
- params=p;
- pointerparams=new Vector();
- primitiveparams=new Vector();
- paramtotemp=new Hashtable();
- temptostore=new Hashtable();
- this.method=md;
- this.tag=tag;
- count=0;
- }
-
- public TempObject(ParamsObject p, TaskDescriptor task, int tag) {
- params=p;
- pointerparams=new Vector();
- primitiveparams=new Vector();
- paramtotemp=new Hashtable();
- temptostore=new Hashtable();
- this.task=task;
- this.tag=tag;
- count=0;
- }
-
- public void addPtr(TempDescriptor t) {
- if (!params.containsTemp(t)&&!pointerparams.contains(t)) {
- Position p=new Position(true, pointerparams.size());
- pointerparams.add(t);
- paramtotemp.put(new Integer(count++), t);
- temptostore.put(t,p);
- }
- }
-
- public void addPrim(TempDescriptor t) {
- if (!params.containsTemp(t)&&!primitiveparams.contains(t)) {
- Position p=new Position(false, primitiveparams.size());
- primitiveparams.add(t);
- paramtotemp.put(new Integer(count++), t);
- temptostore.put(t,p);
- }
- }
-
- public boolean isLocalPtr(TempDescriptor t) {
- if (!params.containsTemp(t)) {
- Position p=(Position)temptostore.get(t);
- return p.inStruct;
- }
- return false;
- }
-
- public boolean isLocalPrim(TempDescriptor t) {
- if (!params.containsTemp(t)) {
- Position p=(Position)temptostore.get(t);
- return !p.inStruct;
- }
- return false;
- }
-
- public boolean isParamPtr(TempDescriptor t) {
- return params.isParamPtr(t);
- }
-
- public boolean isParamPrim(TempDescriptor t) {
- return params.isParamPrim(t);
- }
-
- int numPointers() {
- return pointerparams.size();
- }
-
- TempDescriptor getPointer(int i) {
- return (TempDescriptor) pointerparams.get(i);
- }
-
- int numPrimitives() {
- return primitiveparams.size();
- }
-
- TempDescriptor getPrimitive(int i) {
- return (TempDescriptor) primitiveparams.get(i);
- }
-
- static class Position {
- boolean inStruct;
- int position;
- Position(boolean inStruct, int position) {
- this.inStruct=inStruct;
- this.position=position;
- }
- }
-}
+++ /dev/null
-package IR.Flat;
-import IR.TagDescriptor;
-
-public class TempTagPair {
- TagDescriptor tagd;
- TempDescriptor td;
- TempDescriptor tagt;
-
- public TempTagPair(TempDescriptor td, TagDescriptor tagd, TempDescriptor tagt) {
- this.tagd=tagd;
- this.tagt=tagt;
- this.td=td;
- }
- public int hashCode() {
- return td.hashCode()^tagt.hashCode();
- }
-
- public TempDescriptor getTemp() {
- return td;
- }
-
- public TagDescriptor getTag() {
- return tagd;
- }
-
- public TempDescriptor getTagTemp() {
- return tagt;
- }
-
- public boolean equals(Object o) {
- if (!(o instanceof TempTagPair))
- return false;
- TempTagPair ttp=(TempTagPair)o;
- if (ttp.tagt==tagt&&ttp.td==td) {
- if (ttp.tagd!=null) {
- if (!ttp.tagd.equals(tagd))
- throw new Error();
- } else if (tagd!=null)
- throw new Error();
-
- return true;
- } else return false;
- }
-
- public String toString() {
- return "<"+td+","+tagd+","+tagt+">";
- }
-}
+++ /dev/null
-package IR;
-import IR.Tree.Modifiers;
-import IR.Tree.ExpressionNode;
-import java.util.Vector;
-
-/**
- * Descriptor
- *
- * represents a symbol in the language (var name, function name, etc).
- */
-
-public class MethodDescriptor extends Descriptor {
-
- protected Modifiers modifier;
- protected TypeDescriptor returntype;
- protected String identifier;
- protected Vector params;
- protected SymbolTable paramtable;
- protected ClassDescriptor cd;
- protected VarDescriptor thisvd;
- protected boolean isglobal;
-
- public MethodDescriptor(Modifiers m, TypeDescriptor rt, String identifier) {
- super(identifier);
- this.modifier=m;
- this.returntype=rt;
- this.identifier=identifier;
- this.safename = "___" + name + "___";
- this.uniqueid=count++;
- params=new Vector();
- paramtable=new SymbolTable();
- thisvd=null;
- }
-
- public Modifiers getModifiers() {
- return modifier;
- }
-
- public boolean matches(MethodDescriptor md) {
- /* Check the name */
- if (!identifier.equals(md.identifier))
- return false;
- if (numParameters()!=md.numParameters())
- return false;
- for(int i=0;i<numParameters();i++) {
- Descriptor d1=getParameter(i);
- Descriptor d2=md.getParameter(i);
- TypeDescriptor td1=(d1 instanceof TagVarDescriptor)?((TagVarDescriptor)d1).getType():((VarDescriptor)d1).getType();
- TypeDescriptor td2=(d2 instanceof TagVarDescriptor)?((TagVarDescriptor)d2).getType():((VarDescriptor)d2).getType();
- if (!td1.equals(td2))
- return false;
- }
- return true;
- }
-
- public MethodDescriptor(Modifiers m, String identifier) {
- this(m, identifier, false);
- }
-
- public MethodDescriptor(Modifiers m, String identifier, boolean isglobal) {
- super(identifier);
- this.isglobal=isglobal;
- this.modifier=m;
- this.returntype=null;
- this.identifier=identifier;
- this.safename = "___" + name + "___";
- this.uniqueid=count++;
- params=new Vector();
- paramtable=new SymbolTable();
- thisvd=null;
- }
-
- public void setThis(VarDescriptor vd) {
- thisvd=vd;
- paramtable.add(vd);
- }
-
- public VarDescriptor getThis() {
- return thisvd;
- }
-
- public String getSafeMethodDescriptor() {
- String st="";
- for(int i=0;i<numParameters();i++) {
- st+=getParamType(i).getSafeDescriptor();
- if ((i+1)<numParameters())
- st+="_";
- }
- return st;
- }
-
- public boolean isStatic() {
- return modifier.isStatic();
- }
-
- public boolean isConstructor() {
- return (returntype==null);
- }
-
- public TypeDescriptor getReturnType() {
- return returntype;
- }
-
- public void setClassDesc(ClassDescriptor cd) {
- this.cd=cd;
- }
-
- public ClassDescriptor getClassDesc() {
- return cd;
- }
-
- public SymbolTable getParameterTable() {
- return paramtable;
- }
-
- public void addParameter(TypeDescriptor type, String paramname) {
- if (paramname.equals("this"))
- throw new Error("Can't have parameter named this");
- VarDescriptor vd=new VarDescriptor(type, paramname);
-
- params.add(vd);
- if (paramtable.getFromSameScope(paramname)!=null) {
- throw new Error("Parameter "+paramname+" already defined");
- }
- paramtable.add(vd);
- }
-
- public void addTagParameter(TypeDescriptor type, String paramname) {
- if (paramname.equals("this"))
- throw new Error("Can't have parameter named this");
- TagVarDescriptor vd=new TagVarDescriptor(null, paramname);
-
- params.add(vd);
- if (paramtable.getFromSameScope(paramname)!=null) {
- throw new Error("Parameter "+paramname+" already defined");
- }
- paramtable.add(vd);
- }
-
- public int numParameters() {
- return params.size();
- }
-
- public Descriptor getParameter(int i) {
- return (Descriptor) params.get(i);
- }
-
- public String getParamName(int i) {
- return ((Descriptor)params.get(i)).getSymbol();
- }
-
- public TypeDescriptor getParamType(int i) {
- Descriptor d=(Descriptor)params.get(i);
- if (d instanceof VarDescriptor)
- return ((VarDescriptor)params.get(i)).getType();
- else if (d instanceof TagVarDescriptor)
- return new TypeDescriptor(TypeDescriptor.TAG);
- else throw new Error();
- }
-
- public String toString() {
- String st="";
- String type="";
- if (cd!=null)
- type=cd+".";
- if (returntype!=null)
- st=modifier.toString()+returntype.toString()+" "+type+identifier+"(";
- else
- st=modifier.toString()+" "+type+identifier+"(";
- for(int i=0;i<params.size();i++) {
- st+=getParamType(i)+" "+getParamName(i);
- if ((i+1)!=params.size())
- st+=", ";
- }
- st+=")";
- return st;
- }
-}
+++ /dev/null
-package IR;
-
-public class NameDescriptor extends Descriptor {
- String identifier;
- NameDescriptor nd;
- public NameDescriptor(NameDescriptor nd, String id) {
- super(nd.toString()+"."+id);
- identifier=id;
- this.nd=nd;
- }
-
- public NameDescriptor(String id) {
- super(id);
- identifier=id;
- nd=null;
- }
-
- public String getIdentifier() {
- return identifier;
- }
-
- public NameDescriptor getBase() {
- return nd;
- }
-
- public String getRoot() {
- if (nd==null)
- return identifier;
- else
- return nd.getRoot();
- }
-
- public String toString() {
- if (nd==null)
- return identifier;
- else
- return nd+"."+identifier;
- }
-
-}
+++ /dev/null
-package IR;
-
-public class Operation {
- public static final int LOGIC_OR=1;
- public static final int LOGIC_AND=2;
- public static final int BIT_OR=3;
- public static final int BIT_XOR=4;
- public static final int BIT_AND=5;
- public static final int EQUAL=6;
- public static final int NOTEQUAL=7;
- public static final int LT=8;
- public static final int GT=9;
- public static final int LTE=10;
- public static final int GTE=11;
- public static final int LEFTSHIFT=12;
- public static final int RIGHTSHIFT=13;
- public static final int SUB=14;
- public static final int ADD=15;
- public static final int MULT=16;
- public static final int DIV=17;
- public static final int MOD=18;
- public static final int UNARYPLUS=19;
- public static final int UNARYMINUS=20;
- public static final int POSTINC=21;
- public static final int POSTDEC=22;
- public static final int PREINC=23;
- public static final int PREDEC=24;
- public static final int LOGIC_NOT=25;
- /* Flat Operations */
- public static final int ASSIGN=100;
-
- private int operation;
- public Operation(int op) {
- this.operation=op;
- }
-
- public Operation(String op) {
- this.operation=parseOp(op);
- }
-
- public int getOp() {
- return operation;
- }
-
- public static int parseOp(String st) {
- if (st.equals("logical_or"))
- return LOGIC_OR;
- else if (st.equals("logical_and"))
- return LOGIC_AND;
- else if (st.equals("bitwise_or"))
- return BIT_OR;
- else if (st.equals("bitwise_xor"))
- return BIT_XOR;
- else if (st.equals("bitwise_and"))
- return BIT_AND;
- else if (st.equals("equal"))
- return EQUAL;
- else if (st.equals("not_equal"))
- return NOTEQUAL;
- else if (st.equals("comp_lt"))
- return LT;
- else if (st.equals("comp_gt"))
- return GT;
- else if (st.equals("comp_lte"))
- return LTE;
- else if (st.equals("comp_gte"))
- return GTE;
- else if (st.equals("leftshift"))
- return LEFTSHIFT;
- else if (st.equals("rightshift"))
- return RIGHTSHIFT;
- else if (st.equals("sub"))
- return SUB;
- else if (st.equals("add"))
- return ADD;
- else if (st.equals("mult"))
- return MULT;
- else if (st.equals("div"))
- return DIV;
- else if (st.equals("mod"))
- return MOD;
- else if (st.equals("unaryplus"))
- return UNARYPLUS;
- else if (st.equals("unaryminus"))
- return UNARYMINUS;
- else if (st.equals("postinc"))
- return POSTINC;
- else if (st.equals("postdec"))
- return POSTDEC;
- else if (st.equals("preinc"))
- return PREINC;
- else if (st.equals("predec"))
- return PREDEC;
- else if (st.equals("not"))
- return LOGIC_NOT;
- else
- throw new Error();
- }
-
- public String toString() {
- if (operation==LOGIC_OR)
- return "||";
- else if (operation==LOGIC_AND)
- return "&&";
- else if (operation==LOGIC_NOT)
- return "not";
- else if (operation==BIT_OR)
- return "|";
- else if (operation==BIT_XOR)
- return "^";
- else if (operation==BIT_AND)
- return "&";
- else if (operation==EQUAL)
- return "==";
- else if (operation==NOTEQUAL)
- return "!=";
- else if (operation==LT)
- return "<";
- else if (operation==GT)
- return ">";
- else if (operation==LTE)
- return "<=";
- else if (operation==GTE)
- return ">=";
- else if (operation==LEFTSHIFT)
- return "<<";
- else if (operation==RIGHTSHIFT)
- return ">>";
- else if (operation==SUB)
- return "-";
- else if (operation==ADD)
- return "+";
- else if (operation==MULT)
- return "*";
- else if (operation==DIV)
- return "/";
- else if (operation==MOD)
- return "%";
- else if (operation==UNARYPLUS)
- return "unaryplus";
- else if (operation==UNARYMINUS)
- return "unaryminus";
- else if (operation==POSTINC)
- return "postinc";
- else if (operation==POSTDEC)
- return "postdec";
- else if (operation==PREINC)
- return "preinc";
- else if (operation==PREDEC)
- return "predec";
- else if (operation==ASSIGN)
- return "assign";
- else throw new Error();
- }
-
-
-}
+++ /dev/null
-package IR;
-import IR.Tree.*;
-import IR.Flat.*;
-import IR.*;
-import java.util.*;
-
-public class State {
- public State() {
- this.classes=new SymbolTable();
- this.tasks=new SymbolTable();
- this.treemethodmap=new Hashtable();
- this.flatmethodmap=new Hashtable();
- this.parsetrees=new HashSet();
- this.arraytypes=new HashSet();
- this.arraytonumber=new Hashtable();
- this.tagmap=new Hashtable();
- this.analysisresult=new Hashtable();
- this.optionaltaskdescriptors=new Hashtable();
- }
-
- public void addParseNode(ParseNode parsetree) {
- parsetrees.add(parsetree);
- }
-
- public void storeAnalysisResult(Hashtable result){
- analysisresult = result;
- }
-
- public void storeOptionalTaskDescriptors(Hashtable optionaltaskdescriptors){
- this.optionaltaskdescriptors=optionaltaskdescriptors;
- }
-
- public Hashtable getAnalysisResult(){
- return analysisresult;
- }
-
- public Hashtable getOptionalTaskDescriptors(){
- return optionaltaskdescriptors;
- }
-
- /** Boolean flag which indicates whether compiler is compiling a task-based
- * program. */
- public boolean WEBINTERFACE=false;
- public boolean TASK=false;
- public boolean DSM=false;
- public boolean TASKSTATE=false;
- public boolean OPTIONAL=false;
- public boolean THREAD=false;
- public boolean CONSCHECK=false;
- public boolean INSTRUCTIONFAILURE=false;
- public String structfile;
- public String main;
-
- public SymbolTable classes;
- public SymbolTable tasks;
- public Set parsetrees;
- public Hashtable treemethodmap;
- public Hashtable flatmethodmap;
- private HashSet arraytypes;
- public Hashtable arraytonumber;
- private int numclasses=0;
- private int numtasks=0;
- private int arraycount=0;
-
-
- private Hashtable analysisresult;
- private Hashtable optionaltaskdescriptors;
-
- private Hashtable tagmap;
- private int numtags=0;
-
- public void addArrayType(TypeDescriptor td) {
- if (!arraytypes.contains(td)) {
- arraytypes.add(td);
- arraytonumber.put(td,new Integer(arraycount++));
- }
- }
-
- public Iterator getArrayIterator() {
- return arraytypes.iterator();
- }
-
- public int getTagId(TagDescriptor tag) {
- if (tagmap.containsKey(tag)) {
- return ((Integer) tagmap.get(tag)).intValue();
- } else {
- tagmap.put(tag, new Integer(numtags));
- return numtags++;
- }
- }
-
- public int getArrayNumber(TypeDescriptor td) {
- return ((Integer)arraytonumber.get(td)).intValue();
- }
-
- public int numArrays() {
- return arraytypes.size();
- }
-
- public static TypeDescriptor getTypeDescriptor(int t) {
- TypeDescriptor td=new TypeDescriptor(t);
- return td;
- }
-
- public static TypeDescriptor getTypeDescriptor(NameDescriptor n) {
- TypeDescriptor td=new TypeDescriptor(n);
- return td;
- }
-
- public void addClass(ClassDescriptor tdn) {
- if (classes.contains(tdn.getSymbol()))
- throw new Error("Class "+tdn.getSymbol()+" defined twice");
- classes.add(tdn);
- numclasses++;
- }
-
- public int numClasses() {
- return numclasses;
- }
-
- public BlockNode getMethodBody(MethodDescriptor md) {
- return (BlockNode)treemethodmap.get(md);
- }
-
- public BlockNode getMethodBody(TaskDescriptor td) {
- return (BlockNode)treemethodmap.get(td);
- }
-
- public SymbolTable getClassSymbolTable() {
- return classes;
- }
-
- public SymbolTable getTaskSymbolTable() {
- return tasks;
- }
-
- /** Returns Flat IR representation of MethodDescriptor md. */
-
- public FlatMethod getMethodFlat(MethodDescriptor md) {
- return (FlatMethod)flatmethodmap.get(md);
- }
-
- /** Returns Flat IR representation of TaskDescriptor td. */
-
- public FlatMethod getMethodFlat(TaskDescriptor td) {
- return (FlatMethod)flatmethodmap.get(td);
- }
-
- public void addTreeCode(MethodDescriptor md, BlockNode bn) {
- treemethodmap.put(md,bn);
- }
-
- public void addTreeCode(TaskDescriptor td, BlockNode bn) {
- treemethodmap.put(td,bn);
- }
-
- public void addFlatCode(MethodDescriptor md, FlatMethod bn) {
- flatmethodmap.put(md,bn);
- }
-
- public void addFlatCode(TaskDescriptor td, FlatMethod bn) {
- flatmethodmap.put(td,bn);
- }
-
- public void addTask(TaskDescriptor td) {
- if (tasks.contains(td.getSymbol()))
- throw new Error("Task "+td.getSymbol()+" defined twice");
- tasks.add(td);
- numtasks++;
- }
-}
+++ /dev/null
-package IR;
-
-import java.util.*;
-
-public class SymbolTable {
-
- private Hashtable table;
- private SymbolTable parent;
- private HashSet valueset;
-
- public SymbolTable() {
- table = new Hashtable();
- valueset = new HashSet();
- this.parent = null;
- }
-
- public SymbolTable(SymbolTable parent) {
- table = new Hashtable();
- this.parent = parent;
- }
-
- public void add(Descriptor d) {
- add(d.getSymbol(), d);
- }
-
- public void add(String name, Descriptor d) {
- if (!table.containsKey(name))
- table.put(name, new HashSet());
- HashSet hs=(HashSet)table.get(name);
- hs.add(d);
- valueset.add(d);
- }
-
- public Set getSet(String name) {
- return getPSet(name);
- }
-
- private HashSet getPSet(String name) {
- HashSet hs=null;
- if (parent!=null)
- hs=parent.getPSet(name);
- else
- hs=new HashSet();
- if (table.containsKey(name)) {
- hs.addAll((HashSet)table.get(name));
- }
- return hs;
- }
-
- public Set getSetFromSameScope(String name) {
- return getPSetFromSameScope(name);
- }
-
- private HashSet getPSetFromSameScope(String name) {
- if (table.containsKey(name)) {
- HashSet hs=(HashSet)table.get(name);
- return hs;
- } else
- return new HashSet();
- }
-
- public Descriptor get(String name) {
- Descriptor d = getFromSameScope(name);
- if (d == null && parent != null) {
- return parent.get(name);
- } else {
- return d;
- }
- }
-
- public Descriptor getFromSameScope(String name) {
- if (table.containsKey(name)) {
- HashSet hs=(HashSet) table.get(name);
- return (Descriptor) hs.iterator().next();
- } else
- return null;
-
- }
-
- public Enumeration getNames() {
- return table.keys();
- }
-
- public Iterator getNamesIterator() {
- return table.keySet().iterator();
- }
-
- public Set getValueSet() {
- return valueset;
- }
-
- public Iterator getDescriptorsIterator() {
- return getValueSet().iterator();
- }
-
- public Set getAllValueSet() {
- HashSet hs=null;
- if (parent!=null)
- hs=(HashSet) parent.getAllValueSet();
- else
- hs=new HashSet();
- hs.addAll(valueset);
- return hs;
- }
-
- public Iterator getAllDescriptorsIterator() {
- return getAllValueSet().iterator();
- }
-
- public boolean contains(String name) {
- return (get(name) != null);
- }
-
- public SymbolTable getParent() {
- return parent;
- }
-
- public void setParent(SymbolTable parent) {
- this.parent = parent;
- }
-
- public String toString() {
- return "ST: " + table.toString();
- }
-}
+++ /dev/null
-package IR;
-
-/**
- * Descriptor
- *
- * represents a symbol in the language (var name, function name, etc).
- */
-
-public class TagDescriptor extends Descriptor {
-
- public TagDescriptor(String identifier) {
- super(identifier);
- }
-
- public boolean equals(Object o) {
- if (o instanceof TagDescriptor) {
- TagDescriptor t=(TagDescriptor) o;
- return getSymbol().equals(t.getSymbol());
- } else return false;
- }
-
- public int hashCode() {
- return getSymbol().hashCode();
- }
-
- public String toString() {
- return "Tag "+getSymbol();
- }
-}
+++ /dev/null
-package IR;
-
-/**
- * Descriptor
- *
- * represents a symbol in the language (var name, function name, etc).
- */
-
-public class TagVarDescriptor extends Descriptor {
-
- protected TagDescriptor td;
- protected String identifier;
-
- public TagVarDescriptor(TagDescriptor t, String identifier) {
- super(identifier);
- this.td=t;
- this.identifier=identifier;
- this.safename = "___" + name + "___";
- this.uniqueid=count++;
- }
-
- public String getName() {
- return identifier;
- }
-
- public TagDescriptor getTag() {
- return td;
- }
-
- public TypeDescriptor getType() {
- return new TypeDescriptor(TypeDescriptor.TAG);
- }
-
- /* public boolean equals(Object o) {
- if (o instanceof TagVarDescriptor) {
- TagVarDescriptor tvd=(TagVarDescriptor)o;
- if (tvd.identifier.equals(identifier)) {
- if (tvd.td!=null) {
- if (!tvd.td.equals(td))
- throw new Error();
- } else if (td!=null)
- throw new Error();
- return true;
- }
- }
- return false;
- }
-
- public int hashCode() {
- return identifier.hashCode();
- }*/
-
- public String toString() {
- return td.toString()+" "+identifier;
- }
-}
+++ /dev/null
-package IR;
-import IR.Tree.FlagExpressionNode;
-import IR.Tree.TagExpressionList;
-import IR.Tree.FlagEffects;
-import java.util.Vector;
-import java.util.Hashtable;
-import java.util.Iterator;
-import IR.Tree.Modifiers;
-
-/**
- * Descriptor
- *
- */
-
-public class TaskDescriptor extends Descriptor {
-
- protected Hashtable flagstable;
- protected Hashtable tagstable;
- protected Vector vfe;
- protected String identifier;
- protected Vector params;
- protected Vector optionals;
- protected SymbolTable paramtable;
-
- public TaskDescriptor(String identifier) {
- super(identifier);
- this.identifier=identifier;
- this.uniqueid=count++;
- flagstable=new Hashtable();
- tagstable=new Hashtable(); //BUGFIX - added initialization here
- params=new Vector();
- optionals = new Vector();
- paramtable=new SymbolTable();
- }
-
- public void addFlagEffects(Vector vfe) {
- this.vfe=vfe;
- }
-
- public Vector getFlagEffects() {
- return vfe;
- }
-
- public SymbolTable getParameterTable() {
- return paramtable;
- }
-
- public void addParameter(TypeDescriptor type, String paramname, FlagExpressionNode fen, TagExpressionList tel, boolean isoptional) {
- if (paramname.equals("this"))
- throw new Error("Can't have parameter named this");
- VarDescriptor vd=new VarDescriptor(type, paramname);
- params.add(vd);
- if (isoptional) optionals.add(vd);
- if (fen!=null)
- flagstable.put(vd, fen);
- if (tel!=null) {//BUGFIX - added null check here...test with any bristlecone program
- tagstable.put(vd, tel);
- for(int i=0;i<tel.numTags();i++) {
- TagVarDescriptor tvd=new TagVarDescriptor(new TagDescriptor(tel.getType(i)), tel.getName(i));
- if (paramtable.getFromSameScope(tel.getName(i))==null) {
- paramtable.add(tvd);
- } else if (!((paramtable.getFromSameScope(tel.getName(i)) instanceof TagVarDescriptor)&&((TagVarDescriptor)paramtable.getFromSameScope(tel.getName(i))).getTag().equals(tvd.getTag())))
- throw new Error("Parameter "+paramname+" already defined");
- }
- }
-
- if (paramtable.getFromSameScope(paramname)!=null) {
- throw new Error("Parameter "+paramname+" already defined");
- }
- paramtable.add(vd);
- }
-
- public boolean isOptional(String classname){
- for (Iterator it = optionals.iterator(); it.hasNext();)
- if( ((VarDescriptor)it.next()).getType().getSymbol().compareTo(classname)==0) return true;
- return false;
- }
-
- public int numParameters() {
- return params.size();
- }
-
- public VarDescriptor getParameter(int i) {
- return (VarDescriptor)params.get(i);
- }
-
- public String getParamName(int i) {
- return ((VarDescriptor)params.get(i)).getName();
- }
-
- public TypeDescriptor getParamType(int i) {
- return ((VarDescriptor)params.get(i)).getType();
- }
-
- public FlagExpressionNode getFlag(VarDescriptor vd) {
- return (FlagExpressionNode) flagstable.get(vd);
- }
-
- public TagExpressionList getTag(VarDescriptor vd) {
- //BUG did lookup in wrong table (originally flagstable)...to
- //test, use any task program
- return (TagExpressionList) tagstable.get(vd);
- }
-
- public String toString() {
- String st=identifier+"(";
- for(int i=0;i<params.size();i++) {
- st+=getParamType(i)+" "+getParamName(i);
- if ((i+1)!=params.size())
- st+=", ";
- }
- st+=")";
- return st;
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.FieldDescriptor;
-import IR.TypeDescriptor;
-
-public class ArrayAccessNode extends ExpressionNode {
- ExpressionNode left;
- ExpressionNode index;
-
- public ArrayAccessNode(ExpressionNode l, ExpressionNode index) {
- this.index=index;
- left=l;
- }
-
- public ExpressionNode getIndex() {
- return index;
- }
-
- public ExpressionNode getExpression() {
- return left;
- }
-
- public String printNode(int indent) {
- return left.printNode(indent)+"["+index.printNode(0)+"]";
- }
-
- public int kind() {
- return Kind.ArrayAccessNode;
- }
-
- public TypeDescriptor getType() {
- return left.getType().dereference();
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.AssignOperation;
-import IR.TypeDescriptor;
-
-public class AssignmentNode extends ExpressionNode {
- ExpressionNode left;
- ExpressionNode right;
- AssignOperation op;
-
- public AssignmentNode(ExpressionNode l, ExpressionNode r, AssignOperation op) {
- left=l;
- right=r;
- this.op=op;
- }
-
- public ExpressionNode getDest() {
- return left;
- }
-
- public ExpressionNode getSrc() {
- return right;
- }
-
- public AssignOperation getOperation() {
- return op;
- }
-
- public String printNode(int indent) {
- return left.printNode(indent)+" "+op.toString()+" "+right.printNode(indent);
- }
-
- public TypeDescriptor getType() {
- return left.getType();
- }
-
- public int kind() {
- return Kind.AssignmentNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-public class AtomicNode extends BlockStatementNode {
- BlockNode bn;
- public AtomicNode(BlockNode bn) {
- this.bn=bn;
- }
-
- public String printNode(int indent) {
- return printSpace(indent)+"atomic {\n"+bn.printNode(indent)+"\n"+printSpace(indent)+"}";
- }
-
- public BlockNode getBlockNode() {
- return bn;
- }
-
- public int kind() {
- return Kind.AtomicNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-public class BlockExpressionNode extends BlockStatementNode {
- ExpressionNode en;
- public BlockExpressionNode(ExpressionNode e) {
- this.en=e;
- }
-
- public String printNode(int indent) {
- return en.printNode(indent);
- }
-
- public ExpressionNode getExpression() {
- return en;
- }
-
- public int kind() {
- return Kind.BlockExpressionNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-import java.util.Vector;
-import IR.*;
-
-public class BlockNode extends TreeNode {
- Vector blockstatements;
- int printStyle=0;
- protected SymbolTable table;
-
- public final static int NORMAL=0;
- public final static int NOBRACES=1;
- public final static int EXPRLIST=2;
-
- public BlockNode() {
- blockstatements=new Vector();
- table=new SymbolTable();
- }
-
- public SymbolTable getVarTable() {
- return table;
- }
-
- public void addBlockStatement(BlockStatementNode bsn) {
- blockstatements.add(bsn);
- }
-
- public void setStyle(int style) {
- printStyle=style;
- }
-
- public int size() {
- return blockstatements.size();
- }
-
- public BlockStatementNode get(int i) {
- return (BlockStatementNode) blockstatements.get(i);
- }
-
- public String printNode(int indent) {
- if (printStyle==NORMAL) {
- String st="{\n";
- for(int i=0;i<blockstatements.size();i++) {
- BlockStatementNode bsn=(BlockStatementNode)blockstatements.get(i);
- st+=printSpace(indent+INDENT)+bsn.printNode(indent+INDENT);
- if (!((bsn instanceof SubBlockNode)||
- (bsn instanceof LoopNode)||
- (bsn instanceof IfStatementNode)))
- st+=";\n";
- if (bsn instanceof IfStatementNode)
- st+="\n";
- }
- st+=printSpace(indent)+"}";
- return st;
- } else if (printStyle==NOBRACES) {
- String st="";
- for(int i=0;i<blockstatements.size();i++) {
- BlockStatementNode bsn=(BlockStatementNode)blockstatements.get(i);
- st+=printSpace(indent)+bsn.printNode(indent);
- if (!((bsn instanceof SubBlockNode)||
- (bsn instanceof LoopNode)||
- (bsn instanceof IfStatementNode)))
- st+=";";
- }
- return st;
- } else if (printStyle==EXPRLIST) {
- String st="";
- for(int i=0;i<blockstatements.size();i++) {
- BlockStatementNode bsn=(BlockStatementNode)blockstatements.get(i);
- st+=bsn.printNode(0);
- if ((i+1)!=blockstatements.size())
- st+=", ";
- }
- return st;
- } else throw new Error();
- }
-
- public int kind() {
- return Kind.BlockNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-public class BlockStatementNode extends TreeNode {
- public BlockStatementNode() {
- }
-
- public String printNode(int indent) {
- return null;
- }
-
-}
+++ /dev/null
-package IR.Tree;
-import IR.*;
-import java.util.*;
-
-
-public class BuildIR {
- State state;
- public BuildIR(State state) {
- this.state=state;
- }
- public void buildtree() {
- for(Iterator it=state.parsetrees.iterator();it.hasNext();) {
- ParseNode pn=(ParseNode)it.next();
- parseFile(pn);
- }
- }
-
- /** Parse the classes in this file */
- public void parseFile(ParseNode pn) {
- NameDescriptor packages;
- Vector singleimports=new Vector();
- Vector multiimports=new Vector();
-
- ParseNode ipn=pn.getChild("imports").getChild("import_decls_list");
- if (ipn!=null) {
- ParseNodeVector pnv=ipn.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode pnimport=pnv.elementAt(i);
- NameDescriptor nd=parseName(pnimport.getChild("name"));
- if (isNode(pnimport,"import_single"))
- singleimports.add(nd);
- else
- multiimports.add(nd);
- }
- }
- ParseNode ppn=pn.getChild("packages").getChild("package");
- if (ppn!=null) {
- packages=parseName(pn.getChild("name"));
- }
- ParseNode tpn=pn.getChild("type_declaration_list");
- if (tpn!=null) {
- ParseNodeVector pnv=tpn.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode type_pn=pnv.elementAt(i);
- if (isEmpty(type_pn)) /* Skip the semicolon */
- continue;
- if (isNode(type_pn,"class_declaration")) {
- ClassDescriptor cn=parseTypeDecl(type_pn);
- state.addClass(cn);
- } else if (isNode(type_pn,"task_declaration")) {
- TaskDescriptor td=parseTaskDecl(type_pn);
- state.addTask(td);
- } else {
- throw new Error(type_pn.getLabel());
- }
- }
- }
- }
-
- public TaskDescriptor parseTaskDecl(ParseNode pn) {
- TaskDescriptor td=new TaskDescriptor(pn.getChild("name").getTerminal());
- ParseNode bodyn=pn.getChild("body");
- BlockNode bn=parseBlock(bodyn);
- parseParameterList(td, pn);
- state.addTreeCode(td,bn);
- if (pn.getChild("flag_effects_list")!=null)
- td.addFlagEffects(parseFlags(pn.getChild("flag_effects_list")));
- return td;
- }
-
- public Vector parseFlags(ParseNode pn) {
- Vector vfe=new Vector();
- ParseNodeVector pnv=pn.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode fn=pnv.elementAt(i);
- FlagEffects fe=parseFlagEffects(fn);
- vfe.add(fe);
- }
- return vfe;
- }
-
- public FlagEffects parseFlagEffects(ParseNode pn) {
- if (isNode(pn,"flag_effect")) {
- String flagname=pn.getChild("name").getTerminal();
- FlagEffects fe=new FlagEffects(flagname);
- if (pn.getChild("flag_list")!=null)
- parseFlagEffect(fe, pn.getChild("flag_list"));
- if (pn.getChild("tag_list")!=null)
- parseTagEffect(fe, pn.getChild("tag_list"));
- return fe;
- } else throw new Error();
- }
-
- public void parseTagEffect(FlagEffects fes, ParseNode pn) {
- ParseNodeVector pnv=pn.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode pn2=pnv.elementAt(i);
- boolean status=true;
- if (isNode(pn2,"not")) {
- status=false;
- pn2=pn2.getChild("name");
- }
- String name=pn2.getTerminal();
- fes.addTagEffect(new TagEffect(name,status));
- }
- }
-
- public void parseFlagEffect(FlagEffects fes, ParseNode pn) {
- ParseNodeVector pnv=pn.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode pn2=pnv.elementAt(i);
- boolean status=true;
- if (isNode(pn2,"not")) {
- status=false;
- pn2=pn2.getChild("name");
- }
- String name=pn2.getTerminal();
- fes.addEffect(new FlagEffect(name,status));
- }
- }
-
- public FlagExpressionNode parseFlagExpression(ParseNode pn) {
- if (isNode(pn,"or")) {
- ParseNodeVector pnv=pn.getChildren();
- ParseNode left=pnv.elementAt(0);
- ParseNode right=pnv.elementAt(1);
- return new FlagOpNode(parseFlagExpression(left), parseFlagExpression(right), new Operation(Operation.LOGIC_OR));
- } else if (isNode(pn,"and")) {
- ParseNodeVector pnv=pn.getChildren();
- ParseNode left=pnv.elementAt(0);
- ParseNode right=pnv.elementAt(1);
- return new FlagOpNode(parseFlagExpression(left), parseFlagExpression(right), new Operation(Operation.LOGIC_AND));
- } else if (isNode(pn, "not")) {
- ParseNodeVector pnv=pn.getChildren();
- ParseNode left=pnv.elementAt(0);
- return new FlagOpNode(parseFlagExpression(left), new Operation(Operation.LOGIC_NOT));
-
- } else if (isNode(pn,"name")) {
- return new FlagNode(pn.getTerminal());
- } else {
- throw new Error();
- }
- }
-
- public Vector parseChecks(ParseNode pn) {
- Vector ccs=new Vector();
- ParseNodeVector pnv=pn.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode fn=pnv.elementAt(i);
- ConstraintCheck cc=parseConstraintCheck(fn);
- ccs.add(cc);
- }
- return ccs;
- }
-
- public ConstraintCheck parseConstraintCheck(ParseNode pn) {
- if (isNode(pn,"cons_check")) {
- String specname=pn.getChild("name").getChild("identifier").getTerminal();
- Vector[] args=parseConsArgumentList(pn);
- ConstraintCheck cc=new ConstraintCheck(specname);
- for(int i=0;i<args[0].size();i++) {
- cc.addVariable((String)args[0].get(i));
- cc.addArgument((ExpressionNode)args[1].get(i));
- }
- return cc;
- } else throw new Error();
- }
-
- public void parseParameterList(TaskDescriptor td, ParseNode pn) {
-
- boolean optional;
- ParseNode paramlist=pn.getChild("task_parameter_list");
- if (paramlist==null)
- return;
- ParseNodeVector pnv=paramlist.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode paramn=pnv.elementAt(i);
- if(paramn.getChild("optional")!=null){
- optional = true;
- paramn = paramn.getChild("optional").getFirstChild();
- System.out.println("OPTIONAL FOUND!!!!!!!");
- }
- else { optional = false;
- System.out.println("NOT OPTIONAL");
- }
-
- TypeDescriptor type=parseTypeDescriptor(paramn);
-
- String paramname=paramn.getChild("single").getTerminal();
- FlagExpressionNode fen=null;
- if (paramn.getChild("flag")!=null)
- fen=parseFlagExpression(paramn.getChild("flag").getFirstChild());
-
- ParseNode tagnode=paramn.getChild("tag");
-
- TagExpressionList tel=null;
- if (tagnode!=null) {
- tel=parseTagExpressionList(tagnode);
- }
-
- td.addParameter(type,paramname,fen, tel, optional);
- }
- }
-
- public TagExpressionList parseTagExpressionList(ParseNode pn) {
- //BUG FIX: change pn.getChildren() to pn.getChild("tag_expression_list").getChildren()
- //To test, feed in any input program that uses tags
- ParseNodeVector pnv=pn.getChild("tag_expression_list").getChildren();
- TagExpressionList tel=new TagExpressionList();
- for(int i=0;i<pnv.size();i++) {
- ParseNode tn=pnv.elementAt(i);
- String type=tn.getChild("type").getTerminal();
- String name=tn.getChild("single").getTerminal();
- tel.addTag(type, name);
- }
- return tel;
- }
-
- public ClassDescriptor parseTypeDecl(ParseNode pn) {
- ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal());
- if (!isEmpty(pn.getChild("super").getTerminal())) {
- /* parse superclass name */
- ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
- NameDescriptor nd=parseName(snn);
- cn.setSuper(nd.toString());
- } else {
- if (!(cn.getSymbol().equals(TypeUtil.ObjectClass)||
- cn.getSymbol().equals(TypeUtil.TagClass)))
- cn.setSuper(TypeUtil.ObjectClass);
- }
- cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
- parseClassBody(cn, pn.getChild("classbody"));
- return cn;
- }
-
- private void parseClassBody(ClassDescriptor cn, ParseNode pn) {
- ParseNode decls=pn.getChild("class_body_declaration_list");
- if (decls!=null) {
- ParseNodeVector pnv=decls.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode decl=pnv.elementAt(i);
- if (isNode(decl,"member")) {
- parseClassMember(cn,decl);
- } else if (isNode(decl,"constructor")) {
- parseConstructorDecl(cn,decl.getChild("constructor_declaration"));
- } else if (isNode(decl,"block")) {
- } else throw new Error();
- }
- }
- }
-
- private void parseClassMember(ClassDescriptor cn, ParseNode pn) {
- ParseNode fieldnode=pn.getChild("field");
-
- if (fieldnode!=null) {
- parseFieldDecl(cn,fieldnode.getChild("field_declaration"));
- return;
- }
- ParseNode methodnode=pn.getChild("method");
- if (methodnode!=null) {
- parseMethodDecl(cn,methodnode.getChild("method_declaration"));
- return;
- }
- ParseNode flagnode=pn.getChild("flag");
- if (flagnode!=null) {
- parseFlagDecl(cn, flagnode.getChild("flag_declaration"));
- return;
- }
- throw new Error();
- }
-
- private TypeDescriptor parseTypeDescriptor(ParseNode pn) {
- ParseNode tn=pn.getChild("type");
-
- String type_st=tn.getTerminal();
- if(type_st.equals("byte")) {
- return state.getTypeDescriptor(TypeDescriptor.BYTE);
- } else if(type_st.equals("short")) {
- return state.getTypeDescriptor(TypeDescriptor.SHORT);
- } else if(type_st.equals("boolean")) {
- return state.getTypeDescriptor(TypeDescriptor.BOOLEAN);
- } else if(type_st.equals("int")) {
- return state.getTypeDescriptor(TypeDescriptor.INT);
- } else if(type_st.equals("long")) {
- return state.getTypeDescriptor(TypeDescriptor.LONG);
- } else if(type_st.equals("char")) {
- return state.getTypeDescriptor(TypeDescriptor.CHAR);
- } else if(type_st.equals("float")) {
- return state.getTypeDescriptor(TypeDescriptor.FLOAT);
- } else if(type_st.equals("double")) {
- return state.getTypeDescriptor(TypeDescriptor.DOUBLE);
- } else if(type_st.equals("class")) {
- ParseNode nn=tn.getChild("class");
- return state.getTypeDescriptor(parseName(nn.getChild("name")));
- } else if(type_st.equals("array")) {
- ParseNode nn=tn.getChild("array");
- TypeDescriptor td=parseTypeDescriptor(nn.getChild("basetype"));
- Integer numdims=(Integer)nn.getChild("dims").getLiteral();
- for(int i=0;i<numdims.intValue();i++)
- td=td.makeArray(state);
- return td;
- } else {
- throw new Error();
- }
- }
-
- private NameDescriptor parseName(ParseNode nn) {
- ParseNode base=nn.getChild("base");
- ParseNode id=nn.getChild("identifier");
- if (base==null)
- return new NameDescriptor(id.getTerminal());
- return new NameDescriptor(parseName(base.getChild("name")),id.getTerminal());
-
- }
-
- private void parseFlagDecl(ClassDescriptor cn,ParseNode pn) {
- String name=pn.getChild("name").getTerminal();
- FlagDescriptor flag=new FlagDescriptor(name);
- if (pn.getChild("external")!=null)
- flag.makeExternal();
- cn.addFlag(flag);
- }
-
- private void parseFieldDecl(ClassDescriptor cn,ParseNode pn) {
- ParseNode mn=pn.getChild("modifier");
- Modifiers m=parseModifiersList(mn);
-
- ParseNode tn=pn.getChild("type");
- TypeDescriptor t=parseTypeDescriptor(tn);
- ParseNode vn=pn.getChild("variables").getChild("variable_declarators_list");
- ParseNodeVector pnv=vn.getChildren();
- boolean isglobal=pn.getChild("global")!=null;
-
- for(int i=0;i<pnv.size();i++) {
- ParseNode vardecl=pnv.elementAt(i);
- ParseNode tmp=vardecl;
- TypeDescriptor arrayt=t;
- while (tmp.getChild("single")==null) {
- arrayt=arrayt.makeArray(state);
- tmp=tmp.getChild("array");
- }
- String identifier=tmp.getChild("single").getTerminal();
- ParseNode epn=vardecl.getChild("initializer");
-
- ExpressionNode en=null;
- if (epn!=null)
- en=parseExpression(epn.getFirstChild());
-
- cn.addField(new FieldDescriptor(m, arrayt, identifier, en, isglobal));
- }
- }
-
- private ExpressionNode parseExpression(ParseNode pn) {
- if (isNode(pn,"assignment"))
- return parseAssignmentExpression(pn);
- else if (isNode(pn,"logical_or")||isNode(pn,"logical_and")||
- isNode(pn,"bitwise_or")||isNode(pn,"bitwise_xor")||
- isNode(pn,"bitwise_and")||isNode(pn,"equal")||
- isNode(pn,"not_equal")||isNode(pn,"comp_lt")||
- isNode(pn,"comp_lte")||isNode(pn,"comp_gt")||
- isNode(pn,"comp_gte")||isNode(pn,"leftshift")||
- isNode(pn,"rightshift")||isNode(pn,"sub")||
- isNode(pn,"add")||isNode(pn,"mult")||
- isNode(pn,"div")||isNode(pn,"mod")) {
- ParseNodeVector pnv=pn.getChildren();
- ParseNode left=pnv.elementAt(0);
- ParseNode right=pnv.elementAt(1);
- Operation op=new Operation(pn.getLabel());
- return new OpNode(parseExpression(left),parseExpression(right),op);
- } else if (isNode(pn,"unaryplus")||
- isNode(pn,"unaryminus")||
- isNode(pn,"not")) {
- ParseNode left=pn.getFirstChild();
- Operation op=new Operation(pn.getLabel());
- return new OpNode(parseExpression(left),op);
- } else if (isNode(pn,"postinc")||
- isNode(pn,"postdec")) {
- ParseNode left=pn.getFirstChild();
- AssignOperation op=new AssignOperation(pn.getLabel());
- return new AssignmentNode(parseExpression(left),null,op);
-
- } else if (isNode(pn,"preinc")||
- isNode(pn,"predec")) {
- ParseNode left=pn.getFirstChild();
- AssignOperation op=isNode(pn,"preinc")?new AssignOperation(AssignOperation.PLUSEQ):new AssignOperation(AssignOperation.MINUSEQ);
- return new AssignmentNode(parseExpression(left),
- new LiteralNode("integer",new Integer(1)),op);
- } else if (isNode(pn,"literal")) {
- String literaltype=pn.getTerminal();
- ParseNode literalnode=pn.getChild(literaltype);
- Object literal_obj=literalnode.getLiteral();
- return new LiteralNode(literaltype, literal_obj);
- } else if (isNode(pn,"createobject")) {
- TypeDescriptor td=parseTypeDescriptor(pn);
- Vector args=parseArgumentList(pn);
- boolean isglobal=pn.getChild("global")!=null;
- CreateObjectNode con=new CreateObjectNode(td, isglobal);
- for(int i=0;i<args.size();i++) {
- con.addArgument((ExpressionNode)args.get(i));
- }
- /* Could have flag set or tag added here */
- if (pn.getChild("flag_list")!=null||pn.getChild("tag_list")!=null) {
- FlagEffects fe=new FlagEffects(null);
- if (pn.getChild("flag_list")!=null)
- parseFlagEffect(fe, pn.getChild("flag_list"));
-
- if (pn.getChild("tag_list")!=null)
- parseTagEffect(fe, pn.getChild("tag_list"));
- con.addFlagEffects(fe);
- }
-
- return con;
- } else if (isNode(pn,"createarray")) {
- //System.out.println(pn.PPrint(3,true));
- boolean isglobal=pn.getChild("createarray")!=null;
- TypeDescriptor td=parseTypeDescriptor(pn);
- Vector args=parseDimExprs(pn);
- int num=0;
- if (pn.getChild("dims_opt").getLiteral()!=null)
- num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue();
- for(int i=0;i<(args.size()+num);i++)
- td=td.makeArray(state);
- CreateObjectNode con=new CreateObjectNode(td, isglobal);
- for(int i=0;i<args.size();i++) {
- con.addArgument((ExpressionNode)args.get(i));
- }
- return con;
- } else if (isNode(pn,"name")) {
- NameDescriptor nd=parseName(pn);
- return new NameNode(nd);
- } else if (isNode(pn,"this")) {
- NameDescriptor nd=new NameDescriptor("this");
- return new NameNode(nd);
- } else if (isNode(pn,"methodinvoke1")) {
- NameDescriptor nd=parseName(pn.getChild("name"));
- Vector args=parseArgumentList(pn);
- MethodInvokeNode min=new MethodInvokeNode(nd);
- for(int i=0;i<args.size();i++) {
- min.addArgument((ExpressionNode)args.get(i));
- }
- return min;
- } else if (isNode(pn,"methodinvoke2")) {
- String methodid=pn.getChild("id").getTerminal();
- ExpressionNode exp=parseExpression(pn.getChild("base").getFirstChild());
- Vector args=parseArgumentList(pn);
- MethodInvokeNode min=new MethodInvokeNode(methodid,exp);
- for(int i=0;i<args.size();i++) {
- min.addArgument((ExpressionNode)args.get(i));
- }
- return min;
- } else if (isNode(pn,"fieldaccess")) {
- ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild()); String fieldname=pn.getChild("field").getTerminal();
- return new FieldAccessNode(en,fieldname);
- } else if (isNode(pn,"arrayaccess")) {
- ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
- ExpressionNode index=parseExpression(pn.getChild("index").getFirstChild());
- return new ArrayAccessNode(en,index);
- } else if (isNode(pn,"cast1")) {
- return new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild()));
- } else if (isNode(pn,"cast2")) {
- return new CastNode(parseExpression(pn.getChild("type").getFirstChild()),parseExpression(pn.getChild("exp").getFirstChild()));
- } else {
- System.out.println("---------------------");
- System.out.println(pn.PPrint(3,true));
- throw new Error();
- }
- }
-
- private Vector parseDimExprs(ParseNode pn) {
- Vector arglist=new Vector();
- ParseNode an=pn.getChild("dim_exprs");
- if (an==null) /* No argument list */
- return arglist;
- ParseNodeVector anv=an.getChildren();
- for(int i=0;i<anv.size();i++) {
- arglist.add(parseExpression(anv.elementAt(i)));
- }
- return arglist;
- }
-
- private Vector parseArgumentList(ParseNode pn) {
- Vector arglist=new Vector();
- ParseNode an=pn.getChild("argument_list");
- if (an==null) /* No argument list */
- return arglist;
- ParseNodeVector anv=an.getChildren();
- for(int i=0;i<anv.size();i++) {
- arglist.add(parseExpression(anv.elementAt(i)));
- }
- return arglist;
- }
-
- private Vector[] parseConsArgumentList(ParseNode pn) {
- Vector arglist=new Vector();
- Vector varlist=new Vector();
- ParseNode an=pn.getChild("cons_argument_list");
- if (an==null) /* No argument list */
- return new Vector[] {varlist, arglist};
- ParseNodeVector anv=an.getChildren();
- for(int i=0;i<anv.size();i++) {
- ParseNode cpn=anv.elementAt(i);
- ParseNode var=cpn.getChild("var");
- ParseNode exp=cpn.getChild("exp").getFirstChild();
- varlist.add(var.getTerminal());
- arglist.add(parseExpression(exp));
- }
- return new Vector[] {varlist, arglist};
- }
-
- private ExpressionNode parseAssignmentExpression(ParseNode pn) {
- AssignOperation ao=new AssignOperation(pn.getChild("op").getTerminal());
- ParseNodeVector pnv=pn.getChild("args").getChildren();
-
- AssignmentNode an=new AssignmentNode(parseExpression(pnv.elementAt(0)),parseExpression(pnv.elementAt(1)),ao);
- return an;
- }
-
-
- private void parseMethodDecl(ClassDescriptor cn, ParseNode pn) {
- ParseNode headern=pn.getChild("method_header");
- ParseNode bodyn=pn.getChild("body");
- MethodDescriptor md=parseMethodHeader(headern);
- BlockNode bn=parseBlock(bodyn);
- cn.addMethod(md);
- state.addTreeCode(md,bn);
- }
-
- private void parseConstructorDecl(ClassDescriptor cn, ParseNode pn) {
- ParseNode mn=pn.getChild("modifiers");
- Modifiers m=parseModifiersList(mn);
- ParseNode cdecl=pn.getChild("constructor_declarator");
- boolean isglobal=cdecl.getChild("global")!=null;
- String name=cdecl.getChild("name").getChild("identifier").getTerminal();
- MethodDescriptor md=new MethodDescriptor(m, name, isglobal);
- ParseNode paramnode=cdecl.getChild("parameters");
- parseParameterList(md,paramnode);
- ParseNode bodyn0=pn.getChild("body");
- ParseNode bodyn=bodyn0.getChild("constructor_body");
- cn.addMethod(md);
- BlockNode bn=parseBlock(bodyn);
- state.addTreeCode(md,bn);
- }
-
- public BlockNode parseBlock(ParseNode pn) {
- if (pn==null||isEmpty(pn.getTerminal()))
- return new BlockNode();
- ParseNode bsn=pn.getChild("block_statement_list");
- return parseBlockHelper(bsn);
- }
-
- private BlockNode parseBlockHelper(ParseNode pn) {
- ParseNodeVector pnv=pn.getChildren();
- BlockNode bn=new BlockNode();
- for(int i=0;i<pnv.size();i++) {
- Vector bsv=parseBlockStatement(pnv.elementAt(i));
- for(int j=0;j<bsv.size();j++) {
- bn.addBlockStatement((BlockStatementNode)bsv.get(j));
- }
- }
- return bn;
- }
-
- public BlockNode parseSingleBlock(ParseNode pn) {
- BlockNode bn=new BlockNode();
- Vector bsv=parseBlockStatement(pn);
- for(int j=0;j<bsv.size();j++) {
- bn.addBlockStatement((BlockStatementNode)bsv.get(j));
- }
- bn.setStyle(BlockNode.NOBRACES);
- return bn;
- }
-
- public Vector parseBlockStatement(ParseNode pn) {
- Vector blockstatements=new Vector();
- if (isNode(pn,"tag_declaration")) {
- String name=pn.getChild("single").getTerminal();
- String type=pn.getChild("type").getTerminal();
-
- blockstatements.add(new TagDeclarationNode(name, type));
- } else if (isNode(pn,"local_variable_declaration")) {
- TypeDescriptor t=parseTypeDescriptor(pn);
- ParseNode vn=pn.getChild("variable_declarators_list");
- ParseNodeVector pnv=vn.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode vardecl=pnv.elementAt(i);
-
-
- ParseNode tmp=vardecl;
- TypeDescriptor arrayt=t;
- while (tmp.getChild("single")==null) {
- arrayt=arrayt.makeArray(state);
- tmp=tmp.getChild("array");
- }
- String identifier=tmp.getChild("single").getTerminal();
-
- ParseNode epn=vardecl.getChild("initializer");
-
-
- ExpressionNode en=null;
- if (epn!=null)
- en=parseExpression(epn.getFirstChild());
-
- blockstatements.add(new DeclarationNode(new VarDescriptor(arrayt, identifier),en));
- }
- } else if (isNode(pn,"nop")) {
- /* Do Nothing */
- } else if (isNode(pn,"expression")) {
- blockstatements.add(new BlockExpressionNode(parseExpression(pn.getFirstChild())));
- } else if (isNode(pn,"ifstatement")) {
- blockstatements.add(new IfStatementNode(parseExpression(pn.getChild("condition").getFirstChild()),
- parseSingleBlock(pn.getChild("statement").getFirstChild()),
- pn.getChild("else_statement")!=null?parseSingleBlock(pn.getChild("else_statement").getFirstChild()):null));
- } else if (isNode(pn,"taskexit")) {
- Vector vfe=null;
- if (pn.getChild("flag_effects_list")!=null)
- vfe=parseFlags(pn.getChild("flag_effects_list"));
- Vector ccs=null;
- if (pn.getChild("cons_checks")!=null)
- ccs=parseChecks(pn.getChild("cons_checks"));
-
- blockstatements.add(new TaskExitNode(vfe, ccs));
- } else if (isNode(pn,"atomic")) {
- BlockNode bn=parseBlockHelper(pn);
- blockstatements.add(new AtomicNode(bn));
- } else if (isNode(pn,"return")) {
- if (isEmpty(pn.getTerminal()))
- blockstatements.add(new ReturnNode());
- else {
- ExpressionNode en=parseExpression(pn.getFirstChild());
- blockstatements.add(new ReturnNode(en));
- }
- } else if (isNode(pn,"block_statement_list")) {
- BlockNode bn=parseBlockHelper(pn);
- blockstatements.add(new SubBlockNode(bn));
- } else if (isNode(pn,"empty")) {
- /* nop */
- } else if (isNode(pn,"statement_expression_list")) {
- ParseNodeVector pnv=pn.getChildren();
- BlockNode bn=new BlockNode();
- for(int i=0;i<pnv.size();i++) {
- ExpressionNode en=parseExpression(pnv.elementAt(i));
- blockstatements.add(new BlockExpressionNode(en));
- }
- bn.setStyle(BlockNode.EXPRLIST);
- } else if (isNode(pn,"forstatement")) {
- BlockNode init=parseSingleBlock(pn.getChild("initializer").getFirstChild());
- BlockNode update=parseSingleBlock(pn.getChild("update").getFirstChild());
- ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
- BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
- blockstatements.add(new LoopNode(init,condition,update,body));
- } else if (isNode(pn,"whilestatement")) {
- ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
- BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
- blockstatements.add(new LoopNode(condition,body,LoopNode.WHILELOOP));
- } else if (isNode(pn,"dowhilestatement")) {
- ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
- BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
- blockstatements.add(new LoopNode(condition,body,LoopNode.DOWHILELOOP));
- } else {
- System.out.println("---------------");
- System.out.println(pn.PPrint(3,true));
- throw new Error();
- }
- return blockstatements;
- }
-
- public MethodDescriptor parseMethodHeader(ParseNode pn) {
- ParseNode mn=pn.getChild("modifiers");
- Modifiers m=parseModifiersList(mn);
-
- ParseNode tn=pn.getChild("returntype");
- TypeDescriptor returntype;
- if (tn!=null)
- returntype=parseTypeDescriptor(tn);
- else
- returntype=new TypeDescriptor(TypeDescriptor.VOID);
-
- ParseNode pmd=pn.getChild("method_declarator");
- String name=pmd.getChild("name").getTerminal();
- MethodDescriptor md=new MethodDescriptor(m, returntype, name);
-
- ParseNode paramnode=pmd.getChild("parameters");
- parseParameterList(md,paramnode);
- return md;
- }
-
- public void parseParameterList(MethodDescriptor md, ParseNode pn) {
- ParseNode paramlist=pn.getChild("formal_parameter_list");
- if (paramlist==null)
- return;
- ParseNodeVector pnv=paramlist.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode paramn=pnv.elementAt(i);
-
- if (isNode(paramn, "tag_parameter")) {
- String paramname=paramn.getChild("single").getTerminal();
- TypeDescriptor type=new TypeDescriptor(TypeDescriptor.TAG);
- md.addTagParameter(type, paramname);
- } else {
- TypeDescriptor type=parseTypeDescriptor(paramn);
-
- ParseNode tmp=paramn;
- while (tmp.getChild("single")==null) {
- type=type.makeArray(state);
- tmp=tmp.getChild("array");
- }
- String paramname=tmp.getChild("single").getTerminal();
-
- md.addParameter(type, paramname);
- }
- }
- }
-
- public Modifiers parseModifiersList(ParseNode pn) {
- Modifiers m=new Modifiers();
- ParseNode modlist=pn.getChild("modifier_list");
- if (modlist!=null) {
- ParseNodeVector pnv=modlist.getChildren();
- for(int i=0;i<pnv.size();i++) {
- ParseNode modn=pnv.elementAt(i);
- if (isNode(modn,"public"))
- m.addModifier(Modifiers.PUBLIC);
- else if (isNode(modn,"protected"))
- m.addModifier(Modifiers.PROTECTED);
- else if (isNode(modn,"private"))
- m.addModifier(Modifiers.PRIVATE);
- else if (isNode(modn,"static"))
- m.addModifier(Modifiers.STATIC);
- else if (isNode(modn,"final"))
- m.addModifier(Modifiers.FINAL);
- else if (isNode(modn,"native"))
- m.addModifier(Modifiers.NATIVE);
- else if (isNode(modn,"synchronized"))
- m.addModifier(Modifiers.SYNCHRONIZED);
- else if (isNode(modn,"atomic"))
- m.addModifier(Modifiers.ATOMIC);
- else throw new Error("Unrecognized Modifier");
- }
- }
- return m;
- }
-
- private boolean isNode(ParseNode pn, String label) {
- if (pn.getLabel().equals(label))
- return true;
- else return false;
- }
-
- private static boolean isEmpty(ParseNode pn) {
- if (pn.getLabel().equals("empty"))
- return true;
- else
- return false;
- }
-
- private static boolean isEmpty(String s) {
- if (s.equals("empty"))
- return true;
- else
- return false;
- }
-
- /** Throw an exception if something is unexpected */
- private void check(ParseNode pn, String label) {
- if (pn == null) {
- throw new Error(pn+ "IE: Expected '" + label + "', got null");
- }
- if (! pn.getLabel().equals(label)) {
- throw new Error(pn+ "IE: Expected '" + label + "', got '"+pn.getLabel()+"'");
- }
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.TypeDescriptor;
-
-public class CastNode extends ExpressionNode {
- TypeDescriptor td;
- ExpressionNode etd;
- ExpressionNode exp;
-
- public CastNode(TypeDescriptor type, ExpressionNode exp) {
- this.td=type;
- this.exp=exp;
- this.etd=null;
- }
-
- public CastNode(ExpressionNode type, ExpressionNode exp) {
- this.td=null;
- this.exp=exp;
- this.etd=type;
- }
-
- public TypeDescriptor getType() {
- return td;
- }
-
- public ExpressionNode getExpression() {
- return exp;
- }
-
- public void setType(TypeDescriptor td) {
- this.td=td;
- }
-
- public NameNode getTypeName() {
- return (NameNode) etd;
- }
-
- public String printNode(int indentlevel) {
- if (etd==null)
- return "("+td.toString()+")"+exp.printNode(indentlevel);
- else
- return "("+etd.printNode(indentlevel)+")"+exp.printNode(indentlevel);
- }
-
- public int kind() {
- return Kind.CastNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-import IR.*;
-import java.util.Vector;
-
-public class ConstraintCheck {
- String specname;
- Vector args;
- Vector vars;
-
- public ConstraintCheck(String specname) {
- this.specname=specname;
- args=new Vector();
- vars=new Vector();
- }
-
- public void addVariable(String var) {
- vars.add(var);
- }
-
- public void addArgument(ExpressionNode en) {
- args.add(en);
- }
-
- public String getSpec() {
- return specname;
- }
-
- public int numArgs() {
- return args.size();
- }
-
- public ExpressionNode getArg(int i) {
- return (ExpressionNode) args.get(i);
- }
-
- public String getVar(int i) {
- return (String) vars.get(i);
- }
-
- public String printNode(int indent) {
- String str="assert("+specname+"(";
- for(int i=0;i<numArgs();i++) {
- if (i>0)
- str+=",";
- str+=getVar(i)+" : ";
- str+=getArg(i).printNode(0);
- }
- return str+")";
- }
-}
+++ /dev/null
-package IR.Tree;
-import java.util.Vector;
-import IR.TypeDescriptor;
-import IR.MethodDescriptor;
-
-public class CreateObjectNode extends ExpressionNode {
- TypeDescriptor td;
- Vector argumentlist;
- MethodDescriptor md;
- FlagEffects fe;
- boolean isglobal;
-
- public CreateObjectNode(TypeDescriptor type, boolean isglobal) {
- td=type;
- argumentlist=new Vector();
- this.isglobal=isglobal;
- }
-
- public boolean isGlobal() {
- return isglobal;
- }
-
- public void addFlagEffects(FlagEffects fe) {
- this.fe=fe;
- }
-
- public FlagEffects getFlagEffects() {
- return fe;
- }
-
- public void addArgument(ExpressionNode en) {
- argumentlist.add(en);
- }
-
- public void setConstructor(MethodDescriptor md) {
- this.md=md;
- }
-
- public MethodDescriptor getConstructor() {
- return md;
- }
-
- public TypeDescriptor getType() {
- return td;
- }
-
- public int numArgs() {
- return argumentlist.size();
- }
-
- public ExpressionNode getArg(int i) {
- return (ExpressionNode) argumentlist.get(i);
- }
-
- public String printNode(int indent) {
- String st;
- boolean isarray=td.isArray();
- if (isarray)
- st="new "+td.toString()+"[";
- else
- st="new "+td.toString()+"(";
- for(int i=0;i<argumentlist.size();i++) {
- ExpressionNode en=(ExpressionNode)argumentlist.get(i);
- st+=en.printNode(indent);
- if ((i+1)!=argumentlist.size()) {
- if (isarray)
- st+="][";
- else
- st+=", ";
- }
- }
- if (isarray)
- return st+"]";
- else
- return st+")";
- }
-
- public int kind() {
- return Kind.CreateObjectNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-import java.util.Vector;
-import IR.*;
-
-public class DNFFlag {
- private Vector conjunctions;
- public DNFFlag(FlagNode flag) {
- DNFFlagAtom dfa=new DNFFlagAtom(flag, false);
- conjunctions=new Vector();
- Vector conjunct=new Vector();
- conjunct.add(dfa);
- conjunctions.add(conjunct);
- }
- private DNFFlag() {
- conjunctions=new Vector();
- }
-
- /** Returns the number of conjunctions in the DNF form. */
-
- public int size() {
- return conjunctions.size();
- }
-
- /** Returns a Vector containing the terms in the n'th conjunction. */
-
- public Vector get(int n) {
- return (Vector) conjunctions.get(n);
- }
-
- /** This method negates a DNFFlag expression. */
-
- public DNFFlag not() {
- DNFFlag notflag=null;
- for (int i=0;i<conjunctions.size();i++) {
- Vector conj=(Vector)conjunctions.get(i);
- DNFFlag newflag=null;
- for (int j=0;j<conj.size();j++) {
- DNFFlagAtom dfa=(DNFFlagAtom) conj.get(j);
- DNFFlagAtom negdfa=new DNFFlagAtom(dfa.getFlagNode(),!dfa.getNegated());
- DNFFlag tmp=new DNFFlag();
- Vector v=new Vector();
- tmp.conjunctions.add(v);
- v.add(negdfa);
-
- if (newflag==null)
- newflag=tmp;
- else
- newflag=newflag.or(tmp);
- }
- if (notflag==null)
- notflag=newflag;
- else
- notflag=notflag.and(newflag);
- }
- return notflag;
- }
-
- /** This method or's two DNFFlag expressions together. */
- public DNFFlag or(DNFFlag dnf2) {
- DNFFlag result=new DNFFlag();
- for(int i=0;i<conjunctions.size();i++) {
- Vector conjunct=(Vector)conjunctions.get(i);
- Vector newvector=new Vector();
- result.conjunctions.add(newvector);
- for(int j=0;j<conjunct.size();j++) {
- newvector.add(conjunct.get(j));
- }
- }
-
- for(int i=0;i<dnf2.conjunctions.size();i++) {
- Vector conjunct=(Vector)dnf2.conjunctions.get(i);
- Vector newvector=new Vector();
- result.conjunctions.add(newvector);
- for(int j=0;j<conjunct.size();j++) {
- newvector.add(conjunct.get(j));
- }
- }
- return result;
- }
-
- /** This method and's two DNFFlag expressions together. */
- public DNFFlag and(DNFFlag dnf2) {
- DNFFlag result=new DNFFlag();
- for(int i=0;i<conjunctions.size();i++) {
- for(int i2=0;i2<dnf2.conjunctions.size();i2++) {
- Vector conjunct=(Vector)conjunctions.get(i);
- Vector conjunct2=(Vector)dnf2.conjunctions.get(i2);
- Vector newconjunct=new Vector();
- result.conjunctions.add(newconjunct);
- for(int j=0;j<conjunct.size();j++) {
- newconjunct.add(conjunct.get(j));
- }
- for(int j2=0;j2<conjunct2.size();j2++) {
- newconjunct.add(conjunct2.get(j2));
- }
- }
- }
- return result;
- }
-
- public String toString() {
- String value="";
- for(int i=0;i<conjunctions.size();i++) {
- if (i!=0)
- value+=" || ";
- Vector conjunct=(Vector)conjunctions.get(i);
- for(int j=0;j<conjunct.size();j++) {
- if (j!=0)
- value+="&&";
- value+=conjunct.get(j);
- }
- }
- return value;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-import IR.*;
-
-public class DNFFlagAtom {
- private final FlagNode flag;
- private final boolean negated;
-
- public DNFFlagAtom(FlagNode flag, boolean negated) {
- this.flag=flag;
- this.negated=negated;
- }
-
- public FlagNode getFlagNode() {
- return flag;
- }
-
- public FlagDescriptor getFlag() {
- return flag.getFlag();
- }
-
- public boolean getNegated() {
- return negated;
- }
-
- public String toString() {
- if (negated)
- return "!"+flag.toString();
- else
- return flag.toString();
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.VarDescriptor;
-
-public class DeclarationNode extends BlockStatementNode {
- VarDescriptor vd;
- ExpressionNode init_en;
- public DeclarationNode(VarDescriptor var, ExpressionNode en) {
- vd=var;
- init_en=en;
- }
-
- public String printNode(int indent) {
- if (init_en==null)
- return vd.toString();
- else return vd.toString()+"="+init_en.printNode(0);
- }
-
- public ExpressionNode getExpression() {
- return init_en;
- }
-
- public VarDescriptor getVarDescriptor() {
- return vd;
- }
-
- public int kind() {
- return Kind.DeclarationNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.TypeDescriptor;
-
-public class ExpressionNode extends TreeNode {
- public TypeDescriptor getType() {
- throw new Error();
- }
-
- public String printNode(int indentlevel) {
- return null;
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.FieldDescriptor;
-import IR.TypeDescriptor;
-
-public class FieldAccessNode extends ExpressionNode {
- ExpressionNode left;
- String fieldname;
- FieldDescriptor field;
-
- public FieldAccessNode(ExpressionNode l, String field) {
- fieldname=field;
- left=l;
- }
-
- public void setField(FieldDescriptor fd) {
- field=fd;
- }
-
- public String getFieldName() {
- return fieldname;
- }
-
- public FieldDescriptor getField() {
- return field;
- }
-
- public ExpressionNode getExpression() {
- return left;
- }
-
- public String printNode(int indent) {
- return left.printNode(indent)+"."+fieldname;
- }
- public int kind() {
- return Kind.FieldAccessNode;
- }
- public TypeDescriptor getType() {
- return getField().getType();
- }
-
-}
+++ /dev/null
-package IR.Tree;
-
-import IR.*;
-
-public class FlagEffect {
- FlagDescriptor flag;
- boolean status;
- String name;
-
- public FlagEffect(String flag, boolean status) {
- this.name=flag;
- this.status=status;
- }
-
- public void setFlag(FlagDescriptor flag) {
- this.flag=flag;
- }
-
- public FlagDescriptor getFlag() {
- return flag;
- }
-
- public String getName() {
- return name;
- }
-
- public boolean getStatus() {
- return status;
- }
-
- public String printNode(int indent) {
- if (status)
- return name;
- else
- return "!"+name;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-import IR.*;
-import java.util.*;
-
-public class FlagEffects {
- Vector effects;
- Vector tageffects;
- String name;
- VarDescriptor vd;
-
- public FlagEffects(String name) {
- effects=new Vector();
- tageffects=new Vector();
- this.name=name;
- }
-
- public void setVar(VarDescriptor vd) {
- this.vd=vd;
- }
-
- public VarDescriptor getVar() {
- return vd;
- }
-
- public String getName() {
- return name;
- }
-
- public void addEffect(FlagEffect fe) {
- effects.add(fe);
- }
-
- public void addTagEffect(TagEffect te) {
- tageffects.add(te);
- }
-
- public int numTagEffects() {
- return tageffects.size();
- }
-
- public TagEffect getTagEffect(int i) {
- return (TagEffect) tageffects.get(i);
- }
-
- public int numEffects() {
- return effects.size();
- }
-
- public FlagEffect getEffect(int i) {
- return (FlagEffect) effects.get(i);
- }
-
- public String printNode(int indent) {
- String st=name+"(";
- for(int i=0;i<effects.size();i++) {
- FlagEffect fe=(FlagEffect)effects.get(i);
- st+=fe.printNode(0);
- if ((i+1)!=effects.size())
- st+=",";
- }
- return st+")";
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.TypeDescriptor;
-
-public class FlagExpressionNode extends TreeNode {
- public String printNode(int indentlevel) {
- return null;
- }
-
- public DNFFlag getDNF() {
- throw new Error();
- }
-}
+++ /dev/null
-package IR.Tree;
-import java.util.Vector;
-
-import IR.*;
-
-public class FlagNode extends FlagExpressionNode {
- FlagDescriptor flag;
- String name;
-
- public FlagNode(String flag) {
- this.name=flag;
- }
-
- public void setFlag(FlagDescriptor flag) {
- this.flag=flag;
- }
-
- public FlagDescriptor getFlag() {
- return flag;
- }
-
- public String getFlagName() {
- return name;
- }
-
- public int kind() {
- return Kind.FlagNode;
- }
-
- public String printNode(int indent) {
- return name;
- }
-
- public DNFFlag getDNF() {
- return new DNFFlag(this);
- }
-
- public String toString() {
- return name;
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.Operation;
-
-public class FlagOpNode extends FlagExpressionNode {
- FlagExpressionNode left;
- FlagExpressionNode right;
- Operation op;
-
- public FlagOpNode(FlagExpressionNode l, FlagExpressionNode r, Operation o) {
- left=l;
- right=r;
- op=o;
- }
-
- public FlagOpNode(FlagExpressionNode l, Operation o) {
- left=l;
- right=null;
- op=o;
- }
-
- public FlagExpressionNode getLeft() {
- return left;
- }
-
- public FlagExpressionNode getRight() {
- return right;
- }
-
- public Operation getOp() {
- return op;
- }
-
- public String printNode(int indent) {
- if (right==null)
- return op.toString()+"("+left.printNode(indent)+")";
- else
- return left.printNode(indent)+" "+op.toString()+" "+right.printNode(indent);
- }
-
- public int kind() {
- return Kind.FlagOpNode;
- }
-
- public DNFFlag getDNF() {
- DNFFlag leftflag=left.getDNF();
- DNFFlag rightflag=right!=null?right.getDNF():null;
-
- if (op.getOp()==Operation.LOGIC_NOT) {
- return leftflag.not();
- } else if (op.getOp()==Operation.LOGIC_OR) {
- return leftflag.or(rightflag);
- } else if (op.getOp()==Operation.LOGIC_AND) {
- return leftflag.and(rightflag);
- } else throw new Error();
- }
-}
+++ /dev/null
-package IR.Tree;
-
-public class IfStatementNode extends BlockStatementNode {
- ExpressionNode cond;
- BlockNode true_st;
- BlockNode else_st;
-
- public IfStatementNode(ExpressionNode cond, BlockNode true_st, BlockNode else_st) {
- this.cond=cond;
- this.true_st=true_st;
- this.else_st=else_st;
- }
-
- public ExpressionNode getCondition() {
- return cond;
- }
-
- public BlockNode getTrueBlock() {
- return true_st;
- }
-
- public BlockNode getFalseBlock() {
- return else_st;
- }
-
- public String printNode(int indent) {
- if (else_st==null)
- return "if("+cond.printNode(indent)+") "+true_st.printNode(indent);
- else
- return "if("+cond.printNode(indent)+") "+true_st.printNode(indent)+" else "+ else_st.printNode(indent);
- }
- public int kind() {
- return Kind.IfStatementNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-public class Kind {
- public final static int AssignmentNode=1;
- public final static int OpNode=2;
- public final static int BlockExpressionNode=3;
- public final static int FieldAccessNode=4;
- public final static int BlockNode=5;
- public final static int IfStatementNode=6;
- public final static int ReturnNode=7;
- public final static int LiteralNode=8;
- public final static int SubBlockNode=9;
- public final static int CastNode=10;
- public final static int LoopNode=11;
- public final static int CreateObjectNode=12;
- public final static int MethodInvokeNode=13;
- public final static int DeclarationNode=14;
- public final static int NameNode=15;
- public final static int ArrayAccessNode=16;
- public final static int FlagNode=17;
- public final static int FlagOpNode=18;
- public final static int TaskExitNode=19;
- public final static int TagDeclarationNode=20;
- public final static int AtomicNode=21;
-}
+++ /dev/null
-package IR.Tree;
-import IR.TypeDescriptor;
-import IR.TypeUtil;
-
-
-public class LiteralNode extends ExpressionNode {
- public final static int INTEGER=1;
- public final static int FLOAT=2;
- public final static int BOOLEAN=3;
- public final static int CHAR=4;
- public final static int STRING=5;
- public final static int NULL=6;
-
- Object value;
- TypeDescriptor type;
- String typestr;
-
- public LiteralNode(String type, Object o) {
- typestr=type;
- value=o;
- type=null;
- }
-
- public String getTypeString() {
- return typestr;
- }
-
- public TypeDescriptor getType() {
- return type;
- }
-
- public void setType(TypeDescriptor td) {
- type=td;
- }
-
- public Object getValue() {
- return value;
- }
-
- public String printNode(int indent) {
- if (typestr.equals("null"))
- return "null";
- if (typestr.equals("string")) {
- return '"'+escapeString(value.toString())+'"';
- }
- return "/*"+typestr+ "*/"+value.toString();
- }
- private static String escapeString(String st) {
- String new_st="";
- for(int i=0;i<st.length();i++) {
- char x=st.charAt(i);
- if (x=='\n')
- new_st+="\\n";
- else if (x=='"')
- new_st+="'"+'"'+"'";
- else new_st+=x;
- }
- return new_st;
- }
- public int kind() {
- return Kind.LiteralNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-public class LoopNode extends BlockStatementNode {
- BlockNode initializer;
- ExpressionNode condition;
- BlockNode update;
- BlockNode body;
- int type=0;
- public static int FORLOOP=1;
- public static int WHILELOOP=2;
- public static int DOWHILELOOP=3;
-
- public LoopNode(BlockNode initializer,ExpressionNode condition, BlockNode update, BlockNode body) {
- this.initializer=initializer;
- this.condition=condition;
- this.update=update;
- this.body=body;
- initializer.setStyle(BlockNode.EXPRLIST);
- update.setStyle(BlockNode.EXPRLIST);
- type=FORLOOP;
- }
-
- public LoopNode(ExpressionNode condition, BlockNode body, int type) {
- this.condition=condition;
- this.body=body;
- this.type=type;
- }
-
- public BlockNode getInitializer() {
- return initializer;
- }
-
- public ExpressionNode getCondition() {
- return condition;
- }
-
- public BlockNode getUpdate() {
- return update;
- }
-
- public BlockNode getBody() {
- return body;
- }
-
- public String printNode(int indent) {
- if (type==FORLOOP) {
- return "for("+initializer.printNode(0)+";"+condition.printNode(0)+
- ";"+update.printNode(0)+") "+body.printNode(indent)+"\n";
- } else if (type==WHILELOOP) {
- return "while("+condition.printNode(0)+") "+body.printNode(indent+INDENT)+"\n";
- } else if (type==DOWHILELOOP) {
- return "do "+ body.printNode(indent+INDENT)+
- "while("+condition.printNode(0)+")\n";
- } else throw new Error();
- }
-
- public int getType() {
- return type;
- }
-
- public int kind() {
- return Kind.LoopNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-import java.util.Vector;
-import IR.NameDescriptor;
-import IR.MethodDescriptor;
-import IR.TypeDescriptor;
-
-public class MethodInvokeNode extends ExpressionNode {
- Vector argumentlist;
- String methodid;
- NameDescriptor basename;
- ExpressionNode en;
- MethodDescriptor md;
-
- public MethodInvokeNode(NameDescriptor name) {
- methodid=name.getIdentifier();
- if (name.getBase()!=null) {
- basename=name.getBase();
- }
- argumentlist=new Vector();
- en=null;
- md=null;
- }
-
- public MethodInvokeNode(String methodid, ExpressionNode exp) {
- this.methodid=methodid;
- this.en=exp;
- argumentlist=new Vector();
- md=null;
- this.basename=null;
- }
-
- public NameDescriptor getBaseName() {
- return basename;
- }
-
- public String getMethodName() {
- return methodid;
- }
-
- public ExpressionNode getExpression() {
- return en;
- }
-
- public TypeDescriptor getType() {
- return md.getReturnType();
- }
-
- public void setExpression(ExpressionNode en) {
- this.en=en;
- }
-
- public void setMethod(MethodDescriptor md) {
- this.md=md;
- }
-
- public MethodDescriptor getMethod() {
- return md;
- }
-
- public void addArgument(ExpressionNode en) {
- argumentlist.add(en);
- }
-
- public int numArgs() {
- return argumentlist.size();
- }
-
- public ExpressionNode getArg(int i) {
- return (ExpressionNode) argumentlist.get(i);
- }
-
- public String printNode(int indent) {
- String st;
- if (en!=null)
- st=en.printNode(indent)+"."+methodid+"(";
- else
- st=methodid+"(";
-
- for(int i=0;i<argumentlist.size();i++) {
- ExpressionNode en=(ExpressionNode)argumentlist.get(i);
- st+=en.printNode(indent);
- if ((i+1)!=argumentlist.size())
- st+=", ";
- }
- return st+")";
- }
- public int kind() {
- return Kind.MethodInvokeNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-public class Modifiers {
- public static final int PUBLIC=1;
- public static final int PROTECTED=2;
- public static final int PRIVATE=4;
- public static final int STATIC=8;
-// ABSTRACT=16
- public static final int FINAL=32;
- public static final int NATIVE=64;
- public static final int SYNCHRONIZED=128;
- public static final int ATOMIC=2048;
-// TRANSIENT=256
-// VOLATILE=512
-// STRICTFP=1024
-
- private int value;
-
- public Modifiers() {
- value=0;
- }
-
- public Modifiers(int v) {
- value=v;
- }
-
- public void addModifier(int mod) {
- value|=mod;
- if (isSynchronized()&&isNative())
- throw new Error("Synchronized native methods are not supported");
- }
-
- public boolean isAtomic() {
- return ((value&ATOMIC)!=0);
- }
-
- public boolean isSynchronized() {
- return ((value&SYNCHRONIZED)!=0);
- }
-
- public boolean isStatic() {
- return ((value&STATIC)!=0);
- }
-
- public boolean isNative() {
- return ((value&NATIVE)!=0);
- }
-
- public String toString() {
- String st="";
- if ((value&PUBLIC)!=0)
- st+="public ";
- if ((value&PROTECTED)!=0)
- st+="protected ";
- if ((value&PRIVATE)!=0)
- st+="private ";
- if ((value&STATIC)!=0)
- st+="static ";
- if ((value&FINAL)!=0)
- st+="final ";
- if ((value&NATIVE)!=0)
- st+="native ";
- if ((value&SYNCHRONIZED)!=0)
- st+="synchronized ";
- if ((value&ATOMIC)!=0)
- st+="atomic ";
- return st;
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.NameDescriptor;
-import IR.Descriptor;
-import IR.VarDescriptor;
-import IR.TagVarDescriptor;
-import IR.TypeDescriptor;
-import IR.FieldDescriptor;
-
-public class NameNode extends ExpressionNode {
- NameDescriptor name;
- Descriptor vd;
- FieldDescriptor fd;
- ExpressionNode en;
-
- public NameNode(NameDescriptor nd) {
- this.name=nd;
- this.vd=null;
- this.fd=null;
- }
-
- public ExpressionNode getExpression() {
- return en;
- }
-
- /* Gross hack */
- public void setExpression(ExpressionNode en) {
- this.en=en;
- }
-
- public void setVar(Descriptor vd) {
- this.vd=vd;
- }
-
- public void setField(FieldDescriptor fd) {
- this.fd=fd;
- }
-
- public FieldDescriptor getField() {
- return fd;
- }
-
- public boolean isTag() {
- return (vd instanceof TagVarDescriptor);
- }
-
- public VarDescriptor getVar() {
- return (VarDescriptor) vd;
- }
-
- public TagVarDescriptor getTagVar() {
- return (TagVarDescriptor) vd;
- }
-
- public TypeDescriptor getType() {
- if (en!=null)
- return en.getType();
- else if (fd!=null)
- return fd.getType();
- else if (isTag())
- return new TypeDescriptor(TypeDescriptor.TAG);
- else
- return ((VarDescriptor)vd).getType();
- }
-
- NameDescriptor getName() {
- return name;
- }
-
- public String printNode(int indent) {
- return name.toString();
- }
-
- public int kind() {
- return Kind.NameNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.Operation;
-import IR.TypeDescriptor;
-
-public class OpNode extends ExpressionNode {
- ExpressionNode left;
- ExpressionNode right;
- Operation op;
- TypeDescriptor td;
- TypeDescriptor lefttype;
- TypeDescriptor righttype;
-
- public OpNode(ExpressionNode l, ExpressionNode r, Operation o) {
- left=l;
- right=r;
- op=o;
- }
-
- public OpNode(ExpressionNode l, Operation o) {
- left=l;
- right=null;
- op=o;
- }
-
- public ExpressionNode getLeft() {
- return left;
- }
-
- public ExpressionNode getRight() {
- return right;
- }
-
- public Operation getOp() {
- return op;
- }
-
- public String printNode(int indent) {
- if (right==null)
- return op.toString()+"("+left.printNode(indent)+")";
- else
- return left.printNode(indent)+" "+op.toString()+" "+right.printNode(indent);
- }
-
- public void setLeftType(TypeDescriptor argtype) {
- this.lefttype=argtype;
- }
-
- public TypeDescriptor getLeftType() {
- return lefttype;
- }
-
- public void setRightType(TypeDescriptor argtype) {
- this.righttype=argtype;
- }
-
- public TypeDescriptor getRightType() {
- return righttype;
- }
-
- public TypeDescriptor getType() {
- return td;
- }
-
- public void setType(TypeDescriptor td) {
- this.td=td;
- }
-
- public int kind() {
- return Kind.OpNode;
- }
-}
+++ /dev/null
-/*
-
- Class: ParseNode
- Author: Dan Roy
- Purpose: ParseNode is used to represent a parse production
-
-*/
-
-package IR.Tree;
-
-import java.util.*;
-
-public class ParseNode implements Walkable {
-
- private String label;
- private ParseNode parent;
- private ParseNodeVector children;
- private int line;
- private Object literal;
-
- //private SymbolTable st;
-
- public ParseNode(String label) {
- this.label = label;
- this.line = -1;
- this.parent = null;
- this.literal=null;
- children = new ParseNodeVector();
- }
-
- public ParseNode ( String label, int line ) {
- this.label = label;
- this.line = line;
- this.parent = null;
- this.literal=null;
- children = new ParseNodeVector();
- }
-
- public void setLabel( String label ) {
- this.label = label;
- }
-
- public String getLabel() {
- return label;
- }
-
- public void setLiteral(Object o) {
- literal=o;
- }
-
- public Object getLiteral() {
- return literal;
- }
-
- /*
- public void setSymbolTable(SymbolTable st) {
- if (st == null) {
- throw new IRException("symboltable is null!");
- }
- this.st = st;
- }
-
- public SymbolTable getSymbolTable() {
- if (st == null) {
- if (parent != null) {
- return parent.getSymbolTable();
- } else {
- return null;
- }
- } else {
- return st;
- }
- }
- */
-
- public int getLine() {
- if (line >= 0) {
- return line;
- } else {
- if (parent != null) {
- return parent.getLine();
- } else {
- return 0;
- }
- }
- }
-
- public void setParent( ParseNode parent ) {
- this.parent = parent;
- }
-
- public ParseNode getParent() {
- return parent;
- }
-
- public ParseNode insertChild(ParseNode child) {
- if (child == null) {
- throw new NullPointerException("Can't add null node to parse tree");
- }
-
- children.insertElementAt(child, 0);
- child.setParent(this);
- return child;
- }
-
- public ParseNode insertChild(String newlabel) {
- ParseNode child = new ParseNode(newlabel, -1);
- return insertChild(child);
- }
-
- public ParseNode addChild( ParseNode child ) {
-
- if (child == null) {
- throw new NullPointerException("Can't add null node to parse tree: "+getLabel());
- }
-
- children.addElement (child);
- child.setParent(this);
- return child;
- }
-
- public ParseNode addChild( String newlabel ) {
-
- ParseNode child = new ParseNode(newlabel, -1);
- children.addElement(child);
- child.setParent(this);
- return child;
- }
-
- public ParseNode addChild (String newlabel, int line) {
- ParseNode child = new ParseNode(newlabel, line);
- children.addElement(child);
- child.setParent(this);
- return child;
- }
-
- public ParseNodeVector getChildren() {
- return children;
- }
-
- public ParseNode getChild (String label) {
- int i;
- ParseNode p;
-
- for (i = 0; i < children.size(); i++) {
- p = children.elementAt(i);
- if (p.getLabel().equals(label)) {
- return p;
- }
- }
-
- return null;
- }
-
- public ParseNode getRoot() {
- return (parent == null) ? this : parent.getRoot();
- }
-
- public String getTerminal () {
- ParseNode pn = children.elementAt(0);
- if (pn == null) {
- return null;
- } else {
- return pn.getLabel();
- }
- }
-
- public ParseNode getFirstChild() {
- return children.elementAt(0);
- }
-
- public ParseNodeVector getChildren(String label) {
- int i;
- ParseNodeVector v = new ParseNodeVector();
-
- for (i = 0; i < children.size(); i++) {
- ParseNode pn = children.elementAt(i);
- if (pn.getLabel().equals(label))
- v.addElement(pn);
- }
-
- return v;
- }
-
- public String getNodeName() {
- return label + " - " + getLine();
- }
-
- public int getNeighborCount() {
- return children.size();
- }
-
- public Object getNeighbor(int index) {
- return children.elementAt(index);
- }
-
- public String doIndent(int indent) {
-
- String output = new String();
- for(int i=0;i<indent;i++) output += " ";
- return output;
- }
-
- public String PPrint(int indent, boolean recursive) {
-
- String output = new String();
-
- if (children.size()==0) {
- output += doIndent(indent) + "<" + label + "/>\n";
- } else {
- output += doIndent(indent) + "<" + label + ">\n";
- indent += 2;
-
- if (recursive) {
- for (int i = 0; i < children.size(); i++) {
- Walkable w = (Walkable)children.elementAt(i);
- output += w.PPrint(indent, true);
- }
- } else {
- for (int i = 0; i < children.size(); i++) {
- Walkable w = (Walkable)children.elementAt(i);
- output += doIndent(indent) + "<" + w.getNodeName() + "/>\n";
- }
- }
-
- indent -= 2;
- output += doIndent(indent) + "</" + label + ">\n";
- }
-
- return output;
- }
-
-}
-
+++ /dev/null
-/*
-
- Class: ParseNodeDOTVisitor
- Author: Dan Roy
- Purpose: Traverses a ParseNode tree and generates a DOT file that represents the parse
- tree.
-
-*/
-
-package IR.Tree;
-
-import java.util.*;
-
-public class ParseNodeDOTVisitor {
-
- java.io.PrintWriter output;
- int tokennumber;
- int color;
-
- private ParseNodeDOTVisitor(java.io.OutputStream output) {
- tokennumber = 0;
- color = 0;
- this.output = new java.io.PrintWriter(output, true);
- }
-
- private String getNewID(String name) {
- tokennumber = tokennumber + 1;
- return new String (name+tokennumber);
- }
-
- public static void visit(java.io.OutputStream output, ParseNode root) {
- ParseNodeDOTVisitor visitor = new ParseNodeDOTVisitor(output);
- visitor.make(root);
- }
-
- private void make(ParseNode root) {
- output.println("digraph dotvisitor {");
- output.println("\tsize=\"7, 10\";");
- traverse(root, getNewID("root"));
- output.println("}\n");
- }
-
- private String newColor() {
-
-
- if (color == 0) {
- color++;
- return new String("red");
- } else if (color == 1) {
- color++;
- return new String("green");
- } else {
- color = 0;
- return new String("blue");
- }
- }
-
- private void traverse(ParseNode node, String nodeid) {
- output.println("\t" + nodeid + " [label=\"" + node.getLabel() + "\",shape=box];");
- ParseNodeVector children = node.getChildren();
- for (int i = 0; i < children.size(); i++) {
- ParseNode child = children.elementAt(i);
- String childid = getNewID("node");
- output.println("\t" + nodeid + " -> " + childid + ";");
- if (child.getLabel()=="rule") {
- output.println("\tnode [color=" + newColor() + "];");
- }
- traverse(child, childid);
- }
- }
-}
+++ /dev/null
-package IR.Tree;
-
-import java.util.Vector;
-
-public class ParseNodeVector {
- private Vector v;
-
- public ParseNodeVector() {
- v = new Vector();
- }
-
- public void addElement(ParseNode pn) {
- v.addElement(pn);
- }
-
- public void insertElementAt(ParseNode pn, int n) {
- v.insertElementAt(pn, n);
- }
-
- public ParseNode elementAt(int i) {
- return (ParseNode) v.elementAt(i);
- }
-
- public int size() {
- return v.size();
- }
-}
+++ /dev/null
-package IR.Tree;
-
-public class ReturnNode extends BlockStatementNode {
- ExpressionNode en;
-
- public ReturnNode() {
- en=null;
- }
-
- public ReturnNode(ExpressionNode en) {
- this.en=en;
- }
-
- public ExpressionNode getReturnExpression() {
- return en;
- }
-
- public String printNode(int indent) {
- if (en==null)
- return "return";
- else
- return "return "+en.printNode(indent);
- }
- public int kind() {
- return Kind.ReturnNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-import java.util.*;
-import IR.*;
-
-public class SemanticCheck {
- State state;
- TypeUtil typeutil;
-
- public SemanticCheck(State state, TypeUtil tu) {
- this.state=state;
- this.typeutil=tu;
- }
-
- public void semanticCheck() {
- SymbolTable classtable=state.getClassSymbolTable();
- Iterator it=classtable.getDescriptorsIterator();
- // Do descriptors first
- while(it.hasNext()) {
- ClassDescriptor cd=(ClassDescriptor)it.next();
- //System.out.println("Checking class: "+cd);
- //Set superclass link up
- if (cd.getSuper()!=null) {
- cd.setSuper(typeutil.getClass(cd.getSuper()));
- // Link together Field, Method, and Flag tables so classes
- // inherit these from their superclasses
- cd.getFieldTable().setParent(cd.getSuperDesc().getFieldTable());
- cd.getMethodTable().setParent(cd.getSuperDesc().getMethodTable());
- cd.getFlagTable().setParent(cd.getSuperDesc().getFlagTable());
- }
-
- /* Check to see that fields are well typed */
- for(Iterator field_it=cd.getFields();field_it.hasNext();) {
- FieldDescriptor fd=(FieldDescriptor)field_it.next();
- //System.out.println("Checking field: "+fd);
- checkField(cd,fd);
- }
-
- for(Iterator method_it=cd.getMethods();method_it.hasNext();) {
- MethodDescriptor md=(MethodDescriptor)method_it.next();
- checkMethod(cd,md);
- }
- }
-
- it=classtable.getDescriptorsIterator();
- // Do descriptors first
- while(it.hasNext()) {
- ClassDescriptor cd=(ClassDescriptor)it.next();
- for(Iterator method_it=cd.getMethods();method_it.hasNext();) {
- MethodDescriptor md=(MethodDescriptor)method_it.next();
- checkMethodBody(cd,md);
- }
- }
-
- for(Iterator task_it=state.getTaskSymbolTable().getDescriptorsIterator();task_it.hasNext();) {
- TaskDescriptor td=(TaskDescriptor)task_it.next();
- checkTask(td);
-
- }
-
- }
-
- public void checkTypeDescriptor(TypeDescriptor td) {
- if (td.isPrimitive())
- return; /* Done */
- else if (td.isClass()) {
- String name=td.toString();
- ClassDescriptor field_cd=(ClassDescriptor)state.getClassSymbolTable().get(name);
- if (field_cd==null)
- throw new Error("Undefined class "+name);
- td.setClassDescriptor(field_cd);
- return;
- } else if (td.isTag())
- return;
- else
- throw new Error();
- }
-
- public void checkField(ClassDescriptor cd, FieldDescriptor fd) {
- checkTypeDescriptor(fd.getType());
- }
-
- public void checkConstraintCheck(TaskDescriptor td, SymbolTable nametable, Vector ccs) {
- if (ccs==null)
- return; /* No constraint checks to check */
- for(int i=0;i<ccs.size();i++) {
- ConstraintCheck cc=(ConstraintCheck) ccs.get(i);
-
- for(int j=0;j<cc.numArgs();j++) {
- ExpressionNode en=cc.getArg(j);
- checkExpressionNode(td,nametable,en,null);
- }
- }
- }
-
- public void checkFlagEffects(TaskDescriptor td, Vector vfe, SymbolTable nametable) {
- if (vfe==null)
- return; /* No flag effects to check */
- for(int i=0;i<vfe.size();i++) {
- FlagEffects fe=(FlagEffects) vfe.get(i);
- String varname=fe.getName();
- //Make sure the variable is declared as a parameter to the task
- VarDescriptor vd=(VarDescriptor)td.getParameterTable().get(varname);
- if (vd==null)
- throw new Error("Parameter "+varname+" in Flag Effects not declared");
- fe.setVar(vd);
-
- //Make sure it correspods to a class
- TypeDescriptor type_d=vd.getType();
- if (!type_d.isClass())
- throw new Error("Cannot have non-object argument for flag_effect");
-
- ClassDescriptor cd=type_d.getClassDesc();
- for(int j=0;j<fe.numEffects();j++) {
- FlagEffect flag=fe.getEffect(j);
- String name=flag.getName();
- FlagDescriptor flag_d=(FlagDescriptor)cd.getFlagTable().get(name);
- //Make sure the flag is declared
- if (flag_d==null)
- throw new Error("Flag descriptor "+name+" undefined in class: "+cd.getSymbol());
- if (flag_d.getExternal())
- throw new Error("Attempting to modify external flag: "+name);
- flag.setFlag(flag_d);
- }
- for(int j=0;j<fe.numTagEffects();j++) {
- TagEffect tag=fe.getTagEffect(j);
- String name=tag.getName();
-
- Descriptor d=(Descriptor)nametable.get(name);
- if (d==null)
- throw new Error("Tag descriptor "+name+" undeclared");
- else if (!(d instanceof TagVarDescriptor))
- throw new Error(name+" is not a tag descriptor");
- tag.setTag((TagVarDescriptor)d);
- }
- }
- }
-
- public void checkTask(TaskDescriptor td) {
- for(int i=0;i<td.numParameters();i++) {
- /* Check that parameter is well typed */
- TypeDescriptor param_type=td.getParamType(i);
- checkTypeDescriptor(param_type);
-
- /* Check the parameter's flag expression is well formed */
- FlagExpressionNode fen=td.getFlag(td.getParameter(i));
- if (!param_type.isClass())
- throw new Error("Cannot have non-object argument to a task");
- ClassDescriptor cd=param_type.getClassDesc();
- if (fen!=null)
- checkFlagExpressionNode(cd, fen);
- }
-
- checkFlagEffects(td, td.getFlagEffects(),td.getParameterTable());
- /* Check that the task code is valid */
- BlockNode bn=state.getMethodBody(td);
- checkBlockNode(td, td.getParameterTable(),bn);
- }
-
- public void checkFlagExpressionNode(ClassDescriptor cd, FlagExpressionNode fen) {
- switch(fen.kind()) {
- case Kind.FlagOpNode:
- {
- FlagOpNode fon=(FlagOpNode)fen;
- checkFlagExpressionNode(cd, fon.getLeft());
- if (fon.getRight()!=null)
- checkFlagExpressionNode(cd, fon.getRight());
- break;
- }
- case Kind.FlagNode:
- {
- FlagNode fn=(FlagNode)fen;
- String name=fn.getFlagName();
- FlagDescriptor fd=(FlagDescriptor)cd.getFlagTable().get(name);
- if (fd==null)
- throw new Error("Undeclared flag: "+name);
- fn.setFlag(fd);
- break;
- }
- default:
- throw new Error("Unrecognized FlagExpressionNode");
- }
- }
-
- public void checkMethod(ClassDescriptor cd, MethodDescriptor md) {
- /* Check return type */
- if (!md.isConstructor())
- if (!md.getReturnType().isVoid())
- checkTypeDescriptor(md.getReturnType());
-
- for(int i=0;i<md.numParameters();i++) {
- TypeDescriptor param_type=md.getParamType(i);
- checkTypeDescriptor(param_type);
- }
- /* Link the naming environments */
- if (!md.isStatic()) /* Fields aren't accessible directly in a static method, so don't link in this table */
- md.getParameterTable().setParent(cd.getFieldTable());
- md.setClassDesc(cd);
- if (!md.isStatic()) {
- VarDescriptor thisvd=new VarDescriptor(new TypeDescriptor(cd),"this");
- md.setThis(thisvd);
- }
- }
-
- public void checkMethodBody(ClassDescriptor cd, MethodDescriptor md) {
- //System.out.println("Processing method:"+md);
- BlockNode bn=state.getMethodBody(md);
- checkBlockNode(md, md.getParameterTable(),bn);
- }
-
- public void checkBlockNode(Descriptor md, SymbolTable nametable, BlockNode bn) {
- /* Link in the naming environment */
- bn.getVarTable().setParent(nametable);
- for(int i=0;i<bn.size();i++) {
- BlockStatementNode bsn=bn.get(i);
- checkBlockStatementNode(md, bn.getVarTable(),bsn);
- }
- }
-
- public void checkBlockStatementNode(Descriptor md, SymbolTable nametable, BlockStatementNode bsn) {
- switch(bsn.kind()) {
- case Kind.BlockExpressionNode:
- checkBlockExpressionNode(md, nametable,(BlockExpressionNode)bsn);
- return;
-
- case Kind.DeclarationNode:
- checkDeclarationNode(md, nametable, (DeclarationNode)bsn);
- return;
-
- case Kind.TagDeclarationNode:
- checkTagDeclarationNode(md, nametable, (TagDeclarationNode)bsn);
- return;
-
- case Kind.IfStatementNode:
- checkIfStatementNode(md, nametable, (IfStatementNode)bsn);
- return;
-
- case Kind.LoopNode:
- checkLoopNode(md, nametable, (LoopNode)bsn);
- return;
-
- case Kind.ReturnNode:
- checkReturnNode(md, nametable, (ReturnNode)bsn);
- return;
-
- case Kind.TaskExitNode:
- checkTaskExitNode(md, nametable, (TaskExitNode)bsn);
- return;
-
- case Kind.SubBlockNode:
- checkSubBlockNode(md, nametable, (SubBlockNode)bsn);
- return;
-
- case Kind.AtomicNode:
- checkAtomicNode(md, nametable, (AtomicNode)bsn);
- return;
- }
- throw new Error();
- }
-
- void checkBlockExpressionNode(Descriptor md, SymbolTable nametable, BlockExpressionNode ben) {
- checkExpressionNode(md, nametable, ben.getExpression(), null);
- }
-
- void checkDeclarationNode(Descriptor md, SymbolTable nametable, DeclarationNode dn) {
- VarDescriptor vd=dn.getVarDescriptor();
- checkTypeDescriptor(vd.getType());
- Descriptor d=nametable.get(vd.getSymbol());
- if ((d==null)||
- (d instanceof FieldDescriptor)) {
- nametable.add(vd);
- } else
- throw new Error(vd.getSymbol()+" defined a second time");
- if (dn.getExpression()!=null)
- checkExpressionNode(md, nametable, dn.getExpression(), vd.getType());
- }
-
- void checkTagDeclarationNode(Descriptor md, SymbolTable nametable, TagDeclarationNode dn) {
- TagVarDescriptor vd=dn.getTagVarDescriptor();
- Descriptor d=nametable.get(vd.getSymbol());
- if ((d==null)||
- (d instanceof FieldDescriptor)) {
- nametable.add(vd);
- } else
- throw new Error(vd.getSymbol()+" defined a second time");
- }
-
- void checkSubBlockNode(Descriptor md, SymbolTable nametable, SubBlockNode sbn) {
- checkBlockNode(md, nametable, sbn.getBlockNode());
- }
-
- void checkAtomicNode(Descriptor md, SymbolTable nametable, AtomicNode sbn) {
- checkBlockNode(md, nametable, sbn.getBlockNode());
- }
-
- void checkReturnNode(Descriptor d, SymbolTable nametable, ReturnNode rn) {
- if (d instanceof TaskDescriptor)
- throw new Error("Illegal return appears in Task: "+d.getSymbol());
- MethodDescriptor md=(MethodDescriptor)d;
- if (rn.getReturnExpression()!=null)
- if (md.getReturnType()==null)
- throw new Error("Constructor can't return something.");
- else if (md.getReturnType().isVoid())
- throw new Error(md+" is void");
- else
- checkExpressionNode(md, nametable, rn.getReturnExpression(), md.getReturnType());
- else
- if (md.getReturnType()!=null&&!md.getReturnType().isVoid())
- throw new Error("Need to return something for "+md);
- }
-
- void checkTaskExitNode(Descriptor md, SymbolTable nametable, TaskExitNode ten) {
- if (md instanceof MethodDescriptor)
- throw new Error("Illegal taskexit appears in Method: "+md.getSymbol());
- checkFlagEffects((TaskDescriptor)md, ten.getFlagEffects(),nametable);
- checkConstraintCheck((TaskDescriptor) md, nametable, ten.getChecks());
- }
-
- void checkIfStatementNode(Descriptor md, SymbolTable nametable, IfStatementNode isn) {
- checkExpressionNode(md, nametable, isn.getCondition(), new TypeDescriptor(TypeDescriptor.BOOLEAN));
- checkBlockNode(md, nametable, isn.getTrueBlock());
- if (isn.getFalseBlock()!=null)
- checkBlockNode(md, nametable, isn.getFalseBlock());
- }
-
- void checkExpressionNode(Descriptor md, SymbolTable nametable, ExpressionNode en, TypeDescriptor td) {
- switch(en.kind()) {
- case Kind.AssignmentNode:
- checkAssignmentNode(md,nametable,(AssignmentNode)en,td);
- return;
- case Kind.CastNode:
- checkCastNode(md,nametable,(CastNode)en,td);
- return;
- case Kind.CreateObjectNode:
- checkCreateObjectNode(md,nametable,(CreateObjectNode)en,td);
- return;
- case Kind.FieldAccessNode:
- checkFieldAccessNode(md,nametable,(FieldAccessNode)en,td);
- return;
- case Kind.ArrayAccessNode:
- checkArrayAccessNode(md,nametable,(ArrayAccessNode)en,td);
- return;
- case Kind.LiteralNode:
- checkLiteralNode(md,nametable,(LiteralNode)en,td);
- return;
- case Kind.MethodInvokeNode:
- checkMethodInvokeNode(md,nametable,(MethodInvokeNode)en,td);
- return;
- case Kind.NameNode:
- checkNameNode(md,nametable,(NameNode)en,td);
- return;
- case Kind.OpNode:
- checkOpNode(md,nametable,(OpNode)en,td);
- return;
- }
- throw new Error();
- }
-
- void checkCastNode(Descriptor md, SymbolTable nametable, CastNode cn, TypeDescriptor td) {
- /* Get type descriptor */
- if (cn.getType()==null) {
- NameDescriptor typenamed=cn.getTypeName().getName();
- String typename=typenamed.toString();
- TypeDescriptor ntd=new TypeDescriptor(typeutil.getClass(typename));
- cn.setType(ntd);
- }
-
- /* Check the type descriptor */
- TypeDescriptor cast_type=cn.getType();
- checkTypeDescriptor(cast_type);
-
- /* Type check */
- if (td!=null) {
- if (!typeutil.isSuperorType(td,cast_type))
- throw new Error("Cast node returns "+cast_type+", but need "+td);
- }
-
- ExpressionNode en=cn.getExpression();
- checkExpressionNode(md, nametable, en, null);
- TypeDescriptor etd=en.getType();
- if (typeutil.isSuperorType(cast_type,etd)) /* Cast trivially succeeds */
- return;
-
- if (typeutil.isSuperorType(etd,cast_type)) /* Cast may succeed */
- return;
- if (typeutil.isCastable(etd, cast_type))
- return;
-
- /* Different branches */
- /* TODO: change if add interfaces */
- throw new Error("Cast will always fail\n"+cn.printNode(0));
- }
-
- void checkFieldAccessNode(Descriptor md, SymbolTable nametable, FieldAccessNode fan, TypeDescriptor td) {
- ExpressionNode left=fan.getExpression();
- checkExpressionNode(md,nametable,left,null);
- TypeDescriptor ltd=left.getType();
- String fieldname=fan.getFieldName();
-
- FieldDescriptor fd=null;
- if (ltd.isArray()&&fieldname.equals("length"))
- fd=FieldDescriptor.arrayLength;
- else
- fd=(FieldDescriptor) ltd.getClassDesc().getFieldTable().get(fieldname);
- if (fd==null)
- throw new Error("Unknown field "+fieldname + " in "+fan.printNode(0));
- fan.setField(fd);
- if (td!=null)
- if (!typeutil.isSuperorType(td,fan.getType()))
- throw new Error("Field node returns "+fan.getType()+", but need "+td);
- }
-
- void checkArrayAccessNode(Descriptor md, SymbolTable nametable, ArrayAccessNode aan, TypeDescriptor td) {
- ExpressionNode left=aan.getExpression();
- checkExpressionNode(md,nametable,left,null);
-
- checkExpressionNode(md,nametable,aan.getIndex(),new TypeDescriptor(TypeDescriptor.INT));
- TypeDescriptor ltd=left.getType();
-
- if (td!=null)
- if (!typeutil.isSuperorType(td,aan.getType()))
- throw new Error("Field node returns "+aan.getType()+", but need "+td);
- }
-
- void checkLiteralNode(Descriptor md, SymbolTable nametable, LiteralNode ln, TypeDescriptor td) {
- /* Resolve the type */
- Object o=ln.getValue();
- if (ln.getTypeString().equals("null")) {
- ln.setType(new TypeDescriptor(TypeDescriptor.NULL));
- } else if (o instanceof Integer) {
- ln.setType(new TypeDescriptor(TypeDescriptor.INT));
- } else if (o instanceof Long) {
- ln.setType(new TypeDescriptor(TypeDescriptor.LONG));
- } else if (o instanceof Float) {
- ln.setType(new TypeDescriptor(TypeDescriptor.FLOAT));
- } else if (o instanceof Boolean) {
- ln.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
- } else if (o instanceof Double) {
- ln.setType(new TypeDescriptor(TypeDescriptor.DOUBLE));
- } else if (o instanceof Character) {
- ln.setType(new TypeDescriptor(TypeDescriptor.CHAR));
- } else if (o instanceof String) {
- ln.setType(new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass)));
- }
-
- if (td!=null)
- if (!typeutil.isSuperorType(td,ln.getType()))
- throw new Error("Field node returns "+ln.getType()+", but need "+td);
- }
-
- void checkNameNode(Descriptor md, SymbolTable nametable, NameNode nn, TypeDescriptor td) {
- NameDescriptor nd=nn.getName();
- if (nd.getBase()!=null) {
- /* Big hack */
- /* Rewrite NameNode */
- ExpressionNode en=translateNameDescriptorintoExpression(nd);
- nn.setExpression(en);
- checkExpressionNode(md,nametable,en,td);
- } else {
- String varname=nd.toString();
- Descriptor d=(Descriptor)nametable.get(varname);
- if (d==null) {
- throw new Error("Name "+varname+" undefined");
- }
- if (d instanceof VarDescriptor) {
- nn.setVar(d);
- } else if (d instanceof FieldDescriptor) {
- nn.setField((FieldDescriptor)d);
- nn.setVar((VarDescriptor)nametable.get("this")); /* Need a pointer to this */
- } else if (d instanceof TagVarDescriptor) {
- nn.setVar(d);
- } else throw new Error("Wrong type of descriptor");
- if (td!=null)
- if (!typeutil.isSuperorType(td,nn.getType()))
- throw new Error("Field node returns "+nn.getType()+", but need "+td);
- }
- }
-
- void checkAssignmentNode(Descriptor md, SymbolTable nametable, AssignmentNode an, TypeDescriptor td) {
- boolean postinc=true;
- if (an.getOperation().getBaseOp()==null||
- (an.getOperation().getBaseOp().getOp()!=Operation.POSTINC&&
- an.getOperation().getBaseOp().getOp()!=Operation.POSTDEC))
- postinc=false;
-
- if (!postinc)
- checkExpressionNode(md, nametable, an.getSrc() ,td);
- //TODO: Need check on validity of operation here
- if (!((an.getDest() instanceof FieldAccessNode)||
- (an.getDest() instanceof ArrayAccessNode)||
- (an.getDest() instanceof NameNode)))
- throw new Error("Bad lside in "+an.printNode(0));
- checkExpressionNode(md, nametable, an.getDest(), null);
-
- /* We want parameter variables to tasks to be immutable */
- if (md instanceof TaskDescriptor) {
- if (an.getDest() instanceof NameNode) {
- NameNode nn=(NameNode)an.getDest();
- if (nn.getVar()!=null) {
- if (((TaskDescriptor)md).getParameterTable().contains(nn.getVar().getSymbol()))
- throw new Error("Can't modify parameter "+nn.getVar()+ " to task "+td.getSymbol());
- }
- }
- }
-
- if (!postinc&&!typeutil.isSuperorType(an.getDest().getType(),an.getSrc().getType())) {
- throw new Error("Type of rside ("+an.getSrc().getType()+") not compatible with type of lside ("+an.getDest().getType()+")"+an.printNode(0));
- }
- }
-
- void checkLoopNode(Descriptor md, SymbolTable nametable, LoopNode ln) {
- if (ln.getType()==LoopNode.WHILELOOP||ln.getType()==LoopNode.DOWHILELOOP) {
- checkExpressionNode(md, nametable, ln.getCondition(), new TypeDescriptor(TypeDescriptor.BOOLEAN));
- checkBlockNode(md, nametable, ln.getBody());
- } else {
- //For loop case
- /* Link in the initializer naming environment */
- BlockNode bn=ln.getInitializer();
- bn.getVarTable().setParent(nametable);
- for(int i=0;i<bn.size();i++) {
- BlockStatementNode bsn=bn.get(i);
- checkBlockStatementNode(md, bn.getVarTable(),bsn);
- }
- //check the condition
- checkExpressionNode(md, bn.getVarTable(), ln.getCondition(), new TypeDescriptor(TypeDescriptor.BOOLEAN));
- checkBlockNode(md, bn.getVarTable(), ln.getBody());
- checkBlockNode(md, bn.getVarTable(), ln.getUpdate());
- }
- }
-
-
- void checkCreateObjectNode(Descriptor md, SymbolTable nametable, CreateObjectNode con, TypeDescriptor td) {
- TypeDescriptor[] tdarray=new TypeDescriptor[con.numArgs()];
- for(int i=0;i<con.numArgs();i++) {
- ExpressionNode en=con.getArg(i);
- checkExpressionNode(md,nametable,en,null);
- tdarray[i]=en.getType();
- }
-
- TypeDescriptor typetolookin=con.getType();
- checkTypeDescriptor(typetolookin);
-
- if (td!=null&&!typeutil.isSuperorType(td, typetolookin))
- throw new Error(typetolookin + " isn't a "+td);
-
-
-
- /* Check flag effects */
- if (con.getFlagEffects()!=null) {
- FlagEffects fe=con.getFlagEffects();
- ClassDescriptor cd=typetolookin.getClassDesc();
-
- for(int j=0;j<fe.numEffects();j++) {
- FlagEffect flag=fe.getEffect(j);
- String name=flag.getName();
- FlagDescriptor flag_d=(FlagDescriptor)cd.getFlagTable().get(name);
- //Make sure the flag is declared
- if (flag_d==null)
- throw new Error("Flag descriptor "+name+" undefined in class: "+cd.getSymbol());
- if (flag_d.getExternal())
- throw new Error("Attempting to modify external flag: "+name);
- flag.setFlag(flag_d);
- }
- for(int j=0;j<fe.numTagEffects();j++) {
- TagEffect tag=fe.getTagEffect(j);
- String name=tag.getName();
-
- Descriptor d=(Descriptor)nametable.get(name);
- if (d==null)
- throw new Error("Tag descriptor "+name+" undeclared");
- else if (!(d instanceof TagVarDescriptor))
- throw new Error(name+" is not a tag descriptor");
- tag.setTag((TagVarDescriptor)d);
- }
- }
-
-
- if ((!typetolookin.isClass())&&(!typetolookin.isArray()))
- throw new Error("Can't allocate primitive type:"+con.printNode(0));
-
- if (!typetolookin.isArray()) {
- //Array's don't need constructor calls
- ClassDescriptor classtolookin=typetolookin.getClassDesc();
- //System.out.println("Looking for "+typetolookin.getSymbol());
- //System.out.println(classtolookin.getMethodTable());
-
- Set methoddescriptorset=classtolookin.getMethodTable().getSet(typetolookin.getSymbol());
- MethodDescriptor bestmd=null;
- NextMethod:
- for(Iterator methodit=methoddescriptorset.iterator();methodit.hasNext();) {
- MethodDescriptor currmd=(MethodDescriptor)methodit.next();
- /* Need correct number of parameters */
- //System.out.println("Examining: "+currmd);
- if (con.numArgs()!=currmd.numParameters())
- continue;
- for(int i=0;i<con.numArgs();i++) {
- if (!typeutil.isSuperorType(currmd.getParamType(i),tdarray[i]))
- continue NextMethod;
- }
- /* Method okay so far */
- if (bestmd==null)
- bestmd=currmd;
- else {
- if (isMoreSpecific(currmd,bestmd)) {
- bestmd=currmd;
- } else if (!isMoreSpecific(bestmd, currmd))
- throw new Error("No method is most specific");
-
- /* Is this more specific than bestmd */
- }
- }
- if (bestmd==null)
- throw new Error("No method found for "+con.printNode(0));
- con.setConstructor(bestmd);
- }
- }
-
-
- /** Check to see if md1 is more specific than md2... Informally
- if md2 could always be called given the arguments passed into
- md1 */
-
- boolean isMoreSpecific(MethodDescriptor md1, MethodDescriptor md2) {
- /* Checks if md1 is more specific than md2 */
- if (md1.numParameters()!=md2.numParameters())
- throw new Error();
- for(int i=0;i<md1.numParameters();i++) {
- if (!typeutil.isSuperorType(md2.getParamType(i), md1.getParamType(i)))
- return false;
- }
- if (!typeutil.isSuperorType(md2.getReturnType(), md1.getReturnType()))
- return false;
-
- if (!typeutil.isSuperorType(md2.getClassDesc(), md1.getClassDesc()))
- return false;
-
- return true;
- }
-
- ExpressionNode translateNameDescriptorintoExpression(NameDescriptor nd) {
- String id=nd.getIdentifier();
- NameDescriptor base=nd.getBase();
- if (base==null)
- return new NameNode(nd);
- else
- return new FieldAccessNode(translateNameDescriptorintoExpression(base),id);
- }
-
-
- void checkMethodInvokeNode(Descriptor md, SymbolTable nametable, MethodInvokeNode min, TypeDescriptor td) {
- /*Typecheck subexpressions
- and get types for expressions*/
-
- TypeDescriptor[] tdarray=new TypeDescriptor[min.numArgs()];
- for(int i=0;i<min.numArgs();i++) {
- ExpressionNode en=min.getArg(i);
- checkExpressionNode(md,nametable,en,null);
- tdarray[i]=en.getType();
- }
- TypeDescriptor typetolookin=null;
- if (min.getExpression()!=null) {
- checkExpressionNode(md,nametable,min.getExpression(),null);
- typetolookin=min.getExpression().getType();
- } else if (min.getBaseName()!=null) {
- String rootname=min.getBaseName().getRoot();
- if (nametable.get(rootname)!=null) {
- //we have an expression
- min.setExpression(translateNameDescriptorintoExpression(min.getBaseName()));
- checkExpressionNode(md, nametable, min.getExpression(), null);
- typetolookin=min.getExpression().getType();
- } else {
- //we have a type
- ClassDescriptor cd=typeutil.getClass(min.getBaseName().getSymbol());
- if (cd==null)
- throw new Error(min.getBaseName()+" undefined");
- typetolookin=new TypeDescriptor(cd);
- }
- } else if (md instanceof MethodDescriptor) {
- typetolookin=new TypeDescriptor(((MethodDescriptor)md).getClassDesc());
- } else {
- /* If this a task descriptor we throw an error at this point */
- throw new Error("Unknown method call to "+min.getMethodName()+"in task"+md.getSymbol());
- }
- if (!typetolookin.isClass())
- throw new Error("Error with method call to "+min.getMethodName());
- ClassDescriptor classtolookin=typetolookin.getClassDesc();
- //System.out.println("Method name="+min.getMethodName());
-
- Set methoddescriptorset=classtolookin.getMethodTable().getSet(min.getMethodName());
- MethodDescriptor bestmd=null;
- NextMethod:
- for(Iterator methodit=methoddescriptorset.iterator();methodit.hasNext();) {
- MethodDescriptor currmd=(MethodDescriptor)methodit.next();
- /* Need correct number of parameters */
- if (min.numArgs()!=currmd.numParameters())
- continue;
- for(int i=0;i<min.numArgs();i++) {
- if (!typeutil.isSuperorType(currmd.getParamType(i),tdarray[i]))
- continue NextMethod;
- }
- /* Method okay so far */
- if (bestmd==null)
- bestmd=currmd;
- else {
- if (isMoreSpecific(currmd,bestmd)) {
- bestmd=currmd;
- } else if (!isMoreSpecific(bestmd, currmd))
- throw new Error("No method is most specific");
-
- /* Is this more specific than bestmd */
- }
- }
- if (bestmd==null)
- throw new Error("No method found for :"+min.printNode(0));
- min.setMethod(bestmd);
-
- if ((td!=null)&&(min.getType()!=null)&&!typeutil.isSuperorType(td, min.getType()))
- throw new Error(min.getType()+ " is not equal to or a subclass of "+td);
- /* Check whether we need to set this parameter to implied this */
- if (!bestmd.isStatic()) {
- if (min.getExpression()==null) {
- ExpressionNode en=new NameNode(new NameDescriptor("this"));
- min.setExpression(en);
- checkExpressionNode(md, nametable, min.getExpression(), null);
- }
- }
- }
-
-
- void checkOpNode(Descriptor md, SymbolTable nametable, OpNode on, TypeDescriptor td) {
- checkExpressionNode(md, nametable, on.getLeft(), null);
- if (on.getRight()!=null)
- checkExpressionNode(md, nametable, on.getRight(), null);
- TypeDescriptor ltd=on.getLeft().getType();
- TypeDescriptor rtd=on.getRight()!=null?on.getRight().getType():null;
- TypeDescriptor lefttype=null;
- TypeDescriptor righttype=null;
- Operation op=on.getOp();
-
- switch(op.getOp()) {
- case Operation.LOGIC_OR:
- case Operation.LOGIC_AND:
- if (!(rtd.isBoolean()))
- throw new Error();
- on.setRightType(rtd);
- case Operation.LOGIC_NOT:
- if (!(ltd.isBoolean()))
- throw new Error();
- //no promotion
- on.setLeftType(ltd);
-
- on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
- break;
-
- case Operation.BIT_OR:
- case Operation.BIT_XOR:
- case Operation.BIT_AND:
- // 5.6.2 Binary Numeric Promotion
- //TODO unboxing of reference objects
- if (ltd.isDouble()||rtd.isDouble())
- throw new Error();
- else if (ltd.isFloat()||rtd.isFloat())
- throw new Error();
- else if (ltd.isLong()||rtd.isLong())
- lefttype=new TypeDescriptor(TypeDescriptor.LONG);
- else
- lefttype=new TypeDescriptor(TypeDescriptor.INT);
- righttype=lefttype;
-
- on.setLeftType(lefttype);
- on.setRightType(righttype);
- on.setType(lefttype);
- break;
-
- case Operation.EQUAL:
- case Operation.NOTEQUAL:
- // 5.6.2 Binary Numeric Promotion
- //TODO unboxing of reference objects
- if (ltd.isBoolean()||rtd.isBoolean()) {
- if (!(ltd.isBoolean()&&rtd.isBoolean()))
- throw new Error();
- righttype=lefttype=new TypeDescriptor(TypeDescriptor.BOOLEAN);
- } else if (ltd.isPtr()||ltd.isArray()||rtd.isPtr()||rtd.isArray()) {
- if (!((ltd.isPtr()||ltd.isArray())&&(rtd.isPtr()||rtd.isArray())))
- throw new Error();
- righttype=rtd;
- lefttype=ltd;
- } else if (ltd.isDouble()||rtd.isDouble())
- righttype=lefttype=new TypeDescriptor(TypeDescriptor.DOUBLE);
- else if (ltd.isFloat()||rtd.isFloat())
- righttype=lefttype=new TypeDescriptor(TypeDescriptor.FLOAT);
- else if (ltd.isLong()||rtd.isLong())
- righttype=lefttype=new TypeDescriptor(TypeDescriptor.LONG);
- else
- righttype=lefttype=new TypeDescriptor(TypeDescriptor.INT);
-
- on.setLeftType(lefttype);
- on.setRightType(righttype);
- on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
- break;
-
-
-
- case Operation.LT:
- case Operation.GT:
- case Operation.LTE:
- case Operation.GTE:
- // 5.6.2 Binary Numeric Promotion
- //TODO unboxing of reference objects
- if (!ltd.isNumber()||!rtd.isNumber())
- throw new Error();
-
- if (ltd.isDouble()||rtd.isDouble())
- lefttype=new TypeDescriptor(TypeDescriptor.DOUBLE);
- else if (ltd.isFloat()||rtd.isFloat())
- lefttype=new TypeDescriptor(TypeDescriptor.FLOAT);
- else if (ltd.isLong()||rtd.isLong())
- lefttype=new TypeDescriptor(TypeDescriptor.LONG);
- else
- lefttype=new TypeDescriptor(TypeDescriptor.INT);
- righttype=lefttype;
- on.setLeftType(lefttype);
- on.setRightType(righttype);
- on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
- break;
-
- case Operation.ADD:
- //TODO: Need special case for strings eventually
-
-
- case Operation.SUB:
- case Operation.MULT:
- case Operation.DIV:
- case Operation.MOD:
- // 5.6.2 Binary Numeric Promotion
- //TODO unboxing of reference objects
- if (ltd.isArray()||rtd.isArray()||!ltd.isNumber()||!rtd.isNumber())
- throw new Error("Error in "+on.printNode(0));
-
- if (ltd.isDouble()||rtd.isDouble())
- lefttype=new TypeDescriptor(TypeDescriptor.DOUBLE);
- else if (ltd.isFloat()||rtd.isFloat())
- lefttype=new TypeDescriptor(TypeDescriptor.FLOAT);
- else if (ltd.isLong()||rtd.isLong())
- lefttype=new TypeDescriptor(TypeDescriptor.LONG);
- else
- lefttype=new TypeDescriptor(TypeDescriptor.INT);
- righttype=lefttype;
- on.setLeftType(lefttype);
- on.setRightType(righttype);
- on.setType(lefttype);
- break;
-
- case Operation.LEFTSHIFT:
- case Operation.RIGHTSHIFT:
- if (!rtd.isIntegerType())
- throw new Error();
- //5.6.1 Unary Numeric Promotion
- if (rtd.isByte()||rtd.isShort()||rtd.isInt())
- righttype=new TypeDescriptor(TypeDescriptor.INT);
- else
- righttype=rtd;
-
- on.setRightType(righttype);
- if (!ltd.isIntegerType())
- throw new Error();
- case Operation.UNARYPLUS:
- case Operation.UNARYMINUS:
- /* case Operation.POSTINC:
- case Operation.POSTDEC:
- case Operation.PREINC:
- case Operation.PREDEC:*/
- if (!ltd.isNumber())
- throw new Error();
- //5.6.1 Unary Numeric Promotion
- if (ltd.isByte()||ltd.isShort()||ltd.isInt())
- lefttype=new TypeDescriptor(TypeDescriptor.INT);
- else
- lefttype=ltd;
- on.setLeftType(lefttype);
- on.setType(lefttype);
- break;
- default:
- throw new Error(op.toString());
- }
-
- if (td!=null)
- if (!typeutil.isSuperorType(td, on.getType())) {
- System.out.println(td);
- System.out.println(on.getType());
- throw new Error("Type of rside not compatible with type of lside"+on.printNode(0));
- }
- }
-}
+++ /dev/null
-package IR.Tree;
-
-public class SubBlockNode extends BlockStatementNode {
- BlockNode bn;
- public SubBlockNode(BlockNode bn) {
- this.bn=bn;
- }
-
- public String printNode(int indent) {
- return bn.printNode(indent);
- }
-
- public BlockNode getBlockNode() {
- return bn;
- }
-
- public int kind() {
- return Kind.SubBlockNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-import IR.TagVarDescriptor;
-import IR.TagDescriptor;
-
-public class TagDeclarationNode extends BlockStatementNode {
- String name;
- String tagtype;
- TagVarDescriptor tvd;
-
- public TagDeclarationNode(String name, String tagtype) {
- this.name=name;
- this.tagtype=tagtype;
- tvd=new TagVarDescriptor(new TagDescriptor(tagtype), name);
- }
-
- public String printNode(int indent) {
- return "Tag "+name+"=new("+tagtype+")";
- }
-
- public TagVarDescriptor getTagVarDescriptor() {
- return tvd;
- }
-
- public String getName() {
- return name;
- }
-
- public String getTagType() {
- return tagtype;
- }
-
- public int kind() {
- return Kind.TagDeclarationNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-import IR.*;
-
-public class TagEffect {
- TagVarDescriptor tag;
- boolean status;
- String name;
-
- public TagEffect(String tag, boolean status) {
- this.name=tag;
- this.status=status;
- }
-
- public void setTag(TagVarDescriptor tag) {
- this.tag=tag;
- }
-
- public TagVarDescriptor getTag() {
- return tag;
- }
-
- public String getName() {
- return name;
- }
-
- public boolean getStatus() {
- return status;
- }
-
- public String printNode(int indent) {
- if (status)
- return name;
- else
- return "!"+name;
- }
-}
+++ /dev/null
-package IR.Tree;
-import java.util.Vector;
-import IR.Flat.TempDescriptor;
-
-public class TagExpressionList {
- Vector names;
- Vector types;
- Vector temps;
-
- public TagExpressionList() {
- names=new Vector();
- types=new Vector();
- temps=new Vector();
- }
-
- public void addTag(String type, String name) {
- types.add(type);
- names.add(name);
- }
-
- public int numTags() {
- return names.size();
- }
-
- public void setTemp(int i, TempDescriptor tmp) {
- if (i>=temps.size())
- temps.setSize(i+1);
- temps.set(i, tmp);
- }
-
- public TempDescriptor getTemp(int i) {
- return (TempDescriptor) temps.get(i);
- }
-
- public String getName(int i) {
- return (String) names.get(i);
- }
-
- public String getType(int i) {
- return (String) types.get(i);
- }
-}
-
+++ /dev/null
-package IR.Tree;
-import java.util.Vector;
-
-public class TaskExitNode extends BlockStatementNode {
- Vector vfe;
- Vector ccs;
- public TaskExitNode(Vector vfe, Vector ccs) {
- this.vfe=vfe;
- this.ccs=ccs;
- }
-
- public String printNode(int indent) {
- return "taskexit";
- }
-
- public Vector getFlagEffects() {
- return vfe;
- }
-
- public Vector getChecks() {
- return ccs;
- }
-
- public int kind() {
- return Kind.TaskExitNode;
- }
-}
+++ /dev/null
-package IR.Tree;
-
-public class TreeNode {
- public static final int INDENT=2;
-
- public String printNode(int indent) {
- return null;
- }
- public static String printSpace(int x) {
- String sp="";
- for(int i=0;i<x;i++)
- sp+=" ";
- return sp;
- }
- public int kind() {
- throw new Error();
- }
-}
+++ /dev/null
-package IR.Tree;
-
-/**
- * The Walkable interface specifies a set of methods that defines a web.
- */
-
-public interface Walkable {
-
- /**
- * Returns the name of the node
- */
- public String getNodeName();
-
-
- /**
- * Returns the number of neighbors from this node
- */
- public int getNeighborCount();
-
-
- /**
- * Returns a specific neighbor
- */
- public Object getNeighbor(int index);
-
- /**
- * Returns a pretty print of the representation of the node.
- *
- * @param indent number of blank spaces to skip for a new line
- * @param recursive if true, recursively print children
- */
- public String PPrint(int indent, boolean recursive);
-}
-
+++ /dev/null
-package IR;
-
-/**
- * Descriptor
- *
- * represents a symbol in the language (var name, function name, etc).
- */
-
-public class TypeDescriptor extends Descriptor {
- public static final int BYTE=1;
- public static final int SHORT=2;
- public static final int INT=3;
- public static final int LONG=4;
- public static final int CHAR=5;
- public static final int BOOLEAN=6;
- public static final int FLOAT=7;
- public static final int DOUBLE=8;
- public static final int VOID=9;
- public static final int NULL=10;
- public static final int TAG=11;
- public static final int CLASS=12;
-
-
- int arraycount;
- int type;
- ClassDescriptor class_desc;
-
- public boolean equals(Object o) {
- if (o instanceof TypeDescriptor) {
- TypeDescriptor t=(TypeDescriptor)o;
- if (t.type!=type)
- return false;
- if ((type==CLASS)&&(t.class_desc!=class_desc))
- return false;
- if (t.arraycount!=arraycount)
- return false;
- return true;
- }
- return false;
- }
-
- public int hashCode() {
- int hashcode=type^arraycount;
- if (type==CLASS)
- hashcode^=getSymbol().hashCode();
- return hashcode;
- }
-
- public TypeDescriptor makeArray(State state) {
- TypeDescriptor td=new TypeDescriptor(getSymbol());
- td.arraycount=arraycount+1;
- td.type=type;
- td.class_desc=class_desc;
- state.addArrayType(td);
- return td;
- }
-
- public boolean isArray() {
- return (arraycount>0);
- }
-
- public int getArrayCount() {
- return arraycount;
- }
-
- public TypeDescriptor dereference() {
- TypeDescriptor td=new TypeDescriptor(getSymbol());
- if (arraycount==0)
- throw new Error();
- td.arraycount=arraycount-1;
- td.type=type;
- td.class_desc=class_desc;
- return td;
- }
-
- public String getSafeSymbol() {
- if (isArray())
- return IR.Flat.BuildCode.arraytype;
- else if (isClass())
- return class_desc.getSafeSymbol();
- else if (isByte())
- return "char";
- else if (isChar())
- return "short";
- else if (isShort())
- return "short";
- else if (isInt())
- return "int";
- else if (isBoolean()) //Booleans are ints in C
- return "int";
- else if (isLong())
- return "long long";
- else if (isVoid())
- return "void";
- else if (isDouble())
- return "double";
- else if (isFloat())
- return "float";
- else throw new Error("Error Type: "+type);
- }
-
- public String getRepairSymbol() {
- if (isArray())
- return IR.Flat.BuildCode.arraytype;
- else if (isClass())
- return class_desc.getSymbol();
- else if (isByte())
- return "byte";
- else if (isChar())
- return "short";
- else if (isShort())
- return "short";
- else if (isInt())
- return "int";
- else if (isBoolean()) //Booleans are ints in C
- return "int";
- else if (isLong())
- return "long long";
- else if (isVoid())
- return "void";
- else if (isDouble())
- return "double";
- else if (isFloat())
- return "float";
- else throw new Error("Error Type: "+type);
- }
-
- public String getSafeDescriptor() {
- //Can't safely use [ in C
- if (isArray())
- return "_AR_"+this.dereference().getSafeDescriptor();
- else if (isClass())
- return class_desc.getSafeDescriptor();
- else if (isByte())
- return "B";
- else if (isChar())
- return "C";
- else if (isShort())
- return "S";
- else if (isBoolean())
- return "Z";
- else if (isInt())
- return "I";
- else if (isLong())
- return "J";
- else if (isDouble())
- return "D";
- else if (isFloat())
- return "F";
- else if (isTag())
- return "T";
- else throw new Error();
- }
-
- public boolean isNumber() {
- return (isIntegerType()||isFloat()||isDouble());
- }
-
- public boolean isByte() {
- return type==BYTE;
- }
- public boolean isNull() {
- return type==NULL;
- }
- public boolean isShort() {
- return type==SHORT;
- }
- public boolean isInt() {
- return type==INT;
- }
- public boolean isLong() {
- return type==LONG;
- }
- public boolean isChar() {
- return type==CHAR;
- }
- public boolean isBoolean() {
- return type==BOOLEAN;
- }
- public boolean isFloat() {
- return type==FLOAT;
- }
- public boolean isDouble() {
- return type==DOUBLE;
- }
- public boolean isVoid() {
- return type==VOID;
- }
-
- public boolean isPtr() {
- return (isClass()||isNull()||isTag());
- }
-
- public boolean isIntegerType() {
- return (isInt()||isLong()||isShort()||isChar()||isByte());
- }
-
- public void setClassDescriptor(ClassDescriptor cd) {
- class_desc=cd;
- }
-
- public boolean isPrimitive() {
- return ((type>=BYTE)&&(type<=DOUBLE));
- }
-
- public boolean isClass() {
- return type==CLASS;
- }
-
- public boolean isTag() {
- return type==TAG;
- }
-
- public TypeDescriptor(NameDescriptor name) {
- super(name.toString());
- this.type=CLASS;
- this.class_desc=null;
- this.arraycount=0;
- }
-
- public TypeDescriptor(String st) {
- super(st);
- this.type=CLASS;
- this.class_desc=null;
- this.arraycount=0;
- }
-
- public ClassDescriptor getClassDesc() {
- return class_desc;
- }
-
- public TypeDescriptor(ClassDescriptor cd) {
- super(cd.getSymbol());
- this.type=CLASS;
- this.class_desc=cd;
- this.arraycount=0;
- }
-
- public TypeDescriptor(int t) {
- super(decodeInt(t));
- this.type=t;
- this.arraycount=0;
- }
-
- public String toString() {
- if (type==CLASS)
- return name;
- else
- return decodeInt(type);
- }
-
- private static String decodeInt(int type) {
- if (type==BYTE)
- return "byte";
- else if (type==BOOLEAN)
- return "boolean";
- else if (type==SHORT)
- return "short";
- else if (type==INT)
- return "int";
- else if (type==LONG)
- return "long";
- else if (type==CHAR)
- return "char";
- else if (type==FLOAT)
- return "float";
- else if (type==DOUBLE)
- return "double";
- else if (type==VOID)
- return "void";
- else if (type==NULL)
- return "null";
- else if (type==TAG)
- return TypeUtil.TagClass;
- else throw new Error();
- }
-}
+++ /dev/null
-package IR;
-import java.util.*;
-
-public class TypeUtil {
- public static final String StringClass="String";
- public static final String ObjectClass="Object";
- public static final String StartupClass="StartupObject";
- public static final String TagClass="TagDescriptor";
- State state;
- Hashtable supertable;
- Hashtable subclasstable;
-
- public TypeUtil(State state) {
- this.state=state;
- createTables();
- }
-
- public ClassDescriptor getClass(String classname) {
- ClassDescriptor cd=(ClassDescriptor)state.getClassSymbolTable().get(classname);
- return cd;
- }
-
- private void createTables() {
- supertable=new Hashtable();
-
- Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
- while(classit.hasNext()) {
- ClassDescriptor cd=(ClassDescriptor)classit.next();
- String superc=cd.getSuper();
- if (superc!=null) {
- ClassDescriptor cd_super=getClass(superc);
- supertable.put(cd,cd_super);
- }
- }
- }
-
- public ClassDescriptor getMainClass() {
- return getClass(state.main);
- }
-
- public MethodDescriptor getMain() {
- ClassDescriptor cd=getMainClass();
- Set mainset=cd.getMethodTable().getSet("main");
- for(Iterator mainit=mainset.iterator();mainit.hasNext();) {
- MethodDescriptor md=(MethodDescriptor)mainit.next();
- if (md.numParameters()!=1)
- continue;
- Descriptor pd=md.getParameter(0);
- TypeDescriptor tpd=(pd instanceof TagVarDescriptor)?((TagVarDescriptor)pd).getType():((VarDescriptor)pd)
- .getType();
- if (tpd.getArrayCount()!=1)
- continue;
- if (!tpd.getSymbol().equals("String"))
- continue;
-
- if (!md.getModifiers().isStatic())
- throw new Error("Error: Non static main");
- return md;
- }
- throw new Error(cd+" has no main");
- }
-
- public void createFullTable() {
- subclasstable=new Hashtable();
-
- Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
- while(classit.hasNext()) {
- ClassDescriptor cd=(ClassDescriptor)classit.next();
- ClassDescriptor tmp=cd.getSuperDesc();
-
- while(tmp!=null) {
- if (!subclasstable.containsKey(tmp))
- subclasstable.put(tmp,new HashSet());
- HashSet hs=(HashSet)subclasstable.get(tmp);
- hs.add(cd);
- tmp=tmp.getSuperDesc();
- }
- }
- }
-
- public Set getSubClasses(ClassDescriptor cd) {
- return (Set)subclasstable.get(cd);
- }
-
- public ClassDescriptor getSuper(ClassDescriptor cd) {
- return (ClassDescriptor)supertable.get(cd);
- }
-
- public boolean isCastable(TypeDescriptor original, TypeDescriptor casttype) {
- if (original.isChar()&&
- (casttype.isByte()||
- casttype.isShort()))
- return true;
-
- if (casttype.isChar()&&
- (original.isByte()||
- original.isShort()||
- original.isInt()||
- original.isLong()||
- original.isFloat()||
- original.isDouble()))
- return true;
-
- return false;
- }
-
- public boolean isSuperorType(TypeDescriptor possiblesuper, TypeDescriptor cd2) {
- //Matching type are always okay
- if (possiblesuper.equals(cd2))
- return true;
-
- if ((possiblesuper.isTag() && !cd2.isTag())||
- (!possiblesuper.isTag() && cd2.isTag()))
- return false;
-
- //Handle arrays
- if (cd2.isArray()||possiblesuper.isArray()) {
- // Object is super class of all arrays
- if (possiblesuper.getSymbol().equals(ObjectClass)&&!possiblesuper.isArray())
- return true;
-
- // If we have the same dimensionality of arrays & both are classes, we can default to the normal test
- if (cd2.isClass()&&possiblesuper.isClass()
- &&(possiblesuper.getArrayCount()==cd2.getArrayCount())&&
- isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc()))
- return true;
-
- // Object is superclass of all array classes
- if (possiblesuper.getSymbol().equals(ObjectClass)&&cd2.isClass()
- &&(possiblesuper.getArrayCount()<cd2.getArrayCount()))
- return true;
-
- return false;
- }
-
- if (possiblesuper.isClass()&&
- cd2.isClass())
- return isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc());
- else if (possiblesuper.isClass()&&
- cd2.isNull())
- return true;
- else if (possiblesuper.isNull())
- throw new Error(); //not sure when this case would occur
- else if (possiblesuper.isPrimitive()&&
- cd2.isPrimitive()) {
- ///Primitive widenings from 5.1.2
- if (cd2.isByte()&&(possiblesuper.isByte()||possiblesuper.isShort()||
- possiblesuper.isInt()||possiblesuper.isLong()||
- possiblesuper.isFloat()||possiblesuper.isDouble()))
- return true;
- if (cd2.isShort()&&(possiblesuper.isShort()||
- possiblesuper.isInt()||possiblesuper.isLong()||
- possiblesuper.isFloat()||possiblesuper.isDouble()))
- return true;
- if (cd2.isChar()&&(possiblesuper.isChar()||
- possiblesuper.isInt()||possiblesuper.isLong()||
- possiblesuper.isFloat()||possiblesuper.isDouble()))
- return true;
- if (cd2.isInt()&&(possiblesuper.isInt()||possiblesuper.isLong()||
- possiblesuper.isFloat()||possiblesuper.isDouble()))
- return true;
- if (cd2.isLong()&&(possiblesuper.isLong()||
- possiblesuper.isFloat()||possiblesuper.isDouble()))
- return true;
- if (cd2.isFloat()&&(possiblesuper.isFloat()||possiblesuper.isDouble()))
- return true;
- if (cd2.isDouble()&&possiblesuper.isDouble())
-
- return true;
- if (cd2.isBoolean()&&possiblesuper.isBoolean())
- return true;
-
- return false;
- } else if (possiblesuper.isPrimitive()&&(!possiblesuper.isArray())&&
- (cd2.isArray()||cd2.isPtr()))
- return false;
- else if (cd2.isPrimitive()&&(!cd2.isArray())&&
- (possiblesuper.isArray()||possiblesuper.isPtr()))
- return false;
- else
- throw new Error("Case not handled:"+possiblesuper+" "+cd2);
- }
-
-
- public boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
- if (possiblesuper==cd2)
- return true;
- else
- return isSuper(possiblesuper, cd2);
- }
-
- private boolean isSuper(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
- while(cd2!=null) {
- cd2=getSuper(cd2);
- if (cd2==possiblesuper)
- return true;
- }
- return false;
- }
-}
+++ /dev/null
-package IR;
-import IR.Tree.Modifiers;
-import IR.Tree.ExpressionNode;
-
-/**
- * Descriptor
- *
- * represents a symbol in the language (var name, function name, etc).
- */
-
-public class VarDescriptor extends Descriptor {
-
- protected TypeDescriptor td;
- protected String identifier;
-
- public VarDescriptor(TypeDescriptor t, String identifier) {
- super(identifier);
- this.td=t;
- this.identifier=identifier;
- this.safename = "___" + name + "___";
- this.uniqueid=count++;
- }
-
- public String getName() {
- return identifier;
- }
-
- public TypeDescriptor getType() {
- return td;
- }
-
- public String toString() {
- return td.toString()+" "+identifier;
- }
-
-}
+++ /dev/null
-package IR;
-import java.util.*;
-
-public class Virtual {
- State state;
- Hashtable methodnumber;
- Hashtable classmethodcount;
-
- public int getMethodNumber(MethodDescriptor md) {
- return ((Integer)methodnumber.get(md)).intValue();
- }
-
- public int getMethodCount(ClassDescriptor md) {
- return ((Integer)classmethodcount.get(md)).intValue();
- }
-
- public Virtual(State state) {
- this.state=state;
- methodnumber=new Hashtable();
- classmethodcount=new Hashtable();
- doAnalysis();
- }
-
- private void doAnalysis() {
- Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
- while(classit.hasNext()) {
- ClassDescriptor cd=(ClassDescriptor)classit.next();
- numberMethods(cd);
- }
- }
-
- private int numberMethods(ClassDescriptor cd) {
- if (classmethodcount.containsKey(cd))
- return ((Integer)classmethodcount.get(cd)).intValue();
- ClassDescriptor superdesc=cd.getSuperDesc();
- int start=0;
- if (superdesc!=null)
- start=numberMethods(superdesc);
- for(Iterator it=cd.getMethods();it.hasNext();) {
- MethodDescriptor md=(MethodDescriptor)it.next();
- if (md.isStatic()||md.getReturnType()==null)
- continue;
- if (superdesc!=null) {
- Set possiblematches=superdesc.getMethodTable().getSet(md.getSymbol());
- boolean foundmatch=false;
- for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
- MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
- if (md.matches(matchmd)) {
- int num=((Integer)methodnumber.get(matchmd)).intValue();
- methodnumber.put(md, new Integer(num));
- foundmatch=true;
- break;
- }
- }
- if (!foundmatch)
- methodnumber.put(md, new Integer(start++));
- } else {
- methodnumber.put(md, new Integer(start++));
- }
- }
- classmethodcount.put(cd, new Integer(start));
- return start;
- }
-}
-
+++ /dev/null
-package Interface;
-//****************************************************************************
-// Programmer: Duane M. Gran, ragnar@cs.bsu.edu
-// Program: JhttpServer
-// Date: April 24, 1998
-//****************************************************************************
-
-
-import java.net.*;
-import java.util.*;
-import java.io.*;
-
-//****************************************************************************
-// Class: httpResponse
-// Purpose: constructs the header to be returned by the server
-//****************************************************************************
-
-public class HTTPHeader{
-
- // make a hashtable of return codes to messages
- static private HashStrings rc = new HashStrings();
- static
- {
- rc.put("200", "OK");
- rc.put("403", "Fobidden");
- rc.put("404", "Not found");
- rc.put("501", "Method not implemented");
- }
-
- // hashtable of content type matchings
- static private HashStrings ct = new HashStrings(); // p. 817
- static
- {
- ct.put("txt", "text/plain");
- ct.put("text", "text/plain");
- ct.put("log", "text/plain");
- ct.put("htm", "text/html");
- ct.put("html", "text/html");
- ct.put("gif", "image/gif");
- ct.put("jpg", "image/jpg");
- ct.put("jpeg", "image/jpg");
- ct.put("jpe", "image/jpg");
- ct.put("mpg", "video/mpeg");
- ct.put("mpeg", "video/mpeg");
- ct.put("mpe", "video/mpeg");
- ct.put("qt", "video/quicktime");
- ct.put("mov", "video/quicktime");
- ct.put("au", "audio/basic");
- ct.put("snd", "audio/basic");
- ct.put("wav", "audio/x-wave");
- ct.put("class", "application/octet-stream");
- ct.put("ps", "application/postscript");
- }
-
-//*************************************************************************
-// Constructor: send_header(int, String, int)
-// Purpose: Send an HTTP header
-//*************************************************************************
-
- static public void send_header(OutputStream out, int returnCode,
- String filename, long fileLength){
- String contentType = getContentTypeFor(filename);
- String returnString = (String) rc.get(String.valueOf(returnCode));
- String header;
-
- header = "HTTP/1.0 " + returnCode + " " + returnString + "\n" +
- "Date: " + "1/1/01" + "\n" + // date
- "Expires: 1/1/00\n"+
- "Allow: GET\n" + // allowed methods
- "MIME-Version: 1.0\n" + // mime version
- "Server : SpinWeb Custom HTTP Server\n" + // server type
- "Content-Type: " + contentType + "\n" + // type
- "Content-Length: "+ fileLength + "\n\n"; // length
- try{
- out.write(header.getBytes());
- }
- catch(IOException e){
- e.printStackTrace(); // do nothing!
- }
- }
-
-//*************************************************************************
-// Method: getContentTypeFor(String)
-// Purpose: Looks up the content type (MIME) in a hashtable for the given
-// file suffix. It removes any anchors (#) in case the string is
-// a URL and then operates on the name without path.
-//*************************************************************************
-
- static private String getContentTypeFor(String filename)
- {
- int position = filename.lastIndexOf('#');
- if (position != -1)
- filename = filename.substring(0, position - 1);
-
- File f = new File(filename);
- String name = f.getName(); // name w/o directory
-
- position = name.lastIndexOf('.');
-
- String contentType;
-
- if (position == -1) // if no extension, txt is assigned by default
- contentType = "txt";
- else
- contentType = name.substring(position + 1);
-
- return (String) ct.get(contentType);
- }
-
-}
+++ /dev/null
-package Interface;
-
-
-public class HTTPResponse{
- public int returnCode;
- public long sentBytes;
-}
+++ /dev/null
-package Interface;
-import java.net.*;
-import java.io.*;
-import java.util.*;
-
-public class HTTPServices{
-
- static private String webRoot = ".";
-
- static private FileInputStream get_reader(String fileName,HTTPResponse resp) throws IOException{
-// if(fileName.equals("/daytime")){
-// String date_str = (new Date()).toString();
-// resp.sentBytes = date_str.length();
-// return
-// new StringReader(date_str);
-// }
-
- if(fileName.equals("/viewlog"))
- fileName = LogFile.log_file_name;
- else
- fileName = webRoot + fileName;
-
- File f = new File(fileName);
- resp.sentBytes = f.length();
- return new FileInputStream(f);
- }
-
- public static void GET_handler(String fileName, OutputStream out, HTTPResponse resp){
-
- FileInputStream reader = null;
- byte buffer[];
- int size;
-
- if((reader = HEAD_handler_int(fileName,out,resp)) == null) return;
-
- buffer = new byte[1024];
-
- try{
- while((size = reader.read(buffer,0,buffer.length)) != -1)
- out.write(buffer,0,size);
- reader.close();
- }
- catch(IOException e){
- e.printStackTrace();
- resp.returnCode = 501; // error during transmision
- }
-
- }
-
- public static void POST_handler(String fileName, OutputStream out, HTTPResponse resp){
- GET_handler(fileName,out, resp);
- }
-
- static private FileInputStream HEAD_handler_int(String fileName,
- OutputStream out,HTTPResponse resp){
- FileInputStream reader = null;
-
- try{
- reader = get_reader(fileName, resp);
- resp.returnCode = 200;
- }
- catch(IOException e){
- resp.returnCode = 404; // file not found
- }
-
- if(resp.returnCode == 200)
- HTTPHeader.send_header(out, resp.returnCode, fileName, resp.sentBytes);
- else{
- HTTPHeader.send_header(out, resp.returnCode, fileName, 0);
- return null;
- }
-
- return reader;
- }
-
-
- public static void HEAD_handler(String fileName,
- OutputStream out, HTTPResponse resp){
- HEAD_handler_int(fileName,out,resp);
- }
-}
-
+++ /dev/null
-package Interface;
-
-class HashStrings {
- Pair p[]; // entries in the hash table
- int f; // number of full entries
- public HashStrings() { p = new Pair[38]; f = 0; }
-
- public void put(String key, String value) {
- int n = p.length;
- if (f == n-1) return; // cheese -- a diary product
- int i = key.hashCode() % n;
- while (p[i] != null) {
- if (key.equals(p[i].key)) {
- p[i] = new Pair(key, value);
- return;
- }
- i = (i+1) % n;
- }
- p[i] = new Pair(key, value);
- f = f + 1;
- }
-
- public String get(String key) {
- int n = p.length;
- int i = key.hashCode() % n;
- while (p[i] != null) {
- if (key.equals(p[i].key))
- return p[i].value;
- i = (i+1) % n;
- }
- return null;
- }
-
-}
-
-class Pair {
- String key, value;
- Pair (String key, String value) { this.key = key; this.value = value; }
-}
+++ /dev/null
-package Interface;
-class IdentityRelation{
- String fieldname1;
- String fieldname2;
-
- public IdentityRelation(String fieldname1,String fieldname2) {
- this.fieldname1=fieldname1;
- this.fieldname2=fieldname2;
- }
- public String toString() {
- return fieldname1+"."+fieldname2;
- }
-
- public int hashCode() {
- return fieldname1.hashCode()^fieldname2.hashCode();
- }
-
- public boolean equals(Object obj) {
- if (obj instanceof IdentityRelation) {
- IdentityRelation ir=(IdentityRelation) obj;
- if (fieldname1.equals(ir.fieldname1)&&
- fieldname2.equals(ir.fieldname2))
- return true;
- }
- return false;
- }
-}
+++ /dev/null
-package Interface;
-import java.net.*;
-import java.io.*;
-import java.util.*;
-
-class Imap {
- private Rectangle[] rectangles;
- private Point[] points;
- long THRESHOLD=400;
-
- public Imap(String filename) {
- FileReader fr=null;
- try {
- fr=new FileReader(filename);
- parseFile(fr);
- fr.close();
- } catch (IOException e) {
- System.out.println(e);
- System.exit(-1);
- }
- }
- static class Rectangle {
- String label;
- int x1,y1,x2,y2;
- public Rectangle(String label, int x1,int y1, int x2, int y2) {
- this.label=label;
- this.x1=x1;
- this.y1=y1;
- this.x2=x2;
- this.y2=y2;
- }
- }
-
- String parseclick(int x,int y) {
- System.out.println(x+","+y);
- for(int i=0;i<rectangles.length;i++) {
- Rectangle r=rectangles[i];
- if ((r.x1<=x)&&(r.y1>=y)&&
- (r.x2>=x)&&(r.y2<=y))
- return r.label;
- }
- long mindistance=Long.MAX_VALUE;
- int minindex=-1;
- for(int i=0;i<points.length;i++) {
- Point p=points[i];
- long dx=p.x-x;
- long dy=p.y-y;
- if ((dx*dx+dy*dy)<mindistance) {
- mindistance=dx*dx+dy*dy;
- minindex=i;
- }
- }
- if (mindistance>THRESHOLD)
- return null;
- else
- return points[minindex].label;
- }
-
- static class Point {
- String label;
- int x,y;
- public Point(String label, int x,int y) {
- this.label=label;
- this.x=x;
- this.y=y;
- }
- }
-
- void parseFile(FileReader fr) {
- int firstchar=0;
- ArrayList rectangles=new ArrayList();
- ArrayList points=new ArrayList();
- while(true) {
- try {
- firstchar=fr.read();
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(-1);
- }
- /* EOF?*/
- if (firstchar==-1)
- break;
- switch(firstchar) {
- case'b':
- case'#':
- while(firstchar!='\n') {
- try {
- firstchar=fr.read();
- } catch (IOException e) {
- e.printStackTrace();
- System.exit(-1);
- }
- }
- break;
- case'r':
- {
- nexttoken(fr,false);
- String label=nexttoken(fr,false);
- String x1=nexttoken(fr,true);
- String y1=nexttoken(fr,true);
- String x2=nexttoken(fr,true);
- String y2=nexttoken(fr,true);
- Rectangle r=new Rectangle(label,Integer.parseInt(x1),Integer.parseInt(y1),
- Integer.parseInt(x2),Integer.parseInt(y2));
- rectangles.add(r);
- }
- break;
- case'p':
- {
- nexttoken(fr,false);
- String label=nexttoken(fr,false);
- String x=nexttoken(fr,true);
- String y=nexttoken(fr,true);
- Point p=new Point(label,Integer.parseInt(x),Integer.parseInt(y));
- points.add(p);
- }
- break;
- }
- }
- this.rectangles=(Rectangle[]) rectangles.toArray(new Rectangle[rectangles.size()]);
- this.points=(Point[]) points.toArray(new Point[points.size()]);
- }
-
- String nexttoken(java.io.InputStreamReader isr,boolean commas) {
- String string="";
- int c=0;
- boolean looped=false;
- while(true) {
- try {
- c=isr.read();
- } catch (IOException e) {
- e.printStackTrace();
- System.exit(-1);
- }
- if ((c==' ')||(c=='\n')||(commas&&c==',')) {
- if (!looped) {
- looped=true;
- continue;
- }
- return string;
- }
- string=string+new String(new char[]{(char)c});
- looped=true;
- }
- }
-
-}
-
+++ /dev/null
-package Interface;
-
-//****************************************************************************
-// Programmer: Duane M. Gran, ragnar@cs.bsu.edu
-// Program: JhttpServer
-// Date: April 24, 1998
-//****************************************************************************
-
-import java.net.*;
-import java.io.*;
-
-public class JhttpServer extends Thread{
-
- private ServerSocket server;
- private WebInterface webinterface;
-
-//****************************************************************************
-// Constructor: JhttpServer(int)
-//****************************************************************************
- public JhttpServer(int port, WebInterface webinterface)
- {
- System.out.println("starting...");
- this.webinterface=webinterface;
- try{
- System.out.println("creating the port");
- server = new ServerSocket(port);
- }
- catch (IOException e){
- System.err.println(e);
- System.exit(1);
- }
- }
-
- private void startWorker(Socket client) throws Exception {
- (new JhttpWorker(client,false,webinterface)).start();
- }
-
- public void run(){
- // infinite loop
- while (true){
- try{
- startWorker(server.accept());
- }
- catch (Exception e){
- System.err.println(e);
- }
- }
- }
-}
+++ /dev/null
-package Interface;
-//****************************************************************************
-// Programmer: Duane M. Gran, ragnar@cs.bsu.edu
-// Program: JhttpServer
-// Date: April 24, 1998
-//****************************************************************************
-
-
-import java.net.*;
-import java.io.*;
-import java.util.*;
-
-//****************************************************************************
-// Class: JhttpWorker
-// Purpose: Takes an HTTP request and executes it in a separate thread
-//****************************************************************************
-
-public class JhttpWorker extends Thread{
- public String fileName = null;
- public String methodType = null;
- public String httpVersion = "http/1.0";
- private Socket client;
- public int fileLength, returnCode;
- private boolean logging;
- private WebInterface webinterface;
-
- public JhttpWorker(Socket client, boolean logging, WebInterface webinterface) {
- this.client=client;
- this.logging=logging;
- this.webinterface=webinterface;
- }
-
- public void run(){
- HTTPResponse resp = new HTTPResponse();
-
- BufferedReader in = null;
- OutputStream out = null;
-
- resp.returnCode = 200;
- resp.sentBytes = 0;
-
- try {
-
- in = new BufferedReader(
- new InputStreamReader(
- client.getInputStream()));
-
- out = client.getOutputStream();
- }
- catch(IOException e){
- // I'm not too good at HTTP. Normally, we should put some
- // error code here. Anyway, I have assumed that an error
- // is equivalent to an unhandled request / method (501)
- resp.returnCode = 501;
- }
-
- if(resp.returnCode == 200){
- // call the appropriate hanndler
- switch(method(in)){
-
- case 0:
- if (webinterface.specialRequest(fileName)) {
- String newfile=webinterface.handleresponse(fileName, out, resp);
- if (newfile!=null) {
- HTTPServices.GET_handler(newfile, out, resp);
- }
- } else
- HTTPServices.GET_handler(fileName, out, resp);
- break;
- case 1:
- HTTPServices.HEAD_handler(fileName, out, resp);
- break;
- case 2:
- HTTPServices.POST_handler(fileName, out, resp);
- break;
- default:
- resp.returnCode = 501; //error
- }
-
- try{
- out.flush();
- if (logging)
- LogFile.write_log(client,methodType,fileName,httpVersion,
- resp.returnCode,resp.sentBytes);
-
- out.close();
- in.close();
- client.close();
- }
- catch(IOException e){
- ; // do nothing
- }
- }
-
- // System.out.println(fileName + " is going to finish"); // debug
- }
-
-//*****************************************************************************
-// Function: method()
-// Purpose: Open an InputStream and parse the request made.
-// Note: Regardless of what method is requested, right now it performs a
-// GET operation.
-// Calls:
-// Returns: Boolean value for success or failure
-//*****************************************************************************
-
- private int method(BufferedReader in){
- int ret = -1;
-
- try{
- String line;
-
- // read just the first line
- line = in.readLine();
- // only spaces used
- StringTokenizer tok = new StringTokenizer(line, " ");
- if (tok.hasMoreTokens()) // make sure there is a request
- {
- String str = tok.nextToken();
-
- if ( str.equals("GET") ){
- ret = 0;
- methodType = "GET";
- }
- else if ( str.equals("HEAD") ){
- ret = 1;
- methodType = "HEAD";
- }
- else if ( str.equals("POST") ){
- ret = 2;
- methodType = "POST";
- }
- else{
- System.out.println("501 - unsupported request:" +str);
- return -1;
- }
- }
- else{
- // System.out.println("Request from browser was empty!");
- return -1;
- }
-
- // get the filename
- if (tok.hasMoreTokens())
- {
- fileName = tok.nextToken();
- if(fileName.equals("/"))
- {
- fileName = "/index.html";
- }
- }
- else
- {
- // this is weird... why am i taking the first character of
- // the filename if there are no more tokens?
- // - catch should take care of this
- fileName = fileName.substring(1);
- }
-
- // read the http version number
- // - right now nothing is done with this information
- if (tok.hasMoreTokens())
- {
- httpVersion = tok.nextToken();
- }
- else
- {
- httpVersion = "http/1.0"; // default
- }
-
- // read remainder of the browser's header
- // - nothing done right now with this info... placeholder
- while((line = in.readLine()) != null)
- {
- StringTokenizer token = new StringTokenizer(line," ");
-
- // do processing here
- if(!token.hasMoreTokens())
- {
- break;
- }
- }
- }
- catch(Exception e){
- System.err.println(e);
- return -1;
- }
-
- return ret;
- }
-}
+++ /dev/null
-package Interface;
-//****************************************************************************
-// Programmer: Duane M. Gran, ragnar@cs.bsu.edu
-// Program: JhttpServer
-// Date: April 24, 1998
-//****************************************************************************
-
-
-
-import java.io.*;
-import java.util.*;
-import java.text.SimpleDateFormat;
-import java.net.*;
-
-//****************************************************************************
-// Class: logFile
-// Purpose: Handle the behavior for logging connections. The methods simply
-// add to the private data fields. Has implementation for standard
-// output, as well as output to file.
-//
-// An example log entry looks like:
-//
-// 1.2.3.4 - - [29/JAN/1998:21:40:30 -06] "GET /file.html HTTP/1.0" 200 472
-//
-//****************************************************************************
-
-public class LogFile
-{
- static public final String log_file_name = "server.log";
-
- static public String write_log(Socket s, String Method, String URI,
- String Protocol,
- int ReturnCode, long BytesSent){
-
- // Socket.toString() calls (indirectly) some Hashtable.get
- // method - I tool care of it!
-
- /*
- String addr = s.toString();
- String Address = addr.substring(addr.indexOf('/') + 1,
- addr.indexOf(','));
- */
-
- // SimpleDateFormat sdf =
- // new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz"); // RFC 1123
- // sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
- // String Date = sdf.format(new Date());
-
- String Entry =
- /* Address + */ " - - [" + // IP address
- "Date" + "] \"" + // date
- Method + " " + // get, post, head
- URI + " " + // filename
- Protocol + "\" " + // http/1.?
- ReturnCode + " " + // 200-500
- BytesSent + "\n"; // bytes sent
-
- try{
- BufferedWriter out = new BufferedWriter(
- new OutputStreamWriter(
- new FileOutputStream(log_file_name, true)));
-
- out.write(Entry,0,Entry.length());
- out.flush();
- out.close();
- }
- catch (IOException e){
- System.err.println("Gicu " + e);
- }
-
- return Entry;
- }
-}
+++ /dev/null
-package Interface;
-import java.io.*;
-import Analysis.TaskStateAnalysis.*;
-import IR.*;
-import java.util.*;
-import Util.Namer;
-
-public class WebInterface {
- TaskAnalysis taskanalysis;
- TaskGraph taskgraph;
- TagAnalysis taganalysis;
- State state;
- Hashtable flagstatemap;
- Hashtable taskgraphmap;
- Hashtable sourcenodemap; //to hold the filenames for each of the pages linked to the source nodes.
- Hashtable taskmap; // to hold the filenames for each of the pages linked to tasks in the program.
- GarbageAnalysis garbageanalysis;
-
- public WebInterface(State state, TaskAnalysis taskanalysis, TaskGraph taskgraph, GarbageAnalysis garbageanalysis, TagAnalysis taganalysis) {
- this.state=state;
- this.taskanalysis=taskanalysis;
- this.taskgraph=taskgraph;
- this.garbageanalysis=garbageanalysis;
- this.taganalysis=taganalysis;
-
- flagstatemap=new Hashtable();
- taskgraphmap=new Hashtable();
- taskmap = new Hashtable();
- sourcenodemap=new Hashtable();
-
- for(Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator();it_tasks.hasNext();){
- TaskDescriptor td=(TaskDescriptor)it_tasks.next();
- taskmap.put("/"+td.getSymbol()+".html",td);
- }
-
- for(Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator();it_classes.hasNext();) {
- ClassDescriptor cd=(ClassDescriptor) it_classes.next();
- if(cd.hasFlags()){
- Vector rootnodes=taskanalysis.getRootNodes(cd);
-
- if(rootnodes!=null)
- for(Iterator it_rootnodes=rootnodes.iterator();it_rootnodes.hasNext();){
- FlagState root=(FlagState)it_rootnodes.next();
- Vector cd_nodeid=new Vector(); //Vector is designed to contain only 2 elements: ClassDescriptor,Node label
- // Both the values are required to correctly resolve the rootnode.
- // Should think of a better way to do this, instead of using a vector(maybe a class)
- cd_nodeid.addElement(cd); //adding the ClassDescriptor
- cd_nodeid.addElement(root.getLabel()); //adding the Node label
- System.out.println(cd+" "+root.getLabel());
- sourcenodemap.put("/"+cd.getSymbol()+"_"+root.getLabel()+".html",cd_nodeid);
- }
- }
- }
- }
-
- public boolean specialRequest(String filename) {
- System.out.println(filename);
- if (filename.equals("/index.html"))
- return true;
- if (filename.equals("/UnifiedTaskGraph.html"))
- return true;
- if (flagstatemap.containsKey(filename))
- return true;
- if (taskgraphmap.containsKey(filename))
- return true;
- if (taskmap.containsKey(filename))
- return true;
- if (sourcenodemap.containsKey(filename))
- return true;
- return false;
- }
-
- public String handleresponse(String filename, OutputStream out, HTTPResponse resp) {
- if (filename.equals("/index.html"))
- return indexpage(out, resp);
- if (filename.equals("/UnifiedTaskGraph.html"))
- return unifiedTaskGraph(out,resp);
- if (flagstatemap.containsKey(filename))
- return flagstate((ClassDescriptor) flagstatemap.get(filename), out, resp);
- if (taskgraphmap.containsKey(filename))
- return taskstate((ClassDescriptor) taskgraphmap.get(filename), out, resp);
- if (taskmap.containsKey(filename))
- return task((TaskDescriptor)taskmap.get(filename),out,resp);
- if (sourcenodemap.containsKey(filename))
- return sourcenode((Vector) sourcenodemap.get(filename), out, resp);
- return "NORESP";
- }
-
- private String task(TaskDescriptor td, OutputStream out, HTTPResponse resp){
- try{
- PrintWriter pw=new PrintWriter(out);
- pw.println("<br><br><h3>Task: "+td.toString()+"</h3><br>");
- printTask(td,pw);
-
- //printing out the classes that are instantiated by this task
- pw.println("<br><h3>Instantiated Classes:</h3>");
- Set newstates=taganalysis.getFlagStates(td);
- for(Iterator fsit=newstates.iterator();fsit.hasNext();) {
- FlagState fsnew=(FlagState) fsit.next();
- ClassDescriptor cd=fsnew.getClassDescriptor();
- pw.println(" <a href=\"/"+cd.getSymbol()+".html\">"+cd.getSymbol()+"</a><br>");
- pw.println(" "+fsnew.getTextLabel()+"<br>");
- }
-
- pw.flush();
- } catch (Exception e) {e.printStackTrace();System.exit(-1);}
- return null;
- }
-
- private String printTask(TaskDescriptor td, PrintWriter pw){
- try{
-
- for(int i=0; i < td.numParameters();i++){
- pw.println("FlagState Graph: <a href=\"/"+td.getParamType(i)+".html\">"+td.getParamType(i)+"</a><br>");
- pw.println("Task Graph: <a href=\"/"+td.getParamType(i)+"-t.html\">"
- +td.getParamType(i)+"</a><br>");
- }
- pw.flush();
- }catch(Exception e) {e.printStackTrace();System.exit(-1);}
- return null;
- }
-
- private String sourcenode(Vector cd_nodeid,OutputStream out, HTTPResponse resp){
- Vector rootnodes=taskanalysis.getRootNodes((ClassDescriptor)cd_nodeid.elementAt(0));
- for(Iterator it_rootnodes=rootnodes.iterator();it_rootnodes.hasNext();){
- FlagState root=(FlagState)it_rootnodes.next();
- if (root.getLabel().equals((String)cd_nodeid.elementAt(1))){
- try{
- PrintWriter pw=new PrintWriter(out);
- pw.println("<br><br><h3>Allocating tasks for "+root.getTextLabel()+":</h3><br>");
- Vector tasks=root.getAllocatingTasks();
- for(Iterator it_tasks=tasks.iterator();it_tasks.hasNext();){
- TaskDescriptor td=(TaskDescriptor)it_tasks.next();
- pw.println("<br><strong>Task: "+td.toString()+"</strong><br>");
- printTask(td,pw);
- }
-
- } catch (Exception e) {e.printStackTrace();System.exit(-1);}
- break;
- }
-
- }
- return null;
- }
-
- private String flagstate(ClassDescriptor cd, OutputStream out, HTTPResponse resp) {
- Set objects=taskanalysis.getFlagStates(cd);
- File file=new File(cd.getSymbol()+".dot");
- File mapfile;
- String str;
- Vector namers=new Vector();
- namers.add(new Namer());
- namers.add(garbageanalysis);
- namers.add(new Allocations());
- namers.add(new TaskEdges());
- try {
- //Generate jpg
- Runtime r=Runtime.getRuntime();
-
- FileOutputStream dotstream=new FileOutputStream(file,false);
- FlagState.DOTVisitor.visit(dotstream, objects, namers);
- dotstream.close();
- Process p=r.exec("dot -Tcmapx -o"+cd.getSymbol()+".map -Tjpg -o"+cd.getSymbol()+".jpg "+cd.getSymbol()+".dot");
- p.waitFor();
- p=r.exec("dot -Tps "+cd.getSymbol()+".dot -o"+cd.getSymbol()+".ps");
- p.waitFor();
-
- mapfile=new File(cd.getSymbol()+".map");
- BufferedReader mapbr=new BufferedReader(new FileReader(mapfile));
- PrintWriter pw=new PrintWriter(out);
- pw.println("<a href=\"/"+ cd.getSymbol()+".ps\">ps</a><br>");
- //pw.println("<a href=\"/"+ cd.getSymbol()+".map\"><img src=\"/"+ cd.getSymbol()+".gif\" ismap=\"ismap\"></A>");
- pw.println("<img src=\""+cd.getSymbol()+".jpg\" usemap=\"#dotvisitor\" />");
- while((str=mapbr.readLine())!=null){
- pw.println(str);
- }
-
- pw.flush();
- } catch (Exception e) {e.printStackTrace();System.exit(-1);}
- return null;
- }
-
- private String taskstate(ClassDescriptor cd, OutputStream out, HTTPResponse resp) {
- Set objects=taskgraph.getTaskNodes(cd);
- File file=new File(cd.getSymbol()+"-t.dot");
- File mapfile;
- String str;
- Vector namers=new Vector();
- namers.add(new Namer());
- namers.add(new TaskNodeNamer());
-
- try {
- //Generate jpg
- Runtime r=Runtime.getRuntime();
- FileOutputStream dotstream=new FileOutputStream(file,false);
- FlagState.DOTVisitor.visit(dotstream, objects,namers);
- dotstream.close();
- Process p=r.exec("dot -Tcmapx -o"+cd.getSymbol()+"-t.map -Tjpg -o"+cd.getSymbol()+"-t.jpg "+cd.getSymbol()+"-t.dot");
- p.waitFor();
- p=r.exec("dot -Tps "+cd.getSymbol()+".dot -o"+cd.getSymbol()+"-t.ps");
-
- p.waitFor();
-
- mapfile=new File(cd.getSymbol()+"-t.map");
- BufferedReader mapbr=new BufferedReader(new FileReader(mapfile));
- PrintWriter pw=new PrintWriter(out);
- pw.println("<a href=\"/"+ cd.getSymbol()+"-t.ps\">ps</a><br>");
- // pw.println("<a href=\"/"+ cd.getSymbol()+"-t.map\"><img src=\"/"+ cd.getSymbol()+"-t.gif\" ismap=\"ismap\"></A>");
- pw.println("<img src=\""+cd.getSymbol()+"-t.jpg\" usemap=\"#dotvisitor\" />");
-
- while((str=mapbr.readLine())!=null){
- pw.println(str);
- }
- pw.flush();
- } catch (Exception e) {e.printStackTrace();System.exit(-1);}
- return null;
- }
-
- /* public void taskgraph(
-*/
-
- private String indexpage(OutputStream out, HTTPResponse resp) {
-
- PrintWriter pw=new PrintWriter(out);
- for(Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator();it_classes.hasNext();) {
- ClassDescriptor cd=(ClassDescriptor) it_classes.next();
- if (taskanalysis.getFlagStates(cd)!=null) {
- pw.println("<a href=\""+cd.getSymbol()+".html\">"+ cd.getSymbol() +"</a>");
- pw.println("<br>");
- flagstatemap.put("/"+cd.getSymbol()+".html", cd);
- }
- if (taskgraph.getTaskNodes(cd)!=null) {
- pw.println("<a href=\""+cd.getSymbol()+"-t.html\">Task Graph "+ cd.getSymbol() +"</a>");
- pw.println("<br>");
- taskgraphmap.put("/"+cd.getSymbol()+"-t.html", cd);
- }
- }
- pw.println("<br><br><a href=\"/UnifiedTaskGraph.html\">Program flow</a>");
- pw.flush();
- return null;
- }
-
- private String unifiedTaskGraph(OutputStream out, HTTPResponse resp){
- Set objects=taskgraph.getAllTaskNodes();
- File file=new File("UnifiedTaskGraph.dot");
- String str;
- Vector namers=new Vector();
- namers.add(new Namer());
- namers.add(new TaskNodeNamer());
-
- try {
- //Generate jpg
- Runtime r=Runtime.getRuntime();
- FileOutputStream dotstream=new FileOutputStream(file,false);
- FlagState.DOTVisitor.visit(dotstream, objects, namers);
- dotstream.close();
- Process p=r.exec("dot -Tjpg -oUnifiedTaskGraph.jpg -Tcmapx -oUnifiedTaskGraph.map UnifiedTaskGraph.dot");
- p.waitFor();
- p=r.exec("dot -Tps UnifiedTaskGraph.dot -oUnifiedTaskGraph.ps");
-
- p.waitFor();
-
- File mapfile=new File("UnifiedTaskGraph.map");
- BufferedReader mapbr=new BufferedReader(new FileReader(mapfile));
- PrintWriter pw=new PrintWriter(out);
- pw.println("<a href=\"/UnifiedTaskGraph.ps\">ps</a><br>");
- // pw.println("<a href=\"/"+ cd.getSymbol()+"-t.map\"><img src=\"/"+ cd.getSymbol()+"-t.gif\" ismap=\"ismap\"></A>");
- pw.println("<img src=\"/UnifiedTaskGraph.jpg\" usemap=\"#dotvisitor\" />");
-
- while((str=mapbr.readLine())!=null)
- pw.println(str);
-
- pw.flush();
- } catch (Exception e) {e.printStackTrace();System.exit(-1);}
- return null;
- }
-
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class BooleanLiteral extends Literal {
- Boolean val;
- BooleanLiteral(boolean b) { this.val = new Boolean(b); }
-
- Symbol token() { return new Symbol(Sym.BOOLEAN_LITERAL, val); }
-
- public String toString() { return "BooleanLiteral <"+val.toString()+">"; }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class CharacterLiteral extends Literal {
- Character val;
- CharacterLiteral(char c) { this.val = new Character(c); }
-
- Symbol token() { return new Symbol(Sym.CHARACTER_LITERAL, val); }
-
- public String toString() {
- return "CharacterLiteral <"+Token.escape(val.toString())+">";
- }
-}
+++ /dev/null
-package Lex;
-
-abstract class Comment extends InputElement {
- private StringBuffer comment = new StringBuffer();
-
- String getComment() { return comment.toString(); }
-
- void appendLine(String more) { // 'more' is '\n' terminated.
- int i=0;
-
- // skip leading white space.
- for (; i<more.length(); i++)
- if (!Character.isSpaceChar(more.charAt(i)))
- break;
-
- // skip any leading stars.
- for (; i<more.length(); i++)
- if (more.charAt(i)!='*')
- break;
-
- // the rest of the string belongs to the comment.
- if (i<more.length())
- comment.append(more.substring(i));
- }
-
-}
+++ /dev/null
-package Lex;
-
-class DocumentationComment extends Comment {
- DocumentationComment() { }
-}
-
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class DoubleLiteral extends NumericLiteral {
- DoubleLiteral(double d) { this.val = new Double(d); }
-
- Symbol token() { return new Symbol(Sym.FLOATING_POINT_LITERAL, val); }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class EOF extends Token {
- EOF() {}
- Symbol token() { return new Symbol(Sym.EOF); }
- public String toString() { return "EOF"; }
-}
+++ /dev/null
-package Lex;
-
-class EndOfLineComment extends Comment {
- EndOfLineComment(String comment) { appendLine(comment); }
-}
+++ /dev/null
-package Lex;
-
-import java.io.Reader;
-import java.io.FilterReader;
-import java.io.IOException;
-
-public class EscapedUnicodeReader extends FilterReader {
-
- int pushback=-1;
- boolean isEvenSlash = true;
-
- public EscapedUnicodeReader(Reader in) {
- super(in);
- }
- public int read() throws IOException {
- int r = (pushback==-1)?in.read():pushback; pushback=-1;
-
- if (r!='\\') {
- isEvenSlash=true;
- return r;
- } else { // found a backslash;
- if (!isEvenSlash) { // Only even slashes are eligible unicode escapes.
- isEvenSlash=true;
- return r;
- }
-
- // Check for the trailing u.
- pushback=in.read();
- if (pushback!='u') {
- isEvenSlash=false;
- return '\\';
- }
-
- // OK, we've found backslash-u.
- // Reset pushback and snarf up all trailing u's.
- pushback=-1;
- while((r=in.read())=='u')
- ;
- // Now we should find 4 hex digits.
- // If we don't, we can raise bloody hell.
- int val=0;
- for (int i=0; i<4; i++, r=in.read()) {
- int d=Character.digit((char)r, 16);
- if (r<0 || d<0)
- throw new Error("Invalid unicode escape character.");
- val = (val*16) + d;
- }
- // yeah, we made it.
- pushback = r;
- isEvenSlash=true;
- return val;
- }
- }
- // synthesize array read from single-character read.
- public int read(char cbuf[], int off, int len) throws IOException {
- for (int i=0; i<len; i++) {
- int c = read();
- if (c==-1) return (i==0)?-1:i; // end of stream reached.
- else cbuf[i+off] = (char) c;
- }
- return len;
- }
-
- public boolean markSupported() { return false; }
-
- public boolean ready() throws IOException {
- if (pushback!=-1) return true;
- else return in.ready();
- }
-}
+++ /dev/null
-package Lex;
-
-/** FIFO class. This helps implement the lookahead we need for JSR-14.
- * Copyright (C) 2002 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This program is released under the terms of the GPL; see the file
- * COPYING for more details. There is NO WARRANTY on this code.
- */
-
-class FIFO {
- java_cup.runtime.Symbol[] backing = new java_cup.runtime.Symbol[10];
- int start=0, end=0;
- final Getter getter;
- FIFO(Getter getter) { this.getter = getter; }
- public boolean isEmpty() { return start==end; }
- private boolean isFull() {
- return start==end+1 || (start==0 && end==backing.length-1);
- }
- private int size() {
- return ((end<start)?end+backing.length:end)-start;
- }
- public void put(java_cup.runtime.Symbol o) {
- if (isFull()) {
- java_cup.runtime.Symbol[] nbacking =
- new java_cup.runtime.Symbol[backing.length*2];
- System.arraycopy(backing, start, nbacking, 0, backing.length-start);
- System.arraycopy(backing, 0, nbacking, backing.length-start, start);
- start = 0;
- end = backing.length-1;
- backing = nbacking;
- }
- ASSERT(!isFull());
- backing[end++] = o;
- if (end == backing.length)
- end = 0;
- ASSERT(!isEmpty());
- }
- public java_cup.runtime.Symbol get() throws java.io.IOException {
- if (isEmpty())
- put(getter.next());
- ASSERT(!isEmpty());
- java_cup.runtime.Symbol o = backing[start++];
- if (start == backing.length)
- start = 0;
- ASSERT(!isFull());
- return o;
- }
- public java_cup.runtime.Symbol peek(int i) throws java.io.IOException {
- while (i >= size())
- put(getter.next());
- int index = start+i;
- if (index >= backing.length) index -= backing.length;
- ASSERT(0<= index && index < backing.length);
- return backing[index];
- }
- abstract static class Getter {
- abstract java_cup.runtime.Symbol next()
- throws java.io.IOException;
- }
- private static void ASSERT(boolean b) {
- if (!b) throw new RuntimeException();
- }
-}
-
-
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class FloatLiteral extends NumericLiteral {
- FloatLiteral(float f) { this.val = new Float(f); }
-
- Symbol token() { return new Symbol(Sym.FLOATING_POINT_LITERAL, val); }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-public class Identifier extends Token {
- String identifier;
- public Identifier(String identifier) { this.identifier=identifier; }
-
- public String toString() { return "Identifier <"+identifier+">"; }
-
- /* Ben Walter <bwalter@mit.edu> correctly pointed out that
- * the first released version of this grammar/lexer did not
- * return the string value of the identifier in the parser token.
- * Should be fixed now. ;-) <cananian@alumni.princeton.edu>
- */
- Symbol token() { return new Symbol(Sym.IDENTIFIER, identifier); }
-}
+++ /dev/null
-package Lex;
-
-abstract class InputElement {}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class IntegerLiteral extends NumericLiteral {
- IntegerLiteral(int i) { this.val = new Integer(i); }
-
- Symbol token() { return new Symbol(Sym.INTEGER_LITERAL, val); }
-}
+++ /dev/null
-package Lex;
-
-import java.util.Hashtable;
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class Keyword extends Token {
- String keyword;
- Keyword(String s) { keyword = s; }
-
- Symbol token() {
- Integer i = (Integer) key_table.get(keyword);
- return new Symbol(i.intValue());
- }
- public String toString() { return "Keyword <"+keyword+">"; }
-
- static private final Hashtable key_table = new Hashtable();
- static {
- key_table.put("abstract", new Integer(Sym.ABSTRACT));
- key_table.put("assert", new Integer(Sym.ASSERT));
- key_table.put("boolean", new Integer(Sym.BOOLEAN));
- key_table.put("break", new Integer(Sym.BREAK));
- key_table.put("byte", new Integer(Sym.BYTE));
- key_table.put("case", new Integer(Sym.CASE));
- key_table.put("catch", new Integer(Sym.CATCH));
- key_table.put("char", new Integer(Sym.CHAR));
- key_table.put("class", new Integer(Sym.CLASS));
- key_table.put("const", new Integer(Sym.CONST));
- key_table.put("continue", new Integer(Sym.CONTINUE));
- key_table.put("default", new Integer(Sym.DEFAULT));
- key_table.put("do", new Integer(Sym.DO));
- key_table.put("double", new Integer(Sym.DOUBLE));
- key_table.put("else", new Integer(Sym.ELSE));
- key_table.put("enum", new Integer(Sym.ENUM));
- key_table.put("extends", new Integer(Sym.EXTENDS));
- key_table.put("final", new Integer(Sym.FINAL));
- key_table.put("finally", new Integer(Sym.FINALLY));
- key_table.put("float", new Integer(Sym.FLOAT));
- key_table.put("for", new Integer(Sym.FOR));
- key_table.put("goto", new Integer(Sym.GOTO));
- key_table.put("if", new Integer(Sym.IF));
- key_table.put("import", new Integer(Sym.IMPORT));
- key_table.put("instanceof", new Integer(Sym.INSTANCEOF));
- key_table.put("int", new Integer(Sym.INT));
- key_table.put("long", new Integer(Sym.LONG));
- key_table.put("native", new Integer(Sym.NATIVE));
- key_table.put("new", new Integer(Sym.NEW));
- key_table.put("package", new Integer(Sym.PACKAGE));
- key_table.put("private", new Integer(Sym.PRIVATE));
- key_table.put("protected", new Integer(Sym.PROTECTED));
- key_table.put("public", new Integer(Sym.PUBLIC));
- key_table.put("return", new Integer(Sym.RETURN));
- key_table.put("short", new Integer(Sym.SHORT));
- key_table.put("static", new Integer(Sym.STATIC));
- key_table.put("strictfp", new Integer(Sym.STRICTFP));
- key_table.put("super", new Integer(Sym.SUPER));
- key_table.put("switch", new Integer(Sym.SWITCH));
- key_table.put("synchronized", new Integer(Sym.SYNCHRONIZED));
- key_table.put("this", new Integer(Sym.THIS));
- key_table.put("throw", new Integer(Sym.THROW));
- key_table.put("throws", new Integer(Sym.THROWS));
- key_table.put("transient", new Integer(Sym.TRANSIENT));
- key_table.put("try", new Integer(Sym.TRY));
- key_table.put("void", new Integer(Sym.VOID));
- key_table.put("volatile", new Integer(Sym.VOLATILE));
- key_table.put("while", new Integer(Sym.WHILE));
- //Keywords for failure aware computation
- key_table.put("flag", new Integer(Sym.FLAG));
- key_table.put("external", new Integer(Sym.EXTERNAL));
- key_table.put("optional", new Integer(Sym.OPTIONAL));
- key_table.put("tag", new Integer(Sym.TAG));
- key_table.put("task", new Integer(Sym.TASK));
- key_table.put("taskexit", new Integer(Sym.TASKEXIT));
- //Keywords for transactions
- key_table.put("atomic", new Integer(Sym.ATOMIC));
- key_table.put("global", new Integer(Sym.GLOBAL));
- }
-}
+++ /dev/null
-package Lex;
-
-import java.io.Reader;
-import java.io.LineNumberReader;
-import Parse.Sym;
-
-/* Java lexer.
- * Copyright (C) 2002 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This program is released under the terms of the GPL; see the file
- * COPYING for more details. There is NO WARRANTY on this code.
- */
-
-public class Lexer {
- LineNumberReader reader;
- boolean isJava12;
- boolean isJava14;
- boolean isJava15;
- String line = null;
- int line_pos = 1;
- int line_num = 0;
- LineList lineL = new LineList(-line_pos, null); // sentinel for line #0
-
- public Lexer(Reader reader) {
- this.reader = new LineNumberReader(new EscapedUnicodeReader(reader));
- this.isJava12 = true;
- this.isJava14 = true;
- }
-
- public java_cup.runtime.Symbol nextToken() throws java.io.IOException {
- java_cup.runtime.Symbol sym =
- lookahead==null ? _nextToken() : lookahead.get();
- last = sym;
- return sym;
- }
- private boolean shouldBePLT() throws java.io.IOException {
- // look ahead to see if this LT should be changed to a PLT
- if (last==null || last.sym!=Sym.IDENTIFIER)
- return false;
- if (lookahead==null) lookahead = new FIFO(new FIFO.Getter() {
- java_cup.runtime.Symbol next() throws java.io.IOException
- { return _nextToken(); }
- });
- int i=0;
- // skip past IDENTIFIER (DOT IDENTIFIER)*
- if (lookahead.peek(i++).sym != Sym.IDENTIFIER)
- return false;
- while (lookahead.peek(i).sym == Sym.DOT) {
- i++;
- if (lookahead.peek(i++).sym != Sym.IDENTIFIER)
- return false;
- }
- // skip past (LBRACK RBRACK)*
- while (lookahead.peek(i).sym == Sym.LBRACK) {
- i++;
- if (lookahead.peek(i++).sym != Sym.RBRACK)
- return false;
- }
- // now the next sym has to be one of LT GT COMMA EXTENDS IMPLEMENTS
- switch(lookahead.peek(i).sym) {
- default:
- return false;
- case Sym.LT:
- case Sym.GT:
- case Sym.COMMA:
- case Sym.EXTENDS:
- return true;
- }
- }
- private java_cup.runtime.Symbol last = null;
- private FIFO lookahead = null;
- public java_cup.runtime.Symbol _nextToken() throws java.io.IOException {
- /* tokens are:
- * Identifiers/Keywords/true/false/null (start with java letter)
- * numeric literal (start with number)
- * character literal (start with single quote)
- * string (start with double quote)
- * separator (parens, braces, brackets, semicolon, comma, period)
- * operator (equals, plus, minus, etc)
- * whitespace
- * comment (start with slash)
- */
- InputElement ie;
- int startpos, endpos;
- do {
- startpos = lineL.head + line_pos;
- ie = getInputElement();
- if (ie instanceof DocumentationComment)
- comment = ((Comment)ie).getComment();
- } while (!(ie instanceof Token));
- endpos = lineL.head + line_pos - 1;
-
- // System.out.println(ie.toString()); // uncomment to debug lexer.
- java_cup.runtime.Symbol sym = ((Token)ie).token();
- // fix up left/right positions.
- sym.left = startpos; sym.right = endpos;
- // return token.
- return sym;
- }
- public boolean debug_lex() throws java.io.IOException {
- InputElement ie = getInputElement();
- System.out.println(ie);
- return !(ie instanceof EOF);
- }
-
- String comment;
- public String lastComment() { return comment; }
- public void clearComment() { comment=""; }
-
- InputElement getInputElement() throws java.io.IOException {
- if (line_num == 0)
- nextLine();
- if (line==null)
- return new EOF();
- if (line.length()<=line_pos) { // end of line.
- nextLine();
- if (line==null)
- return new EOF();
- }
-
- switch (line.charAt(line_pos)) {
-
- // White space:
- case ' ': // ASCII SP
- case '\t': // ASCII HT
- case '\f': // ASCII FF
- case '\n': // LineTerminator
- return new WhiteSpace(consume());
-
- // EOF character:
- case '\020': // ASCII SUB
- consume();
- return new EOF();
-
- // Comment prefix:
- case '/':
- return getComment();
-
- // else, a Token
- default:
- return getToken();
- }
- }
- // May get Token instead of Comment.
- InputElement getComment() throws java.io.IOException {
- String comment;
- // line.charAt(line_pos+0) is '/'
- switch (line.charAt(line_pos+1)) {
- case '/': // EndOfLineComment
- comment = line.substring(line_pos+2);
- line_pos = line.length();
- return new EndOfLineComment(comment);
- case '*': // TraditionalComment or DocumentationComment
- line_pos += 2;
- if (line.charAt(line_pos)=='*') { // DocumentationComment
- return snarfComment(new DocumentationComment());
- } else { // TraditionalComment
- return snarfComment(new TraditionalComment());
- }
- default: // it's a token, not a comment.
- return getToken();
- }
- }
-
- Comment snarfComment(Comment c) throws java.io.IOException {
- StringBuffer text=new StringBuffer();
- while(true) { // Grab CommentTail
- while (line.charAt(line_pos)!='*') { // Add NotStar to comment.
- int star_pos = line.indexOf('*', line_pos);
- if (star_pos<0) {
- text.append(line.substring(line_pos));
- c.appendLine(text.toString()); text.setLength(0);
- line_pos = line.length();
- nextLine();
- if (line==null)
- throw new Error("Unterminated comment at end of file.");
- } else {
- text.append(line.substring(line_pos, star_pos));
- line_pos=star_pos;
- }
- }
- // At this point, line.charAt(line_pos)=='*'
- // Grab CommentTailStar starting at line_pos+1.
- if (line.charAt(line_pos+1)=='/') { // safe because line ends with '\n'
- c.appendLine(text.toString()); line_pos+=2; return c;
- }
- text.append(line.charAt(line_pos++)); // add the '*'
- }
- }
-
- Token getToken() {
- // Tokens are: Identifiers, Keywords, Literals, Separators, Operators.
- switch (line.charAt(line_pos)) {
- // Separators: (period is a special case)
- case '(':
- case ')':
- case '{':
- case '}':
- case '[':
- case ']':
- case ';':
- case ',':
- return new Separator(consume());
-
- // Operators:
- case '=':
- case '>':
- case '<':
- case '!':
- case '~':
- case '?':
- case ':':
- case '&':
- case '|':
- case '+':
- case '-':
- case '*':
- case '/':
- case '^':
- case '%':
- return getOperator();
- case '\'':
- return getCharLiteral();
- case '\"':
- return getStringLiteral();
-
- // a period is a special case:
- case '.':
- if (Character.digit(line.charAt(line_pos+1),10)!=-1)
- return getNumericLiteral();
- else if (isJava15 &&
- line.charAt(line_pos+1)=='.' &&
- line.charAt(line_pos+2)=='.') {
- consume(); consume(); consume();
- return new Separator('\u2026'); // unicode ellipsis character.
- } else return new Separator(consume());
- default:
- break;
- }
- if (Character.isJavaIdentifierStart(line.charAt(line_pos)))
- return getIdentifier();
- if (Character.isDigit(line.charAt(line_pos)))
- return getNumericLiteral();
- throw new Error("Illegal character on line "+line_num);
- }
-
- static final String[] keywords = new String[] {
- "abstract", "assert", "atomic", "boolean", "break", "byte", "case", "catch", "char",
- "class", "const", "continue", "default", "do", "double", "else", "enum",
- "extends", "external", "final", "finally",
- "flag", //keyword for failure aware computation
- "float", "for", "global", "goto", "if",
- "implements", "import", "instanceof", "int", "interface", "long",
- "native", "new", "optional", "package", "private", "protected", "public",
- "return", "short", "static", "strictfp", "super", "switch", "synchronized",
- "tag", "task", "taskexit", //keywords for failure aware computation
- "this", "throw", "throws", "transient", "try", "void",
- "volatile", "while"};
- Token getIdentifier() {
- // Get id string.
- StringBuffer sb = new StringBuffer().append(consume());
-
- if (!Character.isJavaIdentifierStart(sb.charAt(0)))
- throw new Error("Invalid Java Identifier on line "+line_num);
- while (Character.isJavaIdentifierPart(line.charAt(line_pos)))
- sb.append(consume());
- String s = sb.toString();
- // Now check against boolean literals and null literal.
- if (s.equals("null")) return new NullLiteral();
- if (s.equals("true")) return new BooleanLiteral(true);
- if (s.equals("false")) return new BooleanLiteral(false);
- // Check against keywords.
- // pre-java 1.5 compatibility:
- if (!isJava15 && s.equals("enum")) return new Identifier(s);
- // pre-java 1.4 compatibility:
- if (!isJava14 && s.equals("assert")) return new Identifier(s);
- // pre-java 1.2 compatibility:
- if (!isJava12 && s.equals("strictfp")) return new Identifier(s);
- // use binary search.
- for (int l=0, r=keywords.length; r > l; ) {
- int x = (l+r)/2, cmp = s.compareTo(keywords[x]);
- if (cmp < 0) r=x; else l=x+1;
- if (cmp== 0) return new Keyword(s);
- }
- // not a keyword.
- return new Identifier(s);
- }
- NumericLiteral getNumericLiteral() {
- int i;
- // leading decimal indicates float.
- if (line.charAt(line_pos)=='.')
- return getFloatingPointLiteral();
- // 0x indicates Hex.
- if (line.charAt(line_pos)=='0' &&
- (line.charAt(line_pos+1)=='x' ||
- line.charAt(line_pos+1)=='X')) {
- line_pos+=2; return getIntegerLiteral(/*base*/16);
- }
- // otherwise scan to first non-numeric
- for (i=line_pos; Character.digit(line.charAt(i),10)!=-1; )
- i++;
- switch(line.charAt(i)) { // discriminate based on first non-numeric
- case '.':
- case 'f':
- case 'F':
- case 'd':
- case 'D':
- case 'e':
- case 'E':
- return getFloatingPointLiteral();
- case 'L':
- case 'l':
- default:
- if (line.charAt(line_pos)=='0')
- return getIntegerLiteral(/*base*/8);
- return getIntegerLiteral(/*base*/10);
- }
- }
- NumericLiteral getIntegerLiteral(int radix) {
- long val=0;
- while (Character.digit(line.charAt(line_pos),radix)!=-1)
- val = (val*radix) + Character.digit(consume(),radix);
- if (line.charAt(line_pos) == 'l' ||
- line.charAt(line_pos) == 'L') {
- consume();
- return new LongLiteral(val);
- }
- // we compare MAX_VALUE against val/2 to allow constants like
- // 0xFFFF0000 to get past the test. (unsigned long->signed int)
- if ((val/2) > Integer.MAX_VALUE ||
- val < Integer.MIN_VALUE)
- throw new Error("Constant does not fit in integer on line "+line_num);
- return new IntegerLiteral((int)val);
- }
- NumericLiteral getFloatingPointLiteral() {
- String rep = getDigits();
- if (line.charAt(line_pos)=='.')
- rep+=consume() + getDigits();
- if (line.charAt(line_pos)=='e' ||
- line.charAt(line_pos)=='E') {
- rep+=consume();
- if (line.charAt(line_pos)=='+' ||
- line.charAt(line_pos)=='-')
- rep+=consume();
- rep+=getDigits();
- }
- try {
- switch (line.charAt(line_pos)) {
- case 'f':
- case 'F':
- consume();
- return new FloatLiteral(Float.valueOf(rep).floatValue());
- case 'd':
- case 'D':
- consume();
- /* falls through */
- default:
- return new DoubleLiteral(Double.valueOf(rep).doubleValue());
- }
- } catch (NumberFormatException e) {
- throw new Error("Illegal floating-point on line "+line_num+": "+e);
- }
- }
- String getDigits() {
- StringBuffer sb = new StringBuffer();
- while (Character.digit(line.charAt(line_pos),10)!=-1)
- sb.append(consume());
- return sb.toString();
- }
-
- Operator getOperator() {
- char first = consume();
- char second= line.charAt(line_pos);
-
- switch(first) {
- // single-character operators.
- case '~':
- case '?':
- case ':':
- return new Operator(new String(new char[] {first}));
- // doubled operators
- case '+':
- case '-':
- case '&':
- case '|':
- if (first==second)
- return new Operator(new String(new char[] {first, consume()}));
- default:
- break;
- }
- // Check for trailing '='
- if (second=='=')
- return new Operator(new String(new char[] {first, consume()}));
-
- // Special-case '<<', '>>' and '>>>'
- if ((first=='<' && second=='<') || // <<
- (first=='>' && second=='>')) { // >>
- String op = new String(new char[] {first, consume()});
- if (first=='>' && line.charAt(line_pos)=='>') // >>>
- op += consume();
- if (line.charAt(line_pos)=='=') // <<=, >>=, >>>=
- op += consume();
- return new Operator(op);
- }
-
- // Otherwise return single operator.
- return new Operator(new String(new char[] {first}));
- }
-
- CharacterLiteral getCharLiteral() {
- char firstquote = consume();
- char val;
- switch (line.charAt(line_pos)) {
- case '\\':
- val = getEscapeSequence();
- break;
- case '\'':
- throw new Error("Invalid character literal on line "+line_num);
- case '\n':
- throw new Error("Invalid character literal on line "+line_num);
- default:
- val = consume();
- break;
- }
- char secondquote = consume();
- if (firstquote != '\'' || secondquote != '\'')
- throw new Error("Invalid character literal on line "+line_num);
- return new CharacterLiteral(val);
- }
- StringLiteral getStringLiteral() {
- char openquote = consume();
- StringBuffer val = new StringBuffer();
- while (line.charAt(line_pos)!='\"') {
- switch(line.charAt(line_pos)) {
- case '\\':
- val.append(getEscapeSequence());
- break;
- case '\n':
- throw new Error("Invalid string literal on line " + line_num);
- default:
- val.append(consume());
- break;
- }
- }
- char closequote = consume();
- if (openquote != '\"' || closequote != '\"')
- throw new Error("Invalid string literal on line " + line_num);
-
- return new StringLiteral(val.toString().intern());
- }
-
- char getEscapeSequence() {
- if (consume() != '\\')
- throw new Error("Invalid escape sequence on line " + line_num);
- switch(line.charAt(line_pos)) {
- case 'b':
- consume(); return '\b';
- case 't':
- consume(); return '\t';
- case 'n':
- consume(); return '\n';
- case 'f':
- consume(); return '\f';
- case 'r':
- consume(); return '\r';
- case '\"':
- consume(); return '\"';
- case '\'':
- consume(); return '\'';
- case '\\':
- consume(); return '\\';
- case '0':
- case '1':
- case '2':
- case '3':
- return (char) getOctal(3);
- case '4':
- case '5':
- case '6':
- case '7':
- return (char) getOctal(2);
- default:
- throw new Error("Invalid escape sequence on line " + line_num);
- }
- }
- int getOctal(int maxlength) {
- int i, val=0;
- for (i=0; i<maxlength; i++)
- if (Character.digit(line.charAt(line_pos), 8)!=-1) {
- val = (8*val) + Character.digit(consume(), 8);
- } else break;
- if ((i==0) || (val>0xFF)) // impossible.
- throw new Error("Invalid octal escape sequence in line " + line_num);
- return val;
- }
-
- char consume() { return line.charAt(line_pos++); }
- void nextLine() throws java.io.IOException {
- line=reader.readLine();
- if (line!=null) line=line+'\n';
- lineL = new LineList(lineL.head+line_pos, lineL); // for error reporting
- line_pos=0;
- line_num++;
- }
-
- // Deal with error messages.
- public void errorMsg(String msg, java_cup.runtime.Symbol info) {
- int n=line_num, c=info.left-lineL.head;
- for (LineList p = lineL; p!=null; p=p.tail, n--)
- if (p.head<=info.left) { c=info.left-p.head; break; }
- System.err.println(msg+" at line "+n);
- num_errors++;
- }
- private int num_errors = 0;
- public int numErrors() { return num_errors; }
-
- class LineList {
- int head;
- LineList tail;
- LineList(int head, LineList tail) { this.head = head; this.tail = tail; }
- }
-}
+++ /dev/null
-package Lex;
-
-abstract class Literal extends Token { }
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class LongLiteral extends NumericLiteral {
- LongLiteral(long l) { this.val = new Long(l); }
-
- Symbol token() { return new Symbol(Sym.INTEGER_LITERAL, val); }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class NullLiteral extends Literal {
- NullLiteral() { }
-
- Symbol token() { return new Symbol(Sym.NULL_LITERAL); }
-
- public String toString() { return "NullLiteral <null>"; }
-}
+++ /dev/null
-package Lex;
-
-abstract class NumericLiteral extends Literal {
- Number val;
-
- public String toString() { return "NumericLiteral <"+val.toString()+">"; }
-}
+++ /dev/null
-package Lex;
-
-import java.util.Hashtable;
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class Operator extends Token {
- String which;
- Operator(String which) { this.which = which; }
-
- public String toString() { return "Operator <"+which+">"; }
-
- Symbol token() {
- Integer i = (Integer) op_table.get(which);
- return new Symbol(i.intValue());
- }
-
- static private final Hashtable op_table = new Hashtable();
- static {
- op_table.put("=", new Integer(Sym.EQ));
- op_table.put(">", new Integer(Sym.GT));
- op_table.put("<", new Integer(Sym.LT));
- op_table.put("!", new Integer(Sym.NOT));
- op_table.put("~", new Integer(Sym.COMP));
- op_table.put("?", new Integer(Sym.QUESTION));
- op_table.put(":", new Integer(Sym.COLON));
- op_table.put("==", new Integer(Sym.EQEQ));
- op_table.put("<=", new Integer(Sym.LTEQ));
- op_table.put(">=", new Integer(Sym.GTEQ));
- op_table.put("!=", new Integer(Sym.NOTEQ));
- op_table.put("&&", new Integer(Sym.ANDAND));
- op_table.put("||", new Integer(Sym.OROR));
- op_table.put("++", new Integer(Sym.PLUSPLUS));
- op_table.put("--", new Integer(Sym.MINUSMINUS));
- op_table.put("+", new Integer(Sym.PLUS));
- op_table.put("-", new Integer(Sym.MINUS));
- op_table.put("*", new Integer(Sym.MULT));
- op_table.put("/", new Integer(Sym.DIV));
- op_table.put("&", new Integer(Sym.AND));
- op_table.put("|", new Integer(Sym.OR));
- op_table.put("^", new Integer(Sym.XOR));
- op_table.put("%", new Integer(Sym.MOD));
- op_table.put("<<", new Integer(Sym.LSHIFT));
- op_table.put(">>", new Integer(Sym.RSHIFT));
- op_table.put(">>>", new Integer(Sym.URSHIFT));
- op_table.put("+=", new Integer(Sym.PLUSEQ));
- op_table.put("-=", new Integer(Sym.MINUSEQ));
- op_table.put("*=", new Integer(Sym.MULTEQ));
- op_table.put("/=", new Integer(Sym.DIVEQ));
- op_table.put("&=", new Integer(Sym.ANDEQ));
- op_table.put("|=", new Integer(Sym.OREQ));
- op_table.put("^=", new Integer(Sym.XOREQ));
- op_table.put("%=", new Integer(Sym.MODEQ));
- op_table.put("<<=", new Integer(Sym.LSHIFTEQ));
- op_table.put(">>=", new Integer(Sym.RSHIFTEQ));
- op_table.put(">>>=", new Integer(Sym.URSHIFTEQ));
- }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class Separator extends Token {
- char which;
- Separator(char which) { this.which = which; }
-
- Symbol token() {
- switch(which) {
- case '(': return new Symbol(Sym.LPAREN);
- case ')': return new Symbol(Sym.RPAREN);
- case '{': return new Symbol(Sym.LBRACE);
- case '}': return new Symbol(Sym.RBRACE);
- case '[': return new Symbol(Sym.LBRACK);
- case ']': return new Symbol(Sym.RBRACK);
- case ';': return new Symbol(Sym.SEMICOLON);
- case ',': return new Symbol(Sym.COMMA);
- case '.': return new Symbol(Sym.DOT);
- case '\u2026': return new Symbol(Sym.ELLIPSIS);
- default:
- throw new Error("Invalid separator.");
- }
- }
-
- public String toString() {
- return "Separator <"+which+">";
- }
-}
+++ /dev/null
-package Lex;
-
-import java_cup.runtime.Symbol;
-import Parse.Sym;
-
-class StringLiteral extends Literal {
- String val;
- StringLiteral(String s) { this.val = s; }
-
- Symbol token() { return new Symbol(Sym.STRING_LITERAL, val); }
-
- public String toString() {
- return "StringLiteral <"+Token.escape(val)+">";
- }
-}
+++ /dev/null
-package Lex;
-
-abstract class Token extends InputElement {
- abstract java_cup.runtime.Symbol token();
-
- protected static String escape(String s) {
- StringBuffer sb = new StringBuffer();
- for (int i=0; i<s.length(); i++)
- switch(s.charAt(i)) {
- case '\t': sb.append("\\t"); break;
- case '\f': sb.append("\\f"); break;
- case '\n': sb.append("\\n"); break;
- default:
- if ((int)s.charAt(i)<32)
- sb.append("\\"+Integer.toOctalString((int)s.charAt(i)));
- else
- sb.append(s.charAt(i));
- }
- return sb.toString();
- }
-}
+++ /dev/null
-package Lex;
-
-class TraditionalComment extends Comment {
- TraditionalComment() { }
-}
+++ /dev/null
-package Lex;
-
-class WhiteSpace extends InputElement {
- char whitespace;
- WhiteSpace(char which) { this.whitespace=which; }
-
- public String toString() {
- String s;
- switch(whitespace) {
- case ' ': s = "SP"; break;
- case '\t': s = "HT"; break;
- case '\f': s = "FF"; break;
- case '\n': s = "LT"; break;
- default: s = "Unknown Whitespace character."; break;
- }
- return "Whitespace <"+s+">";
- }
-}
import java.io.Reader;
import java.io.BufferedReader;
import java.io.FileReader;
+import java.io.FileInputStream;
+import java.util.Iterator;
+import java.util.Vector;
+
import IR.Tree.ParseNode;
import IR.Tree.BuildIR;
import IR.Tree.SemanticCheck;
import IR.Flat.BuildFlat;
import IR.Flat.BuildCode;
+import IR.ClassDescriptor;
import IR.State;
+import IR.TaskDescriptor;
import IR.TypeUtil;
+import Analysis.Scheduling.ScheduleAnalysis;
+import Analysis.Scheduling.ScheduleEdge;
+import Analysis.Scheduling.ScheduleNode;
import Analysis.TaskStateAnalysis.TaskAnalysis;
+import Analysis.TaskStateAnalysis.TaskTagAnalysis;
import Analysis.TaskStateAnalysis.TaskGraph;
import Analysis.CallGraph.CallGraph;
+import Analysis.TaskStateAnalysis.FEdge;
+import Analysis.TaskStateAnalysis.FlagState;
import Analysis.TaskStateAnalysis.TagAnalysis;
import Analysis.TaskStateAnalysis.GarbageAnalysis;
import Analysis.TaskStateAnalysis.ExecutionGraph;
import Analysis.TaskStateAnalysis.SafetyAnalysis;
import Analysis.Locality.LocalityAnalysis;
import Analysis.Locality.GenerateConversions;
+import Analysis.Prefetch.PrefetchAnalysis;
+import Analysis.FlatIRGraph.FlatIRGraph;
+import Analysis.OwnershipAnalysis.OwnershipAnalysis;
import Interface.*;
public class Main {
public static void main(String args[]) throws Exception {
String ClassLibraryPrefix="./ClassLibrary/";
State state=new State();
-
+
for(int i=0;i<args.length;i++) {
String option=args[i];
if (option.equals("-precise"))
IR.Flat.BuildCode.GENERATEPRECISEGC=true;
+ else if (option.equals("-prefetch"))
+ state.PREFETCH=true;
else if (option.equals("-dir"))
IR.Flat.BuildCode.PREFIX=args[++i]+"/";
+ else if (option.equals("-selfloop"))
+ state.selfloops.add(args[++i]);
else if (option.equals("-classlibrary"))
ClassLibraryPrefix=args[++i]+"/";
else if (option.equals("-mainclass"))
state.TASK=true;
else if (option.equals("-taskstate"))
state.TASKSTATE=true;
+ else if (option.equals("-tagstate"))
+ state.TAGSTATE=true;
+ else if (option.equals("-flatirtasks")) {
+ state.FLATIRGRAPH=true;
+ state.FLATIRGRAPHTASKS=true;
+ }
+ else if (option.equals("-flatirusermethods")) {
+ state.FLATIRGRAPH=true;
+ state.FLATIRGRAPHUSERMETHODS=true;
+ }
+ else if (option.equals("-flatirlibmethods")) {
+ state.FLATIRGRAPH=true;
+ state.FLATIRGRAPHLIBMETHODS=true;
+ }
+ else if (option.equals("-ownership"))
+ state.OWNERSHIP=true;
else if (option.equals("-optional"))
state.OPTIONAL=true;
+ else if (option.equals("-scheduling"))
+ state.SCHEDULING=true;
else if (option.equals("-thread"))
state.THREAD=true;
else if (option.equals("-dsm"))
state.INSTRUCTIONFAILURE=true;
else if (option.equals("-help")) {
System.out.println("-classlibrary classlibrarydirectory -- directory where classlibrary is located");
+ System.out.println("-selfloop task -- this task doesn't self loop its parameters forever");
System.out.println("-dir outputdirectory -- output code in outputdirectory");
System.out.println("-struct structfile -- output structure declarations for repair tool");
System.out.println("-mainclass -- main function to call");
System.out.println("-thread -- threads");
System.out.println("-instructionfailures -- insert code for instruction level failures");
System.out.println("-taskstate -- do task state analysis");
+ System.out.println("-flatirtasks -- create dot files for flat IR graphs of tasks");
+ System.out.println("-flatirusermethods -- create dot files for flat IR graphs of user methods");
+ System.out.println("-flatirlibmethods -- create dot files for flat IR graphs of library class methods");
+ System.out.println(" note: -flatirusermethods or -flatirlibmethods currently generate all class method flat IR graphs");
+ System.out.println("-ownership -- do ownership analysis");
System.out.println("-optional -- enable optional arguments");
System.out.println("-webinterface -- enable web interface");
System.out.println("-help -- print out help");
readSourceFile(state, ClassLibraryPrefix+"Integer.java");
readSourceFile(state, ClassLibraryPrefix+"StringBuffer.java");
readSourceFile(state, ClassLibraryPrefix+"FileInputStream.java");
+ readSourceFile(state, ClassLibraryPrefix+"InputStream.java");
+ readSourceFile(state, ClassLibraryPrefix+"OutputStream.java");
readSourceFile(state, ClassLibraryPrefix+"FileOutputStream.java");
readSourceFile(state, ClassLibraryPrefix+"File.java");
+ readSourceFile(state, ClassLibraryPrefix+"Math.java");
readSourceFile(state, ClassLibraryPrefix+"InetAddress.java");
-
+ readSourceFile(state, ClassLibraryPrefix+"SocketInputStream.java");
+ readSourceFile(state, ClassLibraryPrefix+"SocketOutputStream.java");
if (state.TASK) {
readSourceFile(state, ClassLibraryPrefix+"Object.java");
readSourceFile(state, ClassLibraryPrefix+"TagDescriptor.java");
+ } else if (state.DSM) {
+ readSourceFile(state, ClassLibraryPrefix+"ThreadDSM.java");
+ readSourceFile(state, ClassLibraryPrefix+"ObjectJavaDSM.java");
} else {
if (state.THREAD) {
readSourceFile(state, ClassLibraryPrefix+"Thread.java");
BuildFlat bf=new BuildFlat(state,tu);
bf.buildFlat();
+ SafetyAnalysis sa=null;
+
+ if (state.TAGSTATE) {
+ CallGraph callgraph=new CallGraph(state);
+ TagAnalysis taganalysis=new TagAnalysis(state, callgraph);
+ TaskTagAnalysis tta=new TaskTagAnalysis(state, taganalysis);
+ }
if (state.TASKSTATE) {
CallGraph callgraph=new CallGraph(state);
if (state.OPTIONAL) {
ExecutionGraph et=new ExecutionGraph(state, ta);
et.createExecutionGraph();
- SafetyAnalysis sa = new SafetyAnalysis(et.getExecutionGraph(), state, ta);
- sa.buildPath();
+ sa = new SafetyAnalysis(et.getExecutionGraph(), state, ta);
+ sa.doAnalysis();
state.storeAnalysisResult(sa.getResult());
state.storeOptionalTaskDescriptors(sa.getOptionalTaskDescriptors());
}
serve.run();
}
+ if (state.SCHEDULING) {
+ // for test
+ // Randomly set the newRate and probability of FEdges
+ java.util.Random r=new java.util.Random();
+ int tint = 0;
+ for(Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator();it_classes.hasNext();) {
+ ClassDescriptor cd=(ClassDescriptor) it_classes.next();
+ if(cd.hasFlags()){
+ Vector rootnodes=ta.getRootNodes(cd);
+ if(rootnodes!=null)
+ for(Iterator it_rootnodes=rootnodes.iterator();it_rootnodes.hasNext();){
+ FlagState root=(FlagState)it_rootnodes.next();
+ Vector allocatingTasks = root.getAllocatingTasks();
+ if(allocatingTasks != null) {
+ for(int k = 0; k < allocatingTasks.size(); k++) {
+ TaskDescriptor td = (TaskDescriptor)allocatingTasks.elementAt(k);
+ Vector<FEdge> fev = (Vector<FEdge>)ta.getFEdgesFromTD(td);
+ int numEdges = fev.size();
+ for(int j = 0; j < numEdges; j++) {
+ FEdge pfe = fev.elementAt(j);
+ do {
+ tint = r.nextInt()%10;
+ } while(tint <= 0);
+ //int newRate = tint;
+ int newRate = (j+1)%2+1;
+ /*do {
+ tint = r.nextInt()%100;
+ } while(tint <= 0);
+ int probability = tint;*/
+ int probability = 100;
+ pfe.addNewObjInfo(cd, newRate, probability);
+ }
+ }
+ }
+ }
+
+ Iterator it_flags = ta.getFlagStates(cd).iterator();
+ while(it_flags.hasNext()) {
+ FlagState fs = (FlagState)it_flags.next();
+ Iterator it_edges = fs.edges();
+ while(it_edges.hasNext()) {
+ do {
+ tint = r.nextInt()%10;
+ } while(tint <= 0);
+ ((FEdge)it_edges.next()).setExeTime(tint);
+ }
+ }
+ }
+ }
+
+ ScheduleAnalysis scheduleAnalysis = new ScheduleAnalysis(state, ta);
+ scheduleAnalysis.preSchedule();
+
+ // Randomly set the newRate and probability of ScheduleEdges
+ /*Vector<ScheduleEdge> sedges = scheduleAnalysis.getSEdges4Test();
+ java.util.Random r=new java.util.Random();
+ for(int i = 0; i < sedges.size(); i++) {
+ ScheduleEdge temp = sedges.elementAt(i);
+ int tint = 0;
+ do {
+ tint = r.nextInt()%100;
+ }while(tint <= 0);
+ temp.setProbability(tint);
+ do {
+ tint = r.nextInt()%10;
+ } while(tint <= 0);
+ temp.setNewRate(tint);
+ //temp.setNewRate((i+1)%2+1);
+ }
+ //sedges.elementAt(3).setNewRate(2);*/
+ scheduleAnalysis.scheduleAnalysis();
+ scheduleAnalysis.setCoreNum(scheduleAnalysis.getSEdges4Test().size() - 1);
+ scheduleAnalysis.schedule();
+ }
}
if (state.DSM) {
CallGraph callgraph=new CallGraph(state);
+ if (state.PREFETCH) {
+ PrefetchAnalysis pa=new PrefetchAnalysis(state, callgraph, tu);
+ }
LocalityAnalysis la=new LocalityAnalysis(state, callgraph, tu);
GenerateConversions gc=new GenerateConversions(la, state);
+ BuildCode bc=new BuildCode(state, bf.getMap(), tu, la);
+ bc.buildCode();
+ } else {
+ BuildCode bc=new BuildCode(state, bf.getMap(), tu, sa);
+ bc.buildCode();
+ }
+
+ if (state.FLATIRGRAPH) {
+ FlatIRGraph firg = new FlatIRGraph(state,
+ state.FLATIRGRAPHTASKS,
+ state.FLATIRGRAPHUSERMETHODS,
+ state.FLATIRGRAPHLIBMETHODS);
+ }
+
+ if (state.OWNERSHIP) {
+ // OwnershipAnalysis oa = new OwnershipAnalysis(state);
}
- BuildCode bc=new BuildCode(state, bf.getMap(), tu);
- bc.buildCode();
-
System.exit(0);
}
+++ /dev/null
-CLASSFILES=Main/Main.class Lex/BooleanLiteral.class \
-Lex/CharacterLiteral.class Lex/Comment.class \
-Lex/DocumentationComment.class Lex/DoubleLiteral.class Lex/EOF.class \
-Lex/EndOfLineComment.class Lex/EscapedUnicodeReader.class \
-Lex/FIFO.class Lex/FloatLiteral.class Lex/Identifier.class \
-Lex/InputElement.class Lex/IntegerLiteral.class Lex/Keyword.class \
-Lex/Lexer.class Lex/Literal.class Lex/LongLiteral.class \
-Lex/NullLiteral.class Lex/NumericLiteral.class Lex/Operator.class \
-Lex/Separator.class Lex/StringLiteral.class Lex/Token.class \
-Lex/TraditionalComment.class Lex/WhiteSpace.class \
-IR/AssignOperation.class IR/ClassDescriptor.class IR/Descriptor.class \
-IR/FieldDescriptor.class IR/FlagDescriptor.class \
-IR/MethodDescriptor.class IR/NameDescriptor.class IR/Operation.class \
-IR/State.class IR/SymbolTable.class IR/TagDescriptor.class \
-IR/TagVarDescriptor.class IR/TaskDescriptor.class \
-IR/TypeDescriptor.class IR/TypeUtil.class IR/VarDescriptor.class \
-IR/Virtual.class IR/Flat/BuildCode.class IR/Flat/BuildFlat.class \
-IR/Flat/FKind.class IR/Flat/FlatAtomicEnterNode.class \
-IR/Flat/FlatAtomicExitNode.class IR/Flat/FlatBackEdge.class \
-IR/Flat/FlatCall.class IR/Flat/FlatCastNode.class \
-IR/Flat/FlatCheckNode.class IR/Flat/FlatCondBranch.class \
-IR/Flat/FlatElementNode.class IR/Flat/FlatFieldNode.class \
-IR/Flat/FlatFlagActionNode.class IR/Flat/FlatGlobalConvNode.class \
-IR/Flat/FlatLiteralNode.class IR/Flat/FlatMethod.class \
-IR/Flat/FlatNew.class IR/Flat/FlatNode.class IR/Flat/FlatNop.class \
-IR/Flat/FlatOpNode.class IR/Flat/FlatReturnNode.class \
-IR/Flat/FlatSetElementNode.class IR/Flat/FlatSetFieldNode.class \
-IR/Flat/FlatTagDeclaration.class IR/Flat/NodePair.class \
-IR/Flat/ParamsObject.class IR/Flat/TempDescriptor.class \
-IR/Flat/TempFlagPair.class IR/Flat/TempObject.class \
-IR/Flat/TempTagPair.class IR/Tree/ArrayAccessNode.class \
-IR/Tree/AssignmentNode.class IR/Tree/AtomicNode.class \
-IR/Tree/BlockExpressionNode.class IR/Tree/BlockNode.class \
-IR/Tree/BlockStatementNode.class IR/Tree/BuildIR.class \
-IR/Tree/CastNode.class IR/Tree/ConstraintCheck.class \
-IR/Tree/CreateObjectNode.class IR/Tree/DNFFlag.class \
-IR/Tree/DNFFlagAtom.class IR/Tree/DeclarationNode.class \
-IR/Tree/ExpressionNode.class IR/Tree/FieldAccessNode.class \
-IR/Tree/FlagEffect.class IR/Tree/FlagEffects.class \
-IR/Tree/FlagExpressionNode.class IR/Tree/FlagNode.class \
-IR/Tree/FlagOpNode.class IR/Tree/IfStatementNode.class \
-IR/Tree/Kind.class IR/Tree/LiteralNode.class IR/Tree/LoopNode.class \
-IR/Tree/MethodInvokeNode.class IR/Tree/Modifiers.class \
-IR/Tree/NameNode.class IR/Tree/OpNode.class IR/Tree/ParseNode.class \
-IR/Tree/ParseNodeDOTVisitor.class IR/Tree/ParseNodeVector.class \
-IR/Tree/ReturnNode.class IR/Tree/SemanticCheck.class \
-IR/Tree/SubBlockNode.class IR/Tree/TagDeclarationNode.class \
-IR/Tree/TagEffect.class IR/Tree/TagExpressionList.class \
-IR/Tree/TaskExitNode.class IR/Tree/TreeNode.class \
-IR/Tree/Walkable.class Analysis/CallGraph/CallGraph.class \
-Analysis/Locality/GenerateConversions.class \
-Analysis/Locality/LocalityAnalysis.class \
-Analysis/Locality/LocalityBinding.class \
-Analysis/Locality/TempNodePair.class \
-Analysis/TaskStateAnalysis/Allocations.class \
-Analysis/TaskStateAnalysis/EGEdge.class \
-Analysis/TaskStateAnalysis/EGTaskNode.class \
-Analysis/TaskStateAnalysis/ExecutionGraph.class \
-Analysis/TaskStateAnalysis/FEdge.class \
-Analysis/TaskStateAnalysis/FlagState.class \
-Analysis/TaskStateAnalysis/GarbageAnalysis.class \
-Analysis/TaskStateAnalysis/OptionalTaskDescriptor.class \
-Analysis/TaskStateAnalysis/Predicate.class \
-Analysis/TaskStateAnalysis/SafetyAnalysis.class \
-Analysis/TaskStateAnalysis/TEdge.class \
-Analysis/TaskStateAnalysis/TagAnalysis.class \
-Analysis/TaskStateAnalysis/TagBinding.class \
-Analysis/TaskStateAnalysis/TaskAnalysis.class \
-Analysis/TaskStateAnalysis/TaskEdges.class \
-Analysis/TaskStateAnalysis/TaskGraph.class \
-Analysis/TaskStateAnalysis/TaskNode.class \
-Analysis/TaskStateAnalysis/TaskNodeNamer.class Util/Edge.class \
-Util/GraphNode.class Util/Namer.class Util/Relation.class \
-Interface/HTTPHeader.class Interface/HTTPResponse.class \
-Interface/HTTPServices.class Interface/HashStrings.class \
-Interface/JhttpServer.class Interface/JhttpWorker.class \
-Interface/LogFile.class Interface/Pair.class \
-Interface/WebInterface.class
-
-
-
-
-all: Parse/Sym.class Parse/Parser.class $(CLASSFILES) javadoc
-
-Parse/Parser.java Parse/Sym.java: Parse/java14.cup
- cd Parse && \
- java -cp ../../cup:$(CLASSPATH) java_cup.Main -parser Parser -symbols Sym < java14.cup
-
-%.class: %.java
- javac -cp ../cup:.:$(CLASSPATH) $<
-
-javadoc:
- mkdir javadoc
- javadoc -classpath ../cup:.:$(CLASSPATH) -sourcepath . -private -d javadoc Lex Util IR IR.Tree IR.Flat Analysis Analysis.CallGraph Analysis.Flag Analysis.TaskStateAnalysis Main
-
-clean:
- rm IR/*.class IR/Tree/*.class Main/*.class Lex/*.class Parse/*.class Parse/Sym.java Parse/Parser.java IR/Flat/*.class classdefs.h methodheaders.h methods.c structdefs.h virtualtable.h task.h taskdefs.c taskdefs.h Analysis/*.class Analysis/Flag/*.class Analysis/CallGraph/*.class Analysis/TaskStateAnalysis/*.class Interface/*.class Util/*.class Analysis/Locality/*.class
-
-cleandoc:
- rm -rf javadoc
\ No newline at end of file
+++ /dev/null
-package Parse;
-
-import java_cup.runtime.*;
-import Lex.Lexer;
-import IR.Tree.*;
-
-/* Java 1.4 parser for CUP.
- * Copyright (C) 2002-2003 C. Scott Ananian <cananian@alumni.princeton.edu>
- * This program is released under the terms of the GPL; see the file
- * COPYING for more details. There is NO WARRANTY on this code.
- */
-
-/*
-JDK 1.4 Features added:
- assertion statement.
- statement_without_trailing_substatement ::= ...
- | assert_statement ;
- assert_statement ::=
- ASSERT expression SEMICOLON
- | ASSERT expression COLON expression SEMICOLON
- ;
-*/
-parser code {:
- Lexer lexer;
-
- public Parser(Lexer l) {
- this();
- lexer=l;
- }
-
- public void syntax_error(java_cup.runtime.Symbol current) {
- report_error("Syntax error (" + current.sym + ")", current);
- }
- public void report_error(String message, java_cup.runtime.Symbol info) {
- lexer.errorMsg(message, info);
- }
-:};
-
-scan with {: return lexer.nextToken(); :};
-
-terminal BOOLEAN; // primitive_type
-terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
-terminal FLOAT, DOUBLE; // floating_point_type
-terminal LBRACK, RBRACK; // array_type
-terminal java.lang.String IDENTIFIER; // name
-terminal DOT; // qualified_name
-terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
-terminal PACKAGE; // package_declaration
-terminal IMPORT; // import_declaration
-terminal PUBLIC, PROTECTED, PRIVATE; // modifier
-terminal STATIC; // modifier
-terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
-terminal CLASS; // class_declaration
-terminal EXTENDS; // super
-//terminal IMPLEMENTS; // interfaces
-terminal VOID; // method_header
-terminal THROWS; // throws
-terminal THIS, SUPER; // explicit_constructor_invocation
-//terminal INTERFACE; // interface_declaration
-terminal IF, ELSE; // if_then_statement, if_then_else_statement
-terminal SWITCH; // switch_statement
-terminal CASE, DEFAULT; // switch_label
-terminal DO, WHILE; // while_statement, do_statement
-terminal FOR; // for_statement
-terminal BREAK; // break_statement
-terminal CONTINUE; // continue_statement
-terminal RETURN; // return_statement
-terminal THROW; // throw_statement
-terminal TRY; // try_statement
-terminal CATCH; // catch_clause
-terminal FINALLY; // finally
-terminal NEW; // class_instance_creation_expression
-terminal PLUSPLUS; // postincrement_expression
-terminal MINUSMINUS; // postdecrement_expression
-terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
-terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
-terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
-terminal EQEQ, NOTEQ; // equality_expression
-terminal AND; // and_expression
-terminal XOR; // exclusive_or_expression
-terminal OR; // inclusive_or_expression
-terminal ANDAND; // conditional_and_expression
-terminal OROR; // conditional_or_expression
-terminal QUESTION; // conditional_expression
-terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
-terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
-terminal ANDEQ, XOREQ, OREQ; // assignment_operator
-
-terminal java.lang.Number INTEGER_LITERAL;
-terminal java.lang.Number FLOATING_POINT_LITERAL;
-terminal java.lang.Boolean BOOLEAN_LITERAL;
-terminal java.lang.Character CHARACTER_LITERAL;
-terminal java.lang.String STRING_LITERAL;
-terminal NULL_LITERAL;
-
-// Reserved but unused:
-terminal CONST, GOTO;
-// strictfp keyword, new in Java 1.2
-terminal STRICTFP;
-// assert keyword, new in Java 1.4
-terminal ASSERT; // assert_statement
-// lexer compatibility with Java 1.5
-terminal ELLIPSIS;
-terminal ENUM;
-
-
-// 19.2) The Syntactic Grammar
-non terminal ParseNode goal;
-// 19.3) Lexical Structure
-non terminal ParseNode literal;
-// 19.4) Types, Values, and Variables
-non terminal ParseNode type, primitive_type, numeric_type;
-non terminal ParseNode integral_type, floating_point_type;
-non terminal ParseNode reference_type;
-non terminal ParseNode class_or_interface_type;
-non terminal ParseNode class_type;
-//non terminal ParseNode interface_type;
-non terminal ParseNode array_type;
-// 19.5) Names
-non terminal ParseNode name, simple_name, qualified_name;
-// 19.6) Packages
-non terminal ParseNode compilation_unit;
-non terminal ParseNode package_declaration_opt, package_declaration;
-non terminal ParseNode import_declarations_opt, import_declarations;
-non terminal ParseNode type_declarations_opt, type_declarations;
-non terminal ParseNode import_declaration;
-non terminal ParseNode single_type_import_declaration;
-non terminal ParseNode type_import_on_demand_declaration;
-non terminal ParseNode type_declaration;
-// 19.7) Productions used only in the LALR(1) grammar
-non terminal ParseNode modifiers_opt, modifiers, modifier;
-// 19.8.1) Class Declaration
-non terminal ParseNode class_declaration, super, super_opt;
-//non terminal interfaces, interfaces_opt, interface_type_list;
-non terminal ParseNode class_body;
-non terminal ParseNode class_body_declarations, class_body_declarations_opt;
-non terminal ParseNode class_body_declaration, class_member_declaration;
-// 19.8.2) Field Declarations
-non terminal ParseNode field_declaration, variable_declarators, variable_declarator;
-non terminal ParseNode variable_declarator_id;
-non terminal ParseNode variable_initializer;
-// 19.8.3) Method Declarations
-non terminal ParseNode method_declaration, method_header, method_declarator;
-non terminal ParseNode formal_parameter_list_opt, formal_parameter_list;
-non terminal ParseNode formal_parameter;
-//non terminal ParseNode throws_opt;
-//non terminal ParseNode throws;
-//non terminal ParseNode class_type_list;
-non terminal ParseNode method_body;
-// 19.8.4) Static Initializers
-//non terminal ParseNode static_initializer;
-// 19.8.5) Constructor Declarations
-non terminal ParseNode constructor_declaration, constructor_declarator;
-non terminal ParseNode constructor_body;
-//non terminal ParseNode explicit_constructor_invocation;
-// 19.9.1) Interface Declarations
-//non terminal ParseNode interface_declaration;
-//non terminal ParseNode extends_interfaces_opt, extends_interfaces;
-//non terminal ParseNode interface_body;
-//non terminal ParseNode interface_member_declarations_opt, interface_member_declarations;
-//non terminal ParseNode interface_member_declaration, constant_declaration;
-//non terminal ParseNode abstract_method_declaration;
-// 19.10) Arrays
-//non terminal ParseNode array_initializer;
-//non terminal ParseNode variable_initializers;
-// 19.11) Blocks and Statements
-non terminal ParseNode block;
-non terminal ParseNode block_statements_opt, block_statements, block_statement;
-non terminal ParseNode local_variable_declaration_statement, local_variable_declaration;
-non terminal ParseNode statement, statement_no_short_if;
-non terminal ParseNode statement_without_trailing_substatement;
-non terminal ParseNode empty_statement;
-//non terminal ParseNode labeled_statement, labeled_statement_no_short_if;
-non terminal ParseNode expression_statement, statement_expression;
-non terminal ParseNode if_then_statement;
-non terminal ParseNode if_then_else_statement, if_then_else_statement_no_short_if;
-//non terminal ParseNode switch_statement, switch_block;
-//non terminal ParseNode switch_block_statement_groups;
-//non terminal ParseNode switch_block_statement_group;
-//non terminal ParseNode switch_labels, switch_label;
-non terminal ParseNode while_statement, while_statement_no_short_if;
-non terminal ParseNode do_statement;
-non terminal ParseNode for_statement, for_statement_no_short_if;
-non terminal ParseNode for_init_opt, for_init;
-non terminal ParseNode for_update_opt, for_update;
-non terminal ParseNode statement_expression_list;
-//non terminal ParseNode identifier_opt;
-non terminal ParseNode break_statement, continue_statement;
-non terminal ParseNode return_statement;
-//non terminal ParseNode throw_statement;
-//non terminal ParseNode synchronized_statement, try_statement;
-//non terminal ParseNode catches_opt;
-//non terminal ParseNode catches, catch_clause;
-//non terminal ParseNode finally;
-//non terminal ParseNode assert_statement;
-// 19.12) Expressions
-non terminal ParseNode primary, primary_no_new_array;
-non terminal ParseNode class_instance_creation_expression;
-non terminal ParseNode cons_argument_list_opt, cons_argument_list;
-non terminal ParseNode argument_list_opt, argument_list;
-//non terminal ParseNode array_creation_init;
-non terminal ParseNode array_creation_uninit;
-non terminal ParseNode dim_exprs, dim_expr;
-non terminal Integer dims_opt, dims;
-non terminal ParseNode field_access, method_invocation;
-non terminal ParseNode array_access;
-non terminal ParseNode postfix_expression;
-non terminal ParseNode postincrement_expression, postdecrement_expression;
-non terminal ParseNode unary_expression, unary_expression_not_plus_minus;
-non terminal ParseNode preincrement_expression, predecrement_expression;
-non terminal ParseNode cast_expression;
-non terminal ParseNode multiplicative_expression, additive_expression;
-non terminal ParseNode shift_expression, relational_expression, equality_expression;
-non terminal ParseNode and_expression, exclusive_or_expression, inclusive_or_expression;
-non terminal ParseNode conditional_and_expression, conditional_or_expression;
-non terminal ParseNode conditional_expression;
-non terminal ParseNode assignment_expression;
-non terminal ParseNode assignment;
-non terminal ParseNode assignment_operator;
-non terminal ParseNode expression_opt, expression;
-//non terminal ParseNode constant_expression;
-//failure aware computation keywords
-terminal FLAG;
-terminal OPTIONAL;
-terminal EXTERNAL;
-terminal TAG;
-terminal TASK;
-terminal TASKEXIT;
-non terminal ParseNode flag_declaration;
-non terminal ParseNode task_declaration;
-non terminal ParseNode task_parameter_list;
-non terminal ParseNode task_parameter;
-non terminal ParseNode flag_expression;
-non terminal ParseNode flag_andexpression;
-non terminal ParseNode flag_notexpression;
-non terminal ParseNode task_exitstatement;
-non terminal ParseNode flag_effects_opt;
-non terminal ParseNode flag_effects;
-non terminal ParseNode flag_effect;
-non terminal ParseNode flag_list;
-non terminal ParseNode flag_list_opt;
-non terminal ParseNode flag_change;
-
-non terminal ParseNode cons_checks_opt;
-non terminal ParseNode cons_checks;
-non terminal ParseNode cons_check;
-
-non terminal ParseNode tag_variable_declaration_statement;
-non terminal ParseNode tag_expression_list;
-non terminal ParseNode tag_expression;
-non terminal ParseNode tag_list;
-non terminal ParseNode tag_list_opt;
-non terminal ParseNode tag_change;
-
-//distributed transaction keywords
-terminal ATOMIC;
-terminal GLOBAL;
-non terminal ParseNode atomic_statement;
-
-
-start with goal;
-
-
-// Task declarations
-task_declaration ::=
- TASK IDENTIFIER:id LPAREN task_parameter_list:tpl RPAREN
- flag_effects_opt:feo
- method_body:body
- {:
- ParseNode pn=new ParseNode("task_declaration");
- pn.addChild("name").addChild(id);
- pn.addChild(tpl);
- pn.addChild(feo);
- pn.addChild("body").addChild(body);
- RESULT=pn;
- :};
-
-task_parameter_list ::=
- task_parameter:fp {:
- ParseNode pn=new ParseNode("task_parameter_list");
- pn.addChild(fp);
- RESULT=pn;
- :}
- | task_parameter_list:fpl COMMA task_parameter:fp {:
- fpl.addChild(fp);
- RESULT=fpl;
- :}
- ;
-
-task_parameter ::=
- type:type variable_declarator_id:name LBRACE flag_expression:exp RBRACE {:
- ParseNode pn=new ParseNode("task_parameter");
- pn.addChild(type);
- pn.addChild(name);
- pn.addChild("flag").addChild(exp);
- RESULT=pn;
- :}
- | type:type variable_declarator_id:name LBRACE flag_expression:exp RBRACE LBRACE tag_expression_list:texp RBRACE {:
- ParseNode pn=new ParseNode("task_parameter");
- pn.addChild(type);
- pn.addChild(name);
- pn.addChild("flag").addChild(exp);
- pn.addChild("tag").addChild(texp);
- RESULT=pn;
- :}
- | type:type variable_declarator_id:name LBRACE RBRACE LBRACE tag_expression_list:texp RBRACE {:
- ParseNode pn=new ParseNode("task_parameter");
- pn.addChild(type);
- pn.addChild(name);
- pn.addChild("tag").addChild(texp);
- RESULT=pn;
- :}
- | OPTIONAL task_parameter:fp {:
- ParseNode pn=new ParseNode("task_parameter");
- pn.addChild("optional").addChild(fp);
- RESULT=pn;
- :}
-
- ;
-
-tag_expression_list ::= tag_expression:te {:
- ParseNode pn=new ParseNode("tag_expression_list");
- pn.addChild(te);
- RESULT=pn;
- :}
- | tag_expression_list:tel COMMA tag_expression:te {:
- tel.addChild(te);
- RESULT=tel;
- :}
- ;
-
-tag_expression ::= IDENTIFIER:type IDENTIFIER:id {:
- ParseNode pn=new ParseNode("tag_expression");
- pn.addChild("type").addChild(type);
- pn.addChild("single").addChild(id);
- RESULT=pn;
- :}
- ;
-
-tag_list_opt ::= LBRACE tag_list:fl RBRACE {:RESULT=fl;:}
- | LBRACE RBRACE {: RESULT = new ParseNode("empty"); :}
- | {: RESULT = new ParseNode("empty"); :}
- ;
-
-tag_list ::= tag_change:fc {:
- ParseNode pn=new ParseNode("tag_list");
- pn.addChild(fc);
- RESULT=pn;
- :}
- | tag_list:fl COMMA tag_change:fc {:
- fl.addChild(fc);
- RESULT=fl;
- :};
-
-tag_change ::= IDENTIFIER:id {:
- RESULT=new ParseNode("name").addChild(id).getRoot();
- :}
- | NOT IDENTIFIER:id {:
- RESULT=new ParseNode("not").addChild("name").addChild(id).getRoot();
- :};
-
-flag_expression ::=
- flag_andexpression:exp {:
- RESULT=exp;
- :}
- | flag_expression:exp1 OROR flag_andexpression:exp2 {:
- ParseNode pn=new ParseNode("or");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- ;
-
-flag_andexpression ::=
- flag_notexpression:exp {: RESULT=exp; :}
- | flag_notexpression:exp1 ANDAND flag_andexpression:exp2 {:
- ParseNode pn=new ParseNode("and");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- ;
-
-flag_notexpression ::=
- NOT flag_notexpression:exp {:
- ParseNode pn=new ParseNode("not");
- pn.addChild(exp);
- RESULT=pn;
- :}
- | LPAREN flag_expression:exp RPAREN {:
- RESULT=exp;
- :}
- | IDENTIFIER:id {:
- ParseNode pn=new ParseNode("name");
- pn.addChild(id);
- RESULT=pn;
- :}
- ;
-
-task_exitstatement ::= TASKEXIT flag_effects_opt:opt cons_checks_opt:cco SEMICOLON {:
- RESULT=(new ParseNode("taskexit")).addChild(opt).getRoot().addChild(cco).getRoot();
- :};
-
-cons_checks_opt ::= ASSERT LPAREN cons_checks:cc RPAREN {: RESULT=cc; :}
- | {: RESULT = new ParseNode("empty"); :}
- ;
-
-cons_checks ::= cons_check:cc {:
- ParseNode pn=new ParseNode("cons_checks");
- pn.addChild(cc);
- RESULT=pn;
- :}
- | cons_checks:ccs COMMA cons_check:cc {:
- ccs.addChild(cc);
- RESULT=ccs;
- :};
-
-cons_check ::= IDENTIFIER:name LPAREN cons_argument_list_opt:args RPAREN {:
- ParseNode pn=new ParseNode("cons_check");
- pn.addChild("name").addChild("identifier").addChild(name);
- pn.addChild(args);
- RESULT=pn;
- :};
-
-flag_effects_opt ::= LPAREN flag_effects:fe RPAREN {:RESULT=fe;:}
- | {: RESULT = new ParseNode("empty"); :}
- ;
-
-flag_effects ::= flag_effect:fe {:
- ParseNode pn=new ParseNode("flag_effects_list");
- pn.addChild(fe);
- RESULT=pn;
- :}
- | flag_effects:fes COMMA flag_effect:fe {:
- fes.addChild(fe);
- RESULT=fes;
- :};
-
-flag_effect ::= IDENTIFIER:id LBRACE flag_list:fl RBRACE tag_list_opt:tlo {:
- ParseNode pn=new ParseNode("flag_effect");
- pn.addChild("name").addChild(id);
- pn.addChild(fl);
- pn.addChild(tlo);
- RESULT=pn;
- :}
- | IDENTIFIER:id LBRACE RBRACE LBRACE tag_list:tl RBRACE {:
- ParseNode pn=new ParseNode("flag_effect");
- pn.addChild("name").addChild(id);
- pn.addChild(tl);
- RESULT=pn;
- :};
-
-flag_list_opt ::= LBRACE flag_list:fl RBRACE {:RESULT=fl;:}
- | LBRACE RBRACE {: RESULT = new ParseNode("empty"); :}
- |
- {: RESULT = new ParseNode("empty"); :}
- ;
-
-flag_list ::= flag_change:fc {:
- ParseNode pn=new ParseNode("flag_list");
- pn.addChild(fc);
- RESULT=pn;
- :}
- | flag_list:fl COMMA flag_change:fc {:
- fl.addChild(fc);
- RESULT=fl;
- :};
-
-flag_change ::= IDENTIFIER:id {:
- RESULT=new ParseNode("name").addChild(id).getRoot();
- :} |
- NOT IDENTIFIER:id {:
- RESULT=new ParseNode("not").addChild("name").addChild(id).getRoot();
- :};
-
-// 19.2) The Syntactic Grammar
-goal ::= compilation_unit:cu
- {:
- RESULT = cu;
- :}
- ;
-
-// 19.3) Lexical Structure.
-
-
-literal ::= INTEGER_LITERAL:integer_lit
- {:
- ParseNode pn=new ParseNode("literal");
- pn.addChild("integer").setLiteral(integer_lit);
- RESULT=pn;
- :}
- | FLOATING_POINT_LITERAL:float_lit
- {:
- ParseNode pn=new ParseNode("literal");
- pn.addChild("float").setLiteral(float_lit);
- RESULT=pn;
- :}
- | BOOLEAN_LITERAL:boolean_lit
- {:
- ParseNode pn=new ParseNode("literal");
- pn.addChild("boolean").setLiteral(boolean_lit);
- RESULT=pn;
- :}
- | CHARACTER_LITERAL:char_lit
- {:
- ParseNode pn=new ParseNode("literal");
- pn.addChild("char").setLiteral(char_lit);
- RESULT=pn;
- :}
- | STRING_LITERAL:string_lit
- {:
- ParseNode pn=new ParseNode("literal");
- pn.addChild("string").setLiteral(string_lit);
- RESULT=pn;
- :}
- | NULL_LITERAL
- {:
- RESULT=(new ParseNode("literal")).addChild("null").getRoot();
- :}
- ;
-
-// 19.4) Types, Values, and Variables
-type ::= primitive_type:type {: RESULT=type; :}
- | reference_type:type {: RESULT=type; :}
- ;
-
-primitive_type ::=
- numeric_type:type {: RESULT=type; :}
- | BOOLEAN {: RESULT=(new ParseNode("type")).addChild("boolean").getRoot(); :}
- ;
-numeric_type::= integral_type:type {: RESULT=type; :}
- | floating_point_type:type {: RESULT=type; :}
- ;
-integral_type ::=
- BYTE {: RESULT=(new ParseNode("type")).addChild("byte").getRoot(); :}
- | SHORT {: RESULT=(new ParseNode("type")).addChild("short").getRoot(); :}
- | INT {: RESULT=(new ParseNode("type")).addChild("int").getRoot(); :}
- | LONG {: RESULT=(new ParseNode("type")).addChild("long").getRoot(); :}
- | CHAR {: RESULT=(new ParseNode("type")).addChild("char").getRoot(); :}
- ;
-floating_point_type ::=
- FLOAT {: RESULT=(new ParseNode("type")).addChild("float").getRoot(); :}
- | DOUBLE {: RESULT=(new ParseNode("type")).addChild("double").getRoot(); :}
- ;
-
-reference_type ::=
- class_or_interface_type:type {: RESULT=type; :}
- | array_type:type {: RESULT=type; :}
- ;
-class_or_interface_type ::= name:name {:
- RESULT=(new ParseNode("type")).addChild("class").addChild(name).getRoot();
- :};
-
-class_type ::= class_or_interface_type:type {: RESULT=type; :};
-//interface_type ::= class_or_interface_type;
-
-array_type ::= primitive_type:prim dims:dims {:
- ParseNode pn=(new ParseNode("type")).addChild("array");
- pn.addChild("basetype").addChild(prim);
- pn.addChild("dims").setLiteral(dims);
- RESULT=pn.getRoot();
- :}
- | name:name dims:dims {:
- ParseNode pn=(new ParseNode("type")).addChild("array");
- pn.addChild("basetype").addChild("type").addChild("class").addChild(name);
- pn.addChild("dims").setLiteral(dims);
- RESULT=pn.getRoot();
- :}
- ;
-
-// 19.5) Names
-name ::= simple_name:name {: RESULT=name; :}
- | qualified_name:name {: RESULT=name; :}
- ;
-simple_name ::= IDENTIFIER:id {:
- RESULT=(new ParseNode("name")).addChild("identifier").addChild(id).getRoot();
- :}
- ;
-qualified_name ::= name:name DOT IDENTIFIER:id {:
- ParseNode pn=new ParseNode("name");
- pn.addChild("base").addChild(name);
- pn.addChild("identifier").addChild(id);
- RESULT=pn;
- :}
- ;
-
-// 19.6) Packages
-compilation_unit ::=
- package_declaration_opt:pdo
- import_declarations_opt:ido
- type_declarations_opt:tdo {:
- ParseNode pn=new ParseNode("compilation_unit");
- pn.addChild(tdo);
- pn.addChild("packages").addChild(pdo);
- pn.addChild("imports").addChild(ido);
- RESULT=pn;
- :}
- ;
-package_declaration_opt ::= package_declaration:pdo {:
- RESULT=pdo;
- :} |
- {: RESULT=new ParseNode("empty"); :}
-;
-
-import_declarations_opt ::= import_declarations:ido {:
- RESULT=ido;
- :} |
- {: RESULT=new ParseNode("empty"); :}
-;
-type_declarations_opt ::= type_declarations:tds {:
- RESULT=tds;
- :} |
- {: RESULT=new ParseNode("empty"); :}
- ;
-
-import_declarations ::=
- import_declaration:id {:
- ParseNode pn=new ParseNode("import_decls_list");
- pn.addChild(id);
- RESULT=pn;
- :}
- | import_declarations:ids import_declaration:id {:
- ids.addChild(id);
- RESULT=ids;
- :}
- ;
-
-type_declarations ::=
- type_declaration:td {:
- ParseNode pn=new ParseNode("type_declaration_list");
- pn.addChild(td);
- RESULT=pn;
- :}
- | type_declarations:tds type_declaration:td {:
- tds.addChild(td);
- RESULT=tds;
- :}
- ;
-
-package_declaration ::=
- PACKAGE name:name SEMICOLON {:
- ParseNode pn=new ParseNode("package");
- pn.addChild(name);
- RESULT=pn;
- :}
- ;
-import_declaration ::=
- single_type_import_declaration:sid {: RESULT=sid; :}
- | type_import_on_demand_declaration:iod {: RESULT=iod; :}
- ;
-single_type_import_declaration ::=
- IMPORT name:name SEMICOLON {:
- ParseNode pn=new ParseNode("import_single");
- pn.addChild(name);
- RESULT=pn;
-:}
- ;
-type_import_on_demand_declaration ::=
- IMPORT name:name DOT MULT SEMICOLON {:
- ParseNode pn=new ParseNode("import_ondemand");
- pn.addChild(name);
- RESULT=pn;
- :}
- ;
-
-type_declaration ::=
- class_declaration:cd
- {:
- RESULT=cd;
- :}
- | task_declaration:td
- {:
- RESULT=td;
- :}
-// | interface_declaration
- | SEMICOLON {: RESULT=new ParseNode("empty"); :}
- ;
-
-// 19.7) Productions used only in the LALR(1) grammar
-modifiers_opt::=
- {: RESULT=new ParseNode("empty"); :}
- | modifiers:mo {:
- RESULT=mo;
- :}
- ;
-modifiers ::= modifier:mo {:
- ParseNode pn=new ParseNode("modifier_list");
- pn.addChild(mo);
- RESULT=pn;
- :}
- | modifiers:mos modifier:mo {:
- mos.addChild(mo);
- RESULT=mos;
- :}
- ;
-modifier ::=
- PUBLIC {: RESULT=new ParseNode("public"); :}|
- PROTECTED {: RESULT=new ParseNode("protected"); :}|
- PRIVATE {: RESULT=new ParseNode("private"); :}|
- STATIC {: RESULT=new ParseNode("static"); :} |
-// ABSTRACT |
- FINAL {: RESULT=new ParseNode("final"); :}|
- NATIVE {: RESULT=new ParseNode("native"); :} |
- SYNCHRONIZED {: RESULT=new ParseNode("synchronized"); :} |
- ATOMIC {: RESULT=new ParseNode("atomic"); :}
-// TRANSIENT |
-// VOLATILE |
-// STRICTFP // note that semantic analysis must check that the
- // context of the modifier allows strictfp.
- ;
-
-// 19.8) Classes
-
-// 19.8.1) Class Declaration:
-class_declaration ::=
- modifiers_opt:mo CLASS IDENTIFIER:id super_opt:so //interfaces_opt
-class_body:body
- {:
- ParseNode pn=new ParseNode("class_declaration");
- pn.addChild("modifiers").addChild(mo);
- pn.addChild("name").addChild(id);
- pn.addChild("super").addChild(so);
- pn.addChild("classbody").addChild(body);
- RESULT=pn;
- :}
- ;
-super ::= EXTENDS class_type:classtype {:
- RESULT=classtype;
- :}
- ;
-super_opt ::=
- {: RESULT=new ParseNode("empty"); :}
- | super:su {:
- RESULT=su;
- :}
- ;
-
-//interfaces ::= IMPLEMENTS interface_type_list
-// ;
-//interfaces_opt::=
-// | interfaces
-// ;
-//interface_type_list ::=
-// interface_type
-// | interface_type_list COMMA interface_type
-// ;
-
-class_body ::= LBRACE class_body_declarations_opt:cbdo RBRACE {: RESULT=cbdo; :}
- ;
-
-class_body_declarations_opt ::=
- {: RESULT=new ParseNode("empty"); :}
- | class_body_declarations:cbd {: RESULT=cbd; :};
-
-class_body_declarations ::=
- class_body_declaration:cbd {:
- ParseNode pn=new ParseNode("class_body_declaration_list");
- pn.addChild(cbd);
- RESULT=pn;
- :}
- | class_body_declarations:cbds class_body_declaration:cbd {:
- cbds.addChild(cbd);
- RESULT=cbds;
- :}
- ;
-
-class_body_declaration ::=
- class_member_declaration:member {:
- RESULT=(new ParseNode("member")).addChild(member).getRoot();
- :}
-// | static_initializer
- | constructor_declaration:constructor {:
- RESULT=(new ParseNode("constructor")).addChild(constructor).getRoot();
- :}
- | block:block {:
- RESULT=(new ParseNode("block")).addChild(block).getRoot();
-:}
- ;
-class_member_declaration ::=
- //failure aware computation
- flag_declaration:flag {:
- RESULT=(new ParseNode("flag")).addChild(flag).getRoot();
- :}
- |
- field_declaration:field {:
- RESULT=(new ParseNode("field")).addChild(field).getRoot();
- :}
- | method_declaration:method {:
- RESULT=(new ParseNode("method")).addChild(method).getRoot();
- :}
- /* repeat the prod for 'class_declaration' here: */
-// | modifiers_opt CLASS IDENTIFIER super_opt class_body
-// | interface_declaration
- | SEMICOLON {: RESULT=new ParseNode("empty"); :}
- ;
-
-//Failure aware computation
-flag_declaration ::=
- FLAG IDENTIFIER:id SEMICOLON {:
- ParseNode pn=new ParseNode("flag_declaration");
- pn.addChild("name").addChild(id);
- RESULT=pn;
- :} |
- EXTERNAL FLAG IDENTIFIER:id SEMICOLON {:
- ParseNode pn=new ParseNode("flag_declaration");
- pn.addChild("name").addChild(id);
- pn.addChild("external");
- RESULT=pn;
- :}
- ;
-
-// 19.8.2) Field Declarations
-field_declaration ::=
- modifiers_opt:mo type:type variable_declarators:var SEMICOLON {:
- ParseNode pn=new ParseNode("field_declaration");
- pn.addChild("modifier").addChild(mo);
- pn.addChild("type").addChild(type);
- pn.addChild("variables").addChild(var);
- RESULT=pn;
- :} |
- modifiers_opt:mo GLOBAL type:type variable_declarators:var SEMICOLON {:
- ParseNode pn=new ParseNode("field_declaration");
- pn.addChild("modifier").addChild(mo);
- pn.addChild("type").addChild(type);
- pn.addChild("variables").addChild(var);
- pn.addChild("global");
- RESULT=pn;
- :}
- ;
-
-variable_declarators ::=
- variable_declarator:vd {:
- ParseNode pn=new ParseNode("variable_declarators_list");
- pn.addChild(vd);
- RESULT=pn;
- :}
- | variable_declarators:vds COMMA variable_declarator:vd {:
- vds.addChild(vd);
- RESULT=vds;
- :}
- ;
-variable_declarator ::=
- variable_declarator_id:id {:
- ParseNode pn=new ParseNode("variable_declarator");
- pn.addChild(id);
- RESULT=pn;
- :}
- | variable_declarator_id:id EQ variable_initializer:init {:
- ParseNode pn=new ParseNode("variable_declarator");
- pn.addChild(id);
- pn.addChild("initializer").addChild(init);
- RESULT=pn;
- :}
- ;
-variable_declarator_id ::=
- IDENTIFIER:id {:
- RESULT=(new ParseNode("single")).addChild(id).getRoot();:}
- | variable_declarator_id:id LBRACK RBRACK {:
- RESULT=(new ParseNode("array")).addChild(id).getRoot();:}
- ;
-variable_initializer ::=
- expression:exp {: RESULT=exp; :}
-// | array_initializer
- ;
-
-// 19.8.3) Method Declarations
-method_declaration ::=
- method_header:header method_body:body {:
- ParseNode pn=new ParseNode("method_declaration");
- pn.addChild(header);
- pn.addChild("body").addChild(body);
- RESULT=pn;
- :}
- ;
-method_header ::=
- modifiers_opt:mo type:type method_declarator:decl //throws_opt
- {:
- ParseNode pn=new ParseNode("method_header");
- pn.addChild("modifiers").addChild(mo);
- pn.addChild("returntype").addChild(type);
- pn.addChild(decl);
- RESULT=pn;
- :}
- | modifiers_opt:mo VOID method_declarator:decl //throws_opt
- {:
- ParseNode pn=new ParseNode("method_header");
- pn.addChild("modifiers").addChild(mo);
- pn.addChild(decl);
- RESULT=pn;
- :}
- ;
-method_declarator ::=
- IDENTIFIER:id LPAREN formal_parameter_list_opt:params RPAREN {:
- ParseNode pn=new ParseNode("method_declarator");
- pn.addChild("name").addChild(id);
- pn.addChild("parameters").addChild(params);
- RESULT=pn;
- :}
-// | method_declarator LBRACK RBRACK // deprecated
-// be careful; the above production also allows 'void foo() []'
- ;
-formal_parameter_list_opt ::=
- {: RESULT=new ParseNode("empty"); :}
- | formal_parameter_list:fpl {:
- RESULT=fpl;
- :}
- ;
-formal_parameter_list ::=
- formal_parameter:fp {:
- ParseNode pn=new ParseNode("formal_parameter_list");
- pn.addChild(fp);
- RESULT=pn;
- :}
- | formal_parameter_list:fpl COMMA formal_parameter:fp {:
- fpl.addChild(fp);
- RESULT=fpl;
- :}
- ;
-formal_parameter ::=
- type:type variable_declarator_id:name {:
- ParseNode pn=new ParseNode("formal_parameter");
- pn.addChild(type);
- pn.addChild(name);
- RESULT=pn;
- :}
- |
- TAG variable_declarator_id:name {:
- ParseNode pn=new ParseNode("tag_parameter");
- pn.addChild(name);
- RESULT=pn;
- :}
-// | FINAL type variable_declarator_id
- ;
-//throws_opt ::=
-// | throws
-// ;
-//throws ::= THROWS class_type_list
-// ;
-//class_type_list ::=
-// class_type
-// | class_type_list COMMA class_type
-// ;
-method_body ::= block:block {:
- RESULT=block;
- :}
- | SEMICOLON {: RESULT=new ParseNode("empty"); :}
- ;
-
-// 19.8.4) Static Initializers
-//static_initializer ::=
-// STATIC block
-// ;
-
-// 19.8.5) Constructor Declarations
-constructor_declaration ::=
- modifiers_opt:mo constructor_declarator:cd
-//throws_opt
- constructor_body:body {:
- ParseNode pn=new ParseNode("constructor_declaration");
- pn.addChild("modifiers").addChild(mo);
- pn.addChild(cd);
- pn.addChild("body").addChild(body);
- RESULT=pn;
- :} |
- modifiers_opt:mo GLOBAL constructor_declarator:cd
-//throws_opt
- constructor_body:body {:
- ParseNode pn=new ParseNode("constructor_declaration");
- pn.addChild("global");
- pn.addChild("modifiers").addChild(mo);
- pn.addChild(cd);
- pn.addChild("body").addChild(body);
- RESULT=pn;
- :}
- ;
-constructor_declarator ::=
- simple_name:name LPAREN formal_parameter_list_opt:fplo RPAREN {:
- ParseNode pn=new ParseNode("constructor_declarator");
- pn.addChild(name);
- pn.addChild("parameters").addChild(fplo);
- RESULT=pn;
- :}
- ;
-constructor_body ::=
-// LBRACE explicit_constructor_invocation:eci block_statements:bs RBRACE |
-// LBRACE explicit_constructor_invocation RBRACE |
- LBRACE block_statements:block RBRACE {:
- ParseNode pn=new ParseNode("constructor_body");
- pn.addChild(block);
- RESULT=pn;
- :}
- | LBRACE RBRACE {: RESULT=new ParseNode("empty"); :}
- ;
-//explicit_constructor_invocation ::=
-// THIS LPAREN argument_list_opt RPAREN SEMICOLON
-// | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
-// | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON
-// | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
-// ;
-
-// 19.9) Interfaces
-
-// 19.9.1) Interface Declarations
-//interface_declaration ::=
-// modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt
-// interface_body
-// ;
-//extends_interfaces_opt ::=
-// | extends_interfaces
-// ;
-//extends_interfaces ::=
-// EXTENDS interface_type
-// | extends_interfaces COMMA interface_type
-// ;
-//interface_body ::=
-// LBRACE interface_member_declarations_opt RBRACE
-// ;
-//interface_member_declarations_opt ::=
-// | interface_member_declarations
-// ;
-//interface_member_declarations ::=
-// interface_member_declaration
-// | interface_member_declarations interface_member_declaration
-// ;
-//interface_member_declaration ::=
-// constant_declaration
-// | abstract_method_declaration
-// | class_declaration
-// | interface_declaration
-// | SEMICOLON
-// ;
-//constant_declaration ::=
-// field_declaration
-// // need to semantically check that modifiers of field declaration
-// // include only PUBLIC, STATIC, or FINAL. Other modifiers are
-// // disallowed.
-// ;
-//abstract_method_declaration ::=
-// method_header SEMICOLON
-// ;
-
-
-// 19.10) Arrays
-//array_initializer ::=
-// LBRACE variable_initializers COMMA RBRACE
-// | LBRACE variable_initializers RBRACE
-// | LBRACE COMMA RBRACE
-// | LBRACE RBRACE
-// ;
-//variable_initializers ::=
-// variable_initializer
-// | variable_initializers COMMA variable_initializer
-// ;
-
-// 19.11) Blocks and Statements
-block ::= LBRACE block_statements_opt:bso RBRACE {:
- RESULT=bso;
- :}
- ;
-block_statements_opt ::=
- {: RESULT=new ParseNode("empty"); :}
- | block_statements:bs {:
- RESULT=bs;
- :}
- ;
-block_statements ::=
- block_statement:bs {:
- ParseNode pn=new ParseNode("block_statement_list");
- pn.addChild(bs);
- RESULT=pn;
- :}
- | block_statements:bss block_statement:bs {:
- bss.addChild(bs);
- RESULT=bss;
- :}
- ;
-block_statement ::=
- tag_variable_declaration_statement:tvds {:
- RESULT=tvds;
- :}
- | local_variable_declaration_statement:lvds {:
- RESULT=lvds;
- :}
- | statement:statement {:
- RESULT=statement;
- :}
-// | class_declaration
-// | interface_declaration
- ;
-tag_variable_declaration_statement ::=
- TAG IDENTIFIER:id EQ NEW TAG LPAREN IDENTIFIER:type RPAREN SEMICOLON {:
- ParseNode pn=new ParseNode("tag_declaration");
- pn.addChild("single").addChild(id);
- pn.addChild("type").addChild(type);
- RESULT=pn;
- :}
- ;
-local_variable_declaration_statement ::=
- local_variable_declaration:lvd SEMICOLON {:
- RESULT=lvd;
- :}
- ;
-local_variable_declaration ::=
- type:type variable_declarators:var {:
- ParseNode pn=new ParseNode("local_variable_declaration");
- pn.addChild(type);
- pn.addChild(var);
- RESULT=pn;
-:}
-// | FINAL type variable_declarators
- ;
-statement ::= statement_without_trailing_substatement:st {:
- RESULT=st;
- :}
-// | labeled_statement:st {: RESULT=st; :}
- | if_then_statement:st {: RESULT=st; :}
- | if_then_else_statement:st {: RESULT=st; :}
- | while_statement:st {: RESULT=st; :}
- | for_statement:st {: RESULT=st; :}
- ;
-statement_no_short_if ::=
- statement_without_trailing_substatement:st {: RESULT=st; :}
-// | labeled_statement_no_short_if:st {: RESULT=st; :}
- | if_then_else_statement_no_short_if:st {: RESULT=st; :}
- | while_statement_no_short_if:st {: RESULT=st; :}
- | for_statement_no_short_if:st {: RESULT=st; :}
- ;
-statement_without_trailing_substatement ::=
- block:st {: RESULT=st; :}
- | empty_statement:st {: RESULT=st; :}
- | expression_statement:st {: RESULT=st; :}
-// | switch_statement
- | do_statement:dos {:RESULT=dos; :}
- | break_statement:st {: RESULT=st; :}
- | continue_statement:st {: RESULT=st; :}
- | return_statement:st {: RESULT=st; :}
- | task_exitstatement:st {: RESULT=st; :}
- | atomic_statement:st {: RESULT=st; :}
-// | synchronized_statement
-// | throw_statement
-// | try_statement
-// | assert_statement
- ;
-empty_statement ::=
- SEMICOLON {: RESULT=new ParseNode("nop"); :}
- ;
-//labeled_statement ::=
-// IDENTIFIER COLON statement
-// ;
-//labeled_statement_no_short_if ::=
-// IDENTIFIER COLON statement_no_short_if
-// ;
-expression_statement ::=
- statement_expression:se SEMICOLON {:
- ParseNode pn=new ParseNode("expression");
- pn.addChild(se);
- RESULT=pn; :}
- ;
-statement_expression ::=
- assignment:st {: RESULT=st; :}
- | preincrement_expression:st {: RESULT=st; :}
- | predecrement_expression:st {: RESULT=st; :}
- | postincrement_expression:st {: RESULT=st; :}
- | postdecrement_expression:st {: RESULT=st; :}
- | method_invocation:st {: RESULT=st; :}
- | class_instance_creation_expression:st {: RESULT=st; :}
- ;
-if_then_statement ::=
- IF LPAREN expression:exp RPAREN statement:st {:
- ParseNode pn=new ParseNode("ifstatement");
- pn.addChild("condition").addChild(exp);
- pn.addChild("statement").addChild(st);
- RESULT=pn;
- :}
- ;
-if_then_else_statement ::=
- IF LPAREN expression:exp RPAREN statement_no_short_if:st
- ELSE statement:else_st {:
- ParseNode pn=new ParseNode("ifstatement");
- pn.addChild("condition").addChild(exp);
- pn.addChild("statement").addChild(st);
- pn.addChild("else_statement").addChild(else_st);
- RESULT=pn;
- :}
- ;
-if_then_else_statement_no_short_if ::=
- IF LPAREN expression:exp RPAREN statement_no_short_if:st
- ELSE statement_no_short_if:else_st {:
- ParseNode pn=new ParseNode("ifstatement");
- pn.addChild("condition").addChild(exp);
- pn.addChild("statement").addChild(st);
- pn.addChild("else_statement").addChild(else_st);
- RESULT=pn;
- :}
- ;
-//switch_statement ::=
-// SWITCH LPAREN expression RPAREN switch_block
-// ;
-//switch_block ::=
-// LBRACE switch_block_statement_groups switch_labels RBRACE
-// | LBRACE switch_block_statement_groups RBRACE
-// | LBRACE switch_labels RBRACE
-// | LBRACE RBRACE
-// ;
-//switch_block_statement_groups ::=
-// switch_block_statement_group
-// | switch_block_statement_groups switch_block_statement_group
-// ;
-//switch_block_statement_group ::=
-// switch_labels block_statements
-// ;
-//switch_labels ::=
-// switch_label
-// | switch_labels switch_label
-// ;
-//switch_label ::=
-// CASE constant_expression COLON
-// | DEFAULT COLON
-// ;
-
-while_statement ::=
- WHILE LPAREN expression:exp RPAREN statement:st {:
- ParseNode pn=new ParseNode("whilestatement");
- pn.addChild("condition").addChild(exp);
- pn.addChild("statement").addChild(st);
- RESULT=pn;
- :}
- ;
-while_statement_no_short_if ::=
- WHILE LPAREN expression:exp RPAREN statement_no_short_if:st {:
- ParseNode pn=new ParseNode("whilestatement");
- pn.addChild("condition").addChild(exp);
- pn.addChild("statement").addChild(st);
- RESULT=pn;
- :}
- ;
-do_statement ::=
- DO statement:st WHILE LPAREN expression:exp RPAREN SEMICOLON {:
- ParseNode pn=new ParseNode("dowhilestatement");
- pn.addChild("condition").addChild(exp);
- pn.addChild("statement").addChild(st);
- RESULT=pn;
- :}
- ;
-for_statement ::=
- FOR LPAREN for_init_opt:init SEMICOLON expression_opt:exp SEMICOLON
- for_update_opt:update RPAREN statement:st {:
- ParseNode pn=new ParseNode("forstatement");
- pn.addChild("initializer").addChild(init);
- pn.addChild("condition").addChild(exp);
- pn.addChild("update").addChild(update);
- pn.addChild("statement").addChild(st);
- RESULT=pn;
- :}
- ;
-for_statement_no_short_if ::=
- FOR LPAREN for_init_opt:init SEMICOLON expression_opt:exp SEMICOLON
- for_update_opt:update RPAREN statement_no_short_if:st {:
- ParseNode pn=new ParseNode("forstatement");
- pn.addChild("initializer").addChild(init);
- pn.addChild("condition").addChild(exp);
- pn.addChild("update").addChild(update);
- pn.addChild("statement").addChild(st);
- RESULT=pn;
- :}
- ;
-for_init_opt ::=
- {: RESULT=new ParseNode("empty"); :}
- | for_init:init {: RESULT=init; :}
- ;
-for_init ::= statement_expression_list:list {: RESULT=list; :}
- | local_variable_declaration:decl {: RESULT=decl; :}
- ;
-for_update_opt ::=
- {: RESULT=new ParseNode("empty"); :}
- | for_update:update {: RESULT=update; :}
- ;
-for_update ::= statement_expression_list:list {: RESULT=list; :}
- ;
-statement_expression_list ::=
- statement_expression:expr {:
- RESULT=(new ParseNode("statement_expression_list")).addChild(expr).getRoot();
- :}
- | statement_expression_list:list COMMA statement_expression:expr {:
- list.addChild(expr);
- RESULT=list;
- :}
- ;
-
-//identifier_opt ::=
-// | IDENTIFIER
-// ;
-
-break_statement ::=
- BREAK
-//identifier_opt
-SEMICOLON {: RESULT=new ParseNode("break"); :}
- ;
-
-continue_statement ::=
- CONTINUE
-//identifier_opt
-SEMICOLON
-{: RESULT=new ParseNode("continue"); :}
- ;
-return_statement ::=
- RETURN expression_opt:exp SEMICOLON {:
- RESULT=(new ParseNode("return")).addChild(exp).getRoot(); :}
- ;
-//throw_statement ::=
-// THROW expression SEMICOLON
-// ;
-//synchronized_statement ::=
-// SYNCHRONIZED LPAREN expression RPAREN block
-// ;
-atomic_statement ::=
- ATOMIC block:blk {:
- RESULT=(new ParseNode("atomic")).addChild(blk).getRoot();
- :}
- ;
-//try_statement ::=
-// TRY block catches
-// | TRY block catches_opt finally
-// ;
-//catches_opt ::=
-// | catches
-// ;
-//catches ::= catch_clause
-// | catches catch_clause
-// ;
-//catch_clause ::=
-// CATCH LPAREN formal_parameter RPAREN block
-// ;
-//finally ::= FINALLY block
-// ;
-//assert_statement ::=
-// ASSERT expression SEMICOLON
-// | ASSERT expression COLON expression SEMICOLON
-// ;
-
-// 19.12) Expressions
-primary ::= primary_no_new_array:st {:
- RESULT=st; :}
-// | array_creation_init:st {:
-// RESULT=st;
-// :}
- | array_creation_uninit:st {:
- RESULT=st;
- :}
- ;
-primary_no_new_array ::=
- literal:lit {: RESULT=lit; :}
- | THIS {: RESULT=new ParseNode("this"); :}
- | LPAREN expression:exp RPAREN {: RESULT=exp; :}
- | class_instance_creation_expression:exp {: RESULT=exp; :}
- | field_access:exp {: RESULT=exp; :}
- | method_invocation:exp {: RESULT=exp; :}
- | array_access:exp {: RESULT=exp; :}
-// | primitive_type DOT CLASS
-// | VOID DOT CLASS
-// | array_type DOT CLASS
-// | name DOT CLASS
-// | name DOT THIS
- ;
-class_instance_creation_expression ::=
- NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN flag_list_opt:feo {:
- ParseNode pn=new ParseNode("createobject");
- pn.addChild(type);
- pn.addChild(args);
- pn.addChild(feo);
- RESULT=pn;
- :}
- //Global object
- | GLOBAL NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN flag_list_opt:feo {:
- ParseNode pn=new ParseNode("createobject");
- pn.addChild(type);
- pn.addChild(args);
- pn.addChild(feo);
- pn.addChild("global");
- RESULT=pn;
- :}
- | NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN LBRACE RBRACE LBRACE tag_list:tl RBRACE {:
- ParseNode pn=new ParseNode("createobject");
- pn.addChild(type);
- pn.addChild(args);
- pn.addChild(tl);
- RESULT=pn;
- :}
- | NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN LBRACE flag_list:fl RBRACE LBRACE tag_list:tl RBRACE {:
- ParseNode pn=new ParseNode("createobject");
- pn.addChild(type);
- pn.addChild(args);
- pn.addChild(fl);
- pn.addChild(tl);
- RESULT=pn;
- :}
-
-// | NEW class_or_interface_type LPAREN argument_list_opt RPAREN class_body
-// | primary DOT NEW IDENTIFIER
-// LPAREN argument_list_opt RPAREN {:
-//
-// :}
-// | primary DOT NEW IDENTIFIER
-// LPAREN argument_list_opt RPAREN class_body
-// | name DOT NEW IDENTIFIER
-// LPAREN argument_list_opt RPAREN
-// | name DOT NEW IDENTIFIER
-// LPAREN argument_list_opt RPAREN class_body
- ;
-cons_argument_list_opt ::=
- {: RESULT=new ParseNode("empty"); :}
- | cons_argument_list:args {: RESULT=args; :}
- ;
-
-cons_argument_list ::=
- IDENTIFIER:id COLON expression:exp {:
- ParseNode pn=new ParseNode("cons_argument_list");
- ParseNode pnarg=pn.addChild("binding");
- pnarg.addChild("var").addChild(id);
- pnarg.addChild("exp").addChild(exp);
- RESULT=pn;
- :}
- | argument_list:list COMMA IDENTIFIER:id COLON expression:exp {:
- ParseNode pnarg=new ParseNode("binding");
- pnarg.addChild("var").addChild(id);
- pnarg.addChild("exp").addChild(exp);
- list.addChild(pnarg);
- RESULT=list;
- :}
- ;
-
-argument_list_opt ::=
- {: RESULT=new ParseNode("empty"); :}
- | argument_list:args {: RESULT=args; :}
- ;
-
-argument_list ::=
- expression:exp {:
- ParseNode pn=new ParseNode("argument_list");
- pn.addChild(exp);
- RESULT=pn;
- :}
- | argument_list:list COMMA expression:exp {:
- list.addChild(exp);
- RESULT=list;
- :}
- ;
-array_creation_uninit ::=
- NEW primitive_type:type dim_exprs:dimexpr dims_opt:dims {:
- ParseNode pn=new ParseNode("createarray");
- pn.addChild(type);
- pn.addChild(dimexpr);
- pn.addChild("dims_opt").setLiteral(dims);
- RESULT=pn;
- :}
- | NEW class_or_interface_type:type dim_exprs:dimexpr dims_opt:dims {:
- ParseNode pn=new ParseNode("createarray");
- pn.addChild(type);
- pn.addChild(dimexpr);
- pn.addChild("dims_opt").setLiteral(dims);
- RESULT=pn;
- :}
- | NEW GLOBAL primitive_type:type dim_exprs:dimexpr dims_opt:dims {:
- ParseNode pn=new ParseNode("createarray");
- pn.addChild(type);
- pn.addChild(dimexpr);
- pn.addChild("dims_opt").setLiteral(dims);
- pn.addChild("global");
- RESULT=pn;
- :}
- | NEW GLOBAL class_or_interface_type:type dim_exprs:dimexpr dims_opt:dims {:
- ParseNode pn=new ParseNode("createarray");
- pn.addChild(type);
- pn.addChild(dimexpr);
- pn.addChild("dims_opt").setLiteral(dims);
- pn.addChild("global");
- RESULT=pn;
- :}
- ;
-//array_creation_init ::=
-// NEW primitive_type dims array_initializer
-// | NEW class_or_interface_type dims array_initializer
-// ;
-dim_exprs ::= dim_expr:exp {:
- ParseNode pn=new ParseNode("dim_exprs");
- pn.addChild(exp);
- RESULT=pn; :}
- | dim_exprs:base dim_expr:exp {:
- base.addChild(exp);
- RESULT=base;
- :}
- ;
-dim_expr ::= LBRACK expression:exp RBRACK {: RESULT=exp; :}
- ;
-dims_opt ::= {: RESULT=new Integer(0); :}
- | dims:dims {: RESULT = dims; :}
- ;
-
-dims ::= LBRACK RBRACK {: RESULT=new Integer(1); :}
- | dims:dims LBRACK RBRACK {: RESULT=new Integer(dims.intValue()+1); :}
- ;
-
-field_access ::=
- primary:base DOT IDENTIFIER:id {:
- ParseNode pn=new ParseNode("fieldaccess");
- pn.addChild("base").addChild(base);
- pn.addChild("field").addChild(id);
- RESULT=pn;
-:}
-// | SUPER DOT IDENTIFIER
-// | name DOT SUPER DOT IDENTIFIER
- ;
-method_invocation ::=
- name:name LPAREN argument_list_opt:args RPAREN {:
- ParseNode pn=new ParseNode("methodinvoke1");
- pn.addChild(name);
- pn.addChild(args);
- RESULT=pn;
- :}
- | primary:base DOT IDENTIFIER:name LPAREN argument_list_opt:args RPAREN {:
- ParseNode pn=new ParseNode("methodinvoke2");
- pn.addChild("base").addChild(base);
- pn.addChild("id").addChild(name);
- pn.addChild(args);
- RESULT=pn;
- :}
-// | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
-// | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
- ;
-array_access ::=
- name:name LBRACK expression:exp RBRACK {:
- ParseNode pn=new ParseNode("arrayaccess");
- pn.addChild("base").addChild(name);
- pn.addChild("index").addChild(exp);
- RESULT=pn;
- :}
- | primary_no_new_array:base LBRACK expression:exp RBRACK {:
- ParseNode pn=new ParseNode("arrayaccess");
- pn.addChild("base").addChild(base);
- pn.addChild("index").addChild(exp);
- RESULT=pn;
- :}
-// | array_creation_init:init LBRACK expression:exp RBRACK {:
-// ParseNode pn=new ParseNode("arrayaccess");
-// pn.addChild("init").addChild(init);
-// pn.addChild("index").addChild(exp);
-// RESULT=pn;
-// :}
- ;
-postfix_expression ::=
- primary:exp {:
- RESULT=exp; :}
- | name:exp {: RESULT=exp; :}
- | postincrement_expression:exp {: RESULT=exp; :}
- | postdecrement_expression:exp {: RESULT=exp; :}
- ;
-postincrement_expression ::=
- postfix_expression:exp PLUSPLUS
- {: RESULT=(new ParseNode("postinc")).addChild(exp).getRoot(); :}
- ;
-postdecrement_expression ::=
- postfix_expression:exp MINUSMINUS
- {: RESULT=(new ParseNode("postdec")).addChild(exp).getRoot(); :}
- ;
-unary_expression ::=
- preincrement_expression:exp {: RESULT=exp; :}
- | predecrement_expression:exp {: RESULT=exp; :}
- | PLUS unary_expression:exp
- {: RESULT=(new ParseNode("unaryplus")).addChild(exp).getRoot(); :}
- | MINUS unary_expression:exp
- {: RESULT=(new ParseNode("unaryminus")).addChild(exp).getRoot(); :}
- | unary_expression_not_plus_minus:exp {:
- RESULT=exp; :}
- ;
-preincrement_expression ::=
- PLUSPLUS unary_expression:exp
- {: RESULT=(new ParseNode("preinc")).addChild(exp).getRoot(); :}
- ;
-predecrement_expression ::=
- MINUSMINUS unary_expression:exp
- {: RESULT=(new ParseNode("predec")).addChild(exp).getRoot(); :}
- ;
-unary_expression_not_plus_minus ::=
- postfix_expression:exp {:
- RESULT=exp; :}
-// | COMP unary_expression
- | NOT unary_expression:exp
- {: RESULT=(new ParseNode("not")).addChild(exp).getRoot(); :}
- | cast_expression:exp {: RESULT=exp; :}
- ;
-cast_expression ::=
- LPAREN primitive_type:type
- //dims_opt
- RPAREN unary_expression:exp {:
- ParseNode pn=new ParseNode("cast1");
- pn.addChild("type").addChild(type);
- pn.addChild("exp").addChild(exp);
- RESULT=pn;
- :}
- | LPAREN expression:type RPAREN unary_expression_not_plus_minus:exp {:
- ParseNode pn=new ParseNode("cast2");
- pn.addChild("type").addChild(type);
- pn.addChild("exp").addChild(exp);
- RESULT=pn;
-
- :}
-// | LPAREN name dims RPAREN unary_expression_not_plus_minus
- ;
-multiplicative_expression ::=
- unary_expression:exp {:
- RESULT=exp; :}
- | multiplicative_expression:exp1 MULT unary_expression:exp2 {:
- ParseNode pn=new ParseNode("mult");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- | multiplicative_expression:exp1 DIV unary_expression:exp2 {:
- ParseNode pn=new ParseNode("div");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- | multiplicative_expression:exp1 MOD unary_expression:exp2 {:
- ParseNode pn=new ParseNode("mod");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- ;
-additive_expression ::=
- multiplicative_expression:exp {:
- RESULT=exp; :}
- | additive_expression:exp1 PLUS multiplicative_expression:exp2 {:
- ParseNode pn=new ParseNode("add");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- | additive_expression:exp1 MINUS multiplicative_expression:exp2 {:
- ParseNode pn=new ParseNode("sub");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- ;
-shift_expression ::=
- additive_expression:exp {:
- RESULT=exp; :}
- | shift_expression:exp1 LSHIFT additive_expression:exp2 {:
- ParseNode pn=new ParseNode("leftshift");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- | shift_expression:exp1 RSHIFT additive_expression:exp2 {:
- ParseNode pn=new ParseNode("rightshift");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
-// | shift_expression URSHIFT additive_expression
- ;
-relational_expression ::=
- shift_expression:exp {:
- RESULT=exp; :}
- | relational_expression:exp1 LT shift_expression:exp2 {:
- ParseNode pn=new ParseNode("comp_lt");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- | relational_expression:exp1 GT shift_expression:exp2 {:
- ParseNode pn=new ParseNode("comp_gt");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- | relational_expression:exp1 LTEQ shift_expression:exp2 {:
- ParseNode pn=new ParseNode("comp_lte");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- | relational_expression:exp1 GTEQ shift_expression:exp2 {:
- ParseNode pn=new ParseNode("comp_gte");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
-// | relational_expression INSTANCEOF reference_type
- ;
-
-equality_expression ::=
- relational_expression:exp {:
- RESULT=exp; :}
- | equality_expression:exp1 EQEQ relational_expression:exp2 {:
- ParseNode pn=new ParseNode("equal");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- | equality_expression:exp1 NOTEQ relational_expression:exp2 {:
- ParseNode pn=new ParseNode("not_equal");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- ;
-and_expression ::=
- equality_expression:exp {:
- RESULT=exp; :}
- | and_expression:exp1 AND equality_expression:exp2 {:
- ParseNode pn=new ParseNode("bitwise_and");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- ;
-exclusive_or_expression ::=
- and_expression:expr {:
- RESULT=expr;
- :}
- | exclusive_or_expression:exp1 XOR and_expression:exp2 {:
- ParseNode pn=new ParseNode("bitwise_xor");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
-:}
- ;
-inclusive_or_expression ::=
- exclusive_or_expression:exclor {:
- RESULT=exclor; :}
- | inclusive_or_expression:exp1 OR exclusive_or_expression:exp2 {:
- ParseNode pn=new ParseNode("bitwise_or");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- ;
-conditional_and_expression ::=
- inclusive_or_expression:inclor {:
- RESULT=inclor; :}
- | conditional_and_expression:exp1 ANDAND inclusive_or_expression:exp2 {:
- ParseNode pn=new ParseNode("logical_and");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- ;
-conditional_or_expression ::=
- conditional_and_expression:condand {:
- RESULT=condand; :}
- | conditional_or_expression:exp1 OROR conditional_and_expression:exp2 {:
- ParseNode pn=new ParseNode("logical_or");
- pn.addChild(exp1);
- pn.addChild(exp2);
- RESULT=pn;
- :}
- ;
-conditional_expression ::=
- conditional_or_expression:condor {:
- RESULT=condor; :}
-// | conditional_or_expression QUESTION expression
-// COLON conditional_expression
- ;
-assignment_expression ::=
- conditional_expression:expr {:
- RESULT=expr; :} |
- assignment:assign {:
- RESULT=assign; :}
- ;
-// semantic check necessary here to ensure a valid left-hand side.
-// allowing a parenthesized variable here on the lhs was introduced in
-// JLS 2; thanks to Eric Blake for pointing this out.
-assignment ::= postfix_expression:lvalue assignment_operator:op assignment_expression:rvalue {:
- ParseNode pn=new ParseNode("assignment");
- pn.addChild("op").addChild(op);
- ParseNode pnargs=pn.addChild("args");
- pnargs.addChild(lvalue);
- pnargs.addChild(rvalue);
- RESULT=pn;
- :}
- ;
-assignment_operator ::=
- EQ {: RESULT=new ParseNode("eq"); :}
- | MULTEQ {: RESULT=new ParseNode("multeq"); :}
- | DIVEQ {: RESULT=new ParseNode("diveq"); :}
- | MODEQ {: RESULT=new ParseNode("modeq"); :}
- | PLUSEQ {: RESULT=new ParseNode("pluseq"); :}
- | MINUSEQ {: RESULT=new ParseNode("minuseq"); :}
- | LSHIFTEQ {: RESULT=new ParseNode("lshifteq"); :}
- | RSHIFTEQ {: RESULT=new ParseNode("rshifteq"); :}
-// | URSHIFTEQ {: RESULT=new ParseNode("urshifteq"); :}
- | ANDEQ {: RESULT=new ParseNode("andeq"); :}
- | XOREQ {: RESULT=new ParseNode("xoreq"); :}
- | OREQ {: RESULT=new ParseNode("oreq"); :}
- ;
-expression_opt ::=
- {: RESULT=new ParseNode("empty"); :}
- | expression:exp {:
- RESULT=exp; :}
- ;
-expression ::= assignment_expression:exp {:
- RESULT=exp; :}
- ;
-//constant_expression ::=
-// expression
-// ;
+++ /dev/null
-See the wiki page at http://demsky.eecs.uci.edu/compiler/
\ No newline at end of file
+++ /dev/null
-class Example {
- flag needoperation;
- flag needprinting;
- public Example() {}
-
-
- int operation;
- int x;
- int y;
- int z;
-}
-
-/* Startup object is generated with the initialstate flag set by the
- * system to start the computation up */
-
-task Startup(StartupObject s {initialstate}) {
- for(int i=0;i<10;i++) {
- Example e=new Example() {needoperation};
- e.x=i;
- e.y=2;
- e.operation=i%2;
- }
-
- taskexit(s {!initialstate}); /* Turns initial state flag off, so this task won't refire */
-}
-
-/* Fails for x=1 */
-
-task DoOperation(Example e{needoperation}) {
- e.z=10*e.y/(e.x-1);
-
- if (e.operation==0)
- /* Print the result */
- taskexit(e {!needoperation, needprinting}) assert (Example(e : e));
- else
- /* Don't print the result */
- taskexit(e {!needoperation}) assert (Example(e : e));
-}
-
-/* Note that we can write arbitrary boolean expressions for flag
- * expressions. For example, needprinting && ! needoperation would
- * also be a legal flag expression */
-
-task DoPrint(Example e{needprinting}) {
- System.printInt(e.z);
- System.printString("\n");
- taskexit(e {!needprinting});
-}
+++ /dev/null
-[forall e in Example], e.X > 0;
\ No newline at end of file
+++ /dev/null
-Example * e;
\ No newline at end of file
+++ /dev/null
-[], true => e in Example;
-[forall l in Example], true => <l, l.x> in X;
-[forall l in Example], true => <l, l.y> in Y;
-[forall l in Example], true => <l, l.z> in Z;
+++ /dev/null
-// Space Definition Language File
-
-set Example(Example);
-X: Example -> int;
-Y: Example -> int;
-Z: Example -> int;
+++ /dev/null
-[forall e in Example], e.X > 0;
\ No newline at end of file
+++ /dev/null
-Example * e;
\ No newline at end of file
+++ /dev/null
-[], true => e in Example;
-[forall l in Example], true => <l, l.x> in X;
-[forall l in Example], true => <l, l.y> in Y;
-[forall l in Example], true => <l, l.z> in Z;
+++ /dev/null
-// Space Definition Language File
-
-set Example(Example);
-X: Example -> int;
-Y: Example -> int;
-Z: Example -> int;
+++ /dev/null
-Per object possibilities:
-
-1) Lock acquired, version id matches
-
-2) No lock, but version id matches
-
-3) Version id doesn't match
-
-4) Not here
-
-Participant responses to coordinator
-
-A) DISAGREE (if we ever see at least 1 #3)
-
-B) AGREE (all #1)
-
-C) AGREE BUT MISSING OBJECTS (mixture of #1 and #4 - no #2 or #3) -
-return list of oid's for missing objects (need to build list)
-
-D) SOFT ABORT (need #2, could have #1, #4, can't have #3) - make sure
-there are no #3's
-
-Coordinator:
-
-I) ABORT (Any A's) (rerun computation, clear out transaction records, etc...)
-
-II) COMMIT (All B's) - do local commit, free storage
-
-III) ABORT BUT RETRY COMMIT (don't rerun computation) (Need D, can
-have B's, can have C', no A's)
-
-IV) ABORT BUT RETRY COMMIT WITH RELOCATING (don't rerun computation,
-but relookup all missing objects) (Need C, can have B's, no A's, no
-D's)
-
-Other machine involved in transaction:
-
-I) COMMIT - commit object into store, send ACK to coordinator
-
-II) ABORT - unlock objects, free transaction resources, send ACK to coordinator
-
-III) Coordinator unreachable:
-
- 1) Elect leader out of reachable nodes (choose smallest reachable mid)
-
- 2) leader queries everyone for what they've heard
-(ABORT/COMMIT/nothing)
-
- 3) If anyone has heard commit from original leader, all commit
-
- 4) If anyone has heard abort from original leader, all abort
-
- 5) Otherwise leader does following:
-
- for each mid in group send SUSPICIOUS_ABORT()
-
- receive acknowledgements from mid's
-
- for each mid in group send TRUST_ONLY(nodes that send
-acknowledgements)
-
- In case 5, machines become suspicious of all current machines
-not on the list. When first contacting (or being contacted by a
-machine isn't in the list, it is suspicious of all current machines
-except the leader). The machine won't talk to a machine it is
-suspicious of until it can verify that the other machines made the
-same decision on all "suspicious" transactions.
-
-COORDINATOR:
-
-Once it has received ACK's from all other machines in transaction:
-
-1) It sends a recycle transaction id message (they don't need to
-remember the ABORT/COMMIT result of that id anymore)
-
-2) After sending all these messages and receiving ack's, it marks it
-local copy of transaction id recyclable
+++ /dev/null
-control = 1 byte, number of objects = 2 bytes
-
-Client messages:
-<READ_REQUEST - control, oid
-<READ_MULT_REQUEST - control, number of objects, oids
-<MOVE_REQUEST - control, oid
-<MOVE_MULT_REQUEST - control, number of objects, oids
-<TRANS_REQUEST - control, tid, number of machines, number of objects read, number of objects modified, total bytes of modified objects (headers+bytes), list mid's, <oid, version> tuples for read objects, modified objects
-<TRANS_ABORT - control
-<TRANS_COMMIT - control
-
-Server messages:
->OBJECT_FOUND - control, object
->OBJECT_NOT_FOUND - control
->OBJECTS_FOUND - control, number of objects, objects
->OBJECTS_NOT_FOUND - control, number of objects, oids
->TRANS_AGREE - control
->TRANS_DISAGREE - control
->TRANS_SUCCESSFUL - control
-
-possible conversations (conversation means a tcp connection is maintained throughout):
-
-<READ_REQUEST
->OBJECT_FOUND
-
-<READ_REQUEST
->OBJECT_NOT_FOUND
-
-<READ_MULT_REQUEST
->OBJECTS_FOUND
-
-<READ_MULT_REQUEST
->OBJECTS_NOT_FOUND
-
-(some objects found, others not)
-<READ_MULT_REQUEST
->OBJECTS_NOT_FOUND
->OBJECTS_FOUND
-
-<MOVE_REQUEST
->OBJECT_FOUND
-
-<MOVE_REQUEST
->OBJECT_NOT_FOUND
-
-<MOVE_MULT_REQUEST
->OBJECTS_FOUND
-
-<MOVE_MULT_REQUEST
->OBJECTS_NOT_FOUND
-
-(some objects found, others not)
-<MOVE_MULT_REQUEST
->OBJECTS_NOT_FOUND
->OBJECTS_FOUND
-
-<TRANS_REQUEST
->TRANS_DISAGREE
-<TRANS_ABORT
-
-(another host disagreed or failed to respond)
-<TRANS_REQUEST
->TRANS_AGREE
-<TRANS_ABORT
-
-<TRANS_REQUEST
->TRANS_AGREE
-<TRANS_COMMIT
->TRANS_SUCCESSFUL
-
+++ /dev/null
-Q: Why prefetching?
-
-Possible prefech calls
-a) for array fields
-b) for pointer fields
-c) for typecasted oid's
-
-e.g.
-====
-x.y.z
-x.y.r
-x.y.r.t
-x[i].z
-((Integer) x).z
-
-control = 1 byte, oid = 4 bytes, new oid = 4 bytes, depth = 1/ 2 bytes, name/type = 2 bytes, offset = 2 bytes, index = 2 bytes, typecastcheck = 2 bytes,
-
- new oid = The oid found at the Participant side that can be sent to Coordinator sending prefetch message
-
-Assumptions
-===========
-
-1. Assume a max object size
- Q: Why?
-2.
-
-Procedure:
-1. Compiler identifies which oids and oids.offset field to prefetch(analysing the C code)
-and supplies that information to the Coordinator machine wanting to commit transaction.
- Q: How does compiler convey this to a machine? (Design compiler interface)
-
-2. Machine distinguishes and classifies tuples as "shared" or "unique"
- e.g. while prefetching x.y.z and a.y.z if variable x == a then considered shared else unique
- also consider the case of x.y.z and a.y.z.t where x == a ( Then prefetch only a.y.z.t)
-3. If not available in local machine, look up location table and make piles to send
- prefetch control messages to all the Particpant machines from which prefetch is required.
-4. Iteratively look up the data field of the objects at the Particpant side to find objects
- and send them across to Coordinator.
-5. Coordinator takes inventory and finds out the location of the objs not found yet.
- Q: How to implement if some objects are not found through prefetch?
-
-Coordinator messages:
-
-<TRANS_PREFETCH - control, participant machine id + tid, tuples of {oids, offsets/index/typecastcheck, offset2, .....end of chain symbol}, one special
-oid to indicate end of TRANS_PREFETCH
-e.g of tuple for x.y.z
-{ depth of the tuple = 3, oid "x", # of bytes of offset "x", # of array index "x" (in this case is -1), # of bytes of offset "y",
- # of array index "y" = -1, #of bytes of offset "z" (in this case = -1 to mark special character for end of tuple), # of bytes of array index "z" = -1}
-
-
-Participant messages:
-
-<TRANS_PREFETCH_RESPONSE - control,tuples of{oids, object header + object)
-e.g. of tuple for x.y.z where x and y are found but z is not found
-{{oid of x, 0 , object header + obj x, special character}, {oid of x , oid of y, object header + obj y, special character},{
- oid x, oid of z, NULL, special character}}
-Q: How can we represent offset, or index or typechecking .....in bytes i.e. short type number?
-TODO : handle the NULL cases here
-
-
-
+++ /dev/null
-Distributed Shared Transactional Memory
\ No newline at end of file
+++ /dev/null
-d-3:
- gcc -dr -lpthread -g -o d-3 trans.c testd-3.c mlookup.c clookup.c llookup.c dstm.c objstr.c dstmserver.c plookup.c ip.c queue.c prelookup.c mcpileq.c machinepile.c
-
-demsky:
- gcc -DDEBUG -lpthread -g -o demsky dstmserver.c testserver.c plookup.c mlookup.c clookup.c llookup.c dstm.c objstr.c trans.c ip.c queue.c prelookup.c mcpileq.c machinepile.c
-
-d-4:
- gcc -lpthread -g -o d-4 trans.c testd-4.c mlookup.c clookup.c llookup.c dstm.c objstr.c dstmserver.c plookup.c ip.c queue.c prelookup.c mcpileq.c machinepile.c
-
-all:
- gcc -lpthread -g -o d-3 trans.c testd-3.c mlookup.c clookup.c llookup.c dstm.c objstr.c dstmserver.c plookup.c ip.c queue.c prelookup.c mcpileq.c machinepile.c
- gcc -lpthread -g -o demsky dstmserver.c testserver.c plookup.c mlookup.c clookup.c llookup.c dstm.c objstr.c trans.c ip.c queue.c prelookup.c mcpileq.c machinepile.c
- gcc -lpthread -g -o d-4 trans.c testd-4.c mlookup.c clookup.c llookup.c dstm.c objstr.c dstmserver.c plookup.c ip.c queue.c prelookup.c mcpileq.c machinepile.c
-
-
-mac:
- gcc -DMAC -lpthread -g -o d-3 trans.c testd-3.c mlookup.c clookup.c llookup.c dstm.c objstr.c dstmserver.c plookup.c ip.c queue.c prelookup.c mcpileq.c machinepile.c
- gcc -DMAC -lpthread -g -o demsky dstmserver.c testserver.c plookup.c mlookup.c clookup.c llookup.c dstm.c objstr.c trans.c ip.c queue.c prelookup.c mcpileq.c machinepile.c
- gcc -DMAC -lpthread -g -o d-4 trans.c testd-4.c mlookup.c clookup.c llookup.c dstm.c objstr.c dstmserver.c plookup.c ip.c queue.c prelookup.c mcpileq.c machinepile.c
-
-clean:
- rm -rf d-3 d-4 demsky
+++ /dev/null
- #include "clookup.h"
-
-chashtable_t *chashCreate(unsigned int size, float loadfactor) {
- chashtable_t *ctable;
- chashlistnode_t *nodes;
- int i;
-
- if((ctable = calloc(1, sizeof(chashtable_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
-
- // Allocate space for the hash table
- if((nodes = calloc(size, sizeof(chashlistnode_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- free(ctable);
- return NULL;
- }
-
- ctable->table = nodes;
- ctable->size = size;
- ctable->numelements = 0; // Initial number of elements in the hash
- ctable->loadfactor = loadfactor;
-
- return ctable;
-}
-
-//Finds the right bin in the hash table
-unsigned int chashFunction(chashtable_t *table, unsigned int key) {
- return ( key % (table->size));
-}
-
-//Store objects and their pointers into hash
-unsigned int chashInsert(chashtable_t *table, unsigned int key, void *val) {
- unsigned int newsize;
- int index;
- chashlistnode_t *ptr, *node;
-
- if(table->numelements > (table->loadfactor * table->size)) {
- //Resize
- newsize = 2 * table->size + 1;
- chashResize(table,newsize);
- }
-
- ptr = table->table;
- table->numelements++;
- index = chashFunction(table, key);
-#ifdef DEBUG
- printf("DEBUG -> index = %d, key = %d, val = %x\n", index, key, val);
-#endif
- if(ptr[index].next == NULL && ptr[index].key == 0) { // Insert at the first position in the hashtable
- ptr[index].key = key;
- ptr[index].val = val;
- } else { // Insert in the beginning of linked list
- if ((node = calloc(1, sizeof(chashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
- node->key = key;
- node->val = val;
- node->next = ptr[index].next;
- ptr[index].next = node;
- }
- return 0;
-}
-
-// Search for an address for a given oid
-void *chashSearch(chashtable_t *table, unsigned int key) {
- int index;
- chashlistnode_t *ptr, *node;
-
- ptr = table->table;
- index = chashFunction(table, key);
- node = &ptr[index];
- while(node != NULL) {
- if(node->key == key) {
- return node->val;
- }
- node = node->next;
- }
- return NULL;
-}
-
-unsigned int chashRemove(chashtable_t *table, unsigned int key) {
- int index;
- chashlistnode_t *curr, *prev;
- chashlistnode_t *ptr, *node;
-
- ptr = table->table;
- index = chashFunction(table,key);
- curr = &ptr[index];
-
- for (; curr != NULL; curr = curr->next) {
- if (curr->key == key) { // Find a match in the hash table
- table->numelements--; // Decrement the number of elements in the global hashtable
- if ((curr == &ptr[index]) && (curr->next == NULL)) { // Delete the first item inside the hashtable with no linked list of chashlistnode_t
- curr->key = 0;
- curr->val = NULL;
- } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of chashlistnode_t connected
- curr->key = curr->next->key;
- curr->val = curr->next->val;
- node = curr->next;
- curr->next = curr->next->next;
- free(node);
- } else { // Regular delete from linked listed
- prev->next = curr->next;
- free(curr);
- }
- return 0;
- }
- prev = curr;
- }
- return 1;
-}
-
-unsigned int chashResize(chashtable_t *table, unsigned int newsize) {
- chashlistnode_t *node, *ptr, *curr, *next; // curr and next keep track of the current and the next chashlistnodes in a linked list
- unsigned int oldsize;
- int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
- int i,index;
- chashlistnode_t *newnode;
-
- ptr = table->table;
- oldsize = table->size;
-
- if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return 1;
- }
-
- table->table = node; //Update the global hashtable upon resize()
- table->size = newsize;
- table->numelements = 0;
-
- for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
- curr = &ptr[i];
- isfirst = 1;
- while (curr != NULL) { //Inner loop to go through linked lists
- if (curr->key == 0) { //Exit inner loop if there the first element for a given bin/index is NULL
- break; //key = val =0 for element if not present within the hash table
- }
- next = curr->next;
-
- index = chashFunction(table, curr->key);
-#ifdef DEBUG
- printf("DEBUG(resize) -> index = %d, key = %d, val = %x\n", index, curr->key, curr->val);
-#endif
- // Insert into the new table
- if(table->table[index].next == NULL && table->table[index].key == 0) {
- table->table[index].key = curr->key;
- table->table[index].val = curr->val;
- table->numelements++;
- }else {
- if((newnode = calloc(1, sizeof(chashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
- newnode->key = curr->key;
- newnode->val = curr->val;
- newnode->next = table->table[index].next;
- table->table[index].next = newnode;
- table->numelements++;
- }
-
- //free the linked list of chashlistnode_t if not the first element in the hash table
- if (isfirst != 1) {
- free(curr);
- }
-
- isfirst = 0;
- curr = next;
- }
- }
-
- free(ptr); //Free the memory of the old hash table
- return 0;
-}
-
-//Delete the entire hash table
-void chashDelete(chashtable_t *table) {
- int i, isFirst;
- chashlistnode_t *ptr, *curr, *next;
- ptr = table->table;
-
- for(i=0 ; i<table->size ; i++) {
- curr = &ptr[i];
- isFirst = 1 ;
- while(curr != NULL) {
- next = curr->next;
- if(isFirst != 1) {
- free(curr);
- }
- isFirst = 0;
- curr = next;
- }
- }
-
- free(ptr);
- free(table);
- table = NULL;
-}
+++ /dev/null
-#ifndef _CLOOKUP_H_
-#define _CLOOKUP_H_
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#define LOADFACTOR 0.75
-#define HASH_SIZE 100
-
-typedef struct chashlistnode {
- unsigned int key;
- void *val; //this can be cast to another type or used to point to a larger structure
- struct chashlistnode *next;
-} chashlistnode_t;
-
-typedef struct chashtable {
- chashlistnode_t *table; // points to beginning of hash table
- unsigned int size;
- unsigned int numelements;
- float loadfactor;
-} chashtable_t;
-
-/* Prototypes for hash*/
-chashtable_t *chashCreate(unsigned int size, float loadfactor);
-unsigned int chashFunction(chashtable_t *table, unsigned int key);
-unsigned int chashInsert(chashtable_t *table, unsigned int key, void *val);
-void *chashSearch(chashtable_t *table, unsigned int key); //returns val, NULL if not found
-unsigned int chashRemove(chashtable_t *table, unsigned int key); //returns -1 if not found
-unsigned int chashResize(chashtable_t *table, unsigned int newsize);
-void chashDelete(chashtable_t *table);
-/* end hash */
-
-#endif
-
+++ /dev/null
-/*******************************************************************************
-* dht.c
-*
-* High-performance Distributed Hash Table for finding the location of objects
-* in a Distributed Shared Transactional Memory system.
-*
-* Creator: Erik Rubow
-*
-* TODO:
-* 1) Instead of having dhtInsertMult, dhtSearchMult, etc. call their single-key
-* counterparts repeatedly, define some new messages to handle it more
-* efficiently.
-* 2) Improve the efficiency of functions that work with hostArray, hostReplied,
-* and blockOwnerArray.
-* 3) Currently a join or leave causes a rebuild of the entire hash table.
-* Implement more graceful join and leave procedures.
-* 4) Fine tune timeout values for performance, possibly implement a backoff
-* algorithm to prevent overloading the network.
-* 5) Whatever else I'm forgetting
-*
-*******************************************************************************/
-/*******************************************************************************
-* Includes
-*******************************************************************************/
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <sys/time.h>
-#include <sys/poll.h>
-#include <netdb.h>
-#include <net/if.h>
-#include <linux/sockios.h>
-#include <sys/time.h>
-#include <sys/queue.h>
-#include "dht.h"
-#include "clookup.h" //this works for now, do we need anything better?
-#include "mlookup.h"
-
-/*******************************************************************************
-* Local Defines, Structs
-*******************************************************************************/
-
-#define MAX_MSG_SIZE 1500
-#define UDP_PORT 2157
-#define INIT_HOST_ALLOC 3
-#define INIT_NUM_BLOCKS 16
-#define DEFAULT_INTERFACE "eth0"
-#define TIMEOUT_PERIOD 100
-#define INSERT_TIMEOUT_MS 500
-#define INSERT_RETRIES 50
-#define REMOVE_TIMEOUT_MS 500
-#define REMOVE_RETRIES 50
-#define SEARCH_TIMEOUT_MS 500
-#define SEARCH_RETRIES 50
-
-//message types
-//make sure this matches msg_types global var
-enum
-{
- INSERT_CMD,
- INSERT_RES,
- REMOVE_CMD,
- REMOVE_RES,
- SEARCH_CMD,
- SEARCH_RES,
- WHO_IS_LEADER_CMD,
- WHO_IS_LEADER_RES,
- JOIN_REQ,
- JOIN_RES,
- LEAVE_REQ,
- LEAVE_RES,
- DHT_UPDATE_CMD,
- DHT_UPDATE_RES,
- ELECT_LEADER_CMD,
- ELECT_LEADER_RES,
- CONGRATS_CMD,
- REBUILD_REQ,
- REBUILD_CMD,
- FILL_DHT_CMD,
- FILL_DHT_RES,
- RESUME_NORMAL_CMD,
- RESUME_NORMAL_RES,
- NUM_MSG_TYPES
-};
-
-//states
-//make sure this matches state_names, timeout_vals, and retry_vals global vars
-enum
-{
- INIT1_STATE,
- INIT2_STATE,
- NORMAL_STATE,
- LEAD_NORMAL1_STATE,
- LEAD_NORMAL2_STATE,
- ELECT1_STATE,
- ELECT2_STATE,
- REBUILD0_STATE,
- REBUILD1_STATE,
- REBUILD2_STATE,
- REBUILD3_STATE,
- REBUILD4_STATE,
- REBUILD5_STATE,
- LEAD_REBUILD1_STATE,
- LEAD_REBUILD2_STATE,
- LEAD_REBUILD3_STATE,
- LEAD_REBUILD4_STATE,
- EXIT1_STATE,
- EXIT2_STATE,
- NUM_STATES
-};
-
-//status codes
-enum
-{
- OPERATION_OK,
- KEY_NOT_FOUND,
- NOT_KEY_OWNER,
- NOT_LEADER,
- INTERNAL_ERROR
-};
-
-struct hostData
-{
- unsigned int ipAddr;
- unsigned int maxKeyCapacity;
-};
-
-/*******************************************************************************
-* Local Function Prototypes
-*******************************************************************************/
-
-int msgSizeOk(unsigned char *msg, unsigned int size);
-unsigned short read2(unsigned char *msg);
-unsigned int read4(unsigned char *msg);
-void write2(unsigned char *ptr, unsigned short tmp);
-void write4(unsigned char *ptr, unsigned int tmp);
-unsigned int getMyIpAddr(const char *interfaceStr);
-int udpSend(unsigned char *msg, unsigned int size, unsigned int destIp);
-int udpSendAll(unsigned char *msg, unsigned int size);
-unsigned int hash(unsigned int x);
-unsigned int getKeyOwner(unsigned int key);
-void setState(unsigned int newState);
-void makeAssignments();
-int addHost(struct hostData newHost);
-int removeHost(unsigned int ipAddr);
-void removeUnresponsiveHosts();
-int checkReplied(unsigned int ipAddr);
-int allReplied();
-void writeHostList();
-void dhtLog(const char *format, ...);
-void *fillTask();
-void *udpListen();
-
-/*******************************************************************************
-* Global Variables
-*******************************************************************************/
-
-//make sure this matches enumeration above
-const char *msg_types[NUM_MSG_TYPES] =
-{
- "INSERT_CMD",
- "INSERT_RES",
- "REMOVE_CMD",
- "REMOVE_RES",
- "SEARCH_CMD",
- "SEARCH_RES",
- "WHO_IS_LEADER_CMD",
- "WHO_IS_LEADER_RES",
- "JOIN_REQ",
- "JOIN_RES",
- "LEAVE_REQ",
- "LEAVE_RES",
- "DHT_UPDATE_CMD",
- "DHT_UPDATE_RES",
- "ELECT_LEADER_CMD",
- "ELECT_LEADER_RES",
- "CONGRATS_CMD",
- "REBUILD_REQ",
- "REBUILD_CMD",
- "FILL_DHT_CMD",
- "FILL_DHT_RES",
- "RESUME_NORMAL_CMD",
- "RESUME_NORMAL_RES"
-};
-
-const char *state_names[NUM_STATES] =
-{
- "INIT1_STATE",
- "INIT2_STATE",
- "NORMAL_STATE",
- "LEAD_NORMAL1_STATE",
- "LEAD_NORMAL2_STATE",
- "ELECT1_STATE",
- "ELECT2_STATE",
- "REBUILD0_STATE",
- "REBUILD1_STATE",
- "REBUILD2_STATE",
- "REBUILD3_STATE",
- "REBUILD4_STATE",
- "REBUILD5_STATE",
- "LEAD_REBUILD1_STATE",
- "LEAD_REBUILD2_STATE",
- "LEAD_REBUILD3_STATE",
- "LEAD_REBUILD4_STATE",
- "EXIT1_STATE",
- "EXIT2_STATE",
-};
-
-//note: { 0, 0 } means no timeout
-struct timeval timeout_vals[NUM_STATES] =
-{
- { 0, 500000 }, //INIT1_STATE
- { 0, 500000 }, //INIT2_STATE
- { 0, 0 }, //NORMAL_STATE
- { 0, 0 }, //LEAD_NORMAL1_STATE
- { 3, 0 }, //LEAD_NORMAL2_STATE
- { 1, 0 }, //ELECT1_STATE
- { 1, 0 }, //ELECT2_STATE
- { 0, 500000 }, //REBUILD0_STATE
- { 0, 500000 }, //REBUILD1_STATE
- { 10, 0 }, //REBUILD2_STATE
- { 10, 0 }, //REBUILD3_STATE
- { 10, 0 }, //REBUILD4_STATE
- { 1, 0 }, //REBUILD5_STATE
- { 1, 0 }, //LEAD_REBUILD1_STATE
- { 1, 0 }, //LEAD_REBUILD2_STATE
- { 10, 0 }, //LEAD_REBUILD3_STATE
- { 10, 0 }, //LEAD_REBUILD4_STATE
- { 0, 500000 }, //EXIT1_STATE
- { 0, 0 } //EXIT2_STATE
-};
-
-int retry_vals[NUM_STATES] =
-{
- 100, //INIT1_STATE
- 10, //INIT2_STATE
- 0, //NORMAL_STATE
- 0, //LEAD_NORMAL1_STATE
- 0, //LEAD_NORMAL2_STATE
- 10, //ELECT1_STATE
- 10, //ELECT2_STATE
- 10, //REBUILD0_STATE
- 10, //REBUILD1_STATE
- 0, //REBUILD2_STATE
- 0, //REBUILD3_STATE
- 0, //REBUILD4_STATE
- 10, //REBUILD5_STATE
- 10, //LEAD_REBUILD1_STATE
- 10, //LEAD_REBUILD2_STATE
- 10, //LEAD_REBUILD3_STATE
- 10, //LEAD_REBUILD4_STATE
- 10, //EXIT1_STATE
- 0 //EXIT2_STATE
-};
-
-FILE *logfile;
-struct hostData myHostData;
-pthread_t threadUdpListen;
-pthread_t threadFillTask;
-//status of fillTask: 0 = ready to run, 1 = running, 2 = completed, 3 = error
-int fillStatus;
-struct pollfd udpPollSock;
-unsigned int state;
-unsigned int seed;
-unsigned int leader;
-unsigned int electionOriginator;
-unsigned int electionParent;
-unsigned int hostArraySize = 0;
-struct hostData *hostArray = NULL;
-unsigned int numBlocks = 0;
-unsigned short *blockOwnerArray = NULL;
-unsigned char *hostReplied = NULL;
-pthread_mutex_t stateMutex;
-pthread_cond_t stateCond;
-chashtable_t *myHashTable;
-unsigned int numHosts;
-struct timeval timer;
-int timerSet;
-int timeoutCntr;
-
-/*******************************************************************************
-* Interface Function Definitions
-*******************************************************************************/
-
-void dhtInit(unsigned int seedIpAddr, unsigned int maxKeyCapacity)
-{
- struct in_addr tmpAddr;
- char filename[23] = "dht-";
- struct sockaddr_in myAddr;
- struct sockaddr_in seedAddr;
- socklen_t socklen = sizeof(struct sockaddr_in);
- char initMsg;
-
- tmpAddr.s_addr = htonl(getMyIpAddr(DEFAULT_INTERFACE));
- strcat(filename, inet_ntoa(tmpAddr));
- strcat(filename, ".log");
- printf("log file: %s\n", filename);
-
- logfile = fopen(filename, "w");
- dhtLog("dhtInit(): inializing...\n");
-
- myHostData.ipAddr = getMyIpAddr(DEFAULT_INTERFACE);
- myHostData.maxKeyCapacity = maxKeyCapacity;
-
- seed = seedIpAddr;
- leader = 0;
- electionOriginator = 0;
- electionParent = 0;
- hostArraySize = INIT_HOST_ALLOC;
- hostArray = calloc(hostArraySize, sizeof(struct hostData));
- hostReplied = calloc(hostArraySize, sizeof(unsigned char));
- hostArray[0] = myHostData;
- numHosts = 1;
- numBlocks = INIT_NUM_BLOCKS;
- blockOwnerArray = calloc(numBlocks, sizeof(unsigned short));
- pthread_mutex_init(&stateMutex, NULL);
- pthread_cond_init(&stateCond, NULL);
- myHashTable = chashCreate(HASH_SIZE, LOADFACTOR);
-
- udpPollSock.fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (udpPollSock.fd < 0)
- perror("dhtInit():socket()");
-
- udpPollSock.events = POLLIN;
-
- bzero(&myAddr, socklen);
- myAddr.sin_family = AF_INET;
- myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- myAddr.sin_port = htons(UDP_PORT);
-
- if (bind(udpPollSock.fd, (struct sockaddr *)&myAddr, socklen) < 0)
- perror("dhtInit():bind()");
-
- if (seed == 0)
- {
- dhtLog("I am the leader\n");
- leader = myHostData.ipAddr;
- setState(LEAD_NORMAL1_STATE);
- }
- else
- {
- initMsg = WHO_IS_LEADER_CMD;
- udpSend(&initMsg, 1, seed);
- setState(INIT1_STATE);
- }
-
- if (pthread_create(&threadUdpListen, NULL, udpListen, NULL) != 0)
- dhtLog("dhtInit() - ERROR creating threadUdpListen\n");
-
- return;
-}
-
-void dhtExit()
-{ //TODO: do this gracefully, wait for response from leader, etc.
- char msg;
-
- msg = LEAVE_REQ;
- udpSend(&msg, 1, leader);
- dhtLog("dhtExit(): cleaning up...\n");
- pthread_cancel(threadUdpListen);
- close(udpPollSock.fd);
- free(hostArray);
- free(hostReplied);
- free(blockOwnerArray);
- fclose(logfile);
-
- return;
-}
-
-int dhtInsert(unsigned int key, unsigned int val)
-{
- struct sockaddr_in toAddr;
- struct sockaddr_in fromAddr;
- socklen_t socklen = sizeof(struct sockaddr_in);
- struct pollfd pollsock;
- char inBuffer[2];
- char outBuffer[9];
- ssize_t bytesRcvd;
- int i;
- int retval;
- int status = -1;
-
- bzero((char *)&toAddr, socklen);
- toAddr.sin_family = AF_INET;
- toAddr.sin_port = htons(UDP_PORT);
-
- while (status != OPERATION_OK)
- {
- pthread_mutex_lock(&stateMutex);
- while (!(state == NORMAL_STATE || state == LEAD_NORMAL1_STATE
- || state == LEAD_NORMAL2_STATE || state == REBUILD4_STATE
- || state == LEAD_REBUILD3_STATE))
- pthread_cond_wait(&stateCond, &stateMutex);
- toAddr.sin_addr.s_addr = htonl(getKeyOwner(key));
- pthread_mutex_unlock(&stateMutex);
-
- if ((pollsock.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("dhtInsert():socket()");
- return -1;
- }
- pollsock.events = POLLIN;
-
- outBuffer[0] = INSERT_CMD;
- write4(&outBuffer[1], key);
- write4(&outBuffer[5], val);
-
- for (i = 0; i < INSERT_RETRIES; i++)
- {
- if (sendto(pollsock.fd, outBuffer, 9, 0, (struct sockaddr *)&toAddr,
- socklen) < 0)
- {
- perror("dhtInsert():sendto()");
- break;
- }
- retval = poll(&pollsock, 1, INSERT_TIMEOUT_MS);
- if (retval < 0)
- {
- perror("dhtInsert():poll()");
- break;
- }
- if (retval > 0)
- {
- bytesRcvd = recvfrom(pollsock.fd, inBuffer, 2, 0,
- (struct sockaddr *)&fromAddr, &socklen);
- if (fromAddr.sin_addr.s_addr == toAddr.sin_addr.s_addr
- && fromAddr.sin_port == toAddr.sin_port
- && bytesRcvd == 2 && inBuffer[0] == INSERT_RES)
- {
- status = inBuffer[1]; //status from remote host
- break;
- }
- }
- }
- if (status != OPERATION_OK)
- {
- pthread_mutex_lock(&stateMutex);
- setState(REBUILD0_STATE);
- outBuffer[0] = REBUILD_REQ;
- udpSend(outBuffer, 1, leader);
- pthread_mutex_unlock(&stateMutex);
- }
- }
-
- close(pollsock.fd);
-
- return status;
-}
-
-int dhtInsertMult(unsigned int numKeys, unsigned int *keys, unsigned int *vals)
-{
- int status;
- int i;
-
- status = 0;
- for (i = 0; i < numKeys; i++)
- {
- if (dhtInsert(keys[i], vals[i]) != 0)
- status = -1;
- }
- return status;
-}
-
-int dhtRemove(unsigned int key)
-{
- struct sockaddr_in toAddr;
- struct sockaddr_in fromAddr;
- socklen_t socklen = sizeof(struct sockaddr_in);
- struct pollfd pollsock;
- char inBuffer[2];
- char outBuffer[5];
- ssize_t bytesRcvd;
- int i;
- int retval;
- int status = -1;
-
- bzero((char *)&toAddr, socklen);
- toAddr.sin_family = AF_INET;
- toAddr.sin_port = htons(UDP_PORT);
-
- while (!(status == OPERATION_OK || status == KEY_NOT_FOUND))
- {
- pthread_mutex_lock(&stateMutex);
- while (!(state == NORMAL_STATE || state == LEAD_NORMAL1_STATE
- || state == LEAD_NORMAL2_STATE))
- pthread_cond_wait(&stateCond, &stateMutex);
- toAddr.sin_addr.s_addr = htonl(getKeyOwner(key));
- pthread_mutex_unlock(&stateMutex);
-
- if ((pollsock.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("dhtRemove():socket()");
- return -1;
- }
- pollsock.events = POLLIN;
-
- outBuffer[0] = REMOVE_CMD;
- write4(&outBuffer[1], key);
-
- for (i = 0; i < REMOVE_RETRIES; i++)
- {
- if (sendto(pollsock.fd, outBuffer, 5, 0, (struct sockaddr *)&toAddr,
- socklen) < 0)
- {
- perror("dhtRemove():sendto()");
- break;
- }
- retval = poll(&pollsock, 1, REMOVE_TIMEOUT_MS);
- if (retval < 0)
- {
- perror("dhtRemove():poll()");
- break;
- }
- if (retval > 0)
- {
- bytesRcvd = recvfrom(pollsock.fd, inBuffer, 2, 0,
- (struct sockaddr *)&fromAddr, &socklen);
- if (fromAddr.sin_addr.s_addr == toAddr.sin_addr.s_addr
- && fromAddr.sin_port == toAddr.sin_port
- && bytesRcvd == 2 && inBuffer[0] == REMOVE_RES)
- {
- status = inBuffer[1]; //status from remote host
- break;
- }
- }
- }
- if (!(status == OPERATION_OK || status == KEY_NOT_FOUND))
- {
- pthread_mutex_lock(&stateMutex);
- setState(REBUILD0_STATE);
- outBuffer[0] = REBUILD_REQ;
- udpSend(outBuffer, 1, leader);
- pthread_mutex_unlock(&stateMutex);
- }
- }
-
- close(pollsock.fd);
-
- return status;
-}
-
-int dhtRemoveMult(unsigned int numKeys, unsigned int *keys)
-{
- int status;
- int i;
-
- status = 0;
- for (i = 0; i < numKeys; i++)
- {
- if (dhtRemove(keys[i]) != 0)
- status = -1;
- }
- return status;
-}
-
-int dhtSearch(unsigned int key, unsigned int *val)
-{
- struct sockaddr_in toAddr;
- struct sockaddr_in fromAddr;
- socklen_t socklen = sizeof(struct sockaddr_in);
- struct pollfd pollsock;
- char inBuffer[6];
- char outBuffer[5];
- ssize_t bytesRcvd;
- int i;
- int retval;
- int status = -1;
-
- bzero((char *)&toAddr, socklen);
- toAddr.sin_family = AF_INET;
- toAddr.sin_port = htons(UDP_PORT);
-
- while (!(status == OPERATION_OK || status == KEY_NOT_FOUND))
- {
- pthread_mutex_lock(&stateMutex);
- while (numBlocks == 0)
- pthread_cond_wait(&stateCond, &stateMutex);
- toAddr.sin_addr.s_addr = htonl(getKeyOwner(key));
- pthread_mutex_unlock(&stateMutex);
-
- if ((pollsock.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("dhtSearch():socket()");
- return -1;
- }
- pollsock.events = POLLIN;
-
- outBuffer[0] = SEARCH_CMD;
- write4(&outBuffer[1], key);
-
- for (i = 0; i < SEARCH_RETRIES; i++)
- {
- if (sendto(pollsock.fd, outBuffer, 5, 0, (struct sockaddr *)&toAddr,
- socklen) < 0)
- {
- perror("dhtSearch():sendto()");
- break;
- }
- retval = poll(&pollsock, 1, SEARCH_TIMEOUT_MS);
- if (retval < 0)
- {
- perror("dhtSearch():poll()");
- break;
- }
- if (retval > 0)
- {
- bytesRcvd = recvfrom(pollsock.fd, inBuffer, 6, 0,
- (struct sockaddr *)&fromAddr, &socklen);
- if (fromAddr.sin_addr.s_addr == toAddr.sin_addr.s_addr
- && fromAddr.sin_port == toAddr.sin_port
- && bytesRcvd == 6 && inBuffer[0] == SEARCH_RES)
- {
- status = inBuffer[1]; //status from remote host
- *val = read4(&inBuffer[2]);
- break;
- }
- }
- }
- if (!(status == OPERATION_OK || status == KEY_NOT_FOUND))
- {
- pthread_mutex_lock(&stateMutex);
- setState(REBUILD0_STATE);
- outBuffer[0] = REBUILD_REQ;
- udpSend(outBuffer, 1, leader);
- pthread_mutex_unlock(&stateMutex);
- }
- }
-
- close(pollsock.fd);
-
- return status;
-}
-
-int dhtSearchMult(unsigned int numKeys, unsigned int *keys, unsigned int *vals)
-{
- int i;
- int status = 0;
- for (i = 0; i < numKeys; i++)
- {
- if (dhtSearch(keys[i], &vals[i]) != 0)
- status = -1;
- }
- return status;
-}
-
-/*******************************************************************************
-* Local Function Definitions
-*******************************************************************************/
-
-int msgSizeOk(unsigned char *msg, unsigned int size)
-{
- unsigned short tmpNumHosts;
- unsigned short tmpNumBlocks;
-
- if (size < 1)
- return 1;
-
- switch (msg[0])
- {
- case WHO_IS_LEADER_CMD:
- case LEAVE_REQ:
- case LEAVE_RES:
- case DHT_UPDATE_RES:
- case REBUILD_REQ:
- case REBUILD_CMD:
- case FILL_DHT_CMD:
- case FILL_DHT_RES:
- case RESUME_NORMAL_CMD:
- case RESUME_NORMAL_RES:
- return (size == 1);
- case INSERT_RES:
- case REMOVE_RES:
- case JOIN_RES:
- return (size == 2);
- case REMOVE_CMD:
- case SEARCH_CMD:
- case WHO_IS_LEADER_RES:
- case JOIN_REQ:
- case ELECT_LEADER_CMD:
- return (size == 5);
- case SEARCH_RES:
- return (size == 6);
- case INSERT_CMD:
- return (size == 9);
- case DHT_UPDATE_CMD:
- if (size < 5)
- return 1;
- tmpNumHosts = read2(&msg[1]);
- tmpNumBlocks = read2(&msg[3]);
- return (size == (5+sizeof(struct hostData)*tmpNumHosts+2*tmpNumBlocks));
- case ELECT_LEADER_RES:
- if (size < 2)
- return 1;
- if (msg[1] == 0xFF)
- return (size == 2);
- if (size < 4)
- return 1;
- tmpNumHosts = read2(&msg[2]);
- return (size == (4 + sizeof(struct hostData) * tmpNumHosts));
- case CONGRATS_CMD:
- if (size < 3)
- return 1;
- tmpNumHosts = read2(&msg[1]);
- return (size == (3 + sizeof(struct hostData) * tmpNumHosts));
- default:
- return 1;
- }
-}
-
-unsigned short read2(unsigned char *ptr)
-{
- unsigned short tmp = (ptr[1] << 8) | ptr[0];
- return tmp;
-}
-
-unsigned int read4(unsigned char *ptr)
-{
- unsigned int tmp = (ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0];
- return tmp;
-}
-
-void write2(unsigned char *ptr, unsigned short tmp)
-{
- ptr[1] = (tmp >> 8) & 0xFF;
- ptr[0] = tmp & 0xFF;
- return;
-}
-
-void write4(unsigned char *ptr, unsigned int tmp)
-{
- ptr[3] = (tmp >> 24) & 0xFF;
- ptr[2] = (tmp >> 16) & 0xFF;
- ptr[1] = (tmp >> 8) & 0xFF;
- ptr[0] = tmp & 0xFF;
- return;
-}
-
-unsigned int getMyIpAddr(const char *interfaceStr)
-{
- int sock;
- struct ifreq interfaceInfo;
- struct sockaddr_in *myAddr = (struct sockaddr_in *)&interfaceInfo.ifr_addr;
-
- memset(&interfaceInfo, 0, sizeof(struct ifreq));
-
- if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- {
- perror("getMyIpAddr():socket()");
- return 1;
- }
-
- strcpy(interfaceInfo.ifr_name, interfaceStr);
- myAddr->sin_family = AF_INET;
-
- if(ioctl(sock, SIOCGIFADDR, &interfaceInfo) != 0)
- {
- perror("getMyIpAddr():ioctl()");
- return 1;
- }
-
- return ntohl(myAddr->sin_addr.s_addr);
-}
-
-int udpSend(unsigned char *msg, unsigned int size, unsigned int destIp)
-{
- struct sockaddr_in peerAddr;
- socklen_t socklen = sizeof(struct sockaddr_in);
-
- bzero(&peerAddr, socklen);
- peerAddr.sin_family = AF_INET;
- peerAddr.sin_addr.s_addr = htonl(destIp);
- peerAddr.sin_port = htons(UDP_PORT);
-
- if (size >= 1)
- {
- if (msg[0] < NUM_MSG_TYPES)
- dhtLog("udpSend(): sending %s to %s, %d bytes\n", msg_types[msg[0]],
- inet_ntoa(peerAddr.sin_addr), size);
- else
- dhtLog("udpSend(): sending unknown message to %s, %d bytes\n",
- inet_ntoa(peerAddr.sin_addr), size);
- }
-
- if (sendto(udpPollSock.fd, (void *)msg, size, 0, (struct sockaddr *)&peerAddr,
- socklen) < 0)
- {
- perror("udpSend():sendto()");
- return -1;
- }
-
- return 0;
-}
-
-int udpSendAll(unsigned char *msg, unsigned int size)
-{
- int i;
- int status = 0;
- for (i = 0; i < numHosts; i++)
- {
- if ((hostReplied[i] == 0) && (hostArray[i].ipAddr != myHostData.ipAddr))
- {
- if (udpSend(msg, size, hostArray[i].ipAddr) != 0)
- status = -1;
- }
- }
- return status;
-}
-
-//note: make sure this is only executed in a valid state, where numBlocks != 0
-unsigned int hash(unsigned int x)
-{
- return (x % numBlocks);
-}
-
-//note: make sure this is only executed in a valid state, where these arrays
-// are allocated and the index mappings are consistent
-unsigned int getKeyOwner(unsigned int key)
-{
- return hostArray[blockOwnerArray[hash(key)]].ipAddr;
-}
-
-//sets state and timer, if applicable
-void setState(unsigned int newState)
-{
- struct timeval now;
- int i;
-
- gettimeofday(&now, NULL);
-
- if (newState >= NUM_STATES)
- {
- dhtLog("setState(): ERROR: invalid state %d\n", newState);
- }
- else
- {
- if (timeout_vals[newState].tv_sec == 0
- && timeout_vals[newState].tv_usec == 0)
- { //no timer
- timerSet = 0;
- }
- else
- {
- timeradd(&now, &timeout_vals[newState], &timer);
- timerSet = 1;
- }
- timeoutCntr = 0;
- state = newState;
- //TODO: only do this for states that require it
- for (i = 0; i < numHosts; i++)
- hostReplied[i] = 0;
-
- dhtLog("setState(): state set to %s\n", state_names[state]);
- }
-
- return;
-}
-
-//TODO: improve these simple and inefficient functions
-int checkReplied(unsigned int ipAddr)
-{
- int i;
-
- i = findHost(ipAddr);
-
- if (i == -1)
- return -1;
-
- hostReplied[i] = 1;
-
- return 0;
-}
-
-int allReplied()
-{
- int i;
-
- for (i = 0; i < numHosts; i++)
- if ((hostReplied[i] == 0) && (hostArray[i].ipAddr != myHostData.ipAddr))
- return 0;
-
- return 1;
-}
-
-int findHost(unsigned int ipAddr)
-{
- int i;
-
- for (i = 0; i < numHosts; i++)
- if (hostArray[i].ipAddr == ipAddr)
- return i; //found, return index
-
- return -1; //not found
-}
-
-int removeHost(unsigned int ipAddr)
-{
- int i, j;
-
- i = findHost(ipAddr);
-
- if (i == -1)
- return -1;
-
- for (j = 0; j < numBlocks; j++)
- {
- if (blockOwnerArray[j] == i)
- blockOwnerArray[j] = 0; //TODO: is this what I want to have happen?
- else if (blockOwnerArray[j] > i)
- blockOwnerArray[j]--;
- }
-
- for (; i < numHosts - 1; i++)
- {
- hostArray[i] = hostArray[i+1];
- hostReplied[i] = hostReplied[i+1];
- }
- numHosts--;
-
- return 0;
-}
-
-void removeUnresponsiveHosts()
-{
- int i;
-
- for (i = 0; i < numHosts; i++)
- {
- if (!hostReplied[i] && hostArray[i].ipAddr != myHostData.ipAddr)
- removeHost(hostArray[i].ipAddr);
- }
-}
-
-int addHost(struct hostData newHost)
-{
- struct hostData *newHostArray;
- unsigned char *newHostReplied;
- int i;
- int j;
-
- for (i = 0; i < numHosts; i++)
- {
- if (hostArray[i].ipAddr == newHost.ipAddr)
- {
- hostArray[i] = newHost;
- hostReplied[i] = 0;
- return 0;
- }
- else if (hostArray[i].ipAddr > newHost.ipAddr)
- {
- if (numHosts == hostArraySize)
- {
- newHostArray = calloc(2 * hostArraySize, sizeof(struct hostData));
- newHostReplied = calloc(2 * hostArraySize, sizeof(unsigned char));
- memcpy(newHostArray, hostArray, (i * sizeof(struct hostData)));
- memcpy(newHostReplied, hostReplied, (i * sizeof(unsigned char)));
- newHostArray[i] = newHost;
- newHostReplied[i] = 0;
- memcpy(&newHostArray[i+1], &hostArray[i], ((numHosts - i) *
- sizeof(struct hostData)));
- memcpy(&newHostReplied[i+1], &hostReplied[i], ((numHosts - i) *
- sizeof(unsigned char)));
- free(hostArray);
- free(hostReplied);
- hostArray = newHostArray;
- hostReplied = newHostReplied;
- hostArraySize = 2 * hostArraySize;
- }
- else
- {
- for (j = numHosts; j > i; j--)
- {
- hostArray[j] = hostArray[j-1];
- hostReplied[j] = hostReplied[j-1];
- }
- hostArray[i] = newHost;
- hostReplied[i] = 0;
- }
- for(j = 0; j < numBlocks; j++)
- {
- if (blockOwnerArray[j] >= i)
- blockOwnerArray[j]++;
- }
- numHosts++;
- return 1;
- }
- }
-
- //nothing greater, add to end
- if (numHosts == hostArraySize)
- {
- newHostArray = calloc(2 * hostArraySize, sizeof(struct hostData));
- newHostReplied = calloc(2 * hostArraySize, sizeof(unsigned char));
- memcpy(newHostArray, hostArray, (numHosts * sizeof(struct hostData)));
- memcpy(newHostReplied, hostReplied, (numHosts * sizeof(unsigned char)));
- free(hostArray);
- free(hostReplied);
- hostArray = newHostArray;
- hostReplied = newHostReplied;
- hostArraySize = 2 * hostArraySize;
- }
-
- hostArray[numHosts] = newHost;
- hostReplied[numHosts] = 0;
- numHosts++;
- return 1;
-}
-
-void makeAssignments()
-{
- int i;
-
- if (numBlocks < numHosts)
- {
- free(blockOwnerArray);
- while (numBlocks < numHosts)
- numBlocks *= 2;
- blockOwnerArray = calloc(numBlocks, sizeof(unsigned short));
- }
-
- for (i = 0; i < numBlocks; i++)
- blockOwnerArray[i] = i % numHosts;
-
- return;
-}
-
-void writeHostList()
-{
- int i;
- struct in_addr tmpAddr;
-
- fprintf(logfile, "numHosts = %d\n", numHosts);
- for (i = 0; i < numHosts; i++)
- {
- tmpAddr.s_addr = htonl(hostArray[i].ipAddr);
- fprintf(logfile, "%d) %s, %d\n", i, inet_ntoa(tmpAddr),
- hostArray[i].maxKeyCapacity);
- }
- return;
-}
-
-void dhtLog(const char *format, ...)
-{
- va_list args;
-// struct timeval now;
-
-// if (gettimeofday(&now, NULL) < 0)
-// { perror("dhtLog():gettimeofday()"); }
- va_start(args, format);
-// if (fprintf(logfile, "%d.%06d:", now.tv_sec, now.tv_usec) < 0)
-// { perror("dhtLog():fprintf()"); }
- if (vfprintf(logfile, format, args) < 0)
- { perror("dhtLog():vfprintf()"); }
- if (fflush(logfile) == EOF)
- { perror("dhtLog():fflush()"); }
- va_end(args);
-
- return;
-}
-
-void *fillTask()
-{
- unsigned int *vals;
- unsigned int *keys;
- unsigned int numKeys;
- int i;
-
- vals = mhashGetKeys(&numKeys); //note: key of mhash is val of dht
- keys = calloc(numKeys, sizeof(unsigned int));
-
- for (i = 0; i < numKeys; i++)
- keys[i] = myHostData.ipAddr;
-
- if (dhtInsertMult(numKeys, keys, vals) == 0)
- fillStatus = 2;
- else
- fillStatus = 3;
-
- pthread_exit(NULL);
-}
-
-void *udpListen()
-{
- ssize_t bytesRcvd;
- struct sockaddr_in peerAddr;
- unsigned int peerIp;
- socklen_t socklen = sizeof(struct sockaddr_in);
- unsigned char inBuffer[MAX_MSG_SIZE];
- unsigned char outBuffer[MAX_MSG_SIZE];
- int pollret;
- struct timeval now;
- struct in_addr tmpAddr;
- struct hostData tmpHost;
- unsigned int tmpKey;
- unsigned int tmpVal;
- struct hostData *hostDataPtr;
- unsigned short *uShortPtr;
- unsigned int tmpUInt;
- unsigned int tmpUShort;
- int i;
- unsigned int oldState;
-
- dhtLog("udpListen(): linstening on port %d...\n", UDP_PORT);
-
- while (1)
- {
- pollret = poll(&udpPollSock, 1, TIMEOUT_PERIOD);
- pthread_mutex_lock(&stateMutex);
- oldState = state;
- if (pollret < 0)
- {
- perror("udpListen():poll()");
- }
- else if (pollret > 0)
- {
- bytesRcvd = recvfrom(udpPollSock.fd, inBuffer, MAX_MSG_SIZE, 0,
- (struct sockaddr *)&peerAddr, &socklen);
- if (bytesRcvd < 1)
- {
- dhtLog("udpListen(): ERROR: bytesRcvd = %d\n", bytesRcvd);
- }
- else if (inBuffer[0] >= NUM_MSG_TYPES)
- {
- dhtLog("udpListen(): ERROR: unknown msg type = %d\n", inBuffer[0]);
- }
- else if (!msgSizeOk(inBuffer, bytesRcvd))
- {
- dhtLog("udpListen(): ERROR: msg size not ok: type = %s\n, size = %d\n",
- msg_types[inBuffer[0]], bytesRcvd);
- }
- else if (state == EXIT2_STATE)
- {
- //do nothing
- }
- else if (state == INIT1_STATE)
- { //after initialization with seed, do not proceed until seed replies
- dhtLog("udpListen(): received %s from %s, %d bytes\n",
- msg_types[inBuffer[0]], inet_ntoa(peerAddr.sin_addr), bytesRcvd);
- for (i = 0; i < bytesRcvd; i++)
- dhtLog(" %x", inBuffer[i]);
- dhtLog("\n");
- peerIp = ntohl(peerAddr.sin_addr.s_addr);
- if (peerIp == seed && inBuffer[0] == WHO_IS_LEADER_RES)
- {
- tmpHost.ipAddr = peerIp;
- tmpHost.maxKeyCapacity = 0;
- addHost(tmpHost);
- writeHostList();
- leader = read4(&inBuffer[1]);
- tmpAddr.s_addr = htonl(leader);
- dhtLog("leader = %s\n", inet_ntoa(tmpAddr));
- if (leader != 0)
- {
- setState(INIT2_STATE);
- outBuffer[0] = JOIN_REQ;
- write4(&outBuffer[1], myHostData.maxKeyCapacity);
- udpSend(outBuffer, 5, leader);
- }
- else
- {
- electionOriginator = myHostData.ipAddr;
- setState(ELECT1_STATE);
- outBuffer[0] = ELECT_LEADER_CMD;
- write4(&outBuffer[1], myHostData.ipAddr); //originator = me
- udpSendAll(outBuffer, 5);
- }
- }
- }
- else
- {
- dhtLog("udpListen(): received %s from %s, %d bytes\n",
- msg_types[inBuffer[0]], inet_ntoa(peerAddr.sin_addr), bytesRcvd);
- for (i = 0; i < bytesRcvd; i++)
- dhtLog(" %x", inBuffer[i]);
- dhtLog("\n");
- peerIp = ntohl(peerAddr.sin_addr.s_addr);
- switch (inBuffer[0])
- {
- case INSERT_CMD:
- if (state == NORMAL_STATE || state == LEAD_NORMAL1_STATE
- || state == LEAD_NORMAL2_STATE || state == REBUILD4_STATE
- || state == REBUILD5_STATE || state == LEAD_REBUILD3_STATE)
- {
- tmpKey = read4(&inBuffer[1]);
- tmpVal = read4(&inBuffer[5]);
- outBuffer[0] = INSERT_RES;
- if (getKeyOwner(tmpKey) == myHostData.ipAddr)
- {
- if (chashInsert(myHashTable, tmpKey, (void *)tmpVal) == 0)
- outBuffer[1] = OPERATION_OK;
- else
- outBuffer[1] = INTERNAL_ERROR;
- }
- else
- {
- outBuffer[1] = NOT_KEY_OWNER;
- }
- //reply to client socket
- sendto(udpPollSock.fd, outBuffer, 2, 0,
- (struct sockaddr *)&peerAddr, socklen);
- }
- break;
- case REMOVE_CMD:
- if (state == NORMAL_STATE || state == LEAD_NORMAL1_STATE
- || state == LEAD_NORMAL2_STATE)
- {
- tmpKey = read4(&inBuffer[1]);
- outBuffer[0] = REMOVE_RES;
- if (getKeyOwner(tmpKey) == myHostData.ipAddr)
- {
- if (chashRemove(myHashTable, tmpKey) == 0)
- outBuffer[1] = OPERATION_OK;
- else
- outBuffer[1] = KEY_NOT_FOUND;
- }
- else
- {
- outBuffer[1] = NOT_KEY_OWNER;
- }
- //reply to client socket
- sendto(udpPollSock.fd, outBuffer, 2, 0,
- (struct sockaddr *)&peerAddr, socklen);
- }
- break;
- case SEARCH_CMD:
- if (state == NORMAL_STATE || state == LEAD_NORMAL1_STATE
- || state == LEAD_NORMAL2_STATE)
- {
- tmpKey = read4(&inBuffer[1]);
- outBuffer[0] = SEARCH_RES;
- if (getKeyOwner(tmpKey) == myHostData.ipAddr)
- {
- if ((tmpVal = (unsigned int)chashSearch(myHashTable, tmpKey)) != 0)
- {
- outBuffer[1] = OPERATION_OK;
- write4(&outBuffer[2], tmpVal);
- }
- else
- {
- outBuffer[1] = KEY_NOT_FOUND;
- write4(&outBuffer[2], 0);
- }
- }
- else
- {
- outBuffer[1] = NOT_KEY_OWNER;
- write4(&outBuffer[2], 0);
- }
- //reply to client socket
- sendto(udpPollSock.fd, outBuffer, 6, 0,
- (struct sockaddr *)&peerAddr, socklen);
- }
- break;
- case WHO_IS_LEADER_CMD:
- tmpHost.ipAddr = peerIp;
- tmpHost.maxKeyCapacity = 0;
- addHost(tmpHost);
- writeHostList();
- outBuffer[0] = WHO_IS_LEADER_RES;
- //leader == 0 means I don't know who it is
- write4(&outBuffer[1], leader);
- udpSend(outBuffer, 5, peerIp);
- break;
- case JOIN_REQ:
- if (state == LEAD_NORMAL1_STATE || state == LEAD_NORMAL2_STATE)
- {
- tmpHost.ipAddr = peerIp;
- tmpHost.maxKeyCapacity = read4(&inBuffer[1]);
- addHost(tmpHost);
- writeHostList();
- if (state == LEAD_NORMAL1_STATE)
- setState(LEAD_NORMAL2_STATE);
- outBuffer[0] = JOIN_RES;
- outBuffer[1] = 0; //status, success
- udpSend(outBuffer, 2, peerIp);
- }
- else if (state == LEAD_REBUILD1_STATE)
- {
- //note: I don't need to addHost().
- checkReplied(peerIp);
- outBuffer[0] = JOIN_RES;
- outBuffer[1] = 0; //status, success
- udpSend(outBuffer, 2, peerIp);
- if (allReplied())
- {
- makeAssignments();
- setState(LEAD_REBUILD2_STATE);
- outBuffer[0] = DHT_UPDATE_CMD;
- write2(&outBuffer[1], numHosts);
- write2(&outBuffer[3], numBlocks);
- memcpy(&outBuffer[5], hostArray, numHosts*sizeof(struct hostData));
- memcpy(&outBuffer[5+numHosts*sizeof(struct hostData)],
- blockOwnerArray, numBlocks*2);
- udpSendAll(outBuffer, 5 + sizeof(struct hostData) * numHosts
- + 2 * numBlocks);
- }
- }
- break;
- case JOIN_RES:
- if (state == REBUILD1_STATE)
- {
- setState(REBUILD2_STATE);
- }
- else if (state == INIT2_STATE)
- {
- setState(NORMAL_STATE);
- }
- break;
- case LEAVE_REQ:
- if (state == LEAD_NORMAL1_STATE || state == LEAD_NORMAL2_STATE)
- { //TODO: make this graceful, instead of just rebuilding
- removeHost(peerIp);
- if (state != LEAD_NORMAL2_STATE)
- setState(LEAD_NORMAL2_STATE);
- }
- break;
- case DHT_UPDATE_CMD:
- if (state == REBUILD2_STATE && peerIp == leader)
- {
- free(hostArray);
- free(blockOwnerArray);
- numHosts = read2(&inBuffer[1]);
- numBlocks = read2(&inBuffer[3]);
- while (hostArraySize < numHosts)
- hostArraySize *= 2;
- hostArray = calloc(hostArraySize, sizeof(struct hostData));
- blockOwnerArray = calloc(numBlocks, 2);
- memcpy(hostArray, &inBuffer[5], numHosts*sizeof(struct hostData));
- memcpy(blockOwnerArray, &inBuffer[5+numHosts*sizeof(struct hostData)], numBlocks*2);
- writeHostList();
- setState(REBUILD3_STATE);
- outBuffer[0] = DHT_UPDATE_RES;
- udpSend(outBuffer, 1, peerIp);
- }
- break;
- case DHT_UPDATE_RES:
- if (state == LEAD_REBUILD2_STATE)
- {
- checkReplied(peerIp);
- if (allReplied())
- {
- setState(LEAD_REBUILD3_STATE);
- outBuffer[0] = FILL_DHT_CMD;
- udpSendAll(outBuffer, 1);
- if (fillStatus != 0)
- dhtLog("udpListen(): ERROR: fillTask already running\n");
- fillStatus = 1;
- if (pthread_create(&threadFillTask, NULL, fillTask, NULL) != 0)
- dhtLog("udpListen(): ERROR creating threadFillTask\n");
- }
- }
- break;
- case ELECT_LEADER_CMD:
- tmpUInt = read4(&inBuffer[1]);
- if ((state == ELECT1_STATE || state == ELECT2_STATE)
- && tmpUInt >= electionOriginator)
- { //already participating in a higher-priority election
- outBuffer[0] = ELECT_LEADER_RES;
- outBuffer[1] = 0xFF;
- udpSend(outBuffer, 2, peerIp);
- }
- else
- { //join election
- electionOriginator = tmpUInt;
- electionParent = peerIp;
- setState(ELECT1_STATE);
- outBuffer[0] = ELECT_LEADER_CMD;
- write4(&outBuffer[1], electionOriginator);
- //don't bother forwarding the message to originator or parent
- checkReplied(electionOriginator);
- checkReplied(electionParent);
- if (allReplied())
- { //in case that is everybody I know of
- setState(ELECT2_STATE);
- outBuffer[0] = ELECT_LEADER_RES;
- outBuffer[1] = 0;
- write2(&outBuffer[2], numHosts);
- memcpy(&outBuffer[4], hostArray, sizeof(struct hostData)
- * numHosts);
- udpSend(outBuffer, 4 + sizeof(struct hostData) * numHosts,
- electionParent);
- }
- else
- {
- udpSendAll(outBuffer, 5);
- }
- }
- break;
- case ELECT_LEADER_RES:
- if (state == ELECT1_STATE)
- {
- checkReplied(peerIp);
- if (inBuffer[1] != 0xFF)
- {
- tmpUShort = read2(&inBuffer[2]);
- hostDataPtr = (struct hostData *)&inBuffer[4];
- for (i = 0; i < tmpUShort; i++)
- addHost(hostDataPtr[i]);
- writeHostList();
- }
- if (allReplied())
- {
- setState(ELECT2_STATE);
- if (electionOriginator == myHostData.ipAddr)
- {
- leader = hostArray[0].ipAddr;
- if (leader == myHostData.ipAddr)
- { //I am the leader
- dhtLog("I am the leader!\n");
- setState(LEAD_REBUILD1_STATE);
- outBuffer[0] = REBUILD_CMD;
- udpSendAll(outBuffer, 1);
- }
- else
- { //notify leader
- outBuffer[0] = CONGRATS_CMD;
- write2(&outBuffer[1], numHosts);
- hostDataPtr = (struct hostData *)&outBuffer[3];
- for (i = 0; i < numHosts; i++)
- hostDataPtr[i] = hostArray[i];
- udpSend(outBuffer, 3 + sizeof(struct hostData) * numHosts,
- leader);
- }
- }
- else
- {
- outBuffer[0] = ELECT_LEADER_RES;
- outBuffer[1] = 0;
- write2(&outBuffer[2], numHosts);
- hostDataPtr = (struct hostData *)&outBuffer[4];
- for (i = 0; i < numHosts; i++)
- hostDataPtr[i] = hostArray[i];
- udpSend(outBuffer, 4 + sizeof(struct hostData) * numHosts,
- electionParent);
- }
- }
- }
- break;
- case CONGRATS_CMD:
- if (state == ELECT2_STATE)
- { //I am the leader
- leader = myHostData.ipAddr;
- dhtLog("I am the leader!\n");
- tmpUShort = read2(&inBuffer[1]);
- hostDataPtr = (struct hostData *)&inBuffer[3];
- for (i = 0; i < tmpUShort; i++)
- addHost(hostDataPtr[i]);
- writeHostList();
- setState(LEAD_REBUILD1_STATE);
- outBuffer[0] = REBUILD_CMD;
- udpSendAll(outBuffer, 1);
- }
- break;
- case REBUILD_REQ:
- if (state == LEAD_NORMAL1_STATE || state == LEAD_NORMAL2_STATE)
- {
- setState(LEAD_REBUILD1_STATE);
- outBuffer[0] = REBUILD_CMD;
- udpSendAll(outBuffer, 1);
- }
- break;
- case REBUILD_CMD:
- leader = peerIp; //consider this a declaration of authority
- setState(REBUILD1_STATE);
- outBuffer[0] = JOIN_REQ;
- write4(&outBuffer[1], myHostData.maxKeyCapacity);
- udpSend(outBuffer, 5, leader);
- break;
- case FILL_DHT_CMD:
- if (state == REBUILD3_STATE && peerIp == leader)
- {
- setState(REBUILD4_STATE);
- if (fillStatus != 0)
- dhtLog("udpListen(): ERROR: fillTask already running\n");
- fillStatus = 1;
- if (pthread_create(&threadFillTask, NULL, fillTask, NULL) != 0)
- dhtLog("udpListen(): ERROR creating threadFillTask\n");
- }
- break;
- case FILL_DHT_RES:
- if (state == LEAD_REBUILD3_STATE)
- {
- checkReplied(peerIp);
- if (allReplied() && fillStatus == 2)
- {
- fillStatus = 0;
- setState(LEAD_REBUILD4_STATE);
- outBuffer[0] = RESUME_NORMAL_CMD;
- udpSendAll(outBuffer, 1);
- }
- }
- break;
- case RESUME_NORMAL_CMD:
- if (state == REBUILD5_STATE && peerIp == leader)
- {
- setState(NORMAL_STATE);
- outBuffer[0] = RESUME_NORMAL_RES;
- udpSend(outBuffer, 1, leader);
- }
- break;
- case RESUME_NORMAL_RES:
- if (state == LEAD_REBUILD4_STATE)
- {
- checkReplied(peerIp);
- if (allReplied())
- {
- setState(LEAD_NORMAL1_STATE);
- }
- }
- break;
- }
- }
- }
- if (state == REBUILD4_STATE)
- {
- switch (fillStatus)
- {
- case 0: dhtLog("udpListen(): ERROR: fillStatus=0 in REBUILD4_STATE\n");
- break;
- case 1: //do nothing
- break;
- case 2: //done filling the dht, notify leader
- fillStatus = 0;
- setState(REBUILD5_STATE);
- outBuffer[0] = FILL_DHT_RES;
- udpSend(outBuffer, 1, leader);
- break;
- case 3: //error encountered -> restart rebuild
- fillStatus = 0;
- setState(REBUILD0_STATE);
- outBuffer[0] = REBUILD_REQ;
- udpSend(outBuffer, 1, leader);
- break;
- }
- }
- if (state == LEAD_REBUILD3_STATE)
- {
- switch (fillStatus)
- {
- case 0: dhtLog("udpListen(): ERROR: fillStatus=0 in LEAD_REBUILD3_STATE\n");
- break;
- case 1: //do nothing
- break;
- case 2: //I'm done, now is everybody else also done?
- if (allReplied())
- {
- fillStatus = 0;
- setState(LEAD_REBUILD4_STATE);
- outBuffer[0] = RESUME_NORMAL_CMD;
- udpSendAll(outBuffer, 1);
- }
- break;
- case 3: //error encountered -> restart rebuild
- fillStatus = 0;
- setState(LEAD_REBUILD1_STATE);
- outBuffer[0] = REBUILD_CMD;
- udpSendAll(outBuffer, 1);
- break;
- }
- }
- if (timerSet)
- {
- gettimeofday(&now, NULL);
- if (timercmp(&now, &timer, >))
- {
- if (timeoutCntr < retry_vals[state])
- {
- timeoutCntr++;
- timeradd(&now, &timeout_vals[state], &timer);
- dhtLog("udpListen(): retry: %d\n", timeoutCntr);
- switch (state)
- {
- case INIT1_STATE:
- outBuffer[0] = WHO_IS_LEADER_CMD;
- udpSend(outBuffer, 1, seed);
- break;
- case INIT2_STATE:
- outBuffer[0] = JOIN_REQ;
- write4(&outBuffer[1], myHostData.maxKeyCapacity);
- udpSend(outBuffer, 5, leader);
- break;
- case ELECT1_STATE:
- outBuffer[0] = ELECT_LEADER_CMD;
- write4(&outBuffer[1], electionOriginator);
- udpSendAll(outBuffer, 5);
- break;
- case ELECT2_STATE:
- if (electionOriginator == myHostData.ipAddr)
- { //retry notify leader
- outBuffer[0] = CONGRATS_CMD;
- write2(&outBuffer[1], numHosts);
- memcpy(&outBuffer[3], hostArray, sizeof(struct hostData)
- * numHosts);
- udpSend(outBuffer, 3 + sizeof(struct hostData) * numHosts,
- leader);
- }
- else
- {
- outBuffer[0] = ELECT_LEADER_RES;
- outBuffer[1] = 0;
- write2(&outBuffer[2], numHosts);
- memcpy(&outBuffer[4], hostArray, sizeof(struct hostData)
- * numHosts);
- udpSend(outBuffer, 4 + sizeof(struct hostData) * numHosts,
- electionParent);
- }
- break;
- case REBUILD0_STATE:
- outBuffer[0] = REBUILD_REQ;
- udpSend(outBuffer, 1, leader);
- break;
- case REBUILD1_STATE:
- outBuffer[0] = JOIN_REQ;
- write4(&outBuffer[1], myHostData.maxKeyCapacity);
- udpSend(outBuffer, 5, leader);
- break;
- case REBUILD5_STATE:
- outBuffer[0] = FILL_DHT_RES;
- udpSend(outBuffer, 1, leader);
- break;
- case LEAD_REBUILD1_STATE:
- outBuffer[0] = REBUILD_CMD;
- udpSendAll(outBuffer, 1);
- break;
- case LEAD_REBUILD2_STATE:
- outBuffer[0] = DHT_UPDATE_CMD;
- write2(&outBuffer[1], numHosts);
- write2(&outBuffer[3], numBlocks);
- memcpy(&outBuffer[5], hostArray, numHosts
- * sizeof(struct hostData));
- memcpy(&outBuffer[5+numHosts*sizeof(struct hostData)],
- blockOwnerArray, numBlocks*2);
- udpSendAll(outBuffer, 5 + sizeof(struct hostData) * numHosts
- + 2 * numBlocks);
- break;
- case LEAD_REBUILD3_STATE:
- outBuffer[0] = FILL_DHT_CMD;
- udpSendAll(outBuffer, 1);
- break;
- case LEAD_REBUILD4_STATE:
- outBuffer[0] = RESUME_NORMAL_CMD;
- udpSendAll(outBuffer, 1);
- break;
- case EXIT1_STATE: //TODO...
- break;
- case NORMAL_STATE:
- case LEAD_NORMAL1_STATE:
- case LEAD_NORMAL2_STATE:
- case REBUILD2_STATE:
- case REBUILD3_STATE:
- case REBUILD4_STATE:
- case EXIT2_STATE: //we shouldn't get here
- break;
- }
- }
- else
- {
- dhtLog("udpListen(): timed out in state %s after %d retries\n",
- state_names[state], timeoutCntr);
- switch (state)
- {
- case INIT1_STATE:
- setState(EXIT2_STATE);
- break;
- case LEAD_NORMAL2_STATE:
- setState(LEAD_REBUILD1_STATE);
- outBuffer[0] = REBUILD_CMD;
- udpSendAll(outBuffer, 1);
- break;
- case ELECT1_STATE:
- dhtLog("removing unresponsive hosts, before:\n");
- writeHostList();
- removeUnresponsiveHosts();
- dhtLog("after\n");
- writeHostList();
- setState(ELECT2_STATE);
- if (electionOriginator == myHostData.ipAddr)
- {
- leader = hostArray[0].ipAddr;
- if (leader == myHostData.ipAddr)
- { //I am the leader
- dhtLog("I am the leader!\n");
- setState(LEAD_REBUILD1_STATE);
- outBuffer[0] = REBUILD_CMD;
- udpSendAll(outBuffer, 1);
- }
- else
- { //notify leader
- outBuffer[0] = CONGRATS_CMD;
- write2(&outBuffer[1], numHosts);
- memcpy(&outBuffer[3], hostArray, sizeof(struct hostData)
- * numHosts);
- udpSend(outBuffer, 3 + sizeof(struct hostData) * numHosts,
- leader);
- }
- }
- else
- {
- outBuffer[0] = ELECT_LEADER_RES;
- outBuffer[1] = 0;
- write2(&outBuffer[2], numHosts);
- memcpy(&outBuffer[4], hostArray, sizeof(struct hostData)
- * numHosts);
- udpSend(outBuffer, 4 + sizeof(struct hostData) * numHosts,
- electionParent);
- }
- break;
- case INIT2_STATE:
- case ELECT2_STATE:
- case REBUILD0_STATE:
- case REBUILD1_STATE:
- case REBUILD2_STATE:
- case REBUILD3_STATE:
- case REBUILD4_STATE:
- case REBUILD5_STATE:
- case LEAD_REBUILD1_STATE:
- case LEAD_REBUILD2_STATE:
- case LEAD_REBUILD3_STATE:
- case LEAD_REBUILD4_STATE:
- //start election
- electionOriginator = myHostData.ipAddr;
- setState(ELECT1_STATE);
- outBuffer[0] = ELECT_LEADER_CMD;
- write4(&outBuffer[1], myHostData.ipAddr); //originator = me
- udpSendAll(outBuffer, 5);
- break;
- case EXIT1_STATE:
- setState(EXIT2_STATE);
- break;
- case NORMAL_STATE:
- case LEAD_NORMAL1_STATE:
- case EXIT2_STATE: //we shouldn't get here
- break;
- }
- }
- }
- }
- if (state != oldState)
- pthread_cond_broadcast(&stateCond);
- pthread_mutex_unlock(&stateMutex);
- }
-}
-
+++ /dev/null
-#ifndef _DHT_H
-#define _DHT_H
-
-#include <stdio.h>
-
-/*******************************************************************************
-* Local Structs
-*******************************************************************************/
-
-#define DHT_NO_KEY_LIMIT 0xFFFFFFFF
-
-/*******************************************************************************
-* Interface Function Prototypes
-*******************************************************************************/
-
-//called by host which joins (or starts) the system
-void dhtInit(unsigned int seedIp, unsigned int maxKeyCapaciy);
-//exit system, cleanup
-void dhtExit();
-
-//called by whoever performs the creation, move, deletion
-
-//returns 0 if successful, -1 if an error occurred
-int dhtInsert(unsigned int key, unsigned int val);
-//simultaneously inserts the key-val pairs in the given arrays
-int dhtInsertMult(unsigned int numKeys, unsigned int *keys, unsigned int *vals);
-//returns 0 if successful, -1 if an error occurred
-int dhtRemove(unsigned int key);
-//simultaneously delete the keys in the given array
-int dhtRemoveMult(unsigned int numKeys, unsigned int *keys);
-//returns 0 if successful and copies val into *val,
-// 1 if key not found, -1 if an error occurred
-int dhtSearch(unsigned int key, unsigned int *val);
-//simultaneously search for the vals that correspond to the given keys.
-// result is placed in vals[]
-int dhtSearchMult(unsigned int numKeys, unsigned int *keys, unsigned int *vals);
-#endif
-
+++ /dev/null
-#include "dstm.h"
-
-extern int classsize[];
-
-/* BEGIN object header */
-
-// Get a new object id
-unsigned int getNewOID(void) {
- static int id = 1;
- return id++;
-}
-
-// Get the size of the object for a given type
-unsigned int objSize(objheader_t *object) {
- return classsize[object->type];
-}
-
-/* END object header */
-
#define MSG_NOSIGNAL 0
#endif
-#define GET_NTUPLES(x) ((int *)(x + sizeof(prefetchqelem_t)))
-#define GET_PTR_OID(x) ((unsigned int *)(x + sizeof(prefetchqelem_t) + sizeof(int)))
-#define GET_PTR_EOFF(x,n) ((short *)(x + sizeof(prefetchqelem_t) + sizeof(int) + (n*sizeof(unsigned int))))
-#define GET_PTR_ARRYFLD(x,n) ((short *)(x + sizeof(prefetchqelem_t) + sizeof(int) + (n*sizeof(unsigned int)) + (n*sizeof(short))))
-
-
-//Coordinator Messages
+/***********************************************************
+ * Macros
+ **********************************************************/
+#define GET_SITEID(x) ((int *)(x))
+#define GET_NTUPLES(x) ((int *)(x + sizeof(int)))
+#define GET_PTR_OID(x) ((unsigned int *)(x + 2*sizeof(int)))
+#define GET_PTR_EOFF(x,n) ((short *)(x + 2*sizeof(int) + (n*sizeof(unsigned int))))
+#define GET_PTR_ARRYFLD(x,n) ((short *)(x + 2*sizeof(int) + (n*sizeof(unsigned int)) + (n*sizeof(short))))
+#define ENDEBUG(s) { printf("Inside %s()\n", s); fflush(stdout);}
+#define EXDEBUG(s) {printf("Outside %s()\n", s); fflush(stdout);}
+/*****************************************
+ * Coordinator Messages
+ ***************************************/
#define READ_REQUEST 1
#define READ_MULT_REQUEST 2
#define MOVE_REQUEST 3
#define TRANS_PREFETCH 8
#define TRANS_ABORT_BUT_RETRY_COMMIT_WITH_RELOCATING 9
-//Participant Messages
+/*********************************
+ * Participant Messages
+ *******************************/
#define OBJECT_FOUND 10
#define OBJECT_NOT_FOUND 11
#define OBJECTS_FOUND 12
#define TRANS_SOFT_ABORT 20
#define TRANS_SUCESSFUL 21
#define TRANS_PREFETCH_RESPONSE 22
-
-//Control bits for status of objects in Machine pile
-#define OBJ_LOCKED_BUT_VERSION_MATCH 14
-#define OBJ_UNLOCK_BUT_VERSION_MATCH 15
-#define VERSION_NO_MATCH 16
+#define START_REMOTE_THREAD 23
+#define THREAD_NOTIFY_REQUEST 24
+#define THREAD_NOTIFY_RESPONSE 25
+#define TRANS_UNSUCESSFUL 26
+#define CLOSE_CONNECTION 27
//Max number of objects
#define MAX_OBJECTS 20
-
+#define DEFAULT_OBJ_STORE_SIZE 1048510 //1MB
+//Transaction id per machine
+#define TID_LEN 20
+#define LISTEN_PORT 2156
+#define UDP_PORT 2158
+//Prefetch tuning paramters
+#define RETRYINTERVAL 20//N
+#define SHUTDOWNINTERVAL 3 //M
#include <stdlib.h>
#include <stdio.h>
#include "clookup.h"
#include "queue.h"
#include "mcpileq.h"
+#include "threadnotify.h"
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#include "sockpool.h"
+#include <signal.h>
+#include "plookup.h"
+#include "dsmdebug.h"
-#define DEFAULT_OBJ_STORE_SIZE 1048510 //1MB
-#define TID_LEN 20
//bit designations for status field of objheader
#define DIRTY 0x01
#define NEW 0x02
#define LOCK 0x04
#define LOCAL 0x08
+/*******Global statistics *********/
+extern int numprefetchsites;
+
+#ifdef COMPILER
+
+#include "structdefs.h"
+
+typedef struct objheader {
+ threadlist_t *notifylist;
+ unsigned short version;
+ unsigned short rcount;
+} objheader_t;
+
+#define OID(x)\
+ (*((unsigned int *)&((struct ___Object___ *)((unsigned int) x + sizeof(objheader_t)))->___nextobject___))
+
+#define COMPOID(x)\
+ (*((unsigned int *)&((struct ___Object___ *) x)->___nextobject___))
+
+#define STATUS(x)\
+ *((unsigned int *) &(((struct ___Object___ *)((unsigned int) x + sizeof(objheader_t)))->___localcopy___))
+
+#define STATUSPTR(x)\
+ ((unsigned int *) &(((struct ___Object___ *)((unsigned int) x + sizeof(objheader_t)))->___localcopy___))
+
+#define TYPE(x)\
+ ((struct ___Object___ *)((unsigned int) x + sizeof(objheader_t)))->type
+
+#define GETSIZE(size, x) {\
+ int type=TYPE(x);\
+ if (type<NUMCLASSES) {\
+ size=classsize[type];\
+ } else {\
+ size=classsize[type]*((struct ArrayObject *)&((objheader_t *)x)[1])->___length___+sizeof(struct ArrayObject);\
+ }\
+}
+
+#else
+
typedef struct objheader {
+ threadlist_t *notifylist;
unsigned int oid;
unsigned short type;
unsigned short version;
char status;
} objheader_t;
+#define OID(x) x->oid
+#define TYPE(x) x->type
+#define STATUS(x) x->status
+#define STATUSPTR(x) &x->status
+#define GETSIZE(size, x) size=classsize[TYPE(x)]
+#endif
+
typedef struct objstr {
unsigned int size; //this many bytes are allocated after this header
void *top;
struct objstr *next;
} objstr_t;
+typedef struct oidmidpair {
+ unsigned int oid;
+ unsigned int mid;
+} oidmidpair_t;
+
typedef struct transrecord {
- objstr_t *cache;
- chashtable_t *lookupTable;
+ objstr_t *cache;
+ chashtable_t *lookupTable;
+#ifdef COMPILER
+ struct ___Object___ * revertlist;
+#endif
} transrecord_t;
-// Structure that keeps track of responses from the participants
+
+// Structure is a shared structure that keeps track of responses from the participants
typedef struct thread_response {
- char rcv_status;
-}thread_response_t;
+ char rcv_status;
+} thread_response_t;
-// Structure that holds fixed data sizes to be sent along with TRANS_REQUEST
+// Structure that holds fixed data to be sent along with TRANS_REQUEST
typedef struct fixed_data {
- char control;
- char trans_id[TID_LEN];
- int mcount; // Machine count
- short numread; // Number of objects read
- short nummod; // Number of objects modified
- int sum_bytes; // Total bytes modified
-}fixed_data_t;
-
-// Structure that holds variable data sizes per machine participant
+ char control; /* control message */
+ char trans_id[TID_LEN]; /* transaction id */
+ int mcount; /* participant count */
+ unsigned int numread; /* no of objects read */
+ unsigned int nummod; /* no of objects modified */
+ unsigned int numcreated; /* no of objects created */
+ int sum_bytes; /* total bytes of modified objects in a transaction */
+} fixed_data_t;
+
+/* Structure that holds trans request information for each participant */
typedef struct trans_req_data {
- fixed_data_t f;
- unsigned int *listmid;
- char *objread;
- unsigned int *oidmod;
-}trans_req_data_t;
+ fixed_data_t f; /* Holds first few fixed bytes of data sent during TRANS_REQUEST protcol*/
+ unsigned int *listmid; /* Pointer to array holding list of participants */
+ char *objread; /* Pointer to array holding oid and version number of objects that are only read */
+ unsigned int *oidmod; /* Pointer to array holding oids of objects that are modified */
+ unsigned int *oidcreated; /* Pointer to array holding oids of objects that are newly created */
+} trans_req_data_t;
-// Structure passed to dstmAcceptinfo() on server side to complete TRANS_COMMIT process
+/* Structure that holds information of objects that are not found in the participant
+ * and objs locked within a transaction during commit process */
typedef struct trans_commit_data{
- unsigned int *objmod;
- unsigned int *objlocked;
- unsigned int *objnotfound;
- void *modptr;
- int nummod;
- int numlocked;
- int numnotfound;
-}trans_commit_data_t;
+ unsigned int *objlocked; /* Pointer to array holding oids of objects locked inside a transaction */
+ unsigned int *objnotfound; /* Pointer to array holding oids of objects not found on the participant machine */
+ unsigned int *objvernotmatch; /* Pointer to array holding oids whose version doesn't match on the participant machine */
+ void *modptr; /* Pointer to the address in the mainobject store of the participant that holds all modified objects */
+ int numlocked; /* no of objects locked */
+ int numnotfound; /* no of objects not found */
+ int numvernotmatch; /* no of objects whose version doesn't match */
+} trans_commit_data_t;
#define PRINT_TID(PTR) printf("DEBUG -> %x %d\n", PTR->mid, PTR->thread_id);
-//structure for passing multiple arguments to thread
+/* Structure for passing multiple arguments to a thread
+ * spawned to process each transaction on a machine */
typedef struct thread_data_array {
- int thread_id;
- int mid;
- int pilecount;
- trans_req_data_t *buffer;
- thread_response_t *recvmsg;//shared datastructure to keep track of the control message receiv
- pthread_cond_t *threshold; //threshhold for waking up a thread
- pthread_mutex_t *lock; //lock the count variable
- int *count; //variable to count responses of TRANS_REQUEST protocol from all participants
- char *replyctrl; //shared ctrl message that stores the reply to be sent, filled by decideResp
- char *replyretry; //shared variable to find out if we need retry (TRANS_COMMIT case)
- transrecord_t *rec; // To send modified objects
+ int thread_id;
+ int mid;
+ trans_req_data_t *buffer; /* Holds trans request information sent to a participant, based on threadid */
+ thread_response_t *recvmsg; /* Shared datastructure to keep track of the participants response to a trans request */
+ pthread_cond_t *threshold; /* Condition var to waking up a thread */
+ pthread_mutex_t *lock; /* Lock for counting participants response */
+ int *count; /* Variable to count responses from all participants to the TRANS_REQUEST protocol */
+ char *replyctrl; /* Shared ctrl message that stores the reply to be sent to participants, filled by decideResponse() */
+ char *replyretry; /* Shared variable that keep track if coordinator needs retry */
+ transrecord_t *rec; /* Shared variable transaction record send to all thread data */
} thread_data_array_t;
//Structure for passing arguments to the local m/c thread
typedef struct local_thread_data_array {
- thread_data_array_t *tdata;
- trans_commit_data_t *transinfo; //Required for trans commit process
+ thread_data_array_t *tdata; /* Holds all the arguments send to a thread that is spawned when transaction commits */
+ trans_commit_data_t *transinfo; /* Holds information of objects locked and not found in the participant */
} local_thread_data_array_t;
-// Structure to save information about an oid necesaary for the decideControl()
-typedef struct objinfo {
- unsigned int oid;
- int poss_val; //Status of object(locked but version matches, version mismatch, oid not present in machine etc)
-}objinfo_t;
-
-//Structure for members within prefetch tuples
-typedef struct member {
- short offset;
- short index;
- struct member *next;
-}trans_member_t;
-
-/*
-//Structure that holds the compiler generated prefetch data
-typedef struct compprefetchdata {
-transrecord_t *record;
-} compprefetchdata_t;
-*/
+//Structure to store mid and socketid information
+typedef struct midSocketInfo {
+ unsigned int mid; /* To communicate with mid use sockid in this data structure */
+ int sockid;
+} midSocketInfo_t;
/* Initialize main object store and lookup tables, start server thread. */
int dstmInit(void);
+void send_data(int fd, void *buf, int buflen);
+void recv_data(int fd, void *buf, int buflen);
+int recv_data_errorcode(int fd, void *buf, int buflen);
/* Prototypes for object header */
unsigned int getNewOID(void);
-unsigned int objSize(objheader_t *object);
/* end object header */
/* Prototypes for object store */
objstr_t *objstrCreate(unsigned int size); //size in bytes
void objstrDelete(objstr_t *store); //traverse and free entire list
void *objstrAlloc(objstr_t *store, unsigned int size); //size in bytes
+void clearObjStore(); // TODO:currently only clears the prefetch cache object store
/* end object store */
/* Prototypes for server portion */
-void *dstmListen();
+void *dstmListen(void *);
+int startlistening();
void *dstmAccept(void *);
int readClientReq(trans_commit_data_t *, int);
-int processClientReq(fixed_data_t *, trans_commit_data_t *,unsigned int *, char *, void *, int);
+int processClientReq(fixed_data_t *, trans_commit_data_t *,unsigned int *, char *, void *, unsigned int *, int);
char handleTransReq(fixed_data_t *, trans_commit_data_t *, unsigned int *, char *, void *, int);
-int decideCtrlMessage(fixed_data_t *, trans_commit_data_t *, int *, int *, int *, int *, int *, void *, unsigned int *, unsigned int *, unsigned int *, int);
-int transCommitProcess(trans_commit_data_t *, int);
+char decideCtrlMessage(fixed_data_t *, trans_commit_data_t *, int *, int *, int *, int *, int *, void *, unsigned int *, unsigned int *, int);
+int transCommitProcess(void *, unsigned int *, unsigned int *, int, int, int);
+void processReqNotify(unsigned int numoid, unsigned int *oid, unsigned short *version, unsigned int mid, unsigned int threadid);
/* end server portion */
/* Prototypes for transactions */
-void randomdelay(void);
+/* Function called at beginning. Passes in the first parameter. */
+/* Returns 1 if this thread should run the main process */
+
+int dstmStartup(const char *);
+void transInit();
+int processConfigFile();
+void addHost(unsigned int);
+void mapObjMethod(unsigned short);
+
+void randomdelay();
transrecord_t *transStart();
objheader_t *transRead(transrecord_t *, unsigned int);
-objheader_t *transCreateObj(transrecord_t *, unsigned short); //returns oid
+objheader_t *transCreateObj(transrecord_t *, unsigned int); //returns oid header
int transCommit(transrecord_t *record); //return 0 if successful
void *transRequest(void *); //the C routine that the thread will execute when TRANS_REQUEST begins
-void *handleLocalReq(void *); //the C routine that the local m/c thread will execute
-int decideResponse(thread_data_array_t *);// Coordinator decides what response to send to the participant
+void decideResponse(thread_data_array_t *);// Coordinator decides what response to send to the participant
char sendResponse(thread_data_array_t *, int); //Sends control message back to Participants
-void *getRemoteObj(transrecord_t *, unsigned int, unsigned int);
-int transAbortProcess(void *, unsigned int *, int, int, int);
-int transComProcess(trans_commit_data_t *);
-void prefetch(int, unsigned int *, short *, short*);
+void *getRemoteObj(transrecord_t *, unsigned int, unsigned int);// returns object header from main object store after object is copied into it from remote machine
+void *handleLocalReq(void *);//handles Local requests
+int transComProcess(local_thread_data_array_t *);
+int transAbortProcess(local_thread_data_array_t *);
+void transAbort(transrecord_t *trans);
+void sendPrefetchResponse(int sd, char *control, char *sendbuffer, int *size);
+void prefetch(int, int, unsigned int *, unsigned short *, short*);
void *transPrefetch(void *);
void *mcqProcess(void *);
-void checkPrefetchTuples(prefetchqelem_t *);
-prefetchpile_t *foundLocal(prefetchqelem_t *);
-prefetchpile_t *makePreGroups(prefetchqelem_t *, int *);
-void checkPreCache(prefetchqelem_t *, int *, int, int, unsigned int, int, int, int);
+prefetchpile_t *foundLocal(char *);// returns node with prefetch elements(oids, offsets)
+int lookupObject(unsigned int * oid, short offset);
int transPrefetchProcess(transrecord_t *, int **, short);
void sendPrefetchReq(prefetchpile_t*, int);
-void getPrefetchResponse(int, int);
+void sendPrefetchReqnew(prefetchpile_t*, int);
+int getPrefetchResponse(int);
+unsigned short getObjType(unsigned int oid);
+int startRemoteThread(unsigned int oid, unsigned int mid);
+plistnode_t *pInsert(plistnode_t *pile, objheader_t *headeraddr, unsigned int mid, int num_objs);
+
+/* Sends notification request for thread join, if sucessful returns 0 else returns -1 */
+int reqNotify(unsigned int *oidarry, unsigned short *versionarry, unsigned int numoid);
+void threadNotify(unsigned int oid, unsigned short version, unsigned int tid);
+int notifyAll(threadlist_t **head, unsigned int oid, unsigned int version);
+
/* end transactions */
#endif
/* Coordinator => Machine that initiates the transaction request call for commiting a transaction
* Participant => Machines that host the objects involved in a transaction commit */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <netdb.h>
-#include <fcntl.h>
+#include <netinet/tcp.h>
#include "dstm.h"
#include "mlookup.h"
#include "llookup.h"
+#include "threadnotify.h"
+#ifdef COMPILER
+#include "thread.h"
+#endif
-#define LISTEN_PORT 2156
#define BACKLOG 10 //max pending connections
#define RECEIVE_BUFFER_SIZE 2048
-#define PRE_BUF_SIZE 2048
extern int classsize[];
+extern int numHostsInSystem;
+extern pthread_mutex_t notifymutex;
objstr_t *mainobjstore;
-
-int dstmInit(void)
-{
- /* Initialize main object store */
- mainobjstore = objstrCreate(DEFAULT_OBJ_STORE_SIZE);
- /* Create machine lookup table and location lookup table */
- if (mhashCreate(HASH_SIZE, LOADFACTOR))
- return 1; //failure
-
- if (lhashCreate(HASH_SIZE, LOADFACTOR))
- return 1; //failure
-
- return 0;
+pthread_mutex_t mainobjstore_mutex;
+pthread_mutex_t lockObjHeader;
+pthread_mutexattr_t mainobjstore_mutex_attr; /* Attribute for lock to make it a recursive lock */
+
+sockPoolHashTable_t *transPResponseSocketPool;
+
+/* This function initializes the main objects store and creates the
+ * global machine and location lookup table */
+
+int dstmInit(void) {
+ mainobjstore = objstrCreate(DEFAULT_OBJ_STORE_SIZE);
+ /* Initialize attribute for mutex */
+ pthread_mutexattr_init(&mainobjstore_mutex_attr);
+ pthread_mutexattr_settype(&mainobjstore_mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP);
+ pthread_mutex_init(&mainobjstore_mutex, &mainobjstore_mutex_attr);
+ pthread_mutex_init(&lockObjHeader,NULL);
+ if (mhashCreate(HASH_SIZE, LOADFACTOR))
+ return 1; //failure
+
+ if (lhashCreate(HASH_SIZE, LOADFACTOR))
+ return 1; //failure
+
+ if (notifyhashCreate(N_HASH_SIZE, N_LOADFACTOR))
+ return 1; //failure
+
+ //Initialize socket pool
+ if((transPResponseSocketPool = createSockPool(transPResponseSocketPool, DEFAULTSOCKPOOLSIZE)) == NULL) {
+ printf("Error in creating new socket pool at %s line %d\n", __FILE__, __LINE__);
+ return 0;
+ }
+
+ return 0;
}
-void *dstmListen()
-{
- int listenfd, acceptfd;
- struct sockaddr_in my_addr;
- struct sockaddr_in client_addr;
- socklen_t addrlength = sizeof(struct sockaddr);
- pthread_t thread_dstm_accept;
- int i;
- int setsockflag=1;
-
- listenfd = socket(AF_INET, SOCK_STREAM, 0);
- if (listenfd == -1)
- {
- perror("socket");
- exit(1);
- }
- if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &setsockflag, sizeof (setsockflag)) < 0) {
- perror("socket");
- exit(1);
- }
+int startlistening() {
+ int listenfd;
+ struct sockaddr_in my_addr;
+ socklen_t addrlength = sizeof(struct sockaddr);
+ int setsockflag=1;
+
+ listenfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (listenfd == -1) {
+ perror("socket");
+ exit(1);
+ }
+
+ if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &setsockflag, sizeof (setsockflag)) < 0) {
+ perror("socket");
+ exit(1);
+ }
#ifdef MAC
- if (setsockopt(listenfd, SOL_SOCKET, SO_NOSIGPIPE, &setsockflag, sizeof (setsockflag)) < 0) {
- perror("socket");
- exit(1);
- }
+ if (setsockopt(listenfd, SOL_SOCKET, SO_NOSIGPIPE, &setsockflag, sizeof (setsockflag)) < 0) {
+ perror("socket");
+ exit(1);
+ }
#endif
- my_addr.sin_family = AF_INET;
- my_addr.sin_port = htons(LISTEN_PORT);
- my_addr.sin_addr.s_addr = INADDR_ANY;
- memset(&(my_addr.sin_zero), '\0', 8);
-
- if (bind(listenfd, (struct sockaddr *)&my_addr, addrlength) == -1)
- {
- perror("bind");
- exit(1);
- }
-
- if (listen(listenfd, BACKLOG) == -1)
- {
- perror("listen");
- exit(1);
- }
+ my_addr.sin_family = AF_INET;
+ my_addr.sin_port = htons(LISTEN_PORT);
+ my_addr.sin_addr.s_addr = INADDR_ANY;
+ memset(&(my_addr.sin_zero), '\0', 8);
+
+ if (bind(listenfd, (struct sockaddr *)&my_addr, addrlength) == -1) {
+ perror("bind");
+ exit(1);
+ }
+
+ if (listen(listenfd, BACKLOG) == -1) {
+ perror("listen");
+ exit(1);
+ }
+ return listenfd;
+}
- printf("Listening on port %d, fd = %d\n", LISTEN_PORT, listenfd);
- while(1)
- {
- acceptfd = accept(listenfd, (struct sockaddr *)&client_addr, &addrlength);
- pthread_create(&thread_dstm_accept, NULL, dstmAccept, (void *)acceptfd);
- }
- pthread_exit(NULL);
+/* This function starts the thread to listen on a socket
+ * for tranaction calls */
+void *dstmListen(void *lfd) {
+ int listenfd=(int)lfd;
+ int acceptfd;
+ struct sockaddr_in client_addr;
+ socklen_t addrlength = sizeof(struct sockaddr);
+ pthread_t thread_dstm_accept;
+
+ printf("Listening on port %d, fd = %d\n", LISTEN_PORT, listenfd);
+ while(1) {
+ int retval;
+ int flag=1;
+ acceptfd = accept(listenfd, (struct sockaddr *)&client_addr, &addrlength);
+ setsockopt(acceptfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
+ do {
+ retval=pthread_create(&thread_dstm_accept, NULL, dstmAccept, (void *)acceptfd);
+ } while(retval!=0);
+ pthread_detach(thread_dstm_accept);
+ }
}
-/* This function accepts a new connection request, decodes the control message in the connection
+/* This function accepts a new connection request, decodes the control message in the connection
* and accordingly calls other functions to process new requests */
-void *dstmAccept(void *acceptfd)
-{
- int numbytes,i, val, retval;
- unsigned int oid;
- char buffer[RECEIVE_BUFFER_SIZE], control,ctrl;
- char *ptr;
- void *srcObj;
- objheader_t *h;
- trans_commit_data_t transinfo;
-
- int fd_flags = fcntl((int)acceptfd, F_GETFD), size;
-
- printf("Recieved connection: fd = %d\n", (int)acceptfd);
- /* Receive control messages from other machines */
- if((retval = recv((int)acceptfd, &control, sizeof(char), 0)) <= 0) {
- if (retval == 0) {
- return; // Testing connection
- }
- perror("Error in receiving control from coordinator\n");
- return;
- }
-
- switch(control) {
- case READ_REQUEST:
- /* Read oid requested and search if available */
- if((retval = recv((int)acceptfd, &oid, sizeof(unsigned int), 0)) <= 0) {
- perror("Error receiving object from cooridnator\n");
- return NULL;
- }
- srcObj = mhashSearch(oid);
- h = (objheader_t *) srcObj;
- size = sizeof(objheader_t) + sizeof(classsize[h->type]);
- if (h == NULL) {
- ctrl = OBJECT_NOT_FOUND;
- if(send((int)acceptfd, &ctrl, sizeof(char), MSG_NOSIGNAL) < sizeof(char)) {
- perror("Error sending control msg to coordinator\n");
- return NULL;
- }
- } else {
- /* Type */
- char msg[]={OBJECT_FOUND, 0, 0, 0, 0};
- *((int *)&msg[1])=size;
- if(send((int)acceptfd, &msg, sizeof(msg), MSG_NOSIGNAL) < sizeof(msg)) {
- perror("Error sending size of object to coordinator\n");
- return NULL;
- }
- if(send((int)acceptfd, h, size, MSG_NOSIGNAL) < size) {
- perror("Error in sending object\n");
- return NULL;
- }
- }
- break;
-
- case READ_MULT_REQUEST:
- printf("DEBUG-> READ_MULT_REQUEST\n");
- break;
-
- case MOVE_REQUEST:
- printf("DEBUG -> MOVE_REQUEST\n");
- break;
-
- case MOVE_MULT_REQUEST:
- printf("DEBUG -> MOVE_MULT_REQUEST\n");
- break;
-
- case TRANS_REQUEST:
- /* Read transaction request */
- printf("DEBUG -> Recv TRANS_REQUEST\n");
- if((val = readClientReq(&transinfo, (int)acceptfd)) != 0) {
- printf("Error in readClientReq\n");
- return;
- }
- break;
- case TRANS_PREFETCH:
- printf("DEBUG -> Recv TRANS_PREFETCH\n");
- if((val = prefetchReq((int)acceptfd)) != 0) {
- printf("Error in readClientReq\n");
- return;
- }
- break;
-
- default:
- printf("DEBUG -> dstmAccept: Error Unknown opcode %d\n", control);
- }
-
- /* Close connection */
- if (close((int)acceptfd) == -1)
- perror("close");
- else
- printf("Closed connection: fd = %d\n", (int)acceptfd);
-
+void *dstmAccept(void *acceptfd) {
+ int val, retval, size, sum, sockid;
+ unsigned int oid;
+ char *buffer;
+ char control,ctrl;
+ char *ptr;
+ void *srcObj;
+ objheader_t *h;
+ trans_commit_data_t transinfo;
+ unsigned short objType, *versionarry, version;
+ unsigned int *oidarry, numoid, mid, threadid;
+
+ /* Receive control messages from other machines */
+ while(1) {
+ int ret=recv_data_errorcode((int)acceptfd, &control, sizeof(char));
+ if (ret==0)
+ break;
+ if (ret==-1) {
+ printf("DEBUG -> RECV Error!.. retrying\n");
+ break;
+ }
+ switch(control) {
+ case READ_REQUEST:
+ /* Read oid requested and search if available */
+ recv_data((int)acceptfd, &oid, sizeof(unsigned int));
+ if((srcObj = mhashSearch(oid)) == NULL) {
+ printf("Error: Object 0x%x is not found in Main Object Store %s, %d\n", oid, __FILE__, __LINE__);
+ break;
+ }
+ h = (objheader_t *) srcObj;
+ GETSIZE(size, h);
+ size += sizeof(objheader_t);
+ sockid = (int) acceptfd;
+ if (h == NULL) {
+ ctrl = OBJECT_NOT_FOUND;
+ send_data(sockid, &ctrl, sizeof(char));
+ } else {
+ // Type
+ char msg[]={OBJECT_FOUND, 0, 0, 0, 0};
+ *((int *)&msg[1])=size;
+ send_data(sockid, &msg, sizeof(msg));
+ send_data(sockid, h, size);
+ }
+ break;
+
+ case READ_MULT_REQUEST:
+ break;
+
+ case MOVE_REQUEST:
+ break;
+
+ case MOVE_MULT_REQUEST:
+ break;
+
+ case TRANS_REQUEST:
+ /* Read transaction request */
+ transinfo.objlocked = NULL;
+ transinfo.objnotfound = NULL;
+ transinfo.modptr = NULL;
+ transinfo.numlocked = 0;
+ transinfo.numnotfound = 0;
+ if((val = readClientReq(&transinfo, (int)acceptfd)) != 0) {
+ printf("Error: In readClientReq() %s, %d\n", __FILE__, __LINE__);
+ pthread_exit(NULL);
+ }
+ break;
+
+ case TRANS_PREFETCH:
+ if((val = prefetchReq((int)acceptfd)) != 0) {
+ printf("Error: In prefetchReq() %s, %d\n", __FILE__, __LINE__);
+ break;
+ }
+ break;
+
+ case TRANS_PREFETCH_RESPONSE:
+ if((val = getPrefetchResponse((int) acceptfd)) != 0) {
+ printf("Error: In getPrefetchResponse() %s, %d\n", __FILE__, __LINE__);
+ break;
+ }
+ break;
+
+ case START_REMOTE_THREAD:
+ recv_data((int)acceptfd, &oid, sizeof(unsigned int));
+ objType = getObjType(oid);
+ startDSMthread(oid, objType);
+ break;
+
+ case THREAD_NOTIFY_REQUEST:
+ recv_data((int)acceptfd, &numoid, sizeof(unsigned int));
+ size = (sizeof(unsigned int) + sizeof(unsigned short)) * numoid + 2 * sizeof(unsigned int);
+ if((buffer = calloc(1,size)) == NULL) {
+ printf("%s() Calloc error at %s, %d\n", __func__, __FILE__, __LINE__);
+ pthread_exit(NULL);
+ }
+
+ recv_data((int)acceptfd, buffer, size);
+
+ oidarry = calloc(numoid, sizeof(unsigned int));
+ memcpy(oidarry, buffer, sizeof(unsigned int) * numoid);
+ size = sizeof(unsigned int) * numoid;
+ versionarry = calloc(numoid, sizeof(unsigned short));
+ memcpy(versionarry, buffer+size, sizeof(unsigned short) * numoid);
+ size += sizeof(unsigned short) * numoid;
+ mid = *((unsigned int *)(buffer+size));
+ size += sizeof(unsigned int);
+ threadid = *((unsigned int *)(buffer+size));
+ processReqNotify(numoid, oidarry, versionarry, mid, threadid);
+ free(buffer);
+
+ break;
+
+ case THREAD_NOTIFY_RESPONSE:
+ size = sizeof(unsigned short) + 2 * sizeof(unsigned int);
+ if((buffer = calloc(1,size)) == NULL) {
+ printf("%s() Calloc error at %s, %d\n", __func__, __FILE__, __LINE__);
pthread_exit(NULL);
+ }
+
+ recv_data((int)acceptfd, buffer, size);
+
+ oid = *((unsigned int *)buffer);
+ size = sizeof(unsigned int);
+ version = *((unsigned short *)(buffer+size));
+ size += sizeof(unsigned short);
+ threadid = *((unsigned int *)(buffer+size));
+ threadNotify(oid,version,threadid);
+ free(buffer);
+ break;
+
+ case CLOSE_CONNECTION:
+ goto closeconnection;
+
+ default:
+ printf("Error: dstmAccept() Unknown opcode %d at %s, %d\n", control, __FILE__, __LINE__);
+ }
+ }
+
+closeconnection:
+ /* Close connection */
+ if (close((int)acceptfd) == -1)
+ perror("close");
+ pthread_exit(NULL);
}
/* This function reads the information available in a transaction request
* and makes a function call to process the request */
int readClientReq(trans_commit_data_t *transinfo, int acceptfd) {
- char *ptr;
- void *modptr;
- fixed_data_t fixed;
- int sum = 0, i, N, n, val;
-
- /* Read fixed_data_t data structure */
- N = sizeof(fixed) - 1;
- ptr = (char *)&fixed;;
- fixed.control = TRANS_REQUEST;
- do {
- n = recv((int)acceptfd, (void *) ptr+1+sum, N-sum, 0);
- sum += n;
- } while(sum < N && n != 0);
-
- /* Read list of mids */
- int mcount = fixed.mcount;
- N = mcount * sizeof(unsigned int);
- unsigned int listmid[mcount];
- ptr = (char *) listmid;
- sum = 0;
- do {
- n = recv((int)acceptfd, (void *) ptr+sum, N-sum, 0);
- sum += n;
- } while(sum < N && n != 0);
-
- /* Read oid and version tuples for those objects that are not modified in the transaction */
- int numread = fixed.numread;
- N = numread * (sizeof(unsigned int) + sizeof(short));
- char objread[N];
- if(numread != 0) { //If pile contains more than one object to be read,
- // keep reading all objects
- sum = 0;
- do {
- n = recv((int)acceptfd, (void *) objread, N, 0);
- sum += n;
- } while(sum < N && n != 0);
- }
-
- /* Read modified objects */
- if(fixed.nummod != 0) { // If pile contains more than one modified object,
- // allocate new object store and recv all modified objects
- // TODO deallocate this space
- if ((modptr = objstrAlloc(mainobjstore, fixed.sum_bytes)) == NULL) {
- printf("objstrAlloc error for modified objects %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
- sum = 0;
- do { // Recv the objs that are modified by the Coordinator
- n = recv((int)acceptfd, modptr+sum, fixed.sum_bytes-sum, 0);
- sum += n;
- } while (sum < fixed.sum_bytes && n != 0);
- }
-
- /*Process the information read */
- if((val = processClientReq(&fixed, transinfo, listmid, objread, modptr, acceptfd)) != 0) {
- printf("Error in processClientReq %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
-
- return 0;
+ char *ptr;
+ void *modptr;
+ unsigned int *oidmod, oid;
+ fixed_data_t fixed;
+ objheader_t *headaddr;
+ int sum, i, size, n, val;
+
+ oidmod = NULL;
+
+ /* Read fixed_data_t data structure */
+ size = sizeof(fixed) - 1;
+ ptr = (char *)&fixed;;
+ fixed.control = TRANS_REQUEST;
+ recv_data((int)acceptfd, ptr+1, size);
+
+ /* Read list of mids */
+ int mcount = fixed.mcount;
+ size = mcount * sizeof(unsigned int);
+ unsigned int listmid[mcount];
+ ptr = (char *) listmid;
+ recv_data((int)acceptfd, ptr, size);
+
+ /* Read oid and version tuples for those objects that are not modified in the transaction */
+ int numread = fixed.numread;
+ size = numread * (sizeof(unsigned int) + sizeof(unsigned short));
+ char objread[size];
+ if(numread != 0) { //If pile contains more than one object to be read,
+ // keep reading all objects
+ recv_data((int)acceptfd, objread, size);
+ }
+
+ /* Read modified objects */
+ if(fixed.nummod != 0) {
+ if ((modptr = calloc(1, fixed.sum_bytes)) == NULL) {
+ printf("calloc error for modified objects %s, %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+ size = fixed.sum_bytes;
+ recv_data((int)acceptfd, modptr, size);
+ }
+
+ /* Create an array of oids for modified objects */
+ oidmod = (unsigned int *) calloc(fixed.nummod, sizeof(unsigned int));
+ if (oidmod == NULL){
+ printf("calloc error %s, %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+ ptr = (char *) modptr;
+ for(i = 0 ; i < fixed.nummod; i++) {
+ int tmpsize;
+ headaddr = (objheader_t *) ptr;
+ oid = OID(headaddr);
+ oidmod[i] = oid;
+ GETSIZE(tmpsize, headaddr);
+ ptr += sizeof(objheader_t) + tmpsize;
+ }
+
+ /*Process the information read */
+ if((val = processClientReq(&fixed, transinfo, listmid, objread, modptr, oidmod, acceptfd)) != 0) {
+ printf("Error: In processClientReq() %s, %d\n", __FILE__, __LINE__);
+ /* Free resources */
+ if(oidmod != NULL) {
+ free(oidmod);
+ }
+ return 1;
+ }
+
+ /* Free resources */
+ if(oidmod != NULL) {
+ free(oidmod);
+ }
+
+ return 0;
}
-/* This function processes the Coordinator's transaction request using "handleTransReq"
+/* This function processes the Coordinator's transaction request using "handleTransReq"
* function and sends a reply to the co-ordinator.
* Following this it also receives a new control message from the co-ordinator and processes this message*/
int processClientReq(fixed_data_t *fixed, trans_commit_data_t *transinfo,
- unsigned int *listmid, char *objread, void *modptr, int acceptfd) {
- char *ptr, control, sendctrl;
- objheader_t *tmp_header;
- void *header;
- int i = 0, val, retval;
-
- /* Send reply to the Coordinator */
- if((retval = handleTransReq(fixed, transinfo, listmid, objread, modptr,acceptfd)) == 0 ) {
- printf("Handle Trans Req error %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
- /* Read new control message from Coordiator */
- if((retval = recv((int)acceptfd, &control, sizeof(char), 0)) <= 0 ) {
- perror("Error in receiving control message\n");
- return 1;
- }
-
- /* Process the new control message */
- switch(control) {
- case TRANS_ABORT:
- /* Set all ref counts as 1 and do garbage collection */
- ptr = modptr;
- for(i = 0; i< fixed->nummod; i++) {
- tmp_header = (objheader_t *)ptr;
- tmp_header->rcount = 1;
- ptr += sizeof(objheader_t) + classsize[tmp_header->type];
- }
- /* Unlock objects that was locked due to this transaction */
- for(i = 0; i< transinfo->numlocked; i++) {
- header = mhashSearch(transinfo->objlocked[i]);// find the header address
- ((objheader_t *)header)->status &= ~(LOCK);
- }
-
- /* Send ack to Coordinator */
- printf("DEBUG -> Recv TRANS_ABORT\n");
- sendctrl = TRANS_SUCESSFUL;
- if(send((int)acceptfd, &sendctrl, sizeof(char), MSG_NOSIGNAL) < sizeof(char)) {
- perror("Error sending ACK to coordinator\n");
- return 1;
- }
- ptr = NULL;
- // return 0;
- break;
-
- case TRANS_COMMIT:
- /* Invoke the transCommit process() */
- printf("DEBUG -> Recv TRANS_COMMIT \n");
- if((val = transCommitProcess(transinfo, (int)acceptfd)) != 0) {
- printf("Error in transCommitProcess %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
- break;
-
- case TRANS_ABORT_BUT_RETRY_COMMIT_WITH_RELOCATING:
- //TODO expect another transrequest from client
- printf("DEBUG -> Recv TRANS_ABORT_BUT_RETRY_COMMIT_WITH_RELOCATING\n");
- break;
- default:
- printf("No response to TRANS_AGREE OR DISAGREE protocol\n");
- //TODO Use fixed.trans_id TID since Client may have died
- break;
- }
- /* Free memory */
- printf("DEBUG -> Freeing...\n");
- fflush(stdout);
- if (transinfo->objmod != NULL) {
- free(transinfo->objmod);
- transinfo->objmod = NULL;
- }
- if (transinfo->objlocked != NULL) {
- free(transinfo->objlocked);
- transinfo->objlocked = NULL;
- }
- if (transinfo->objnotfound != NULL) {
- free(transinfo->objnotfound);
- transinfo->objnotfound = NULL;
- }
- return 0;
+ unsigned int *listmid, char *objread, void *modptr, unsigned int *oidmod, int acceptfd) {
+ char control, sendctrl, retval;
+ objheader_t *tmp_header;
+ void *header;
+ int i = 0, val;
+
+ /* Send reply to the Coordinator */
+ if((retval = handleTransReq(fixed, transinfo, listmid, objread, modptr,acceptfd)) == 0 ) {
+ printf("Error: In handleTransReq() %s, %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+
+ recv_data((int)acceptfd, &control, sizeof(char));
+
+ /* Process the new control message */
+ switch(control) {
+ case TRANS_ABORT:
+ if (fixed->nummod > 0)
+ free(modptr);
+ /* Unlock objects that was locked due to this transaction */
+ for(i = 0; i< transinfo->numlocked; i++) {
+ if((header = mhashSearch(transinfo->objlocked[i])) == NULL) {
+ printf("mhashSearch returns NULL at %s, %d\n", __FILE__, __LINE__); // find the header address
+ return 1;
+ }
+ UnLock(STATUSPTR(header));
+ }
+
+ /* Send ack to Coordinator */
+ sendctrl = TRANS_UNSUCESSFUL;
+ send_data((int)acceptfd, &sendctrl, sizeof(char));
+ break;
+
+ case TRANS_COMMIT:
+ /* Invoke the transCommit process() */
+ if((val = transCommitProcess(modptr, oidmod, transinfo->objlocked, fixed->nummod, transinfo->numlocked, (int)acceptfd)) != 0) {
+ printf("Error: In transCommitProcess() %s, %d\n", __FILE__, __LINE__);
+ /* Free memory */
+ if (transinfo->objlocked != NULL) {
+ free(transinfo->objlocked);
+ }
+ if (transinfo->objnotfound != NULL) {
+ free(transinfo->objnotfound);
+ }
+ return 1;
+ }
+ break;
+
+ case TRANS_ABORT_BUT_RETRY_COMMIT_WITH_RELOCATING:
+ break;
+
+ default:
+ printf("Error: No response to TRANS_AGREE OR DISAGREE protocol %s, %d\n", __FILE__, __LINE__);
+ //TODO Use fixed.trans_id TID since Client may have died
+ break;
+ }
+
+ /* Free memory */
+ if (transinfo->objlocked != NULL) {
+ free(transinfo->objlocked);
+ }
+ if (transinfo->objnotfound != NULL) {
+ free(transinfo->objnotfound);
+ }
+ return 0;
}
-/* This function increments counters while running a voting decision on all objects involved
- * in TRANS_REQUEST */
-
+/* This function increments counters while running a voting decision on all objects involved
+ * in TRANS_REQUEST and If a TRANS_DISAGREE sends the response immediately back to the coordinator */
char handleTransReq(fixed_data_t *fixed, trans_commit_data_t *transinfo, unsigned int *listmid, char *objread, void *modptr, int acceptfd) {
- int val, i = 0;
- short version;
- char control = 0, *ptr;
- unsigned int oid;
- unsigned int *oidnotfound, *oidlocked, *oidmod;
- void *mobj;
- objheader_t *headptr;
-
- /* Counters and arrays to formulate decision on control message to be sent */
- oidnotfound = (unsigned int *) calloc(fixed->numread + fixed->nummod, sizeof(unsigned int));
- oidlocked = (unsigned int *) calloc(fixed->numread + fixed->nummod, sizeof(unsigned int));
- oidmod = (unsigned int *) calloc(fixed->nummod, sizeof(unsigned int));
- int objnotfound = 0, objlocked = 0, objmod =0, v_nomatch = 0, v_matchlock = 0, v_matchnolock = 0;
- int objmodnotfound = 0, nummodfound = 0;
-
- /* modptr points to the beginning of the object store
- * created at the Pariticipant.
- * Object store holds the modified objects involved in the transaction request */
- ptr = modptr;
-
- /* Process each oid in the machine pile/ group per thread */
- for (i = 0; i < fixed->numread + fixed->nummod; i++) {
- if (i < fixed->numread) {//Objs only read and not modified
- int incr = sizeof(unsigned int) + sizeof(short);// Offset that points to next position in the objread array
- incr *= i;
- oid = *((unsigned int *)(objread + incr));
- incr += sizeof(unsigned int);
- version = *((short *)(objread + incr));
- } else {//Objs modified
- headptr = (objheader_t *) ptr;
- oid = headptr->oid;
- oidmod[objmod] = oid;//Array containing modified oids
- objmod++;
- version = headptr->version;
- ptr += sizeof(objheader_t) + classsize[headptr->type];
- }
-
- /* Check if object is still present in the machine since the beginning of TRANS_REQUEST */
-
- if ((mobj = mhashSearch(oid)) == NULL) {/* Obj not found */
- /* Save the oids not found and number of oids not found for later use */
- //oidnotfound[objnotfound] = ((objheader_t *)mobj)->oid;
- oidnotfound[objnotfound] = oid;
- objnotfound++;
- } else { /* If Obj found in machine (i.e. has not moved) */
- /* Check if Obj is locked by any previous transaction */
- if ((((objheader_t *)mobj)->status & LOCK) == LOCK) {
- if (version == ((objheader_t *)mobj)->version) { /* If not locked then match versions */
- v_matchlock++;
- } else {/* If versions don't match ...HARD ABORT */
- v_nomatch++;
- /* Send TRANS_DISAGREE to Coordinator */
- control = TRANS_DISAGREE;
- if((val = send(acceptfd, &control, sizeof(char), MSG_NOSIGNAL)) < sizeof(char)) {
- perror("Error in sending control to the Coordinator\n");
- return 0;
- }
- printf("DEBUG -> Sending TRANS_DISAGREE\n");
- return control;
- }
- } else {/* If Obj is not locked then lock object */
- ((objheader_t *)mobj)->status |= LOCK;
-
- /*TESTING Add random wait to make transactions run for a long time such that
- * we can test for soft abort case */
-
- randomdelay();
-
- /* Save all object oids that are locked on this machine during this transaction request call */
- oidlocked[objlocked] = ((objheader_t *)mobj)->oid;
- objlocked++;
- if (version == ((objheader_t *)mobj)->version) { /* Check if versions match */
- v_matchnolock++;
- } else { /* If versions don't match ...HARD ABORT */
- v_nomatch++;
- control = TRANS_DISAGREE;
- /* Send TRANS_DISAGREE to Coordinator */
- if((val = send(acceptfd, &control, sizeof(char), MSG_NOSIGNAL)) < sizeof(char)) {
- perror("Error in sending control to the Coordinator\n");
- return 0;
- }
- printf("DEBUG -> Sending TRANS_DISAGREE\n");
- return control;
- }
- }
- }
+ int val, i = 0, j;
+ unsigned short version;
+ char control = 0, *ptr;
+ unsigned int oid;
+ unsigned int *oidnotfound, *oidlocked, *oidvernotmatch;
+ void *mobj;
+ objheader_t *headptr;
+
+ /* Counters and arrays to formulate decision on control message to be sent */
+ oidnotfound = (unsigned int *) calloc(fixed->numread + fixed->nummod, sizeof(unsigned int));
+ oidlocked = (unsigned int *) calloc(fixed->numread + fixed->nummod, sizeof(unsigned int));
+ oidvernotmatch = (unsigned int *) calloc(fixed->numread + fixed->nummod, sizeof(unsigned int));
+ int objnotfound = 0, objlocked = 0, objvernotmatch = 0;
+ int v_nomatch = 0, v_matchlock = 0, v_matchnolock = 0;
+ int numBytes = 0;
+ /* modptr points to the beginning of the object store
+ * created at the Pariticipant.
+ * Object store holds the modified objects involved in the transaction request */
+ ptr = (char *) modptr;
+
+ /* Process each oid in the machine pile/ group per thread */
+ for (i = 0; i < fixed->numread + fixed->nummod; i++) {
+ if (i < fixed->numread) { //Objs only read and not modified
+ int incr = sizeof(unsigned int) + sizeof(unsigned short); // Offset that points to next position in the objread array
+ incr *= i;
+ oid = *((unsigned int *)(objread + incr));
+ incr += sizeof(unsigned int);
+ version = *((unsigned short *)(objread + incr));
+ } else { //Objs modified
+ int tmpsize;
+ headptr = (objheader_t *) ptr;
+ oid = OID(headptr);
+ version = headptr->version;
+ GETSIZE(tmpsize, headptr);
+ ptr += sizeof(objheader_t) + tmpsize;
+ }
+
+ /* Check if object is still present in the machine since the beginning of TRANS_REQUEST */
+
+ if ((mobj = mhashSearch(oid)) == NULL) { /* Obj not found */
+ /* Save the oids not found and number of oids not found for later use */
+ oidnotfound[objnotfound] = oid;
+ objnotfound++;
+ } else { /* If Obj found in machine (i.e. has not moved) */
+ /* Check if Obj is locked by any previous transaction */
+ if (test_and_set(STATUSPTR(mobj))) {
+ //don't have lock
+ if (version == ((objheader_t *)mobj)->version) { /* If locked then match versions */
+ v_matchlock++;
+ } else { /* If versions don't match ...HARD ABORT */
+ v_nomatch++;
+ oidvernotmatch[objvernotmatch] = oid;
+ objvernotmatch++;
+ int size;
+ GETSIZE(size, mobj);
+ size += sizeof(objheader_t);
+ numBytes += size;
+ /* Send TRANS_DISAGREE to Coordinator */
+ control = TRANS_DISAGREE;
+ }
+ } else { /* If Obj is not locked then lock object */
+ /* Save all object oids that are locked on this machine during this transaction request call */
+ oidlocked[objlocked] = OID(((objheader_t *)mobj));
+ objlocked++;
+ if (version == ((objheader_t *)mobj)->version) { /* Check if versions match */
+ v_matchnolock++;
+ } else { /* If versions don't match ...HARD ABORT */
+ v_nomatch++;
+ oidvernotmatch[objvernotmatch] = oid;
+ objvernotmatch++;
+ int size;
+ GETSIZE(size, mobj);
+ size += sizeof(objheader_t);
+ numBytes += size;
+ control = TRANS_DISAGREE;
}
-
- /* Decide what control message to send to Coordinator */
- if ((val = decideCtrlMessage(fixed, transinfo, &v_matchnolock, &v_matchlock, &v_nomatch, &objnotfound, &objlocked,
- modptr, oidnotfound, oidlocked, oidmod, acceptfd)) == 0) {
- printf("Error in decideCtrlMessage %s, %d\n", __FILE__, __LINE__);
- return 0;
+ }
+ }
+ }
+
+ /* send TRANS_DISAGREE and objs*/
+ if(v_nomatch > 0) {
+#ifdef CACHE
+ char *objs = calloc(1, numBytes);
+ int j, offset = 0;
+ for(j = 0; j<objvernotmatch; j++) {
+ objheader_t *header = mhashSearch(oidvernotmatch[j]);
+ int size = 0;
+ GETSIZE(size, header);
+ size += sizeof(objheader_t);
+ memcpy(objs+offset, header, size);
+ offset += size;
+ }
+#endif
+ if (objlocked > 0) {
+ for(j = 0; j < objlocked; j++) {
+ if((headptr = mhashSearch(oidlocked[j])) == NULL) {
+ printf("mhashSearch returns NULL at %s, %d\n", __FILE__, __LINE__);
+ return 0;
}
-
- return val;
+ UnLock(STATUSPTR(headptr));
+ }
+ free(oidlocked);
+ }
+ send_data(acceptfd, &control, sizeof(char));
+#ifdef CACHE
+ send_data(acceptfd, &numBytes, sizeof(int));
+ send_data(acceptfd, objs, numBytes);
+ transinfo->objvernotmatch = oidvernotmatch;
+ transinfo->numvernotmatch = objvernotmatch;
+ free(objs);
+ free(transinfo->objvernotmatch);
+#endif
+ return control;
+ }
+
+ /* Decide what control message to send to Coordinator */
+ if ((control = decideCtrlMessage(fixed, transinfo, &v_matchnolock, &v_matchlock, &v_nomatch, &objnotfound, &objlocked,
+ modptr, oidnotfound, oidlocked, acceptfd)) == 0) {
+ printf("Error: In decideCtrlMessage() %s, %d\n", __FILE__, __LINE__);
+ return 0;
+ }
+ return control;
}
/* This function decides what control message such as TRANS_AGREE, TRANS_DISAGREE or TRANS_SOFT_ABORT
* to send to Coordinator based on the votes of oids involved in the transaction */
-int decideCtrlMessage(fixed_data_t *fixed, trans_commit_data_t *transinfo, int *v_matchnolock, int *v_matchlock,
- int *v_nomatch, int *objnotfound, int *objlocked, void *modptr,
- unsigned int *oidnotfound, unsigned int *oidlocked, unsigned int *oidmod,
- int acceptfd) {
- int val;
- char control = 0;
- /* Condition to send TRANS_AGREE */
- if(*(v_matchnolock) == fixed->numread + fixed->nummod) {
- control = TRANS_AGREE;
- if((val = send(acceptfd, &control, sizeof(char), MSG_NOSIGNAL)) < sizeof(char)) {
- perror("Error in sending control to Coordinator\n");
- return 0;
- }
- printf("DEBUG -> Sending TRANS_AGREE\n");
- }
- /* Condition to send TRANS_SOFT_ABORT */
- if((*(v_matchlock) > 0 && *(v_nomatch) == 0) || (*(objnotfound) > 0 && *(v_nomatch) == 0)) {
- control = TRANS_SOFT_ABORT;
- char msg[]={TRANS_SOFT_ABORT, 0,0,0,0};
- *((int*)&msg[1])= *(objnotfound);
-
- printf("DEBUG -> Sending TRANS_SOFT_ABORT\n");
- /* Send control message */
- if((val = send(acceptfd, &msg, sizeof(msg),MSG_NOSIGNAL)) < sizeof(msg)) {
- perror("Error in sending no of objects that are not found\n");
- return 0;
- }
- /* Send number of oids not found and the missing oids if objects are missing in the machine */
- if(*(objnotfound) != 0) {
- int size = sizeof(unsigned int)* *(objnotfound);
- if((val = send(acceptfd, oidnotfound, size ,MSG_NOSIGNAL)) < size) {
- perror("Error in sending objects that are not found\n");
- return 0;
- }
- }
- }
-
- /* Fill out the trans_commit_data_t data structure. This is required for a trans commit process
- * if Participant receives a TRANS_COMMIT */
- transinfo->objmod = oidmod;
- transinfo->objlocked = oidlocked;
- transinfo->objnotfound = oidnotfound;
- transinfo->modptr = modptr;
- transinfo->nummod = fixed->nummod;
- transinfo->numlocked = *(objlocked);
- transinfo->numnotfound = *(objnotfound);
-
- return control;
+char decideCtrlMessage(fixed_data_t *fixed, trans_commit_data_t *transinfo, int *v_matchnolock, int *v_matchlock,
+ int *v_nomatch, int *objnotfound, int *objlocked, void *modptr,
+ unsigned int *oidnotfound, unsigned int *oidlocked, int acceptfd) {
+ int val;
+ char control = 0;
+
+ /* Condition to send TRANS_AGREE */
+ if(*(v_matchnolock) == fixed->numread + fixed->nummod) {
+ control = TRANS_AGREE;
+ /* Send control message */
+ send_data(acceptfd, &control, sizeof(char));
+ }
+ /* Condition to send TRANS_SOFT_ABORT */
+ if((*(v_matchlock) > 0 && *(v_nomatch) == 0) || (*(objnotfound) > 0 && *(v_nomatch) == 0)) {
+ control = TRANS_SOFT_ABORT;
+
+ /* Send control message */
+ send_data(acceptfd, &control, sizeof(char));
+
+ /* FIXME how to send objs Send number of oids not found and the missing oids if objects are missing in the machine */
+ if(*(objnotfound) != 0) {
+ int msg[1];
+ msg[0] = *(objnotfound);
+ send_data(acceptfd, &msg, sizeof(int));
+ int size = sizeof(unsigned int)* *(objnotfound);
+ send_data(acceptfd, oidnotfound, size);
+ }
+ }
+
+ /* Fill out the trans_commit_data_t data structure. This is required for a trans commit process
+ * if Participant receives a TRANS_COMMIT */
+ transinfo->objlocked = oidlocked;
+ transinfo->objnotfound = oidnotfound;
+ transinfo->modptr = modptr;
+ transinfo->numlocked = *(objlocked);
+ transinfo->numnotfound = *(objnotfound);
+
+ return control;
}
-/* This function processes all modified objects involved in a TRANS_COMMIT and updates pointer
+/* This function processes all modified objects involved in a TRANS_COMMIT and updates pointer
* addresses in lookup table and also changes version number
* Sends an ACK back to Coordinator */
-int transCommitProcess(trans_commit_data_t *transinfo, int acceptfd) {
- objheader_t *header;
- int i = 0, offset = 0;
- char control;
- /* Process each modified object saved in the mainobject store */
- for(i=0; i<transinfo->nummod; i++) {
- if((header = (objheader_t *) mhashSearch(transinfo->objmod[i])) == NULL) {
- printf("mhashsearch returns NULL at %s, %d\n", __FILE__, __LINE__);
- }
- /* Change reference count of older address and free space in objstr ?? */
- header->rcount = 1; //Not sure what would be the val
-
- /* Change ptr address in mhash table */
- printf("DEBUG -> removing object oid = %d\n", transinfo->objmod[i]);
- mhashRemove(transinfo->objmod[i]);
- mhashInsert(transinfo->objmod[i], (transinfo->modptr + offset));
- offset += sizeof(objheader_t) + classsize[header->type];
-
- /* Update object version number */
- header = (objheader_t *) mhashSearch(transinfo->objmod[i]);
- header->version += 1;
- }
- /* Unlock locked objects */
- for(i=0; i<transinfo->numlocked; i++) {
- header = (objheader_t *) mhashSearch(transinfo->objlocked[i]);
- header->status &= ~(LOCK);
- }
+int transCommitProcess(void *modptr, unsigned int *oidmod, unsigned int *oidlocked, int nummod, int numlocked, int acceptfd) {
+ objheader_t *header;
+ objheader_t *newheader;
+ int i = 0, offset = 0;
+ char control;
+ int tmpsize;
+
+ /* Process each modified object saved in the mainobject store */
+ for(i = 0; i < nummod; i++) {
+ if((header = (objheader_t *) mhashSearch(oidmod[i])) == NULL) {
+ printf("Error: mhashsearch returns NULL at %s, %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+ GETSIZE(tmpsize,header);
+ memcpy((char*)header + sizeof(objheader_t), ((char *)modptr + sizeof(objheader_t) + offset), tmpsize);
+ header->version += 1;
+ /* If threads are waiting on this object to be updated, notify them */
+ if(header->notifylist != NULL) {
+ notifyAll(&header->notifylist, OID(header), header->version);
+ }
+ offset += sizeof(objheader_t) + tmpsize;
+ }
+
+ if (nummod > 0)
+ free(modptr);
+
+ /* Unlock locked objects */
+ for(i = 0; i < numlocked; i++) {
+ if((header = (objheader_t *) mhashSearch(oidlocked[i])) == NULL) {
+ printf("Error: mhashsearch returns NULL at %s, %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+ UnLock(STATUSPTR(header));
+ }
+ //TODO Update location lookup table
+
+ /* Send ack to coordinator */
+ control = TRANS_SUCESSFUL;
+ send_data((int)acceptfd, &control, sizeof(char));
+ return 0;
+}
- //TODO Update location lookup table
+/* This function recevies the oid and offset tuples from the Coordinator's prefetch call.
+ * Looks for the objects to be prefetched in the main object store.
+ * If objects are not found then record those and if objects are found
+ * then use offset values to prefetch references to other objects */
- /* Send ack to coordinator */
- control = TRANS_SUCESSFUL;
- printf("DEBUG-> TRANS_SUCESSFUL\n");
- if(send((int)acceptfd, &control, sizeof(char), MSG_NOSIGNAL) < sizeof(char)) {
- perror("Error sending ACK to coordinator\n");
+int prefetchReq(int acceptfd) {
+ int i, size, objsize, numoffset = 0;
+ int length;
+ char *recvbuffer, control;
+ unsigned int oid, mid=-1;
+ objheader_t *header;
+ oidmidpair_t oidmid;
+ int sd = -1;
+
+ while(1) {
+ recv_data((int)acceptfd, &numoffset, sizeof(int));
+ if(numoffset == -1)
+ break;
+ recv_data((int)acceptfd, &oidmid, 2*sizeof(unsigned int));
+ oid = oidmid.oid;
+ if (mid != oidmid.mid) {
+ if (mid!=-1) {
+ freeSockWithLock(transPResponseSocketPool, mid, sd);
+ }
+ mid=oidmid.mid;
+ sd = getSockWithLock(transPResponseSocketPool, mid);
+ }
+ short offsetarry[numoffset];
+ recv_data((int) acceptfd, offsetarry, numoffset*sizeof(short));
+
+ /*Process each oid */
+ if ((header = mhashSearch(oid)) == NULL) { /* Obj not found */
+ /* Save the oids not found in buffer for later use */
+ size = sizeof(int) + sizeof(char) + sizeof(unsigned int) ;
+ char sendbuffer[size];
+ *((int *) sendbuffer) = size;
+ *((char *)(sendbuffer + sizeof(int))) = OBJECT_NOT_FOUND;
+ *((unsigned int *)(sendbuffer + sizeof(int) + sizeof(char))) = oid;
+ control = TRANS_PREFETCH_RESPONSE;
+ sendPrefetchResponse(sd, &control, sendbuffer, &size);
+ } else { /* Object Found */
+ int incr = 0;
+ GETSIZE(objsize, header);
+ size = sizeof(int) + sizeof(char) + sizeof(unsigned int) + sizeof(objheader_t) + objsize;
+ char sendbuffer[size];
+ *((int *)(sendbuffer + incr)) = size;
+ incr += sizeof(int);
+ *((char *)(sendbuffer + incr)) = OBJECT_FOUND;
+ incr += sizeof(char);
+ *((unsigned int *)(sendbuffer+incr)) = oid;
+ incr += sizeof(unsigned int);
+ memcpy(sendbuffer + incr, header, objsize + sizeof(objheader_t));
+
+ control = TRANS_PREFETCH_RESPONSE;
+ sendPrefetchResponse(sd, &control, sendbuffer, &size);
+
+ /* Calculate the oid corresponding to the offset value */
+ for(i = 0 ; i< numoffset ; i++) {
+ /* Check for arrays */
+ if(TYPE(header) > NUMCLASSES) {
+ int elementsize = classsize[TYPE(header)];
+ struct ArrayObject *ao = (struct ArrayObject *) (((char *)header) + sizeof(objheader_t));
+ unsigned short length = ao->___length___;
+ /* Check if array out of bounds */
+ if(offsetarry[i]< 0 || offsetarry[i] >= length) {
+ break;
+ }
+ oid = *((unsigned int *)(((char *)header) + sizeof(objheader_t) + sizeof(struct ArrayObject) + (elementsize*offsetarry[i])));
+ } else {
+ oid = *((unsigned int *)(((char *)header) + sizeof(objheader_t) + offsetarry[i]));
}
-
- return 0;
+
+ /* Don't continue if we hit a NULL pointer */
+ if (oid==0)
+ break;
+
+ if((header = mhashSearch(oid)) == NULL) {
+ size = sizeof(int) + sizeof(char) + sizeof(unsigned int) ;
+ char sendbuffer[size];
+ *((int *) sendbuffer) = size;
+ *((char *)(sendbuffer + sizeof(int))) = OBJECT_NOT_FOUND;
+ *((unsigned int *)(sendbuffer + sizeof(int) + sizeof(char))) = oid;
+
+ control = TRANS_PREFETCH_RESPONSE;
+ sendPrefetchResponse(sd, &control, sendbuffer, &size);
+ break;
+ } else { /* Obj Found */
+ int incr = 0;
+ GETSIZE(objsize, header);
+ size = sizeof(int) + sizeof(char) + sizeof(unsigned int) + sizeof(objheader_t) + objsize;
+ char sendbuffer[size];
+ *((int *)(sendbuffer + incr)) = size;
+ incr += sizeof(int);
+ *((char *)(sendbuffer + incr)) = OBJECT_FOUND;
+ incr += sizeof(char);
+ *((unsigned int *)(sendbuffer+incr)) = oid;
+ incr += sizeof(unsigned int);
+ memcpy(sendbuffer + incr, header, objsize + sizeof(objheader_t));
+
+ control = TRANS_PREFETCH_RESPONSE;
+ sendPrefetchResponse(sd, &control, sendbuffer, &size);
+ }
+ }
+ }
+ }
+ //Release socket
+ if (mid!=-1)
+ freeSockWithLock(transPResponseSocketPool, mid, sd);
+
+ return 0;
}
-int prefetchReq(int acceptfd) {
- int i, length, sum, n, numbytes, numoffset, N, objnotfound = 0, size, count = 0;
- unsigned int oid, index = 0;
- char *ptr, buffer[PRE_BUF_SIZE];
- void *mobj;
- unsigned int objoid;
- char *header, control;
- objheader_t * head;
-
- /* Repeatedly recv the oid and offset pairs sent for prefetch */
- while(numbytes = recv((int)acceptfd, &length, sizeof(int), 0) != 0) {
- count++;
- if(length == -1)
- break;
- sum = 0;
- index = sizeof(unsigned int); // Index starts with sizeof unsigned int because the
- // first 4 bytes are saved to send the
- // size of the buffer (that is computed at the end of the loop)
- oid = recv((int)acceptfd, &oid, sizeof(unsigned int), 0);
- numoffset = (length - (sizeof(int) + sizeof(unsigned int)))/ sizeof(short);
- N = numoffset * sizeof(short);
- short offset[numoffset];
- ptr = (char *)&offset;
- /* Recv the offset values per oid */
- do {
- n = recv((int)acceptfd, (void *)ptr+sum, N-sum, 0);
- sum += n;
- } while(sum < N && n != 0);
-
- /* Process each oid */
- /* Check if object is still present in the machine since the beginning of TRANS_PREFETCH */
- if ((mobj = mhashSearch(oid)) == NULL) {/* Obj not found */
- /* Save the oids not found in buffer for later use */
- *(buffer + index) = OBJECT_NOT_FOUND;
- index += sizeof(char);
- memcpy(buffer+index, &oid, sizeof(unsigned int));
- index += sizeof(unsigned int);
- } else { /* If Obj found in machine (i.e. has not moved) */
- /* send the oid, it's size, it's header and data */
- header = (char *) mobj;
- head = (objheader_t *) header;
- size = sizeof(objheader_t) + sizeof(classsize[head->type]);
- *(buffer + index) = OBJECT_FOUND;
- index += sizeof(char);
- memcpy(buffer+index, &oid, sizeof(unsigned int));
- index += sizeof(unsigned int);
- memcpy(buffer+index, &size, sizeof(int));
- index += sizeof(int);
- memcpy(buffer + index, header, size);
- index += size;
- /* Calculate the oid corresponding to the offset value */
- for(i = 0 ; i< numoffset ; i++) {
- objoid = *((int *)(header + sizeof(objheader_t) + offset[i]));
- if((header = (char *) mhashSearch(objoid)) == NULL) {
- /* Obj not found, send oid */
- *(buffer + index) = OBJECT_NOT_FOUND;
- index += sizeof(char);
- memcpy(buffer+index, &oid, sizeof(unsigned int));
- index += sizeof(unsigned int);
- break;
- } else {/* Obj Found */
- /* send the oid, it's size, it's header and data */
- head = (objheader_t *) header;
- size = sizeof(objheader_t) + sizeof(classsize[head->type]);
- *(buffer + index) = OBJECT_FOUND;
- index += sizeof(char);
- memcpy(buffer+index, &oid, sizeof(unsigned int));
- index += sizeof(unsigned int);
- memcpy(buffer+index, &size, sizeof(int));
- index += sizeof(int);
- memcpy(buffer + index, header, size);
- index += size;
- continue;
- }
- }
- }
- /* Check for overflow in the buffer */
- if (index >= PRE_BUF_SIZE) {
- printf("Char buffer is overflowing\n");
- return 1;
- }
- /* Send Prefetch response control message only once*/
- if(count == 1) {
- control = TRANS_PREFETCH_RESPONSE;
- if((numbytes = send(acceptfd, &control, sizeof(char), MSG_NOSIGNAL)) < sizeof(char)) {
- perror("Error in sending PREFETCH RESPONSE to Coordinator\n");
- return 1;
- }
- }
-
- /* Add the buffer size into buffer as a parameter */
- memcpy(buffer, &index, sizeof(unsigned int));
- /* Send the entire buffer with its size and oids found and not found */
- if(send((int)acceptfd, &buffer, sizeof(index - 1), MSG_NOSIGNAL) < sizeof(index -1)) {
- perror("Error sending oids found\n");
- return 1;
- }
+void sendPrefetchResponse(int sd, char *control, char *sendbuffer, int *size) {
+ send_data(sd, control, sizeof(char));
+ /* Send the buffer with its size */
+ int length = *(size);
+ send_data(sd, sendbuffer, length);
+}
+
+void processReqNotify(unsigned int numoid, unsigned int *oidarry, unsigned short *versionarry, unsigned int mid, unsigned int threadid) {
+ objheader_t *header;
+ unsigned int oid;
+ unsigned short newversion;
+ char msg[1+ 2 * sizeof(unsigned int) + sizeof(unsigned short)];
+ int sd;
+ struct sockaddr_in remoteAddr;
+ int bytesSent;
+ int size;
+ int i = 0;
+
+ while(i < numoid) {
+ oid = *(oidarry + i);
+ if((header = (objheader_t *) mhashSearch(oid)) == NULL) {
+ printf("Error: mhashsearch returns NULL at %s, %d\n", __FILE__, __LINE__);
+ return;
+ } else {
+ /* Check to see if versions are same */
+checkversion:
+ if (test_and_set(STATUSPTR(header))==0) {
+ //have lock
+ newversion = header->version;
+ if(newversion == *(versionarry + i)) {
+ //Add to the notify list
+ if((header->notifylist = insNode(header->notifylist, threadid, mid)) == NULL) {
+ printf("Error: Obj notify list points to NULL %s, %d\n", __FILE__, __LINE__);
+ return;
+ }
+ UnLock(STATUSPTR(header));
+ } else {
+ UnLock(STATUSPTR(header));
+ if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
+ perror("processReqNotify():socket()");
+ return;
+ }
+ bzero(&remoteAddr, sizeof(remoteAddr));
+ remoteAddr.sin_family = AF_INET;
+ remoteAddr.sin_port = htons(LISTEN_PORT);
+ remoteAddr.sin_addr.s_addr = htonl(mid);
+
+ if (connect(sd, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr)) < 0){
+ printf("Error: processReqNotify():error %d connecting to %s:%d\n", errno,
+ inet_ntoa(remoteAddr.sin_addr), LISTEN_PORT);
+ close(sd);
+ return;
+ } else {
+ //Send Update notification
+ msg[0] = THREAD_NOTIFY_RESPONSE;
+ *((unsigned int *)&msg[1]) = oid;
+ size = sizeof(unsigned int);
+ *((unsigned short *)(&msg[1]+size)) = newversion;
+ size += sizeof(unsigned short);
+ *((unsigned int *)(&msg[1]+size)) = threadid;
+ size = 1+ 2*sizeof(unsigned int) + sizeof(unsigned short);
+ send_data(sd, msg, size);
+ }
+ close(sd);
}
- return 0;
+ } else {
+ randomdelay();
+ goto checkversion;
+ }
+ }
+ i++;
+ }
+ free(oidarry);
+ free(versionarry);
}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "ip.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <string.h>
-
-#define LISTEN_PORT 2156
-
-unsigned int iptoMid(char *addr) {
- ip_t i;
- unsigned int mid;
-
- sscanf(addr, "%d.%d.%d.%d", &i.a, &i.b, &i.c, &i.d);
- mid = (i.a << 24) | (i.b << 16) | (i.c << 8) | i.d;
- fflush(stdout);
- return mid;
-}
-
-void midtoIP(unsigned int mid, char *ptr) {
- ip_t i;
-
- i.a = (mid & 0xff000000) >> 24;
- i.b = (mid & 0x00ff0000) >> 16;
- i.c = (mid & 0x0000ff00) >> 8;
- i.d = mid & 0x000000ff;
- sprintf(ptr, "%d.%d.%d.%d", i.a, i.b, i.c, i.d);
- return;
-}
-
-int checkServer(int mid, char *machineip) {
- int tmpsd;
- struct sockaddr_in serv_addr;
- char m[20];
-
- strncpy(m, machineip, strlen(machineip));
- // Foreach machine you want to transact with
- // check if its up and running
- if ((tmpsd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("");
- return(-1);
- }
- bzero((char*) &serv_addr, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(LISTEN_PORT);
- midtoIP(mid, m);
- m[15] = '\0';
- serv_addr.sin_addr.s_addr = inet_addr(m);
- while (connect(tmpsd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr)) < 0) {
- sleep(1);
- }
- close(tmpsd);
- return 0;
-}
-/*
-main() {
- unsigned int mid;
- ip_t i;
- char ip[16];
-
- memset(ip, 0, 16);
- mid = iptoMid("192.10.0.1");
- printf("mid = %x\n", mid);
- midtoIP(mid, ip);
- ip[15] = '\0';
- printf("%s\n",ip);
-}
-*/
+++ /dev/null
-#ifndef _ip_h_
-#define _ip_h_
-
-typedef struct ip {
- short a;
- short b;
- short c;
- short d;
-}ip_t;
-
-unsigned int iptoMid(char *);
-void midtoIP(unsigned int, char *);
-int checkServer(int, char *);
-
-#endif
+++ /dev/null
-/************************************************************************************************
- IMP NOTE:
- All llookup hash function prototypes returns 0 on sucess and 1 otherwise
- llookup hash is an array of lhashlistnode_t
- oid = mid = 0 in a given lhashlistnode_t for each bin in the hash table ONLY if the entry is empty =>
- the OID's can be any unsigned int except 0
-
- Uses pthreads. compile using -lpthread option
-***************************************************************************************************/
-#include "llookup.h"
-
-lhashtable_t llookup; //Global Hash table
-
-// Creates a hash table with size and an array of lhashlistnode_t
-unsigned int lhashCreate(unsigned int size, float loadfactor) {
- lhashlistnode_t *nodes;
- int i;
-
- // Allocate space for the hash table
- if((nodes = calloc(size, sizeof(lhashlistnode_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return 1;
- }
-
- llookup.table = nodes;
- llookup.size = size;
- llookup.numelements = 0; // Initial number of elements in the hash
- llookup.loadfactor = loadfactor;
- //Initialize the pthread_mutex variable
- pthread_mutex_init(&llookup.locktable, NULL);
- return 0;
-}
-
-// Assign to oids to bins inside hash table
-unsigned int lhashFunction(unsigned int oid) {
- return( oid % (llookup.size));
-}
-
-// Insert oid and mid mapping into the hash table
-unsigned int lhashInsert(unsigned int oid, unsigned int mid) {
- unsigned int newsize;
- int index;
- lhashlistnode_t *ptr, *node;
-
- if (llookup.numelements > (llookup.loadfactor * llookup.size)) {
- //Resize Table
- newsize = 2 * llookup.size + 1;
- pthread_mutex_lock(&llookup.locktable);
- lhashResize(newsize);
- pthread_mutex_unlock(&llookup.locktable);
- }
-
- ptr = llookup.table;
- llookup.numelements++;
-
- index = lhashFunction(oid);
-#ifdef DEBUG
- printf("DEBUG(insert) oid = %d, mid =%d, index =%d\n",oid,mid, index);
-#endif
- pthread_mutex_lock(&llookup.locktable);
- if(ptr[index].next == NULL && ptr[index].oid == 0) { // Insert at the first position in the hashtable
- ptr[index].oid = oid;
- ptr[index].mid = mid;
- } else { // Insert in the linked list
- if ((node = calloc(1, sizeof(lhashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- pthread_mutex_unlock(&llookup.locktable);
- return 1;
- }
- node->oid = oid;
- node->mid = mid;
- node->next = ptr[index].next;
- ptr[index].next = node;
- }
-
- pthread_mutex_unlock(&llookup.locktable);
- return 0;
-}
-
-// Return mid for a given oid in the hash table
-unsigned int lhashSearch(unsigned int oid) {
- int index;
- lhashlistnode_t *ptr, *node;
-
- ptr = llookup.table; // Address of the beginning of hash table
- index = lhashFunction(oid);
- node = &ptr[index];
- pthread_mutex_lock(&llookup.locktable);
- while(node != NULL) {
- if(node->oid == oid) {
- pthread_mutex_unlock(&llookup.locktable);
- return node->mid;
- }
- node = node->next;
- }
- pthread_mutex_unlock(&llookup.locktable);
- return 0;
-}
-
-// Remove an entry from the hash table
-unsigned int lhashRemove(unsigned int oid) {
- int index;
- lhashlistnode_t *curr, *prev;
- lhashlistnode_t *ptr, *node;
-
- ptr = llookup.table;
- index = lhashFunction(oid);
- curr = &ptr[index];
-
- pthread_mutex_lock(&llookup.locktable);
- for (; curr != NULL; curr = curr->next) {
- if (curr->oid == oid) { // Find a match in the hash table
- llookup.numelements--; // Decrement the number of elements in the global hashtable
- if ((curr == &ptr[index]) && (curr->next == NULL)) { // Delete the first item inside the hashtable with no linked list of lhashlistnode_t
- curr->oid = 0;
- curr->mid = 0;
- } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of lhashlistnode_t connected
- curr->oid = curr->next->oid;
- curr->mid = curr->next->mid;
- node = curr->next;
- curr->next = curr->next->next;
- free(node);
- } else { // Regular delete from linked listed
- prev->next = curr->next;
- free(curr);
- }
- pthread_mutex_unlock(&llookup.locktable);
- return 0;
- }
- prev = curr;
- }
- pthread_mutex_unlock(&llookup.locktable);
- return 1;
-}
-
-// Resize table
-unsigned int lhashResize(unsigned int newsize) {
- lhashlistnode_t *node, *ptr, *curr, *next; // curr and next keep track of the current and the next lhashlistnodes in a linked list
- unsigned int oldsize;
- int isfirst; // Keeps track of the first element in the lhashlistnode_t for each bin in hashtable
- int i,index;
- lhashlistnode_t *newnode;
-
- ptr = llookup.table;
- oldsize = llookup.size;
-
- if((node = calloc(newsize, sizeof(lhashlistnode_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return 1;
- }
-
- llookup.table = node; //Update the global hashtable upon resize()
- llookup.size = newsize;
- llookup.numelements = 0;
-
- for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
- curr = &ptr[i];
- isfirst = 1;
- while (curr != NULL) { //Inner loop to go through linked lists
- if (curr->oid == 0) { //Exit inner loop if there the first element for a given bin/index is NULL
- break; //oid = mid =0 for element if not present within the hash table
- }
- next = curr->next;
- index = lhashFunction(curr->oid);
- // Insert into the new table
- if(llookup.table[index].next == NULL && llookup.table[index].oid == 0) {
- llookup.table[index].oid = curr->oid;
- llookup.table[index].mid = curr->mid;
- llookup.numelements++;
- }else {
- if((newnode = calloc(1, sizeof(lhashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
- newnode->oid = curr->oid;
- newnode->mid = curr->mid;
- newnode->next = llookup.table[index].next;
- llookup.table[index].next = newnode;
- llookup.numelements++;
- }
-
- //free the linked list of lhashlistnode_t if not the first element in the hash table
- if (isfirst != 1) {
- free(curr);
- }
-
- isfirst = 0;
- curr = next;
-
- }
- }
-
- free(ptr); //Free the memory of the old hash table
- return 0;
-}
+++ /dev/null
-#ifndef _LLOOKUP_H_
-#define _LLOOKUP_H_
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <pthread.h>
-
-#define LOADFACTOR 0.75
-#define HASH_SIZE 100
-
-typedef struct lhashlistnode {
- unsigned int oid;
- unsigned int mid;
- struct lhashlistnode *next;
-} lhashlistnode_t;
-
-typedef struct lhashtable {
- lhashlistnode_t *table; // points to beginning of hash table
- unsigned int size;
- unsigned int numelements;
- float loadfactor;
- pthread_mutex_t locktable;
-} lhashtable_t;
-
-unsigned int lhashCreate(unsigned int size, float loadfactor);// returns 0 for success and 0 for failure
-unsigned int lhashFunction(unsigned int oid); // returns 0 for success and 0 for failure
-unsigned int lhashInsert(unsigned int oid, unsigned int mid); // returns 0 for success and 0 for failure
-unsigned int lhashSearch(unsigned int oid); //returns mid, 0 if not found
-unsigned int lhashRemove(unsigned int oid); //returns 0 if not success
-unsigned int lhashResize(unsigned int newsize); // returns 0 for success and 0 for failure
-
-#endif
+++ /dev/null
-#include "machinepile.h"
-
-int insertPile(int mid, unsigned int oid, short numoffset, short *offset, prefetchpile_t *head) {
- prefetchpile_t *tmp = head;
- objpile_t *objnode;
- unsigned int *oidarray;
- int ntuples;
- char found = 0;
-
- while (tmp != NULL) {
- if (tmp->mid == mid) { // Found a match with exsisting machine id
- if ((objnode = (objpile_t *) calloc(1, sizeof(objpile_t))) == NULL) {
- printf("Calloc error: %s %d\n", __FILE__, __LINE__);
- return -1;
- }
- /* Fill objpiles DS */
- objnode->oid = oid;
- objnode->numoffset = numoffset;
- objnode->offset = offset;
- objnode->next = tmp->objpiles;
- tmp->objpiles = objnode;
- found = 1;
- break;
- }
- tmp = tmp->next;
- }
- if (!found) {// Not found => insert new mid DS
- if ((tmp = (prefetchpile_t *) calloc(1, sizeof(prefetchpile_t))) == NULL) {
- printf("Calloc error: %s %d\n", __FILE__, __LINE__);
- return -1;
- }
- tmp->mid = mid;
- if ((objnode = (objpile_t *) calloc(1, sizeof(objpile_t))) == NULL) {
- printf("Calloc error: %s %d\n", __FILE__, __LINE__);
- return -1;
- }
- /* Fill objpiles DS */
- objnode->oid = oid;
- objnode->numoffset = numoffset;
- objnode->offset = offset;
- objnode->next = tmp->objpiles; // i.e., objnode->next = NULL;
- tmp->objpiles = objnode;
- tmp->next = head;
- head = tmp;
- }
- return 0;
-}
-
-//TODO
-int deletePile() {
-
- return 0;
-}
+++ /dev/null
-#ifndef _MACHINEPILE_H_
-#define _MACHINEPILE_H_
-
-#include "mcpileq.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-int insertPile(int, unsigned int, short, short *, prefetchpile_t *);
-int deletePile();
-
-#endif
+++ /dev/null
-#include<stdio.h>
-#include<string.h>
-#include<stdlib.h>
-#include "dstm.h"
-
-#define size 1000000
-
-
-obj_addr_table_t mlut;
-int classsize[]={sizeof(int),sizeof(char),sizeof(short), sizeof(void *)};
-
-int main() {
- int i;
-
- dstm_init();
- create_objstr(size);
- createHash(&mlut, HASH_SIZE, 0.75);
-
- for(i=0; i< 4 ; i++) {
- createObject(i);
- }
-
- createObject(3);
- return 0;
-}
+++ /dev/null
-#include "mcpileq.h"
-
-mcpileq_t mcqueue;
-
-void mcpileqInit(void) {
- /* Initialize machine queue that containing prefetch oids and offset values sorted by remote machineid */
- mcqueue.front = mcqueue.rear = NULL;
- pthread_mutex_init(&mcqueue.qlock, NULL);
- pthread_cond_init(&mcqueue.qcond, NULL);
-}
-
-/* Insert to the rear of machine pile queue */
-/*
-void mcpileenqueue(prefetchpile_t *node) {
- if(mcqueue.front == NULL && mcqueue.rear == NULL) {
- mcqueue.front = mcqueue.rear = node;
- } else {
- node->next = NULL;
- mcqueue.rear->next = node;
- mcqueue.rear = node;
- }
-}
-*/
-
-/* Insert to the rear of machine pile queue */
-void mcpileenqueue(prefetchpile_t *node) {
- prefetchpile_t *tmp, *prev;
- if(mcqueue.front == NULL && mcqueue.rear == NULL) {
- tmp = mcqueue.front = node;
- while(tmp != NULL) {
- prev = tmp;
- tmp = tmp->next;
- }
- mcqueue.rear = prev;
- } else {
- tmp = mcqueue.rear->next = node;
- while(tmp != NULL) {
- prev = tmp;
- tmp = tmp->next;
- }
- mcqueue.rear = prev;
- }
-}
-
-/* Return the node pointed to by the front ptr of the queue */
-prefetchpile_t *mcpiledequeue(void) {
- prefetchpile_t *retnode;
- if(mcqueue.front == NULL) {
- printf("Machune pile queue empty: Underfloe %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
- retnode = mcqueue.front;
- mcqueue.front = mcqueue.front->next;
- retnode->next = NULL;
-
- return retnode;
-}
-
-/* Delete the node pointed to by the front ptr of the queue */
-void delnode() {
- prefetchpile_t *delnode;
- if((mcqueue.front == NULL) && (mcqueue.rear == NULL)) {
- printf("The queue is empty: UNDERFLOW %s, %d\n", __FILE__, __LINE__);
- return;
- } else if ((mcqueue.front == mcqueue.rear) && mcqueue.front != NULL && mcqueue.rear != NULL) {
- printf("TEST1\n");
- free(mcqueue.front);
- mcqueue.front = mcqueue.rear = NULL;
- } else {
- delnode = mcqueue.front;
- mcqueue.front = mcqueue.front->next;
- printf("TEST2\n");
- free(delnode);
- }
-}
-
-void mcpiledelete(void) {
- /* Remove each element */
- while(mcqueue.front != NULL)
- delqnode();
- mcqueue.front = mcqueue.rear = NULL;
-}
-
-
-void mcpiledisplay() {
- int mid;
-
- prefetchpile_t *tmp = mcqueue.front;
- while(tmp != NULL) {
- printf("Remote machine id = %d\n", tmp->mid);
- tmp = tmp->next;
- }
-}
-
-void mcdealloc(prefetchpile_t *node) {
- /* Remove the offset ptr and linked lists of objpile_t */
- objpile_t *delnode;
- while(node->objpiles != NULL) {
- node->objpiles->offset = NULL;
- delnode = node->objpiles;
- node->objpiles = node->objpiles->next;
- free(delnode);
- node->objpiles->next = NULL;
- }
- free(node);
- node->next = NULL;
-}
+++ /dev/null
-#ifndef _MCPILEQ_H_
-#define _MCPILEQ_H_
-
-#include<pthread.h>
-#include<stdio.h>
-#include<stdlib.h>
-#include<string.h>
-
-//Structure to make machine groups when prefetching
-typedef struct objpile {
- unsigned int oid;
- short numoffset;
- short *offset;
- struct objpile *next;
-}objpile_t;
-
-//Structure for prefetching tuples generated by the compiler
-typedef struct prefetchpile {
- int mid;
- objpile_t *objpiles;
- struct prefetchpile *next;
-}prefetchpile_t;
-
-typedef struct mcpileq {
- prefetchpile_t *front, *rear;
- pthread_mutex_t qlock;
- pthread_cond_t qcond;
-}mcpileq_t;
-
-void mcpileqInit(void);
-void mcpileenqueue(prefetchpile_t *);
-prefetchpile_t *mcpiledequeue(void);
-void delnode();
-void mcpiledelete();
-void mcpiledisplay();
-void mcdealloc(prefetchpile_t *);
-
-#endif
+++ /dev/null
-#include "mlookup.h"
-
-mhashtable_t mlookup; //Global hash table
-
-// Creates a machine lookup table with size =" size"
-unsigned int mhashCreate(unsigned int size, float loadfactor) {
- mhashlistnode_t *nodes;
- int i;
-
- // Allocate space for the hash table
- if((nodes = calloc(size, sizeof(mhashlistnode_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return 1;
- }
-
- mlookup.table = nodes;
- mlookup.size = size;
- mlookup.numelements = 0; // Initial number of elements in the hash
- mlookup.loadfactor = loadfactor;
- //Initialize the pthread_mutex variable
- pthread_mutex_init(&mlookup.locktable, NULL);
- return 0;
-}
-
-// Assign to keys to bins inside hash table
-unsigned int mhashFunction(unsigned int key) {
- return( key % (mlookup.size));
-}
-
-// Insert value and key mapping into the hash table
-unsigned int mhashInsert(unsigned int key, void *val) {
- unsigned int newsize;
- int index;
- mhashlistnode_t *ptr, *node;
-
- if (mlookup.numelements > (mlookup.loadfactor * mlookup.size)) {
- //Resize Table
- newsize = 2 * mlookup.size + 1;
- pthread_mutex_lock(&mlookup.locktable);
- mhashResize(newsize);
- pthread_mutex_unlock(&mlookup.locktable);
- }
- ptr = mlookup.table;
- mlookup.numelements++;
-
- index = mhashFunction(key);
-#ifdef DEBUG
- printf("DEBUG -> index = %d, key = %d, val = %x\n", index, key, val);
-#endif
- pthread_mutex_lock(&mlookup.locktable);
- if(ptr[index].next == NULL && ptr[index].key == 0) { // Insert at the first position in the hashtable
- ptr[index].key = key;
- ptr[index].val = val;
- } else { // Insert in the beginning of linked list
- if ((node = calloc(1, sizeof(mhashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- pthread_mutex_unlock(&mlookup.locktable);
- return 1;
- }
- node->key = key;
- node->val = val ;
- node->next = ptr[index].next;
- ptr[index].next = node;
- }
- pthread_mutex_unlock(&mlookup.locktable);
- return 0;
-}
-
-// Return val for a given key in the hash table
-void *mhashSearch(unsigned int key) {
- int index;
- mhashlistnode_t *ptr, *node;
-
- ptr = mlookup.table; // Address of the beginning of hash table
- index = mhashFunction(key);
- node = &ptr[index];
- pthread_mutex_lock(&mlookup.locktable);
- while(node != NULL) {
- if(node->key == key) {
- pthread_mutex_unlock(&mlookup.locktable);
- return node->val;
- }
- node = node->next;
- }
- pthread_mutex_unlock(&mlookup.locktable);
- return NULL;
-}
-
-// Remove an entry from the hash table
-unsigned int mhashRemove(unsigned int key) {
- int index;
- mhashlistnode_t *curr, *prev;
- mhashlistnode_t *ptr, *node;
-
- ptr = mlookup.table;
- index = mhashFunction(key);
- curr = &ptr[index];
-
- pthread_mutex_lock(&mlookup.locktable);
- for (; curr != NULL; curr = curr->next) {
- if (curr->key == key) { // Find a match in the hash table
- mlookup.numelements--; // Decrement the number of elements in the global hashtable
- if ((curr == &ptr[index]) && (curr->next == NULL)) { // Delete the first item inside the hashtable with no linked list of mhashlistnode_t
- curr->key = 0;
- curr->val = NULL;
- } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of mhashlistnode_t connected
- curr->key = curr->next->key;
- curr->val = curr->next->val;
- node = curr->next;
- curr->next = curr->next->next;
- free(node);
- } else { // Regular delete from linked listed
- prev->next = curr->next;
- free(curr);
- }
- pthread_mutex_unlock(&mlookup.locktable);
- return 0;
- }
- prev = curr;
- }
- pthread_mutex_unlock(&mlookup.locktable);
- return 1;
-}
-
-// Resize table
-unsigned int mhashResize(unsigned int newsize) {
- mhashlistnode_t *node, *ptr, *curr, *next; // curr and next keep track of the current and the next mhashlistnodes in a linked list
- unsigned int oldsize;
- int isfirst; // Keeps track of the first element in the mhashlistnode_t for each bin in hashtable
- int i,index;
- mhashlistnode_t *newnode;
-
- ptr = mlookup.table;
- oldsize = mlookup.size;
-
- if((node = calloc(newsize, sizeof(mhashlistnode_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return 1;
- }
-
- mlookup.table = node; //Update the global hashtable upon resize()
- mlookup.size = newsize;
- mlookup.numelements = 0;
-
- for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
- curr = &ptr[i];
- isfirst = 1;
- while (curr != NULL) { //Inner loop to go through linked lists
- if (curr->key == 0) { //Exit inner loop if there the first element for a given bin/index is NULL
- break; //key = val =0 for element if not present within the hash table
- }
- next = curr->next;
-
- index = mhashFunction(curr->key);
-#ifdef DEBUG
- printf("DEBUG(resize) -> index = %d, key = %d, val = %x\n", index, curr->key, curr->val);
-#endif
- // Insert into the new table
- if(mlookup.table[index].next == NULL && mlookup.table[index].key == 0) {
- mlookup.table[index].key = curr->key;
- mlookup.table[index].val = curr->val;
- mlookup.numelements++;
- }else {
- if((newnode = calloc(1, sizeof(mhashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
- newnode->key = curr->key;
- newnode->val = curr->val;
- newnode->next = mlookup.table[index].next;
- mlookup.table[index].next = newnode;
- mlookup.numelements++;
- }
-
- //free the linked list of mhashlistnode_t if not the first element in the hash table
- if (isfirst != 1) {
- free(curr);
- }
-
- isfirst = 0;
- curr = next;
-
- }
- }
-
- free(ptr); //Free the memory of the old hash table
- return 0;
-}
-
-unsigned int *mhashGetKeys(unsigned int *numKeys)
-{
- unsigned int *keys;
- int i, keyindex;
- mhashlistnode_t *curr;
-
- pthread_mutex_lock(&mlookup.locktable);
-
- *numKeys = mlookup.numelements;
- keys = calloc(*numKeys, sizeof(unsigned int));
-
- keyindex = 0;
- for (i = 0; i < mlookup.size; i++)
- {
- if (mlookup.table[i].key != 0)
- {
- curr = &mlookup.table[i];
- while (curr != NULL)
- {
- keys[keyindex++] = curr->key;
- curr = curr->next;
- }
- }
- }
-
- if (keyindex != *numKeys)
- printf("mhashGetKeys(): WARNING: incorrect mlookup.numelements value!\n");
-
- pthread_mutex_unlock(&mlookup.locktable);
- return keys;
-}
-
+++ /dev/null
-#ifndef _MLOOKUP_H_
-#define _MLOOKUP_H_
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <pthread.h>
-
-#define LOADFACTOR 0.75
-#define HASH_SIZE 100
-
-typedef struct mhashlistnode {
- unsigned int key;
- void *val; //this can be cast to another type or used to point to a larger structure
- struct mhashlistnode *next;
-} mhashlistnode_t;
-
-typedef struct mhashtable {
- mhashlistnode_t *table; // points to beginning of hash table
- unsigned int size;
- unsigned int numelements;
- float loadfactor;
- pthread_mutex_t locktable;
-} mhashtable_t;
-
-unsigned int mhashCreate(unsigned int size, float loadfactor);
-unsigned int mhashFunction(unsigned int key);
-unsigned mhashInsert(unsigned int key, void *val);
-void *mhashSearch(unsigned int key); //returns val, NULL if not found
-unsigned int mhashRemove(unsigned int key); //returns -1 if not found
-unsigned int mhashResize(unsigned int newsize);
-unsigned int *mhashGetKeys(unsigned int *numKeys);
-void mhashPrint();
-
-#endif
-
+++ /dev/null
-#include "dstm.h"
-
-objstr_t *objstrCreate(unsigned int size)
-{
- objstr_t *tmp = malloc(sizeof(objstr_t) + size);
- tmp->size = size;
- tmp->top = tmp + 1; //points to end of objstr_t structure!
- return tmp;
-}
-
-//free entire list, starting at store
-void objstrDelete(objstr_t *store)
-{
- objstr_t *tmp;
- while (store != NULL)
- {
- tmp = store->next;
- free(store);
- store = tmp;
- }
- return;
-}
-
-void *objstrAlloc(objstr_t *store, unsigned int size)
-{
- void *tmp;
- while (1)
- {
- if (((unsigned int)store->top - (unsigned int)store - sizeof(objstr_t) + size) <= store->size)
- { //store not full
- tmp = store->top;
- store->top += size;
- return tmp;
- }
- //store full
- if (store->next == NULL)
- { //end of list, all full
- if (size > DEFAULT_OBJ_STORE_SIZE) //in case of large objects
- {
- store->next = (objstr_t *)malloc(sizeof(objstr_t) + size);
- store = store->next;
- store->size = size;
- }
- else
- {
- store->next = malloc(sizeof(objstr_t) + DEFAULT_OBJ_STORE_SIZE);
- store = store->next;
- store->size = DEFAULT_OBJ_STORE_SIZE;
- }
- store->top = (void *)((unsigned int)store + sizeof(objstr_t) + size);
- return (void *)((unsigned int)store + sizeof(objstr_t));
- }
- else //try the next one
- store = store->next;
- }
-}
-
+++ /dev/null
-#include "plookup.h"
-extern int classsize[];
-
-plistnode_t *pCreate(int objects) {
- plistnode_t *pile;
-
- //Create main structure
- if((pile = calloc(1, sizeof(plistnode_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
- pile->next = NULL;
- if ((pile->oidmod = calloc(objects, sizeof(unsigned int))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
- if ((pile->oidread = calloc(objects, sizeof(unsigned int))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
- pile->nummod = pile->numread = pile->sum_bytes = 0;
- if ((pile->objread = calloc(objects, sizeof(int) + sizeof(short))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
- pile->objmodified = NULL;
- pile->nummod = pile->numread = pile->sum_bytes = 0;
-
- return pile;
-}
-
-plistnode_t *pInsert(plistnode_t *pile, objheader_t *headeraddr, unsigned int mid, int num_objs) {
- plistnode_t *ptr, *tmp;
- int found = 0, offset;
-
- tmp = pile;
- //Add oid into a machine that is a part of the pile linked list structure
- while(tmp != NULL) {
- if (tmp->mid == mid) {
- if ((headeraddr->status & DIRTY) == 1) {
- tmp->oidmod[tmp->nummod] = headeraddr->oid;
- tmp->nummod = tmp->nummod + 1;
- tmp->sum_bytes += sizeof(objheader_t) + classsize[headeraddr->type];
- } else {
- tmp->oidread[tmp->numread] = headeraddr->oid;
- offset = (sizeof(unsigned int) + sizeof(short)) * tmp->numread;
- memcpy(tmp->objread + offset, &headeraddr->oid, sizeof(unsigned int));
- offset += sizeof(unsigned int);
- memcpy(tmp->objread + offset, &headeraddr->version, sizeof(short));
- tmp->numread = tmp->numread + 1;
- // printf("DEBUG->pInsert() No of obj read = %d\n", tmp->numread);
- }
- found = 1;
- break;
- }
- tmp = tmp->next;
- }
- //Add oid for any new machine
- if (!found) {
- if((ptr = pCreate(num_objs)) == NULL) {
- return NULL;
- }
- ptr->mid = mid;
- if ((headeraddr->status & DIRTY) == 1) {
- ptr->oidmod[ptr->nummod] = headeraddr->oid;
- ptr->nummod = ptr->nummod + 1;
- ptr->sum_bytes += sizeof(objheader_t) + classsize[headeraddr->type];
- } else {
- ptr->oidread[ptr->numread] = headeraddr->oid;
- memcpy(ptr->objread, &headeraddr->oid, sizeof(unsigned int));
- memcpy(ptr->objread + sizeof(unsigned int), &headeraddr->version, sizeof(short));
- ptr->numread = ptr->numread + 1;
- }
- ptr->next = pile;
- pile = ptr;
- }
-
- return pile;
-}
-
-//Count the number of machine groups
-int pCount(plistnode_t *pile) {
- plistnode_t *tmp;
- int pcount = 0;
- tmp = pile;
- while(tmp != NULL) {
- pcount++;
- tmp = tmp->next;
- }
- return pcount;
-}
-
-//Make a list of mid's for each machine group
-int pListMid(plistnode_t *pile, unsigned int *list) {
- int i = 0;
- plistnode_t *tmp;
- tmp = pile;
- while (tmp != NULL) {
- list[i] = tmp->mid;
- i++;
- tmp = tmp->next;
- }
- return 0;
-}
-
-//Delete the entire pile
-void pDelete(plistnode_t *pile) {
- plistnode_t *next, *tmp;
- tmp = pile;
- while(tmp != NULL) {
- next = tmp->next;
- free(tmp->oidmod);
- free(tmp->oidread);
- free(tmp->objread);
- free(tmp);
- tmp = next;
- }
- return;
-}
+++ /dev/null
-#ifndef _PLOOKUP_H_
-#define _PLOOKUP_H_
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "dstm.h"
-
-typedef struct plistnode {
- unsigned int mid;
- int local; /*Variable that keeps track if this pile is for LOCAL machine */
- unsigned int *oidmod;
- unsigned int *oidread;
- int nummod;
- int numread;
- int sum_bytes;
- char *objread;
- char *objmodified;
- int vote;
- struct plistnode *next;
-} plistnode_t;
-
-plistnode_t *pCreate(int);
-plistnode_t *pInsert(plistnode_t *pile, objheader_t *headeraddr, unsigned int mid, int num_objs);
-int pCount(plistnode_t *pile);
-int pListMid(plistnode_t *pile, unsigned int *list);
-void pDelete(plistnode_t *pile);
-
-#endif
-
+++ /dev/null
-#include "dstm.h"
-
-/* Make a queue of prefetchpile_t type */
-prefetchpile_t poolqueue; //Global queue for machine piles
-
-/* Create new machine group */
-prefetchpile_t *createPile(int numoffsets) {
- prefetchpile_t *pile;
- if((pile = calloc(1, sizeof(prefetchpile_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
-
- /* Create a new object pile */
- if((pile->objpiles = calloc(1, sizeof(objpile_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
-
- /* Create a ptr to the offset array for a given prefetch oid tuple */
- if((pile->objpiles->offset = calloc(numoffsets, sizeof(short))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
-
- pile->next = NULL;
-
- return pile;
-}
-
-/* Into into prefetch pile*/
-void pileIns(prefetchpile_t *pile, short *endoffsets, short* arryfields, unsigned int *oid,int mnum,int noffsets, int index) {
- prefetchpile_t *tmp, *ptr;
- objpile_t *opile;
- short *offsetarry;
- int found = 0, k;
-
- tmp = pile;
- while(tmp != NULL) {
- //Check if mnum already exists in the pile
- if(tmp->mid == mnum) {
- /* Create a new object pile */
- if((opile = calloc(1, sizeof(objpile_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
- opile->next = tmp->objpiles;
- tmp->objpiles = opile;
-
- tmp->objpiles->oid = oid[index];
- if(index == 0)
- k = 0;
- else
- k = endoffsets[index -1];
- //Copy the offset values into objpile
- for(i = 0; i < numoffsets[i]; i++) {
- ptr->objpile->offsets[i] = arryfields[k];
- k++;
- }
- /* Create a ptr to the offset array for a given prefetch oid tuple */
- if((offsetarry = calloc(numoffsets, sizeof(short))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return NULL;
- }
-
-
- found = 1;
- break;
- }
- tmp = tmp->next;
- }
-
- //Add New machine pile to the linked list
- if(!found) {
- if((ptr = createPile(noffsets)) == NULL) {
- printf("No new pile created %s %d\n", __FILE__, __LINE__);
- return;
- }
- ptr->mid = mnum;
- ptr->objpile->oid = oid[index];
- if(index == 0)
- k = 0;
- else
- k = endoffsets[index -1];
- //Copy the offset values into objpile
- for(i = 0; i < numoffsets[i]; i++) {
- ptr->objpile->offsets[i] = arryfields[k];
- k++;
- }
- ptr->next = pile;
- pile = ptr;
- }
-
- return pile;
-}
-
-/* Insert into object pile */
-
-
+++ /dev/null
- #include "prelookup.h"
-
-prehashtable_t pflookup; //Global prefetch cache table
-
-unsigned int prehashCreate(unsigned int size, float loadfactor) {
- prehashlistnode_t *nodes;
- int i;
-
- // Allocate space for the hash table
- if((nodes = calloc(size, sizeof(prehashlistnode_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return 1;
- }
-
- pflookup.table = nodes;
- pflookup.size = size;
- pflookup.numelements = 0; // Initial number of elements in the hash
- pflookup.loadfactor = loadfactor;
-
- //Initialize mutex var
- pthread_mutex_init(&pflookup.lock, NULL);
-
- return 0;
-}
-
-//Assign keys to bins inside hash table
-unsigned int prehashFunction(unsigned int key) {
- return ( key % (pflookup.size));
-}
-
-//Store oids and their pointers into hash
-unsigned int prehashInsert(unsigned int key, void *val) {
- unsigned int newsize;
- int index;
- prehashlistnode_t *ptr, *node;
-
- if(pflookup.numelements > (pflookup.loadfactor * pflookup.size)) {
- //Resize
- newsize = 2 * pflookup.size + 1;
- pthread_mutex_lock(&pflookup.lock);
- prehashResize(newsize);
- pthread_mutex_unlock(&pflookup.lock);
- }
-
- ptr = pflookup.table;
- pflookup.numelements++;
- index = prehashFunction(key);
-
- pthread_mutex_lock(&pflookup.lock);
- if(ptr[index].next == NULL && ptr[index].key == 0) { // Insert at the first position in the hashtable
- ptr[index].key = key;
- ptr[index].val = val;
- } else { // Insert in the beginning of linked list
- if ((node = calloc(1, sizeof(prehashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- pthread_mutex_unlock(&pflookup.lock);
- return 1;
- }
- node->key = key;
- node->val = val ;
- node->next = ptr[index].next;
- ptr[index].next = node;
- }
- pthread_mutex_unlock(&pflookup.lock);
- return 0;
-}
-
-// Search for an address for a given oid
-void *prehashSearch(unsigned int key) {
- int index;
- prehashlistnode_t *ptr, *node;
-
- ptr = pflookup.table;
- index = prehashFunction(key);
- node = &ptr[index];
- pthread_mutex_lock(&pflookup.lock);
- while(node != NULL) {
- if(node->key == key) {
- pthread_mutex_unlock(&pflookup.lock);
- return node->val;
- }
- node = node->next;
- }
- pthread_mutex_unlock(&pflookup.lock);
- return NULL;
-}
-
-unsigned int prehashRemove(unsigned int key) {
- int index;
- prehashlistnode_t *curr, *prev;
- prehashlistnode_t *ptr, *node;
-
- ptr = pflookup.table;
- index = prehashFunction(key);
- curr = &ptr[index];
-
- pthread_mutex_lock(&pflookup.lock);
- for (; curr != NULL; curr = curr->next) {
- if (curr->key == key) { // Find a match in the hash table
- pflookup.numelements--; // Decrement the number of elements in the global hashtable
- if ((curr == &ptr[index]) && (curr->next == NULL)) { // Delete the first item inside the hashtable with no linked list of prehashlistnode_t
- curr->key = 0;
- curr->val = NULL;
- } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of prehashlistnode_t connected
- curr->key = curr->next->key;
- curr->val = curr->next->val;
- node = curr->next;
- curr->next = curr->next->next;
- free(node);
- } else { // Regular delete from linked listed
- prev->next = curr->next;
- free(curr);
- }
- pthread_mutex_unlock(&pflookup.lock);
- return 0;
- }
- prev = curr;
- }
- pthread_mutex_unlock(&pflookup.lock);
- return 1;
-}
-
-unsigned int prehashResize(unsigned int newsize) {
- prehashlistnode_t *node, *ptr, *curr, *next; // curr and next keep track of the current and the next chashlistnodes in a linked list
- unsigned int oldsize;
- int isfirst; // Keeps track of the first element in the prehashlistnode_t for each bin in hashtable
- int i,index;
- prehashlistnode_t *newnode;
-
- ptr = pflookup.table;
- oldsize = pflookup.size;
-
- if((node = calloc(newsize, sizeof(prehashlistnode_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return 1;
- }
-
- pflookup.table = node; //Update the global hashtable upon resize()
- pflookup.size = newsize;
- pflookup.numelements = 0;
-
- for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
- curr = &ptr[i];
- isfirst = 1;
- while (curr != NULL) { //Inner loop to go through linked lists
- if (curr->key == 0) { //Exit inner loop if there the first element for a given bin/index is NULL
- break; //key = val =0 for element if not present within the hash table
- }
- next = curr->next;
- index = prehashFunction(curr->key);
- // Insert into the new table
- if(pflookup.table[index].next == NULL && pflookup.table[index].key == 0) {
- pflookup.table[index].key = curr->key;
- pflookup.table[index].val = curr->val;
- pflookup.numelements++;
- }else {
- if((newnode = calloc(1, sizeof(prehashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
- newnode->key = curr->key;
- newnode->val = curr->val;
- newnode->next = pflookup.table[index].next;
- pflookup.table[index].next = newnode;
- pflookup.numelements++;
- }
-
- //free the linked list of prehashlistnode_t if not the first element in the hash table
- if (isfirst != 1) {
- free(curr);
- }
-
- isfirst = 0;
- curr = next;
- }
- }
-
- free(ptr); //Free the memory of the old hash table
- return 0;
-}
-
-/* Deletes the prefetch Cache */
-void prehashDelete() {
- int i, isFirst;
- prehashlistnode_t *ptr, *curr, *next;
- ptr = pflookup.table;
-
- for(i=0 ; i<pflookup.size ; i++) {
- curr = &ptr[i];
- isFirst = 1;
- while(curr != NULL) {
- next = curr->next;
- if(isFirst != 1) {
- free(curr);
- }
- isFirst = 0;
- curr = next;
- }
- }
-
- free(ptr);
-}
+++ /dev/null
-#ifndef _PRELOOKUP_H_
-#define _PRELOOKUP_H_
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <pthread.h>
-
-#define LOADFACTOR 0.75
-#define HASH_SIZE 100
-
-typedef struct prehashlistnode {
- unsigned int key;
- void *val; //this can be cast to another type or used to point to a larger structure
- struct prehashlistnode *next;
-} prehashlistnode_t;
-
-typedef struct prehashtable {
- prehashlistnode_t *table; // points to beginning of hash table
- unsigned int size;
- unsigned int numelements;
- float loadfactor;
- pthread_mutex_t lock;
- pthread_cond_t cond;
-} prehashtable_t;
-
-/* Prototypes for hash*/
-unsigned int prehashCreate(unsigned int size, float loadfactor);
-unsigned int prehashFunction(unsigned int key);
-unsigned int prehashInsert(unsigned int key, void *val);
-void *prehashSearch(unsigned int key); //returns val, NULL if not found
-unsigned int prehashRemove(unsigned int key); //returns -1 if not found
-unsigned int prehashResize(unsigned int newsize);
-/* end hash */
-
-#endif
-
+++ /dev/null
-#include "queue.h"
-
-primarypfq_t pqueue; //Global queue
-
-void queueInit(void) {
- /* Intitialize primary queue */
- pqueue.front = pqueue.rear = NULL;
- pthread_mutex_init(&pqueue.qlock, NULL);
- pthread_cond_init(&pqueue.qcond, NULL);
-}
-
-/* Delete the node pointed to by the front ptr of the queue */
-void delqnode() {
- prefetchqelem_t *delnode;
- if((pqueue.front == NULL) && (pqueue.rear == NULL)) {
- printf("The queue is empty: UNDERFLOW %s, %d\n", __FILE__, __LINE__);
- return;
- } else if ((pqueue.front == pqueue.rear) && pqueue.front != NULL && pqueue.rear != NULL) {
- printf("TEST1\n");
- free(pqueue.front);
- pqueue.front = pqueue.rear = NULL;
- } else {
- delnode = pqueue.front;
- pqueue.front = pqueue.front->next;
- printf("TEST2\n");
- free(delnode);
- }
-}
-
-void queueDelete(void) {
- /* Remove each element */
- while(pqueue.front != NULL)
- delqnode();
- pqueue.front = pqueue.rear = NULL;
-}
-
-/* Inserts to the rear of primary prefetch queue */
-void enqueue(prefetchqelem_t *qnode) {
- if(pqueue.front == NULL && pqueue.rear == NULL) {
- pqueue.front = pqueue.rear = qnode;
- } else {
- qnode->next = NULL;
- pqueue.rear->next = qnode;
- pqueue.rear = qnode;
- }
-}
-
-/* Return the node pointed to by the front ptr of the queue */
-prefetchqelem_t *dequeue(void) {
- prefetchqelem_t *retnode;
- if (pqueue.front == NULL) {
- printf("Queue empty: Underflow %s, %d\n", __FILE__, __LINE__);
- return NULL;
- }
- retnode = pqueue.front;
- pqueue.front = pqueue.front->next;
-
- return retnode;
-}
-
-void queueDisplay() {
- int offset = sizeof(prefetchqelem_t);
- int *ptr;
- int ntuples;
- char *ptr1;
- prefetchqelem_t *tmp = pqueue.front;
- while(tmp != NULL) {
- ptr1 = (char *) tmp;
- ptr = (int *)(ptr1 + offset);
- ntuples = *ptr;
- printf("Number of tuples = %d\n", ntuples);
- tmp = tmp->next;
- }
-}
-
-void predealloc(prefetchqelem_t *node) {
- free(node);
- node->next = NULL;
-}
-
-
-#if 0
-main() {
- unsigned int oids[] = {11, 13};
- short endoffsets[] = {2, 5};
- short arrayfields[] = {2, 2, 1, 5, 6};
- queueInit();
- queueDisplay();
- prefetch(2, oids, endoffsets, arrayfields);
- queueDisplay();
- unsigned int oids1[] = {21, 23, 25, 27};
- short endoffsets1[] = {1, 2, 3, 4};
- short arrayfields1[] = {3, 2, 1, 3};
- prefetch(4, oids1, endoffsets1, arrayfields1);
- queueDisplay();
- delqnode();
- queueDisplay();
- delqnode();
- queueDisplay();
- delqnode();
- queueDisplay();
- delqnode();
-
-}
-
-#endif
-
-
+++ /dev/null
-#ifndef _QUEUE_H_
-#define _QUEUE_H_
-
-#include<stdio.h>
-#include<stdlib.h>
-#include<pthread.h>
-#include<string.h>
-
-// DS that contains information to be shared between threads.
-typedef struct prefetchqelem {
- struct prefetchqelem *next;
-} prefetchqelem_t;
-
-typedef struct primarypfq {
- prefetchqelem_t *front, *rear;
- pthread_mutex_t qlock;
- pthread_cond_t qcond;
-} primarypfq_t;
-
-
-void queueInit(void);
-void delqnode();
-void queueDelete(void);
-void enqueue(prefetchqelem_t *);
-prefetchqelem_t *dequeue(void);
-void queueDisplay();
-void predealloc(prefetchqelem_t *);
-#endif
+++ /dev/null
-#include<stdio.h>
-#include<pthread.h>
-#include "dstm.h"
-#include "llookup.h"
-#include "ip.h"
-
-#define LISTEN_PORT 2156
-
-extern objstr_t *mainobjstore;
-
-int classsize[]={sizeof(int),sizeof(char),sizeof(short), sizeof(void *)};
-
-unsigned int createObjects(transrecord_t *record) {
- objheader_t *header, *tmp;
- unsigned int size, mid;
- int i = 0;
- for(i = 20 ; i< 23; i++) {
- size = sizeof(objheader_t) + classsize[i-20] ;
- tmp = (objheader_t *)objstrAlloc(record->cache, size);
- tmp->oid = i;
- tmp->type = (i-20);
- tmp->version = 1;
- tmp->rcount = 0; //? not sure how to handle this yet
- tmp->status = 0;
- tmp->status |= NEW;
- chashInsert(record->lookupTable, tmp->oid, tmp);
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- memcpy(header, tmp, size);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");//machine d-2
- printf("DEBUG -> createObjects mid is %x\n", mid);
- lhashInsert(header->oid, mid);
- }
- // printf("Insert oid = %d at address %x\n",tmp->oid, tmp);
- size = sizeof(objheader_t) + classsize[0] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 30;
- header->type = 0;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 28;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= LOCK;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 29;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= LOCK;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
- return 0;
-}
-
-int main()
-{
-// test2();
-// test3();
-// test4();
- test5();
-// test5a();
-// test2a();
-// test2b();
-// test7();
-
-}
-
-int test1(void) {
-
- transrecord_t *record;
- objheader_t *h1,*h2,*h3,*h4,*h5, *h6;
-
- dstmInit();
- record = transStart();
- printf("DEBUG -> Init done\n");
- h1 = transRead(record, 1);
- printf("oid = %d\tsize = %d\n", h1->oid,classsize[h1->type]);
- h3 = transRead(record, 3);
- printf("oid = %d\tsize = %d\n", h3->oid,classsize[h3->type]);
- h4 = transRead(record, 4);
- printf("oid = %d\tsize = %d\n", h4->oid,classsize[h4->type]);
- h2 = transRead(record, 2);
- printf("oid = %d\tsize = %d\n", h2->oid,classsize[h2->type]);
- h4 = transRead(record, 4);
- printf("oid = %d\tsize = %d\n", h4->oid,classsize[h4->type]);
- h3 = transRead(record, 3);
- printf("oid = %d\tsize = %d\n", h3->oid,classsize[h3->type]);
- h5 = transRead(record, 5);
- printf("oid = %d\tsize = %d\n", h5->oid,classsize[h5->type]);
-// getRemoteObj(&record, 0,1);
-}
-
-int test2(void) {
-
- transrecord_t *record;
- objheader_t *h1,*h2,*h3,*h4,*h5, *h6;
-
- dstmInit();
- record = transStart();
-
- lhashInsert(1,1);
- lhashInsert(2,1);
- lhashInsert(3,1);
- lhashInsert(4,1);
- lhashInsert(5,1);
- lhashInsert(6,1);
- printf("DEBUG -> Init done\n");
- h1 = transRead(record, 1);
- lhashInsert(h1->oid, 1);
- h2 = transRead(record, 2);
- lhashInsert(h2->oid, 1);
- h3 = transRead(record, 3);
- lhashInsert(h3->oid, 1);
- h4 = transRead(record, 4);
- lhashInsert(h4->oid, 1);
-// h4->status |= DIRTY;
- h5 = transRead(record, 5);
- lhashInsert(h5->oid, 1);
- h6 = transRead(record, 6);
- lhashInsert(h6->oid, 1);
-// h6->status |= DIRTY;
-
- transCommit(record);
-
- return 0;
-}
-
-//Read objects when objects are found in remote location
-int test2a(void) {
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 22
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 22;
- header->type = 3;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.200.9.26"); //d-1.eecs.uci.edu
- lhashInsert(31, mid);
- lhashInsert(32, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.200.9.26");
- //Check if machine d-1 is up and running
- checkServer(mid, "128.200.9.26");
-
- // Start Transaction
- myTrans = transStart();
-
- sleep(2);
- //read object 1
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 2
- if((h2 = transRead(myTrans, 2)) == NULL) {
- printf("Object not found\n");
- }
-
- pthread_join(thread_Listen, NULL);
- return 0;
-}
-
-//Read objects that are both remote and local and are available on machines
-int test2b(void) {
-
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2, *h3, *h4;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 22
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 22;
- header->type = 3;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.200.9.26"); //d-1.eecs.uci.edu
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.200.9.26");
- //Check if machine d-1 is up and running
- checkServer(mid, "128.200.9.26");
-
- // Start Transaction
- myTrans = transStart();
-
- //sleep(2);
- //read object 1 (found on demksy)
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 2 (found on demsky)
- if((h2 = transRead(myTrans, 2)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 21 (found on local)
- if((h3 = transRead(myTrans, 21)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 32 (found on d-1)
- if((h4 = transRead(myTrans, 32)) == NULL) {
- printf("Object not found\n");
- }
-
- pthread_join(thread_Listen, NULL);
- return 0;
-
-}
-
-
-//Read objects when objects are not found in any participant
-int test3(void){
- transrecord_t *record;
- objheader_t *h1,*h2;
-
- dstmInit();
- record = transStart();
- printf("DEBUG -> Init done\n");
- //read object 11
- if((h1 = transRead(record, 11)) == NULL){
- printf("Object not found\n");
- }
- //read object 12
- if((h2 = transRead(record, 12)) == NULL) {
- printf("Object not found\n");
- }
- transCommit(record);
-
- return 0;
-}
-
-//Read objects when some objects are found and other objects not found in any participant
-int test4(void) {
- transrecord_t *record;
- objheader_t *h1,*h2, *h3, *h4;
-
- dstmInit();
- record = transStart();
- printf("DEBUG -> Init done\n");
- //read object 1
- if((h1 = transRead(record, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 2
- if((h2 = transRead(record, 2)) == NULL) {
- printf("Object not found\n");
- }
- //read object 11
- if((h3 = transRead(record, 11)) == NULL) {
- printf("Object not found\n");
- }
- //read object 13
- if((h4 = transRead(record, 13)) == NULL) {
- printf("Object not found\n");
- }
- if((h1 != NULL) && (h2 != NULL) && (h3 != NULL) && h4 !=NULL) {
- transCommit(record);
- }else {
- printf("Cannot complete this transaction\n");
- }
-
- return 0;
-}
-
-//Commit for transaction objects when the objs are part of other
-//transactions running simultaneously
-int test5(void) {
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2, *h3, *h4, *h5, *h6;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 22
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 22;
- header->type = 3;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.200.9.26"); //d-1.eecs.uci.edu
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.200.9.26");
- //Check if machine d-1 is up and running
- checkServer(mid, "128.200.9.26");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 1 (found on demksy)
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 31 (found on d-1)
- if((h2 = transRead(myTrans, 31)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 22 (found locally)
- if((h3 = transRead(myTrans, 22)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 2 (found on demsky)
- if((h4 = transRead(myTrans, 2)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 21 (found locally)
- if((h5 = transRead(myTrans, 21)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 32 (found on d-2)
- if((h6 = transRead(myTrans, 32)) == NULL) {
- printf("Object not found\n");
- }
-
- //Commit transaction
- if((h1 != NULL) && (h2 != NULL) && (h3 != NULL) && (h4 !=NULL) && (h5 != NULL) && (h6 != NULL))
- transCommit(myTrans);
- else
- printf("Cannot complete this transaction \n");
-
- pthread_join(thread_Listen, NULL);
- return 0;
-}
-int test5a(void) {
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2, *h3;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 22
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 22;
- header->type = 3;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.200.9.26"); //d-1.eecs.uci.edu
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.200.9.26");
- //Check if machine d-1 is up and running
- checkServer(mid, "128.200.9.26");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 1 (found on demksy)
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 31 (found on d-1)
- if((h2 = transRead(myTrans, 32)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 22 (found locally)
- if((h3 = transRead(myTrans, 22)) == NULL) {
- printf("Object not found\n");
- }
-
- //Commit transaction
- if((h1 != NULL) && (h2 != NULL) && (h3 != NULL))
- transCommit(myTrans);
- else
- printf("Cannot complete this transaction \n");
-
- pthread_join(thread_Listen, NULL);
- return 0;
-}
-
-int test6(void) {
- transrecord_t *record;
- objheader_t *header;
- unsigned int size, mid;
- pthread_t thread_Listen;
- pthread_attr_t attr;
- objheader_t *h1,*h2, *h3, *h4, *h5, *h6;
- int tmpsd;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
- //pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- record = transStart();
- //printf("DEBUG -> Init done\n");
- mid = iptoMid("128.200.9.10");// Machine demsky.eecs.uci.edu
- lhashInsert(1,mid);
- lhashInsert(2,mid);
- lhashInsert(3,mid);
- lhashInsert(4,mid);
- lhashInsert(5,mid);
- lhashInsert(6,mid);
-
- mid = iptoMid("128.200.9.26");// Machine demsky.eecs.uci.edu
- lhashInsert(31,mid);
- lhashInsert(32,mid);
- lhashInsert(33,mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- checkServer(mid, "128.200.9.26");
- mid = iptoMid("128.200.9.10");
- checkServer(mid, "128.200.9.10");
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
- sleep(3);
- //read object 1 //from demsky
- if((h1 = transRead(record, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 2
- if((h2 = transRead(record, 2)) == NULL) {
- printf("Object not found\n");
- }
- //read object 31 //Found in d-1
- if((h2 = transRead(record, 31)) == NULL) {
- printf("Object not found\n");
- }
- //read object 32 //Found in d-1
- if((h2 = transRead(record, 32)) == NULL) {
- printf("Object not found\n");
- }
- //read object 20(present in local machine)
- if((h3 = transRead(record, 20)) == NULL) {
- printf("Object not found\n");
- }
- //read object 21(present in local machine)
- if((h4 = transRead(record, 21)) == NULL) {
- printf("Object not found\n");
- }
- transCommit(record);
- pthread_join(thread_Listen, NULL);
- return 0;
-}
-//Commit transactions on local and remote objects that are NOT a part of
-//any other transaction
-int test7(void) {
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2, *h3;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 22
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 22;
- header->type = 3;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.27");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.200.9.26"); //d-1.eecs.uci.edu
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.200.9.26");
- //Check if machine d-1 is up and running
- checkServer(mid, "128.200.9.26");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 3 (found on demksy)
- if((h1 = transRead(myTrans, 3)) == NULL){
- printf("Object not found\n");
- }
- //read object 32 (found on d-1)
- if((h2 = transRead(myTrans, 32)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 22 (found locally)
- if((h3 = transRead(myTrans, 22)) == NULL) {
- printf("Object not found\n");
- }
-
- //Commit transaction
- transCommit(myTrans);
-
- pthread_join(thread_Listen, NULL);
- return 0;
-}
+++ /dev/null
-#include <stdio.h>
-#include "clookup.h"
-
-main()
-{
- int i;
- void *val;
- chashtable_t *ctable;
-
- if (( ctable = chashCreate(1000, 0.40)) == NULL) {
- printf("chashCreate error\n"); //creates hashtable
- }
-
- for (i = 1; i <= 2000; i++) { // Checks the insert() and resize()
- if (chashInsert(ctable, 10*i, &i) == 1)
- printf("chashInsert error\n");
- }
-
- i = chashRemove(ctable, 10);//Delete first element in the hashtable
- if(i == 1)
- printf("chashRemove error ");
-
- for (i = 1; i <= 2000; i++) { // Check if it can search for all keys in hash table
- val = chashSearch(ctable, 10*i);
- if (val != &i)
- printf("chashSearch error - val = %d\n", val);
- else
- printf("chashSearch key = %d val = %x\n",10*i, val);
- }
-
- i = chashRemove(ctable, 30);
- if(i == 1)
- printf("chashRemove error\n ");
- i = chashRemove(ctable, 40);
- if(i == 1)
- printf("chashRemove error\n ");
- i = chashRemove(ctable, 80);
- if(i == 1)
- printf("chashRemove error\n ");
- i = chashRemove(ctable, 100);
- if(i == 1)
- printf("chashRemove error\n ");
- i = chashRemove(ctable, 90);
- if(i == 1)
- printf("chashRemove error\n ");
-
- for (i = 1; i <= 2000; i++) { //Prints all left over elements inside hash after deletion and prints error if element not found in hash
- val = chashSearch(ctable, 10*i);
- if (val != &i)
- printf("chashSearch error - val = %d\n", val);
- else
- printf("chashSearch key = %d val = %x\n",10*i, val);
- }
-
- printf("The total number of elements in table : %d\n", ctable->numelements);
-
- chashDelete(ctable);
-}
+++ /dev/null
-#include<stdio.h>
-#include<pthread.h>
-#include "dstm.h"
-#include "llookup.h"
-#include "ip.h"
-
-#define LISTEN_PORT 2156
-
-extern objstr_t *mainobjstore;
-
-int classsize[]={sizeof(int),sizeof(char),sizeof(short), sizeof(void *)};
-
-int main()
-{
-// test2();
-// test3();
-// test4();
- test5();
-// test5a();
-// test2a();
-// test2b();
-// test7();
-
-}
-
-int test1(void) {
-
- transrecord_t *record;
- objheader_t *h1,*h2,*h3,*h4,*h5, *h6;
-
- dstmInit();
- record = transStart();
- printf("DEBUG -> Init done\n");
- h1 = transRead(record, 1);
- printf("oid = %d\tsize = %d\n", h1->oid,classsize[h1->type]);
- h3 = transRead(record, 3);
- printf("oid = %d\tsize = %d\n", h3->oid,classsize[h3->type]);
- h4 = transRead(record, 4);
- printf("oid = %d\tsize = %d\n", h4->oid,classsize[h4->type]);
- h2 = transRead(record, 2);
- printf("oid = %d\tsize = %d\n", h2->oid,classsize[h2->type]);
- h4 = transRead(record, 4);
- printf("oid = %d\tsize = %d\n", h4->oid,classsize[h4->type]);
- h3 = transRead(record, 3);
- printf("oid = %d\tsize = %d\n", h3->oid,classsize[h3->type]);
- h5 = transRead(record, 5);
- printf("oid = %d\tsize = %d\n", h5->oid,classsize[h5->type]);
-}
-
-int test2(void) {
-
- transrecord_t *record;
- objheader_t *h1,*h2,*h3,*h4,*h5, *h6;
-
- dstmInit();
- record = transStart();
-
- lhashInsert(1,1);
- lhashInsert(2,1);
- lhashInsert(3,1);
- lhashInsert(4,1);
- lhashInsert(5,1);
- lhashInsert(6,1);
- printf("DEBUG -> Init done\n");
- h1 = transRead(record, 1);
- lhashInsert(h1->oid, 1);
- h2 = transRead(record, 2);
- lhashInsert(h2->oid, 1);
- h3 = transRead(record, 3);
- lhashInsert(h3->oid, 1);
- h4 = transRead(record, 4);
- lhashInsert(h4->oid, 1);
- h5 = transRead(record, 5);
- lhashInsert(h5->oid, 1);
- h6 = transRead(record, 6);
- lhashInsert(h6->oid, 1);
-
- transCommit(record);
-
- return 0;
-}
-
-//Read objects when objects are found in remote location
-int test2a(void) {
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 22
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 22;
- header->type = 3;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.195.175.69"); //dw-1.eecs.uci.edu
- lhashInsert(31, mid);
- lhashInsert(32, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.195.175.69");
- //Check if machine dw-1 is up and running
- checkServer(mid, "128.195.175.69");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 1
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 2
- if((h2 = transRead(myTrans, 2)) == NULL) {
- printf("Object not found\n");
- }
-
- pthread_join(thread_Listen, NULL);
- return 0;
-}
-
-//Read objects that are both remote and local and are available on machines
-int test2b(void) {
-
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2, *h3, *h4;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 22
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 22;
- header->type = 3;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.195.175.69"); //dw-1.eecs.uci.edu
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.195.175.69");
- //Check if machine dw-1 is up and running
- checkServer(mid, "128.195.175.69");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 1 (found on demksy)
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 2 (found on demsky)
- if((h2 = transRead(myTrans, 2)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 21 (found on local)
- if((h3 = transRead(myTrans, 21)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 32 (found on dw-1)
- if((h4 = transRead(myTrans, 32)) == NULL) {
- printf("Object not found\n");
- }
-
- pthread_join(thread_Listen, NULL);
- return 0;
-
-}
-
-
-//Read objects when objects are not found in any participant
-int test3(void){
- transrecord_t *record;
- objheader_t *h1,*h2;
-
- dstmInit();
- record = transStart();
- printf("DEBUG -> Init done\n");
- //read object 11
- if((h1 = transRead(record, 11)) == NULL){
- printf("Object not found\n");
- }
- //read object 12
- if((h2 = transRead(record, 12)) == NULL) {
- printf("Object not found\n");
- }
- transCommit(record);
-
- return 0;
-}
-
-//Read objects when some objects are found and other objects not found in any participant
-int test4(void) {
- transrecord_t *record;
- objheader_t *h1,*h2, *h3, *h4;
-
- dstmInit();
- record = transStart();
- printf("DEBUG -> Init done\n");
- //read object 1
- if((h1 = transRead(record, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 2
- if((h2 = transRead(record, 2)) == NULL) {
- printf("Object not found\n");
- }
- //read object 11
- if((h3 = transRead(record, 11)) == NULL) {
- printf("Object not found\n");
- }
- //read object 13
- if((h4 = transRead(record, 13)) == NULL) {
- printf("Object not found\n");
- }
- if((h1 != NULL) && (h2 != NULL) && (h3 != NULL) && h4 !=NULL) {
- transCommit(record);
- }else {
- printf("Cannot complete this transaction\n");
- }
-
- return 0;
-}
-
-//Commit for transaction objects when the objs are part of other
-//transactions running simultaneously
-int test5(void) {
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2, *h3, *h4, *h5, *h6;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 22
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 22;
- header->type = 3;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.195.175.69"); //dw-1.eecs.uci.edu
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.195.175.69");
- //Check if machine dw-1 is up and running
- checkServer(mid, "128.195.175.69");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 1 (found on demksy)
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 2 (found on demksy)
- if((h2 = transRead(myTrans,2)) == NULL){
- printf("Object not found\n");
- }
- //read object 22 (found locally )
- if((h3 = transRead(myTrans, 22)) == NULL) {
- printf("Object not found\n");
- }
-
- //Commit transaction
- transCommit(myTrans);
-
- pthread_join(thread_Listen, NULL);
- return 0;
-}
-int test5a(void) {
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2, *h3;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- //read object 31 (found on dw-1)
- if((h2 = transRead(myTrans, 31)) == NULL) {
- printf("Object not found\n");
- }
-
- //Commit transaction
- transCommit(myTrans);
-
- pthread_join(thread_Listen, NULL);
- return 0;
-}
-int test5b(void) {
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2, *h3;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 22
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 22;
- header->type = 3;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.195.175.69"); //dw-1.eecs.uci.edu
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.195.175.69");
- //Check if machine dw-1 is up and running
- checkServer(mid, "128.195.175.69");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 1 (found on demksy)
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 31 (found on dw-1)
- if((h2 = transRead(myTrans, 31)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 22 (found locally)
- if((h3 = transRead(myTrans, 22)) == NULL) {
- printf("Object not found\n");
- }
-
- //Commit transaction
- if((h1 != NULL) && (h2 != NULL) && (h3 != NULL))
- transCommit(myTrans);
- else
- printf("Cannot complete this transaction \n");
-
- pthread_join(thread_Listen, NULL);
- return 0;
-}
-//Commit transactions on local and remote objects that are NOT a part of
-//any other transaction
-int test7(void) {
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header, *h1, *h2, *h3;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 20
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 20;
- header->type = 2;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 21
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 21;
- header->type = 1;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 22
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- header->oid = 22;
- header->type = 3;
- header->version = 1;
- header->rcount = 0; //? not sure how to handle this yet
- header->status = 0;
- header->status |= NEW;
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.29");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.195.175.69"); //dw-1.eecs.uci.edu
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.195.175.69");
- //Check if machine dw-1 is up and running
- checkServer(mid, "128.195.175.69");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 3 (found on demksy)
- if((h1 = transRead(myTrans, 3)) == NULL){
- printf("Object not found\n");
- }
- //read object 32 (found on dw-1)
- if((h2 = transRead(myTrans, 32)) == NULL) {
- printf("Object not found\n");
- }
-
- //read object 22 (found locally)
- if((h3 = transRead(myTrans, 22)) == NULL) {
- printf("Object not found\n");
- }
-
- //Commit transaction
- transCommit(myTrans);
-
- pthread_join(thread_Listen, NULL);
- return 0;
-}
+++ /dev/null
-#include <pthread.h>
-#include "dstm.h"
-
-extern objstr_t *mainobjstore;
-int classsize[]={sizeof(int),sizeof(char),sizeof(short), sizeof(void *)};
-
-int main()
-{
- test1();
-// test2();
-// test3();
-// test4();
-}
-
-void init_obj(objheader_t *h, unsigned int oid, unsigned short type, \
- unsigned short version,\
- unsigned short rcount, char status) {
- h->oid = oid;
- h->type = type;
- h->version = version;
- h->rcount = rcount;
- h->status |= status;
- return;
-}
-
-//Test case to create objects and do nothing else
-int test1() {
- unsigned int val, mid;
- unsigned int size;
- transrecord_t *myTrans;
- objheader_t *header;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 31
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 31, 2, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 32
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 32, 1, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 33
- size = sizeof(objheader_t) + classsize[0] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 33, 0, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable into d-3.eecs
- mid = iptoMid("128.200.9.29"); //d-3.eecs.uci.edu
- lhashInsert(20, mid);
- lhashInsert(21, mid);
- lhashInsert(22, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable of demsky.eecs
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.200.9.29");
- //Check if machine d-3 is up and running
- checkServer(mid, "128.200.9.29");
-
- pthread_join(thread_Listen, NULL);
-
- return 0;
-}
-
-//Read objects from remote and local machines ; NOTE objects are all available
-int test2() {
-
- unsigned int val, mid;
- unsigned int size;
- transrecord_t *myTrans;
- objheader_t *header, *h1, *h2, *h3, *h4;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 31
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 31, 2, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 32
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 32, 1, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 33
- size = sizeof(objheader_t) + classsize[0] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 33, 0, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable into d-3.eecs
- mid = iptoMid("128.200.9.29"); //d-3.eecs.uci.edu
- lhashInsert(20, mid);
- lhashInsert(21, mid);
- lhashInsert(22, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable of demsky.eecs
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.200.9.29");
- //Check if machine d-2 is up and running
- checkServer(mid, "128.200.9.29");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 1 (found on demksy)
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
-
- //read object 33 (found on local)
- if((h2 = transRead(myTrans, 33)) == NULL){
- printf("Object not found\n");
- }
-
- //read object 21 (found on d-3)
- if((h3 = transRead(myTrans, 21)) == NULL){
- printf("Object not found\n");
- }
-
- //read object 32 (found on local)
- if((h4 = transRead(myTrans, 32)) == NULL){
- printf("Object not found\n");
- }
-
- pthread_join(thread_Listen, NULL);
-
- return 0;
-}
-
-int test3() {
-
- unsigned int val, mid;
- unsigned int size;
- transrecord_t *myTrans;
- objheader_t *header, *h1, *h2, *h3;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 31
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 31, 2, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 32
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 32, 1, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 33
- size = sizeof(objheader_t) + classsize[0] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 33, 0, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable into d-3.eecs
- mid = iptoMid("128.200.9.29"); //d-3.eecs.uci.edu
- lhashInsert(20, mid);
- lhashInsert(21, mid);
- lhashInsert(22, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable of demsky.eecs
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.200.9.29");
- //Check if machine d-3 is up and running
- checkServer(mid, "128.200.9.29");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 4 (found on demksy)
- if((h1 = transRead(myTrans, 4)) == NULL){
- printf("Object not found\n");
- }
- //read object 33 (found on local)
- if((h2 = transRead(myTrans, 33)) == NULL){
- printf("Object not found\n");
- }
- //read object 20 (found on d-3)
- if((h3 = transRead(myTrans, 20)) == NULL){
- printf("Object not found\n");
- }
-
- //Commit transaction
- transCommit(myTrans);
-
- pthread_join(thread_Listen, NULL);
-
- return 0;
-}
-//Commit transaction for some objects that are available and some that are
-//not available anywhere
-int test4() {
- unsigned int val, mid;
- unsigned int size;
- transrecord_t *myTrans;
- objheader_t *header, *h1, *h2, *h3, *h4;
- pthread_t thread_Listen;
- pthread_attr_t attr;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- //Create and Insert Oid 31
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 31, 2, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 32
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 32, 1, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Create and Insert Oid 33
- size = sizeof(objheader_t) + classsize[0] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 33, 0, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.195.175.69");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable into d-3.eecs
- mid = iptoMid("128.200.9.29"); //d-3.eecs.uci.edu
- lhashInsert(20, mid);
- lhashInsert(21, mid);
- lhashInsert(22, mid);
-
- mid = iptoMid("128.200.9.10"); //demsky.eecs.uci.edu
- //Inserting into lhashtable of demsky.eecs
- lhashInsert(1, mid);
- lhashInsert(2, mid);
- lhashInsert(3, mid);
- lhashInsert(4, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine demsky is up and running
- checkServer(mid, "128.200.9.10");
- mid = iptoMid("128.200.9.29");
- //Check if machine d-2 is up and running
- checkServer(mid, "128.200.9.29");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 4 (found on demksy)
- if((h1 = transRead(myTrans, 4)) == NULL){
- printf("Object not found\n");
- }
- //read object 33 (found on local)
- if((h2 = transRead(myTrans, 33)) == NULL){
- printf("Object not found\n");
- }
- //read object 24 (found nowhere)
- if((h3 = transRead(myTrans, 24)) == NULL){
- printf("Object not found\n");
- }
- //read object 50 (found nowhere)
- if((h4 = transRead(myTrans, 50)) == NULL){
- printf("Object not found\n");
- }
-
- //Commit transaction
- if((h1 != NULL) && (h2 != NULL) && (h3 != NULL) && (h4 !=NULL))
- transCommit(myTrans);
- else
- printf("Cannot complete this transaction\n");
-
- pthread_join(thread_Listen, NULL);
- return 0;
-
-}
+++ /dev/null
-#include <stdio.h>
-#include "dht.h"
-#include "clookup.h"
-
-#define NUM_ITEMS 100000
-
-int main()
-{
- unsigned int key;
- unsigned int val;
- unsigned int vals[NUM_ITEMS];
- int retval;
- int error;
- chashtable_t *localHash;
-
- dhtInit(0x80C3AF45, DHT_NO_KEY_LIMIT);
-
- localHash = chashCreate(HASH_SIZE, LOADFACTOR);
- srandom(time(0));
-
- for (key = 1; key < NUM_ITEMS; key++)
- {
- vals[key] = random();
- }
-
- sleep(5);
-
- printf("testing dhtInsert() and dhtSearch()\n");
-
- for (key = 0; key < NUM_ITEMS; key++)
- {
- dhtInsert(key, vals[key]);
- }
-
- error = 0;
- for (key = 1; key < NUM_ITEMS; key++)
- {
- retval = dhtSearch(key, &val);
- if (retval == 1)
- {
- printf("item not found: key = %d, expected val = %d\n", key, vals[key]);
- error = 1;
- }
- else if (retval == -1)
- {
- printf("internal error: key = %d, expected val = %d\n", key, vals[key]);
- error = 1;
- }
- else if (retval == 0)
- {
- if (vals[key] != val)
- {
- printf("unexpected value: key = %d, expected val = %d, val = %d\n", key, vals[key], val);
- error = 1;
- }
- }
- }
- if (!error)
- printf("test completed successfully\n");
- else
- printf("one or more errors occurred\n");
-
- printf("(this currently fails if key = 0 OR val = 0, due to underlying hash table)\n");
- printf("testing underlying hash table (clookup.h)\n");
-
- for (key = 1; key < NUM_ITEMS; key++)
- {
- chashInsert(localHash, key, (void *)vals[key]);
- }
-
- error = 0;
- for (key = 1; key < NUM_ITEMS; key++)
- {
- val = (unsigned int)chashSearch(localHash, key);
- if ((void *)val == NULL)
- {
- printf("item not found: key = %d, expected val = %d\n", key, vals[key]);
- error = 1;
- }
- else
- {
- if (vals[key] != val)
- {
- printf("unexpected value: key = %d, expected val = %d, val = %d\n", key, vals[key], val);
- error = 1;
- }
- }
- for (key = NUM_ITEMS; key < NUM_ITEMS + 20; key++)
- {
- val = (unsigned int)chashSearch(localHash, key);
- if ((void *)val != NULL)
- {
- printf("error: returned value for key that wasn't inserted: key = %d, val = %d\n", key, val);
- error = 1;
- }
- }
- }
-
- if (!error)
- printf("test completed successfully\n");
- else
- printf("one or more errors occurred\n");
-
- printf("testing dhtRemove(), removing half of the keys, and verifying that the other half is still there\n");
-
- for (key = 0; key < NUM_ITEMS / 2; key++)
- {
- dhtRemove(key);
- }
- error = 0;
- for (key = 0; key < NUM_ITEMS / 2; key++)
- {
- retval = dhtSearch(key, &val);
- if (retval == 0)
- {
- printf("error: found removed item: key = %d, val = %d\n", key, val);
- error = 1;
- }
- else if (retval == -1)
- {
- printf("internal error: key = %d, val = %d\n", key, val);
- error = 1;
- }
- }
- for (key = NUM_ITEMS / 2; key < NUM_ITEMS; key++)
- {
- retval = dhtSearch(key, &val);
- if (retval == 1)
- {
- printf("item not found: key = %d, expected val = %d\n", key, vals[key]);
- error = 1;
- }
- else if (retval == -1)
- {
- printf("internal error: key = %d, expected val = %d\n", key, vals[key]);
- error = 1;
- }
- else if (retval == 0)
- {
- if (vals[key] != val)
- {
- printf("unexpected value: key = %d, expected val = %d, val = %d\n", key, vals[key], val);
- error = 1;
- }
- }
- }
-
- if (!error)
- printf("test completed successfully\n");
- else
- printf("one or more errors occurred\n");
-
- sleep(5);
-
- dhtExit();
-
- return 0;
-}
-
+++ /dev/null
-#include <stdio.h>
-#include "llookup.h"
-extern lhashtable_t llookup;
-
-main()
-{
- int i, mid;
-
- if (lhashCreate(10, 0.20) == 1) {
- printf("lhashCreate error\n"); //creates hashtable
- }
- for (i = 1; i <= 7; i++) { // Checks the insert() and resize()
- if (lhashInsert(10*i, i) == 1)
- printf("lhashInsert error\n");
- }
-
- i = lhashRemove(10);//Delete first element in the hashtable
- if(i == 1)
- printf("lhashRemove error ");
-
- for (i = 1; i <=7; i++) { // Check if it can search for all oids in hash table
- mid = lhashSearch(10*i);
- if (mid != i)
- printf("lhashSearch error - mid = %d\n", mid);
- else
- printf("lhashSearch oid = %d mid = %d\n",10*i, mid);
- }
-
- i = lhashRemove(60);
- if(i == 1)
- printf("lhashRemove error ");
-
- for (i = 1; i <= 7; i++) { //Prints all left over elements inside hash after deletion and prints error if element not found in hash
- mid = lhashSearch(10*i);
- if (mid != i)
- printf("lhashSearch error - mid = %d\n", mid);
- else
- printf("lhashSearch oid = %d mid = %d\n",10*i, mid);
- }
-
- printf(" The total number of elements in table : %d\n", llookup.numelements);
-
-}
+++ /dev/null
-#include <stdio.h>
-#include "mlookup.h"
-extern mhashtable_t mlookup;
-
-main()
-{
- int i;
- void *val;
- val = NULL;
-
- if (mhashCreate(10, 0.20) == 1) {
- printf("mhashCreate error\n"); //creates hashtable
- }
- for (i = 1; i <= 7; i++) { // Checks the insert() and resize()
- if (mhashInsert(10*i, &i) == 1)
- printf("mhashInsert error\n");
- }
-
- i = mhashRemove(60);//Delete first element in the hashtable
- if(i == 1)
- printf("mhashRemove error ");
-
- for (i = 1; i <=7; i++) { // Check if it can search for all oids in hash table
- val = mhashSearch(10*i);
- if (val != &i)
- printf("mhashSearch error - val = %d\n", val);
- else
- printf("mhashSearch oid = %d val = %x\n",10*i, val);
- }
-
- i = mhashRemove(30);
- if(i == 1)
- printf("mhashRemove error ");
-
- for (i = 1; i <= 7; i++) { //Prints all left over elements inside hash after deletion and prints error if element not found in hash
- val = mhashSearch(10*i);
- if (val != &i)
- printf("mhashSearch error - val = %d\n", val);
- else
- printf("mhashSearch oid = %d val = %x\n",10*i, val);
- }
-
- printf("The total number of elements in table : %d\n", mlookup.numelements);
-
-}
+++ /dev/null
-#include "dstm.h"
-
-#define NUMITEMS 1000000 //uses four object stores
-
-int main(void)
-{
- objstr_t *myObjStr = objstrCreate(1048510);
- int i;
- int *j[NUMITEMS];
- int data[NUMITEMS];
- int fail = 0;
-
- for (i = 0; i < NUMITEMS; i++)
- {
- j[i] = objstrAlloc(myObjStr, sizeof(int));
- *j[i] = data[i] = i;
- }
- for (i = 0; i < NUMITEMS; i++)
- {
- if (data[i] != *j[i])
- fail = 1;
- }
-
- if (fail)
- printf("test failed\n");
- else
- printf("test succeeded\n");
-
- objstrDelete(myObjStr);
- return 0;
-}
-
+++ /dev/null
-#include <pthread.h>
-#include "dstm.h"
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include "ip.h"
-
-extern objstr_t *mainobjstore;
-int classsize[]={sizeof(int),sizeof(char),sizeof(short), sizeof(void *)};
-
-int test1(void);
-int test2(void);
-int test3(void);
-
-unsigned int createObjects(transrecord_t *record, unsigned short type) {
- objheader_t *header, *tmp;
- struct sockaddr_in antelope;
- unsigned int size, mid;
- size = sizeof(objheader_t) + classsize[type] ;
- //Inserts in chashtable
- header = transCreateObj(record, type);
- tmp = (objheader_t *) objstrAlloc(mainobjstore, size);
- memcpy(tmp, header, size);
- mhashInsert(tmp->oid, tmp);
- mid = iptoMid("128.200.9.10");
- lhashInsert(tmp->oid, mid);
- //Lock oid 3 object
-// if(tmp->oid == 3)
-// tmp->status |= LOCK;
- return 0;
-}
-
-void init_obj(objheader_t *h, unsigned int oid, unsigned short type, \
- unsigned short version,\
- unsigned short rcount, char status) {
- h->oid = oid;
- h->type = type;
- h->version = version;
- h->rcount = rcount;
- h->status |= status;
- return;
-}
-
-
-int main()
-{
-// test1();
-// test3();
- test4();
-}
-
-int test1()
-{
- unsigned int val;
- transrecord_t *myTrans;
- pthread_t thread_Listen;
-
- dstmInit();
- pthread_create(&thread_Listen, NULL, dstmListen, NULL);
- // Start Transaction
- myTrans = transStart();
-
- printf("Creating Transaction\n");
- //Create Object1
- if((val = createObjects(myTrans, 0)) != 0) {
- printf("Error transCreateObj1");
- }
- //Create Object2
- if((val = createObjects(myTrans, 1)) != 0) {
- printf("Error transCreateObj2");
- }
- //Create Object3
- if((val = createObjects(myTrans, 2)) != 0) {
- printf("Error transCreateObj3");
- }
- //Create Object4
- if((val = createObjects(myTrans, 3)) != 0) {
- printf("Error transCreateObj4");
- }
- //Create Object5
- if((val = createObjects(myTrans, 0)) != 0) {
- printf("Error transCreateObj5");
- }
- //Create Object6
- if((val = createObjects(myTrans, 1)) != 0) {
- printf("Error transCreateObj6");
- }
- pthread_join(thread_Listen, NULL);
- return 0;
-}
-
-int test2() {
-
- unsigned int val, mid;
- transrecord_t *myTrans;
- pthread_t thread_Listen;
-
- dstmInit();
- mid = iptoMid("128.200.9.27"); //d-2.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(20, mid);
- lhashInsert(21, mid);
- lhashInsert(22, mid);
- lhashInsert(23, mid);
- lhashInsert(30, mid);
- lhashInsert(28, mid);
- lhashInsert(29, mid);
- pthread_create(&thread_Listen, NULL, dstmListen, NULL);
- // Start Transaction
- myTrans = transStart();
-
- printf("Creating Transaction\n");
- //Create Object1
- if((val = createObjects(myTrans, 0)) != 0) {
- printf("Error transCreateObj1");
- }
- //Create Object2
- if((val = createObjects(myTrans, 1)) != 0) {
- printf("Error transCreateObj2");
- }
- //Create Object3
- if((val = createObjects(myTrans, 2)) != 0) {
- printf("Error transCreateObj3");
- }
- //Create Object4
- if((val = createObjects(myTrans, 3)) != 0) {
- printf("Error transCreateObj4");
- }
- //Create Object5
- if((val = createObjects(myTrans, 0)) != 0) {
- printf("Error transCreateObj5");
- }
- //Create Object6
- if((val = createObjects(myTrans, 1)) != 0) {
- printf("Error transCreateObj6");
- }
- pthread_join(thread_Listen, NULL);
-}
-//Commit transaction with all locally available objects
-int test3() {
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header;
- pthread_t thread_Listen;
- pthread_attr_t attr;
- objheader_t *h1, *h2, *h3;//h1,h2,h3 from local
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- // Create and Insert Oid 1
- size = sizeof(objheader_t) + classsize[0] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 1, 0, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- // Create and Insert Oid 2
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 2, 1, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
-
- // Create and Insert Oid 3
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 3, 2, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- // Create and Insert Oid 4
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 4, 3, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.200.9.29"); //d-3.eecs.uci.edu
- lhashInsert(20, mid);
- lhashInsert(21, mid);
- lhashInsert(22, mid);
-
- mid = iptoMid("128.195.175.69"); //dw-1.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- //Check if machine dw-1 is up and running
- checkServer(mid, "128.195.175.69");
- mid = iptoMid("128.200.9.29");
- //Check if machine d-3 is up and running
- checkServer(mid, "128.200.9.29");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 1(present in local machine)
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 2present in local machine)
- if((h2 = transRead(myTrans, 2)) == NULL) {
- printf("Object not found\n");
- }
- //read object 3(present in local machine)
- if((h3 = transRead(myTrans, 3)) == NULL) {
- printf("Object not found\n");
- }
-
- // Commit transaction
- transCommit(myTrans);
-
- pthread_join(thread_Listen, NULL);
-
- return 0;
-}
-
-//Commit transaction with few locally available objects and other objects from machine d-1
-// and d-2
-int test4() {
-
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header;
- pthread_t thread_Listen;
- pthread_attr_t attr;
- objheader_t *h1, *h2, *h3, *h4;//h1,h2 from local ; h3 from d-1 , h-4 from d-2
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- // Create and Insert Oid 1
- size = sizeof(objheader_t) + classsize[0] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 1, 0, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- // Create and Insert Oid 2
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 2, 1, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
-
- // Create and Insert Oid 3
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 3, 2, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- // Create and Insert Oid 4
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 4, 3, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- //Inserting into lhashtable
- mid = iptoMid("128.200.9.29"); //d-3.eecs.uci.edu
- lhashInsert(20, mid);
- lhashInsert(21, mid);
- lhashInsert(22, mid);
-
- mid = iptoMid("128.195.175.69"); //dw-1.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
-
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
- //Check if machine dw-1 is up and running
- checkServer(mid, "128.195.175.69");
- mid = iptoMid("128.200.9.29");
- //Check if machine d-3 is up and running
- checkServer(mid, "128.200.9.29");
-
- // Start Transaction
- myTrans = transStart();
-
- //read object 1(present in local machine)
- if((h1 = transRead(myTrans, 2)) == NULL){
- printf("Object not found\n");
- }
-
- //read object 2present in local machine)
- if((h2 = transRead(myTrans, 1)) == NULL) {
- printf("Object not found\n");
- }
- //read object 31(present in dw-1 machine)
- if((h3 = transRead(myTrans, 31)) == NULL) {
- printf("Object not found\n");
- }
- //read object 21(present in d-3 machine)
- if((h4 = transRead(myTrans, 21)) == NULL) {
- printf("Object not found\n");
- }
-
- // Commit transaction
- transCommit(myTrans);
-
- pthread_join(thread_Listen, NULL);
-
- return 0;
-}
-int test5() {
-
- unsigned int val, mid;
- transrecord_t *myTrans;
- unsigned int size;
- objheader_t *header;
- pthread_t thread_Listen;
- pthread_attr_t attr;
- objheader_t *h1, *h2, *h3, *h4, *h5;
-
- dstmInit();
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- mid = iptoMid("128.200.9.27"); //d-2.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(20, mid);
- lhashInsert(21, mid);
- lhashInsert(22, mid);
-
- mid = iptoMid("128.200.9.26"); //d-1.eecs.uci.edu
- //Inserting into lhashtable
- lhashInsert(31, mid);
- lhashInsert(32, mid);
- lhashInsert(33, mid);
- pthread_create(&thread_Listen, &attr, dstmListen, NULL);
-
- printf("DEBUG -> mid = %d\n", mid);
- checkServer(mid, "128.200.9.26");
- mid = iptoMid("128.200.9.27");
- printf("DEBUG -> mid = %d\n", mid);
- checkServer(mid, "128.200.9.27");
-
- // Start Transaction
- myTrans = transStart();
-
- // Create and Insert Oid 1
- size = sizeof(objheader_t) + classsize[0] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 1, 0, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- // Create and Insert Oid 2
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 2, 1, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
-
- // Create and Insert Oid 3
- size = sizeof(objheader_t) + classsize[2] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 3, 2, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- // Create and Insert Oid 4
- size = sizeof(objheader_t) + classsize[3] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 4, 3, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- // Create and Insert Oid 5
- size = sizeof(objheader_t) + classsize[0] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 5, 0, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- // Create and Insert Oid 6
- size = sizeof(objheader_t) + classsize[1] ;
- header = (objheader_t *) objstrAlloc(mainobjstore, size);
- init_obj(header, 6, 1, 1, 0, NEW);
- mhashInsert(header->oid, header);
- mid = iptoMid("128.200.9.10");
- lhashInsert(header->oid, mid);
-
- //read object 1(present in local machine)
- if((h1 = transRead(myTrans, 1)) == NULL){
- printf("Object not found\n");
- }
- //read object 2present in local machine)
- if((h2 = transRead(myTrans, 2)) == NULL) {
- printf("Object not found\n");
- }
- //read object 3(present in local machine)
- if((h3 = transRead(myTrans, 3)) == NULL) {
- printf("Object not found\n");
- }
- //read object 31 (present in d-1. eecs)
- if((h4 = transRead(myTrans, 31)) == NULL) {
- printf("Object not found\n");
- }
- //read object 20 (present in d-2. eecs)
- if((h5 = transRead(myTrans, 20)) == NULL) {
- printf("Object not found\n");
- }
-
- transCommit(myTrans);
-
- pthread_join(thread_Listen, NULL);
-
- return 0;
-}
#include "llookup.h"
#include "plookup.h"
#include "prelookup.h"
+#include "threadnotify.h"
#include "queue.h"
#include <pthread.h>
#include <sys/types.h>
#include <errno.h>
#include <time.h>
#include <string.h>
-#include <pthread.h>
+#ifdef COMPILER
+#include "thread.h"
+#endif
#define LISTEN_PORT 2156
#define RECEIVE_BUFFER_SIZE 2048
#define NUM_THREADS 10
#define PREFETCH_CACHE_SIZE 1048576 //1MB
+#define CONFIG_FILENAME "dstm.conf"
/* Global Variables */
extern int classsize[];
-extern primarypfq_t pqueue; // shared prefetch queue
+extern primarypfq_t pqueue; //Shared prefetch queue
extern mcpileq_t mcqueue; //Shared queue containing prefetch requests sorted by remote machineids
-objstr_t *prefetchcache; //Global Prefetch cache
+objstr_t *prefetchcache; //Global Prefetch cache
+pthread_mutex_t prefetchcache_mutex;// Mutex to lock Prefetch Cache
+pthread_mutexattr_t prefetchcache_mutex_attr; /* Attribute for lock to make it a recursive lock */
+extern pthread_mutex_t mainobjstore_mutex;// Mutex to lock main Object store
extern prehashtable_t pflookup; //Global Prefetch cache's lookup table
pthread_t wthreads[NUM_THREADS]; //Worker threads for working on the prefetch queue
-pthread_t tPrefetch;
+pthread_t tPrefetch; /* Primary Prefetch thread that processes the prefetch queue */
extern objstr_t *mainobjstore;
-
+unsigned int myIpAddr;
+unsigned int *hostIpAddrs;
+int sizeOfHostArray;
+int numHostsInSystem;
+int myIndexInHostArray;
+unsigned int oidsPerBlock;
+unsigned int oidMin;
+unsigned int oidMax;
+void *mlist[10000];
+pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;
+
+void printhex(unsigned char *, int);
plistnode_t *createPiles(transrecord_t *);
+
+void printhex(unsigned char *ptr, int numBytes)
+{
+ int i;
+ for (i = 0; i < numBytes; i++)
+ {
+ if (ptr[i] < 16)
+ printf("0%x ", ptr[i]);
+ else
+ printf("%x ", ptr[i]);
+ }
+ printf("\n");
+ return;
+}
+
inline int arrayLength(int *array) {
int i;
for(i=0 ;array[i] != -1; i++)
}
/* This function is a prefetch call generated by the compiler that
* populates the shared primary prefetch queue*/
-void prefetch(int ntuples, unsigned int *oids, short *endoffsets, short *arrayfields) {
+void prefetch(int ntuples, unsigned int *oids, unsigned short *endoffsets, short *arrayfields) {
int qnodesize;
int len = 0;
-
+ int i, rc;
+
/* Allocate for the queue node*/
char *node;
- qnodesize = sizeof(prefetchqelem_t) + sizeof(int) + ntuples * (sizeof(short) + sizeof(unsigned int)) + endoffsets[ntuples - 1] * sizeof(short);
- if((node = calloc(1, qnodesize)) == NULL) {
- printf("Calloc Error %s, %d\n", __FILE__, __LINE__);
- return;
+ if(ntuples > 0) {
+ qnodesize = sizeof(prefetchqelem_t) + sizeof(int) + ntuples * (sizeof(unsigned short) + sizeof(unsigned int)) + endoffsets[ntuples - 1] * sizeof(unsigned short);
+ if((node = calloc(1, qnodesize)) == NULL) {
+ printf("Calloc Error %s, %d\n", __FILE__, __LINE__);
+ return;
+ }
+ /* Set queue node values */
+ len = sizeof(prefetchqelem_t);
+ memcpy(node + len, &ntuples, sizeof(int));
+ len += sizeof(int);
+ memcpy(node + len, oids, ntuples*sizeof(unsigned int));
+ len += ntuples * sizeof(unsigned int);
+ memcpy(node + len, endoffsets, ntuples*sizeof(unsigned short));
+ len += ntuples * sizeof(unsigned short);
+ memcpy(node + len, arrayfields, endoffsets[ntuples-1]*sizeof(unsigned short));
+ /* Lock and insert into primary prefetch queue */
+ pthread_mutex_lock(&pqueue.qlock);
+ pre_enqueue((prefetchqelem_t *)node);
+ pthread_cond_signal(&pqueue.qcond);
+ pthread_mutex_unlock(&pqueue.qlock);
+ }
+}
+
+/* This function starts up the transaction runtime. */
+int dstmStartup(const char * option) {
+ pthread_t thread_Listen;
+ pthread_attr_t attr;
+ int master=option!=NULL && strcmp(option, "master")==0;
+
+ if (processConfigFile() != 0)
+ return 0; //TODO: return error value, cause main program to exit
+#ifdef COMPILER
+ if (!master)
+ threadcount--;
+#endif
+
+ dstmInit();
+ transInit();
+
+ if (master) {
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create(&thread_Listen, &attr, dstmListen, NULL);
+ return 1;
+ } else {
+ dstmListen();
+ return 0;
+ }
+
+}
+
+//TODO Use this later
+void *pCacheAlloc(objstr_t *store, unsigned int size) {
+ void *tmp;
+ objstr_t *ptr;
+ ptr = store;
+ int success = 0;
+
+ while(ptr->next != NULL) {
+ /* check if store is empty */
+ if(((unsigned int)ptr->top - (unsigned int)ptr - sizeof(objstr_t) + size) <= ptr->size) {
+ tmp = ptr->top;
+ ptr->top += size;
+ success = 1;
+ return tmp;
+ } else {
+ ptr = ptr-> next;
+ }
+ }
+
+ if(success == 0) {
+ return NULL;
}
- /* Set queue node values */
- len = sizeof(prefetchqelem_t);
- memcpy(node + len, &ntuples, sizeof(int));
- len += sizeof(int);
- memcpy(node + len, oids, ntuples*sizeof(unsigned int));
- len += ntuples * sizeof(unsigned int);
- memcpy(node + len, endoffsets, ntuples*sizeof(short));
- len += ntuples * sizeof(short);
- memcpy(node + len, arrayfields, endoffsets[ntuples-1]*sizeof(short));
- /* Lock and insert into primary prefetch queue */
- pthread_mutex_lock(&pqueue.qlock);
- enqueue((prefetchqelem_t *)node);
- pthread_cond_signal(&pqueue.qcond);
- pthread_mutex_unlock(&pqueue.qlock);
}
/* This function initiates the prefetch thread
* processes the prefetch requests */
void transInit() {
int t, rc;
+ int retval;
//Create and initialize prefetch cache structure
prefetchcache = objstrCreate(PREFETCH_CACHE_SIZE);
+ //prefetchcache->next = objstrCreate(PREFETCH_CACHE_SIZE);
+ //prefetchcache->next->next = objstrCreate(PREFETCH_CACHE_SIZE);
+
+ /* Initialize attributes for mutex */
+ pthread_mutexattr_init(&prefetchcache_mutex_attr);
+ pthread_mutexattr_settype(&prefetchcache_mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP);
+
+ pthread_mutex_init(&prefetchcache_mutex, &prefetchcache_mutex_attr);
+
//Create prefetch cache lookup table
if(prehashCreate(HASH_SIZE, LOADFACTOR))
return; //Failure
queueInit();
//Initialize machine pile w/prefetch oids and offsets shared queue
mcpileqInit();
+
//Create the primary prefetch thread
- pthread_create(&tPrefetch, NULL, transPrefetch, NULL);
+ do {
+ retval=pthread_create(&tPrefetch, NULL, transPrefetch, NULL);
+ } while(retval!=0);
+ pthread_detach(tPrefetch);
+
//Create and Initialize a pool of threads
+ /* Threads are active for the entire period runtime is running */
for(t = 0; t< NUM_THREADS; t++) {
+ do {
rc = pthread_create(&wthreads[t], NULL, mcqProcess, (void *)t);
- if (rc) {
- printf("Thread create error %s, %d\n", __FILE__, __LINE__);
- return;
- }
+ } while(rc!=0);
+ pthread_detach(wthreads[t]);
}
- //TODO when to deletethreads
}
/* This function stops the threads spawned */
/* This functions inserts randowm wait delays in the order of msec
* Mostly used when transaction commits retry*/
-void randomdelay(void)
+void randomdelay()
{
- struct timespec req, rem;
+ struct timespec req;
time_t t;
t = time(NULL);
req.tv_sec = 0;
req.tv_nsec = (long)(1000000 + (t%10000000)); //1-11 msec
- nanosleep(&req, &rem);
+ nanosleep(&req, NULL);
return;
}
/* This function initializes things required in the transaction start*/
transrecord_t *transStart()
{
- transrecord_t *tmp = malloc(sizeof(transrecord_t));
+ transrecord_t *tmp = calloc(1, sizeof(transrecord_t));
tmp->cache = objstrCreate(1048576);
tmp->lookupTable = chashCreate(HASH_SIZE, LOADFACTOR);
-
+#ifdef COMPILER
+ tmp->revertlist=NULL;
+#endif
return tmp;
}
/* This function finds the location of the objects involved in a transaction
* and returns the pointer to the object if found in a remote location */
-objheader_t *transRead(transrecord_t *record, unsigned int oid)
-{
+objheader_t *transRead(transrecord_t *record, unsigned int oid) {
unsigned int machinenumber;
objheader_t *tmp, *objheader;
- void *objcopy;
+ objheader_t *objcopy;
int size, rc, found = 0;
void *buf;
struct timespec ts;
struct timeval tp;
+
+ if(oid == 0) {
+ return NULL;
+ }
rc = gettimeofday(&tp, NULL);
+ /* 1ms delay */
+ tp.tv_usec += 1000;
+ if (tp.tv_usec >= 1000000)
+ {
+ tp.tv_usec -= 1000000;
+ tp.tv_sec += 1;
+ }
/* Convert from timeval to timespec */
+ ts.tv_sec = tp.tv_sec;
ts.tv_nsec = tp.tv_usec * 1000;
/* Search local transaction cache */
if((objheader = (objheader_t *)chashSearch(record->lookupTable, oid)) != NULL){
- return(objheader);
+#ifdef COMPILER
+ return &objheader[1];
+#else
+ return objheader;
+#endif
} else if ((objheader = (objheader_t *) mhashSearch(oid)) != NULL) {
/* Look up in machine lookup table and copy into cache*/
- tmp = mhashSearch(oid);
- size = sizeof(objheader_t)+classsize[tmp->type];
- objcopy = objstrAlloc(record->cache, size);
- memcpy(objcopy, (void *)objheader, size);
+ GETSIZE(size, objheader);
+ size += sizeof(objheader_t);
+ objcopy = (objheader_t *) objstrAlloc(record->cache, size);
+ memcpy(objcopy, objheader, size);
/* Insert into cache's lookup table */
- chashInsert(record->lookupTable, objheader->oid, objcopy);
- return(objcopy);
+ chashInsert(record->lookupTable, OID(objheader), objcopy);
+#ifdef COMPILER
+ return &objcopy[1];
+#else
+ return objcopy;
+#endif
} else if((tmp = (objheader_t *) prehashSearch(oid)) != NULL) { /* Look up in prefetch cache */
- found = 1;
- size = sizeof(objheader_t)+classsize[tmp->type];
- objcopy = objstrAlloc(record->cache, size);
- memcpy(objcopy, (void *)tmp, size);
+ GETSIZE(size, tmp);
+ size+=sizeof(objheader_t);
+ objcopy = (objheader_t *) objstrAlloc(record->cache, size);
+ memcpy(objcopy, tmp, size);
/* Insert into cache's lookup table */
- chashInsert(record->lookupTable, tmp->oid, objcopy);
- return(objcopy);
- } else { /* If not found anywhere, then block until object appears in prefetch cache */
+ chashInsert(record->lookupTable, OID(tmp), objcopy);
+#ifdef COMPILER
+ return &objcopy[1];
+#else
+ return objcopy;
+#endif
+ } else {
+ /*If object not found in prefetch cache then block until object appears in the prefetch cache */
pthread_mutex_lock(&pflookup.lock);
while(!found) {
rc = pthread_cond_timedwait(&pflookup.cond, &pflookup.lock, &ts);
- if(rc == ETIMEDOUT) {
- printf("Wait timed out\n");
- /* Check Prefetch cache again */
- if((tmp = (objheader_t *) prehashSearch(oid)) != NULL) { /* Look up in prefetch cache */
- found = 1;
- size = sizeof(objheader_t)+classsize[tmp->type];
- objcopy = objstrAlloc(record->cache, size);
- memcpy(objcopy, (void *)tmp, size);
- /* Insert into cache's lookup table */
- chashInsert(record->lookupTable, tmp->oid, objcopy);
- return(objcopy);
- } else {
- pthread_mutex_unlock(&pflookup.lock);
- break;
- }
+ /* Check Prefetch cache again */
+ if((tmp =(objheader_t *) prehashSearch(oid)) != NULL) {
+ found = 1;
+ GETSIZE(size,tmp);
+ size+=sizeof(objheader_t);
+ objcopy = (objheader_t *) objstrAlloc(record->cache, size);
+ memcpy(objcopy, tmp, size);
+ chashInsert(record->lookupTable, OID(tmp), objcopy);
+ pthread_mutex_unlock(&pflookup.lock);
+#ifdef COMPILER
+ return &objcopy[1];
+#else
+ return objcopy;
+#endif
+ } else if (rc == ETIMEDOUT) {
pthread_mutex_unlock(&pflookup.lock);
+ break;
}
}
+
/* Get the object from the remote location */
machinenumber = lhashSearch(oid);
objcopy = getRemoteObj(record, machinenumber, oid);
if(objcopy == NULL) {
- //If object is not found in Remote location
- //printf("Object oid = %d not found in Machine %d\n", oid, machinenumber);
+ printf("Error: Object not found in Remote location %s, %d\n", __FILE__, __LINE__);
return NULL;
+ } else {
+#ifdef COMPILER
+ return &objcopy[1];
+#else
+ return objcopy;
+#endif
}
- else {
- //printf("Object oid = %d found in Machine %d\n", oid, machinenumber);
- return(objcopy);
- }
- }
+ }
}
/* This function creates objects in the transaction record */
-objheader_t *transCreateObj(transrecord_t *record, unsigned short type)
+objheader_t *transCreateObj(transrecord_t *record, unsigned int size)
{
- objheader_t *tmp = (objheader_t *) objstrAlloc(record->cache, (sizeof(objheader_t) + classsize[type]));
- tmp->oid = getNewOID();
- tmp->type = type;
+ objheader_t *tmp = (objheader_t *) objstrAlloc(record->cache, (sizeof(objheader_t) + size));
+ tmp->notifylist = NULL;
+ OID(tmp) = getNewOID();
tmp->version = 1;
- tmp->rcount = 0; //? not sure how to handle this yet
- tmp->status = 0;
- tmp->status |= NEW;
- chashInsert(record->lookupTable, tmp->oid, tmp);
+ tmp->rcount = 1;
+ STATUS(tmp) = NEW;
+ chashInsert(record->lookupTable, OID(tmp), tmp);
+
+#ifdef COMPILER
+ return &tmp[1]; //want space after object header
+#else
return tmp;
+#endif
}
/* This function creates machine piles based on all machines involved in a
break;
}
next = curr->next;
- //Get machine location for object id
- if ((machinenum = lhashSearch(curr->key)) == 0) {
- printf("Error: No such machine %s, %d\n", __FILE__, __LINE__);
+ if ((headeraddr = chashSearch(record->lookupTable, curr->key)) == NULL) {
+ printf("Error: No such oid %s, %d\n", __FILE__, __LINE__);
return NULL;
}
- if ((headeraddr = chashSearch(record->lookupTable, curr->key)) == NULL) {
- printf("Error: No such oid %s, %d\n", __FILE__, __LINE__);
+ //Get machine location for object id (and whether local or not)
+ if (STATUS(headeraddr) & NEW || (mhashSearch(curr->key) != NULL)) {
+ machinenum = myIpAddr;
+ } else if ((machinenum = lhashSearch(curr->key)) == 0) {
+ printf("Error: No such machine %s, %d\n", __FILE__, __LINE__);
return NULL;
}
+
//Make machine groups
if ((pile = pInsert(pile, headeraddr, machinenum, record->lookupTable->numelements)) == NULL) {
printf("pInsert error %s, %d\n", __FILE__, __LINE__);
return NULL;
}
- /* Check if local or not */
- if((localmachinenum = mhashSearch(curr->key)) != NULL) {
- /* Set the pile->local flag*/
- pile->local = 1; //True i.e. local
- }
-
curr = next;
}
}
/* This function initiates the transaction commit process
* Spawns threads for each of the new connections with Participants
- * and creates new piles by calling the createPiles(),
- * Fills the piles with necesaary information and
- * Sends a transrequest() to each pile*/
+ * and creates new piles by calling the createPiles(),
+ * Sends a transrequest() to each remote machines for objects found remotely
+ * and calls handleLocalReq() to process objects found locally */
int transCommit(transrecord_t *record) {
unsigned int tot_bytes_mod, *listmid;
- plistnode_t *pile;
- int i, rc, val;
- int pilecount = 0, offset, threadnum = 0, trecvcount = 0, tmachcount = 0;
+ plistnode_t *pile, *pile_ptr;
+ int i, j, rc, val;
+ int pilecount, offset, threadnum = 0, trecvcount = 0;
char buffer[RECEIVE_BUFFER_SIZE],control;
char transid[TID_LEN];
trans_req_data_t *tosend;
char treplyctrl = 0, treplyretry = 0; /* keeps track of the common response that needs to be sent */
char localstat = 0;
+
+
/* Look through all the objects in the transaction record and make piles
* for each machine involved in the transaction*/
- pile = createPiles(record);
+ pile_ptr = pile = createPiles(record);
/* Create the packet to be sent in TRANS_REQUEST */
pthread_mutex_t tlshrd;
thread_data_array_t *thread_data_array;
- thread_data_array = (thread_data_array_t *) malloc(sizeof(thread_data_array_t)*pilecount);
+ if((thread_data_array = (thread_data_array_t *) calloc(pilecount, sizeof(thread_data_array_t))) == NULL) {
+ printf("Calloc error %s, %d\n", __FILE__, __LINE__);
+ pthread_cond_destroy(&tcond);
+ pthread_mutex_destroy(&tlock);
+ pDelete(pile_ptr);
+ free(listmid);
+ return 1;
+ }
+
local_thread_data_array_t *ltdata;
if((ltdata = calloc(1, sizeof(local_thread_data_array_t))) == NULL) {
printf("Calloc error %s, %d\n", __FILE__, __LINE__);
+ pthread_cond_destroy(&tcond);
+ pthread_mutex_destroy(&tlock);
+ pDelete(pile_ptr);
+ free(listmid);
+ free(thread_data_array);
return 1;
}
while(pile != NULL) {
//Create transaction id
newtid++;
- //trans_req_data_t *tosend;
if ((tosend = calloc(1, sizeof(trans_req_data_t))) == NULL) {
printf("Calloc error %s, %d\n", __FILE__, __LINE__);
+ pthread_cond_destroy(&tcond);
+ pthread_mutex_destroy(&tlock);
+ pDelete(pile_ptr);
+ free(listmid);
+ free(thread_data_array);
+ free(ltdata);
return 1;
}
tosend->f.control = TRANS_REQUEST;
tosend->f.mcount = pilecount;
tosend->f.numread = pile->numread;
tosend->f.nummod = pile->nummod;
+ tosend->f.numcreated = pile->numcreated;
tosend->f.sum_bytes = pile->sum_bytes;
tosend->listmid = listmid;
tosend->objread = pile->objread;
tosend->oidmod = pile->oidmod;
+ tosend->oidcreated = pile->oidcreated;
thread_data_array[threadnum].thread_id = threadnum;
thread_data_array[threadnum].mid = pile->mid;
- thread_data_array[threadnum].pilecount = pilecount;
thread_data_array[threadnum].buffer = tosend;
thread_data_array[threadnum].recvmsg = rcvd_control_msg;
thread_data_array[threadnum].threshold = &tcond;
thread_data_array[threadnum].replyretry = &treplyretry;
thread_data_array[threadnum].rec = record;
/* If local do not create any extra connection */
- if(pile->local != 1) { /* Not local */
- rc = pthread_create(&thread[threadnum], NULL, transRequest, (void *) &thread_data_array[threadnum]);
- if (rc) {
+ if(pile->mid != myIpAddr) { /* Not local */
+ do {
+ rc = pthread_create(&thread[threadnum], &attr, transRequest, (void *) &thread_data_array[threadnum]);
+ } while(rc!=0);
+ if(rc) {
perror("Error in pthread create\n");
+ pthread_cond_destroy(&tcond);
+ pthread_mutex_destroy(&tlock);
+ pDelete(pile_ptr);
+ free(listmid);
+ for (i = 0; i < threadnum; i++)
+ free(thread_data_array[i].buffer);
+ free(thread_data_array);
+ free(ltdata);
return 1;
}
} else { /*Local*/
- /*Unset the pile->local flag*/
- pile->local = 0;
- /*Set flag to identify that Local machine is involved*/
ltdata->tdata = &thread_data_array[threadnum];
ltdata->transinfo = &transinfo;
- val = pthread_create(&thread[threadnum], NULL, handleLocalReq, (void *) ltdata);
- if (val) {
+ do {
+ val = pthread_create(&thread[threadnum], &attr, handleLocalReq, (void *) ltdata);
+ } while(val!=0);
+ if(val) {
perror("Error in pthread create\n");
+ pthread_cond_destroy(&tcond);
+ pthread_mutex_destroy(&tlock);
+ pDelete(pile_ptr);
+ free(listmid);
+ for (i = 0; i < threadnum; i++)
+ free(thread_data_array[i].buffer);
+ free(thread_data_array);
+ free(ltdata);
return 1;
}
}
+
threadnum++;
pile = pile->next;
}
/* Free attribute and wait for the other threads */
pthread_attr_destroy(&attr);
- for (i = 0 ;i < pilecount ; i++) {
+
+ for (i = 0; i < threadnum; i++) {
rc = pthread_join(thread[i], NULL);
- if (rc)
+ if(rc)
{
- printf("ERROR return code from pthread_join() is %d\n", rc);
+ printf("Error: return code from pthread_join() is %d\n", rc);
+ pthread_cond_destroy(&tcond);
+ pthread_mutex_destroy(&tlock);
+ pDelete(pile_ptr);
+ free(listmid);
+ for (j = i; j < threadnum; j++) {
+ free(thread_data_array[j].buffer);
+ }
return 1;
}
+ free(thread_data_array[i].buffer);
}
/* Free resources */
pthread_cond_destroy(&tcond);
pthread_mutex_destroy(&tlock);
- free(tosend);
free(listmid);
- pDelete(pile);
- free(thread_data_array);
- free(ltdata);
-
- /* Retry trans commit procedure if not sucessful in the first try */
- if(treplyretry == 1) {
- /* wait a random amount of time */
- randomdelay();
- //sleep(1);
- /* Retry the commiting transaction again */
- transCommit(record);
- }
+ pDelete(pile_ptr);
+
+
+ if(treplyctrl == TRANS_ABORT) {
+ /* Free Resources */
+ objstrDelete(record->cache);
+ chashDelete(record->lookupTable);
+ free(record);
+ free(thread_data_array);
+ free(ltdata);
+ return TRANS_ABORT;
+ } else if(treplyctrl == TRANS_COMMIT) {
+ /* Free Resources */
+ objstrDelete(record->cache);
+ chashDelete(record->lookupTable);
+ free(record);
+ free(thread_data_array);
+ free(ltdata);
+ return 0;
+ } else {
+ //TODO Add other cases
+ printf("DEBUG-> THIS SHOULD NOT HAPPEN.....EXIT PROGRAM\n");
+ exit(-1);
+ }
return 0;
}
-/* This function sends information involved in the transaction request and
- * accepts a response from particpants.
+/* This function sends information involved in the transaction request
+ * to participants and accepts a response from particpants.
* It calls decideresponse() to decide on what control message
- * to send next and sends the message using sendResponse()*/
+ * to send next to participants and sends the message using sendResponse()*/
void *transRequest(void *threadarg) {
int sd, i, n;
struct sockaddr_in serv_addr;
- struct hostent *server;
thread_data_array_t *tdata;
objheader_t *headeraddr;
char buffer[RECEIVE_BUFFER_SIZE], control, recvcontrol;
char machineip[16], retval;
+
tdata = (thread_data_array_t *) threadarg;
/* Send Trans Request */
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Error in socket for TRANS_REQUEST\n");
- return NULL;
+ pthread_exit(NULL);
}
bzero((char*) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
/* Open Connection */
if (connect(sd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr)) < 0) {
perror("Error in connect for TRANS_REQUEST\n");
- return NULL;
+ close(sd);
+ pthread_exit(NULL);
}
- printf("DEBUG-> trans.c Sending TRANS_REQUEST to mid %s\n", machineip);
/* Send bytes of data with TRANS_REQUEST control message */
if (send(sd, &(tdata->buffer->f), sizeof(fixed_data_t),MSG_NOSIGNAL) < sizeof(fixed_data_t)) {
perror("Error sending fixed bytes for thread\n");
- return NULL;
+ close(sd);
+ pthread_exit(NULL);
}
/* Send list of machines involved in the transaction */
{
- int size=sizeof(unsigned int)*tdata->pilecount;
+ int size=sizeof(unsigned int)*tdata->buffer->f.mcount;
if (send(sd, tdata->buffer->listmid, size, MSG_NOSIGNAL) < size) {
perror("Error sending list of machines for thread\n");
- return NULL;
+ close(sd);
+ pthread_exit(NULL);
}
}
/* Send oids and version number tuples for objects that are read */
int size=(sizeof(unsigned int)+sizeof(short))*tdata->buffer->f.numread;
if (send(sd, tdata->buffer->objread, size, MSG_NOSIGNAL) < size) {
perror("Error sending tuples for thread\n");
- return NULL;
+ close(sd);
+ pthread_exit(NULL);
}
}
/* Send objects that are modified */
for(i = 0; i < tdata->buffer->f.nummod ; i++) {
int size;
headeraddr = chashSearch(tdata->rec->lookupTable, tdata->buffer->oidmod[i]);
- size=sizeof(objheader_t)+classsize[headeraddr->type];
+ GETSIZE(size,headeraddr);
+ size+=sizeof(objheader_t);
if (send(sd, headeraddr, size, MSG_NOSIGNAL) < size) {
perror("Error sending obj modified for thread\n");
- return NULL;
+ close(sd);
+ pthread_exit(NULL);
}
}
/* Read control message from Participant */
if((n = read(sd, &control, sizeof(char))) <= 0) {
perror("Error in reading control message from Participant\n");
- return NULL;
+ close(sd);
+ pthread_exit(NULL);
}
+
recvcontrol = control;
/* Update common data structure and increment count */
tdata->recvmsg[tdata->thread_id].rcv_status = recvcontrol;
/* Lock and update count */
- //Thread sleeps until all messages from pariticipants are received by coordinator
+ /* Thread sleeps until all messages from pariticipants are received by coordinator */
pthread_mutex_lock(tdata->lock);
(*(tdata->count))++; /* keeps track of no of messages received by the coordinator */
/* Wake up the threads and invoke decideResponse (once) */
- if(*(tdata->count) == tdata->pilecount) {
- if (decideResponse(tdata) != 0) {
- printf("decideResponse returned error %s,%d\n", __FILE__, __LINE__);
- pthread_mutex_unlock(tdata->lock);
- close(sd);
- return NULL;
- }
+ if(*(tdata->count) == tdata->buffer->f.mcount) {
+ decideResponse(tdata);
pthread_cond_broadcast(tdata->threshold);
} else {
pthread_cond_wait(tdata->threshold, tdata->lock);
* to all participants in their respective socket */
if (sendResponse(tdata, sd) == 0) {
printf("sendResponse returned error %s,%d\n", __FILE__, __LINE__);
- pthread_mutex_unlock(tdata->lock);
close(sd);
- return NULL;
+ pthread_exit(NULL);
+ }
+
+ do {
+ retval = recv((int)sd, &control, sizeof(char), 0);
+ } while (retval < sizeof(char));
+
+ if(control == TRANS_UNSUCESSFUL) {
+ //printf("DEBUG-> TRANS_ABORTED\n");
+ } else if(control == TRANS_SUCESSFUL) {
+ //printf("DEBUG-> TRANS_SUCCESSFUL\n");
+ } else {
+ //printf("DEBUG-> Error: Incorrect Transaction End Message %d\n", control);
}
/* Close connection */
}
/* This function decides the reponse that needs to be sent to
- * all Participant machines involved in the transaction commit */
-int decideResponse(thread_data_array_t *tdata) {
+ * all Participant machines after the TRANS_REQUEST protocol */
+void decideResponse(thread_data_array_t *tdata) {
char control;
int i, transagree = 0, transdisagree = 0, transsoftabort = 0; /* Counters to formulate decision of what
message to send */
- //Check common data structure
- for (i = 0 ; i < tdata->pilecount ; i++) {
- /*Switch on response from Participant */
+ for (i = 0 ; i < tdata->buffer->f.mcount; i++) {
control = tdata->recvmsg[i].rcv_status; /* tdata: keeps track of all participant responses
written onto the shared array */
switch(control) {
+ default:
+ printf("Participant sent unknown message in %s, %d\n", __FILE__, __LINE__);
+ /* treat as disagree, pass thru */
case TRANS_DISAGREE:
- printf("DEBUG-> trans.c Recv TRANS_DISAGREE\n");
transdisagree++;
break;
case TRANS_AGREE:
- printf("DEBUG-> trans.c Recv TRANS_AGREE\n");
transagree++;
break;
case TRANS_SOFT_ABORT:
- printf("DEBUG-> trans.c Recv TRANS_SOFT_ABORT\n");
transsoftabort++;
break;
- default:
- printf("Participant sent unknown message in %s, %d\n", __FILE__, __LINE__);
- return -1;
}
}
- /* Decide what control message to send to Participant */
if(transdisagree > 0) {
/* Send Abort */
*(tdata->replyctrl) = TRANS_ABORT;
- printf("DEBUG-> trans.c Sending TRANS_ABORT\n");
- objstrDelete(tdata->rec->cache);
- chashDelete(tdata->rec->lookupTable);
- free(tdata->rec);
- } else if(transagree == tdata->pilecount){
+ *(tdata->replyretry) = 0;
+ /* clear objects from prefetch cache */
+ for (i = 0; i < tdata->buffer->f.numread; i++)
+ prehashRemove(*((unsigned int *)(((char *)tdata->buffer->objread) + (sizeof(unsigned int) + sizeof(unsigned short))*i)));
+ for (i = 0; i < tdata->buffer->f.nummod; i++)
+ prehashRemove(tdata->buffer->oidmod[i]);
+ } else if(transagree == tdata->buffer->f.mcount){
/* Send Commit */
*(tdata->replyctrl) = TRANS_COMMIT;
- printf("DEBUG-> trans.c Sending TRANS_COMMIT\n");
- objstrDelete(tdata->rec->cache);
- chashDelete(tdata->rec->lookupTable);
- free(tdata->rec);
- } else if(transsoftabort > 0 && transdisagree == 0) {
+ *(tdata->replyretry) = 0;
+ } else {
/* Send Abort in soft abort case followed by retry commiting transaction again*/
*(tdata->replyctrl) = TRANS_ABORT;
*(tdata->replyretry) = 1;
- printf("DEBUG-> trans.c Sending TRANS_ABORT\n");
- } else {
- printf("DEBUG -> %s, %d: Error: undecided response\n", __FILE__, __LINE__);
- return -1;
}
- return 0;
+ return;
}
-/* This function sends the final response to all threads in their respective socket id */
+/* This function sends the final response to remote machines per thread in their respective socket id
+ * It returns a char that is only needed to check the correctness of execution of this function inside
+ * transRequest()*/
char sendResponse(thread_data_array_t *tdata, int sd) {
- int n, N, sum, oidcount = 0;
+ int n, N, sum, oidcount = 0, control;
char *ptr, retval = 0;
unsigned int *oidnotfound;
+ control = *(tdata->replyctrl);
+ if (send(sd, &control, sizeof(char), MSG_NOSIGNAL) < sizeof(char)) {
+ perror("Error sending ctrl message for participant\n");
+ return 0;
+ }
+
+ //FIXME read missing objects
/* If the decided response is due to a soft abort and missing objects at the Participant's side */
+ /*
if(tdata->recvmsg[tdata->thread_id].rcv_status == TRANS_SOFT_ABORT) {
- /* Read list of objects missing */
+ // Read list of objects missing
if((read(sd, &oidcount, sizeof(int)) != 0) && (oidcount != 0)) {
N = oidcount * sizeof(unsigned int);
if((oidnotfound = calloc(oidcount, sizeof(unsigned int))) == NULL) {
printf("Calloc error %s, %d\n", __FILE__, __LINE__);
+ return 0;
}
ptr = (char *) oidnotfound;
do {
}
retval = TRANS_SOFT_ABORT;
}
+ */
+
/* If the decided response is TRANS_ABORT */
if(*(tdata->replyctrl) == TRANS_ABORT) {
retval = TRANS_ABORT;
- } else if(*(tdata->replyctrl) == TRANS_COMMIT) { /* If the decided response is TRANS_COMMIT */
+ } else if(*(tdata->replyctrl) == TRANS_COMMIT) { /* If the decided response is TRANS_COMMIT */
retval = TRANS_COMMIT;
}
- /* Send response to the Participant */
- if (send(sd, tdata->replyctrl, sizeof(char),MSG_NOSIGNAL) < sizeof(char)) {
- perror("Error sending ctrl message for participant\n");
- }
-
+
return retval;
}
/* This function opens a connection, places an object read request to the
* remote machine, reads the control message and object if available and
* copies the object and its header to the local cache.
- * TODO replace mnum and midtoIP() with MACHINE_IP address later */
+ * */
void *getRemoteObj(transrecord_t *record, unsigned int mnum, unsigned int oid) {
int sd, size, val;
struct sockaddr_in serv_addr;
- struct hostent *server;
char control;
char machineip[16];
objheader_t *h;
void *objcopy;
+
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Error in socket\n");
return NULL;
}
+
bzero((char*) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(LISTEN_PORT);
- //serv_addr.sin_addr.s_addr = inet_addr(MACHINE_IP);
midtoIP(mnum,machineip);
machineip[15] = '\0';
serv_addr.sin_addr.s_addr = inet_addr(machineip);
+
/* Open connection */
if (connect(sd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr)) < 0) {
- perror("Error in connect\n");
+ perror("getRemoteObj() Error in connect\n");
return NULL;
}
char readrequest[sizeof(char)+sizeof(unsigned int)];
readrequest[0] = READ_REQUEST;
*((unsigned int *)(&readrequest[1])) = oid;
- if (send(sd, &readrequest, sizeof(readrequest), MSG_NOSIGNAL) < sizeof(readrequest)) {
+ if (send(sd, readrequest, sizeof(readrequest), MSG_NOSIGNAL) < sizeof(readrequest)) {
perror("Error sending message\n");
return NULL;
}
-#ifdef DEBUG1
- printf("DEBUG -> ready to rcv ...\n");
-#endif
/* Read response from the Participant */
if((val = read(sd, &control, sizeof(char))) <= 0) {
perror("No control response for getRemoteObj sent\n");
}
switch(control) {
case OBJECT_NOT_FOUND:
- printf("DEBUG -> Control OBJECT_NOT_FOUND received\n");
return NULL;
case OBJECT_FOUND:
/* Read object if found into local cache */
return NULL;
}
objcopy = objstrAlloc(record->cache, size);
- if((val = read(sd, objcopy, size)) <= 0) {
+ if((val = read(sd, (char *)objcopy, size)) <= 0) {
perror("No objects are read from the remote participant\n");
return NULL;
}
return objcopy;
}
-/*This function handles the local trans requests involved in a transaction commiting process
- * makes a decision if the local machine sends AGREE or DISAGREE or SOFT_ABORT
- * Activates the other nonlocal threads that are waiting for the decision and the
- * based on common decision by all groups involved in the transaction it
- * either commits or aborts the transaction.
- * It also frees the calloced memory resources
- */
-
+/* This function handles the local objects involved in a transaction commiting process.
+ * It also makes a decision if this local machine sends AGREE or DISAGREE or SOFT_ABORT to coordinator.
+ * Note Coordinator = local machine
+ * It wakes up the other threads from remote participants that are waiting for the coordinator's decision and
+ * based on common agreement it either commits or aborts the transaction.
+ * It also frees the memory resources */
void *handleLocalReq(void *threadarg) {
- int val, i = 0;
- short version;
- char control = 0, *ptr;
+ unsigned int *oidnotfound = NULL, *oidlocked = NULL;
+ local_thread_data_array_t *localtdata;
+ int objnotfound = 0, objlocked = 0;
+ int v_nomatch = 0, v_matchlock = 0, v_matchnolock = 0;
+ int numread, i;
unsigned int oid;
- unsigned int *oidnotfound = NULL, *oidlocked = NULL, *oidmod = NULL;
- void *mobj, *modptr;
+ unsigned short version;
+ void *mobj;
objheader_t *headptr;
- local_thread_data_array_t *localtdata;
localtdata = (local_thread_data_array_t *) threadarg;
/* Counters and arrays to formulate decision on control message to be sent */
oidnotfound = (unsigned int *) calloc((localtdata->tdata->buffer->f.numread + localtdata->tdata->buffer->f.nummod), sizeof(unsigned int));
oidlocked = (unsigned int *) calloc((localtdata->tdata->buffer->f.numread + localtdata->tdata->buffer->f.nummod), sizeof(unsigned int));
- oidmod = (unsigned int *) calloc(localtdata->tdata->buffer->f.nummod, sizeof(unsigned int));
- int objnotfound = 0, objlocked = 0, objmod =0, v_nomatch = 0, v_matchlock = 0, v_matchnolock = 0;
- int objmodnotfound = 0, nummodfound = 0;
-
- /* modptr points to the beginning of the object store
- * created at the Pariticipant */
- if ((modptr = objstrAlloc(mainobjstore, localtdata->tdata->buffer->f.sum_bytes)) == NULL) {
- printf("objstrAlloc error for modified objects %s, %d\n", __FILE__, __LINE__);
- return NULL;
- }
-
- ptr = modptr;
+ numread = localtdata->tdata->buffer->f.numread;
/* Process each oid in the machine pile/ group per thread */
for (i = 0; i < localtdata->tdata->buffer->f.numread + localtdata->tdata->buffer->f.nummod; i++) {
- if (i < localtdata->tdata->buffer->f.numread) {//Objs only read and not modified
+ if (i < localtdata->tdata->buffer->f.numread) {
int incr = sizeof(unsigned int) + sizeof(short);// Offset that points to next position in the objread array
incr *= i;
- oid = *((unsigned int *)(localtdata->tdata->buffer->objread + incr));
- incr += sizeof(unsigned int);
- version = *((short *)(localtdata->tdata->buffer->objread + incr));
- } else {//Objs modified
- headptr = (objheader_t *) ptr;
- oid = headptr->oid;
- oidmod[objmod] = oid;//Array containing modified oids
- objmod++;
+ oid = *((unsigned int *)(((char *)localtdata->tdata->buffer->objread) + incr));
+ version = *((short *)(((char *)localtdata->tdata->buffer->objread) + incr + sizeof(unsigned int)));
+ } else { // Objects Modified
+ int tmpsize;
+ headptr = (objheader_t *) chashSearch(localtdata->tdata->rec->lookupTable, localtdata->tdata->buffer->oidmod[i-numread]);
+ if (headptr == NULL) {
+ printf("Error: handleLocalReq() returning NULL %s, %d\n", __FILE__, __LINE__);
+ return NULL;
+ }
+ oid = OID(headptr);
version = headptr->version;
- ptr += sizeof(objheader_t) + classsize[headptr->type];
}
-
/* Check if object is still present in the machine since the beginning of TRANS_REQUEST */
/* Save the oids not found and number of oids not found for later use */
- if ((mobj = mhashSearch(oid)) == NULL) {/* Obj not found */
+ if ((mobj = mhashSearch(oid)) == NULL) { /* Obj not found */
/* Save the oids not found and number of oids not found for later use */
-
- oidnotfound[objnotfound] = ((objheader_t *)mobj)->oid;
+ oidnotfound[objnotfound] = oid;
objnotfound++;
} else { /* If Obj found in machine (i.e. has not moved) */
/* Check if Obj is locked by any previous transaction */
- if ((((objheader_t *)mobj)->status & LOCK) == LOCK) {
- if (version == ((objheader_t *)mobj)->version) { /* If not locked then match versions */
+ if ((STATUS((objheader_t *)mobj) & LOCK) == LOCK) {
+ if (version == ((objheader_t *)mobj)->version) { /* If locked then match versions */
v_matchlock++;
} else {/* If versions don't match ...HARD ABORT */
v_nomatch++;
/* Send TRANS_DISAGREE to Coordinator */
localtdata->tdata->recvmsg[localtdata->tdata->thread_id].rcv_status = TRANS_DISAGREE;
- printf("DEBUG -> Sending TRANS_DISAGREE\n");
- //return tdata->recvmsg[tdata->thread_id].rcv_status;
}
} else {/* If Obj is not locked then lock object */
- ((objheader_t *)mobj)->status |= LOCK;
- //TODO Remove this for Testing
- randomdelay();
-
+ STATUS(((objheader_t *)mobj)) |= LOCK;
/* Save all object oids that are locked on this machine during this transaction request call */
- oidlocked[objlocked] = ((objheader_t *)mobj)->oid;
+ oidlocked[objlocked] = OID(((objheader_t *)mobj));
objlocked++;
if (version == ((objheader_t *)mobj)->version) { /* Check if versions match */
v_matchnolock++;
v_nomatch++;
/* Send TRANS_DISAGREE to Coordinator */
localtdata->tdata->recvmsg[localtdata->tdata->thread_id].rcv_status = TRANS_DISAGREE;
- printf("DEBUG -> Sending TRANS_DISAGREE\n");
- // return tdata->recvmsg[tdata->thread_id].rcv_status;
}
}
}
- }
-
- /*Decide the response to be sent to the Coordinator( the local machine in this case)*/
-
+ } // End for
/* Condition to send TRANS_AGREE */
if(v_matchnolock == localtdata->tdata->buffer->f.numread + localtdata->tdata->buffer->f.nummod) {
localtdata->tdata->recvmsg[localtdata->tdata->thread_id].rcv_status = TRANS_AGREE;
- printf("DEBUG -> Sending TRANS_AGREE\n");
}
/* Condition to send TRANS_SOFT_ABORT */
if((v_matchlock > 0 && v_nomatch == 0) || (objnotfound > 0 && v_nomatch == 0)) {
localtdata->tdata->recvmsg[localtdata->tdata->thread_id].rcv_status = TRANS_SOFT_ABORT;
- printf("DEBUG -> Sending TRANS_SOFT_ABORT\n");
- //TODO currently the only soft abort case that is supported is when object locked by previous
- //transaction => v_matchlock > 0
- //The other case for SOFT ABORT i.e. when object is not found but versions match is not supported
- /* Send number of oids not found and the missing oids if objects are missing in the machine */
- /* TODO Remember to store the oidnotfound for later use
- if(objnotfound != 0) {
- int size = sizeof(unsigned int)* objnotfound;
- }
- */
}
/* Fill out the trans_commit_data_t data structure. This is required for a trans commit process
* if Participant receives a TRANS_COMMIT */
- localtdata->transinfo->objmod = oidmod;
localtdata->transinfo->objlocked = oidlocked;
localtdata->transinfo->objnotfound = oidnotfound;
- localtdata->transinfo->modptr = modptr;
- localtdata->transinfo->nummod = localtdata->tdata->buffer->f.nummod;
+ localtdata->transinfo->modptr = NULL;
localtdata->transinfo->numlocked = objlocked;
localtdata->transinfo->numnotfound = objnotfound;
-
- /*Set flag to show that common data structure for this individual thread has been written to */
- //*(tdata->localstatus) |= LM_UPDATED;
-
/* Lock and update count */
//Thread sleeps until all messages from pariticipants are received by coordinator
pthread_mutex_lock(localtdata->tdata->lock);
(*(localtdata->tdata->count))++; /* keeps track of no of messages received by the coordinator */
/* Wake up the threads and invoke decideResponse (once) */
- if(*(localtdata->tdata->count) == localtdata->tdata->pilecount) {
- if (decideResponse(localtdata->tdata) != 0) {
- printf("decideResponse returned error %s,%d\n", __FILE__, __LINE__);
- pthread_mutex_unlock(localtdata->tdata->lock);
- return NULL;
- }
+ if(*(localtdata->tdata->count) == localtdata->tdata->buffer->f.mcount) {
+ decideResponse(localtdata->tdata);
pthread_cond_broadcast(localtdata->tdata->threshold);
} else {
pthread_cond_wait(localtdata->tdata->threshold, localtdata->tdata->lock);
}
pthread_mutex_unlock(localtdata->tdata->lock);
-
- /*Based on DecideResponse(), Either COMMIT or ABORT the operation*/
if(*(localtdata->tdata->replyctrl) == TRANS_ABORT){
- if(transAbortProcess(modptr,oidlocked, localtdata->transinfo->numlocked, localtdata->transinfo->nummod, localtdata->tdata->buffer->f.numread) != 0) {
+ if(transAbortProcess(localtdata) != 0) {
printf("Error in transAbortProcess() %s,%d\n", __FILE__, __LINE__);
- return NULL;
+ pthread_exit(NULL);
}
- }else if(*(localtdata->tdata->replyctrl) == TRANS_COMMIT){
- if(transComProcess(localtdata->transinfo) != 0) {
+ } else if(*(localtdata->tdata->replyctrl) == TRANS_COMMIT) {
+ if(transComProcess(localtdata) != 0) {
printf("Error in transComProcess() %s,%d\n", __FILE__, __LINE__);
- return NULL;
+ pthread_exit(NULL);
}
}
-
/* Free memory */
- printf("DEBUG -> Freeing...\n");
- fflush(stdout);
- if (localtdata->transinfo->objmod != NULL) {
- free(localtdata->transinfo->objmod);
- localtdata->transinfo->objmod = NULL;
- }
if (localtdata->transinfo->objlocked != NULL) {
free(localtdata->transinfo->objlocked);
- localtdata->transinfo->objlocked = NULL;
}
if (localtdata->transinfo->objnotfound != NULL) {
free(localtdata->transinfo->objnotfound);
- localtdata->transinfo->objnotfound = NULL;
}
pthread_exit(NULL);
}
-/* This function completes the ABORT process if the transaction is aborting
-*/
-int transAbortProcess(void *modptr, unsigned int *objlocked, int numlocked, int nummod, int numread) {
- char *ptr;
- int i;
- objheader_t *tmp_header;
+
+/* This function completes the ABORT process if the transaction is aborting */
+int transAbortProcess(local_thread_data_array_t *localtdata) {
+ int i, numlocked;
+ unsigned int *objlocked;
void *header;
- printf("DEBUG -> Recv TRANS_ABORT\n");
- /* Set all ref counts as 1 and do garbage collection */
- ptr = modptr;
- for(i = 0; i< nummod; i++) {
- tmp_header = (objheader_t *)ptr;
- tmp_header->rcount = 1;
- ptr += sizeof(objheader_t) + classsize[tmp_header->type];
- }
- /* Unlock objects that was locked due to this transaction */
- for(i = 0; i< numlocked; i++) {
- header = mhashSearch(objlocked[i]);// find the header address
- ((objheader_t *)header)->status &= ~(LOCK);
- }
+ numlocked = localtdata->transinfo->numlocked;
+ objlocked = localtdata->transinfo->objlocked;
- /* Send ack to Coordinator */
- printf("DEBUG-> TRANS_SUCCESSFUL\n");
+ for (i = 0; i < numlocked; i++) {
+ if((header = mhashSearch(objlocked[i])) == NULL) {
+ printf("mhashsearch returns NULL at %s, %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+ STATUS(((objheader_t *)header)) &= ~(LOCK);
+ }
- /*Free the pointer */
- ptr = NULL;
return 0;
}
-/*This function completes the COMMIT process is the transaction is commiting
-*/
-int transComProcess(trans_commit_data_t *transinfo) {
- objheader_t *header;
- int i = 0, offset = 0;
- char control;
-
- printf("DEBUG -> Recv TRANS_COMMIT\n");
- /* Process each modified object saved in the mainobject store */
- for(i=0; i<transinfo->nummod; i++) {
- if((header = (objheader_t *) mhashSearch(transinfo->objmod[i])) == NULL) {
- printf("mhashsearch returns NULL at %s, %d\n", __FILE__, __LINE__);
+/*This function completes the COMMIT process is the transaction is commiting*/
+int transComProcess(local_thread_data_array_t *localtdata) {
+ objheader_t *header, *tcptr;
+ int i, nummod, tmpsize, numcreated, numlocked;
+ unsigned int *oidmod, *oidcreated, *oidlocked;
+ void *ptrcreate;
+
+ nummod = localtdata->tdata->buffer->f.nummod;
+ oidmod = localtdata->tdata->buffer->oidmod;
+ numcreated = localtdata->tdata->buffer->f.numcreated;
+ oidcreated = localtdata->tdata->buffer->oidcreated;
+ numlocked = localtdata->transinfo->numlocked;
+ oidlocked = localtdata->transinfo->objlocked;
+
+ for (i = 0; i < nummod; i++) {
+ if((header = (objheader_t *) mhashSearch(oidmod[i])) == NULL) {
+ printf("Error: transComProcess() mhashsearch returns NULL at %s, %d\n", __FILE__, __LINE__);
+ return 1;
}
- /* Change reference count of older address and free space in objstr ?? */
- header->rcount = 1; //TODO Not sure what would be the val
-
- /* Change ptr address in mhash table */
- mhashRemove(transinfo->objmod[i]);
- mhashInsert(transinfo->objmod[i], (transinfo->modptr + offset));
- offset += sizeof(objheader_t) + classsize[header->type];
-
- /* Update object version number */
- header = (objheader_t *) mhashSearch(transinfo->objmod[i]);
+ /* Copy from transaction cache -> main object store */
+ if ((tcptr = ((objheader_t *) chashSearch(localtdata->tdata->rec->lookupTable, oidmod[i]))) == NULL) {
+ printf("Error: transComProcess() chashSearch returned NULL at %s, %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+ GETSIZE(tmpsize, header);
+ pthread_mutex_lock(&mainobjstore_mutex);
+ memcpy((char*)header+sizeof(objheader_t), (char *)tcptr+ sizeof(objheader_t), tmpsize);
header->version += 1;
+ if(header->notifylist != NULL) {
+ notifyAll(&header->notifylist, OID(header), header->version);
+ }
+ pthread_mutex_unlock(&mainobjstore_mutex);
+ }
+ /* If object is newly created inside transaction then commit it */
+ for (i = 0; i < numcreated; i++) {
+ if ((header = ((objheader_t *) chashSearch(localtdata->tdata->rec->lookupTable, oidcreated[i]))) == NULL) {
+ printf("Error: transComProcess() chashSearch returned NULL at %s, %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+ GETSIZE(tmpsize, header);
+ tmpsize += sizeof(objheader_t);
+ pthread_mutex_lock(&mainobjstore_mutex);
+ if ((ptrcreate = objstrAlloc(mainobjstore, tmpsize)) == NULL) {
+ printf("Error: transComProcess() failed objstrAlloc %s, %d\n", __FILE__, __LINE__);
+ pthread_mutex_unlock(&mainobjstore_mutex);
+ return 1;
+ }
+ pthread_mutex_unlock(&mainobjstore_mutex);
+ memcpy(ptrcreate, header, tmpsize);
+ mhashInsert(oidcreated[i], ptrcreate);
+ lhashInsert(oidcreated[i], myIpAddr);
}
-
/* Unlock locked objects */
- for(i=0; i<transinfo->numlocked; i++) {
- header = (objheader_t *) mhashSearch(transinfo->objlocked[i]);
- header->status &= ~(LOCK);
+ for(i = 0; i < numlocked; i++) {
+ if((header = (objheader_t *) mhashSearch(oidlocked[i])) == NULL) {
+ printf("mhashsearch returns NULL at %s, %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+ STATUS(header) &= ~(LOCK);
}
- //TODO Update location lookup table
-
- /* Send ack to Coordinator */
- printf("DEBUG-> TRANS_SUCESSFUL\n");
return 0;
}
oid = GET_PTR_OID(ptr);
endoffsets = GET_PTR_EOFF(ptr, ntuples);
arryfields = GET_PTR_ARRYFLD(ptr, ntuples);
+
/* Find offset length for each tuple */
int numoffset[ntuples];
numoffset[0] = endoffsets[0];
}
/* Check for redundant tuples by comparing oids of each tuple */
for(i = 0; i < ntuples; i++) {
- if(oid[i] == -1)
+ if(oid[i] == 0)
continue;
for(j = i+1 ; j < ntuples; j++) {
- if(oid[j] == -1)
+ if(oid[j] == 0)
continue;
/*If oids of tuples match */
if (oid[i] == oid[j]) {
if(i == 0) {
k = 0;
- index = endoffsets[j -1];
- for(count = 0; count < slength; count ++) {
- if (arryfields[k] != arryfields[index]) {
- break;
- }
- index++;
- k++;
- }
} else {
k = endoffsets[i-1];
- index = endoffsets[j-1];
- printf("Value of slength = %d\n", slength);
- for(count = 0; count < slength; count++) {
- if(arryfields[k] != arryfields[index]) {
- break;
- }
- index++;
- k++;
- }
}
-
+ index = endoffsets[j -1];
+ for(count = 0; count < slength; count ++) {
+ if (arryfields[k] != arryfields[index]) {
+ break;
+ }
+ index++;
+ k++;
+ }
if(slength == count) {
- oid[sindex] = -1;
- }
- }
- }
- }
-}
-
-void checkPreCache(prefetchqelem_t *node, int *numoffset, int counter, int loopcount, unsigned int objoid, int index, int iter, int oidnfound) {
- char *ptr, *tmp;
- int ntuples, i, k, flag;
- unsigned int * oid;
- short *endoffsets, *arryfields;
- objheader_t *header;
-
- ptr = (char *) node;
- ntuples = *(GET_NTUPLES(ptr));
- oid = GET_PTR_OID(ptr);
- endoffsets = GET_PTR_EOFF(ptr, ntuples);
- arryfields = GET_PTR_ARRYFLD(ptr, ntuples);
-
- if(oidnfound == 1) {
- if((header = (objheader_t *) prehashSearch(objoid)) == NULL) {
- return;
- } else { //Found in Prefetch Cache
- //TODO Decide if object is too old, if old remove from cache
- tmp = (char *) header;
- /* Check if any of the offset oid is available in the Prefetch cache */
- for(i = counter; i < loopcount; i++) {
- objoid = *(tmp + sizeof(objheader_t) + arryfields[counter]);
- if((header = (objheader_t *)prehashSearch(objoid)) != NULL) {
- flag = 0;
- } else {
- flag = 1;
- break;
+ oid[sindex] = 0;
}
}
}
- } else {
- for(i = counter; i<loopcount; i++) {
- if((header = (objheader_t *)prehashSearch(objoid)) != NULL) {
- tmp = (char *) header;
- objoid = *(tmp + sizeof(objheader_t) + arryfields[index]);
- flag = 0;
- index++;
- } else {
- flag = 1;
- break;
- }
- }
- }
-
- /* If oid not found locally or in prefetch cache then
- * assign the latest oid found as the new oid
- * and copy left over offsets into the arrayoffsetfieldarray*/
- oid[iter] = objoid;
- numoffset[iter] = numoffset[iter] - (i+1);
- for(k = 0; k < numoffset[iter] ; k++) {
- arryfields[endoffsets[counter]+k] = arryfields[endoffsets[counter]+k+1];
- }
-
- if(flag == 0) {
- oid[iter] = -1;
- numoffset[iter] = 0;
}
}
-
/* This function makes machine piles to be added into the machine pile queue for each prefetch call */
prefetchpile_t *makePreGroups(prefetchqelem_t *node, int *numoffset) {
- char *ptr, *tmp;
- int ntuples, slength, i, machinenum;
- int maxoffset;
+ char *ptr;
+ int ntuples, i, machinenum, count=0;
unsigned int *oid;
short *endoffsets, *arryfields, *offset;
- prefetchpile_t *head = NULL;
+ prefetchpile_t *head = NULL, *tmp = NULL;
/* Check for the case x.y.z and a.b.c are same oids */
ptr = (char *) node;
endoffsets = GET_PTR_EOFF(ptr, ntuples);
arryfields = GET_PTR_ARRYFLD(ptr, ntuples);
+ if((head = (prefetchpile_t *) calloc(1, sizeof(prefetchpile_t))) == NULL) {
+ printf("Calloc error: %s %d\n", __FILE__, __LINE__);
+ return NULL;
+ }
+
/* Check for redundant tuples by comparing oids of each tuple */
for(i = 0; i < ntuples; i++) {
- if(oid[i] == -1)
+ if(oid[i] == 0){
+ if(head->next != NULL) {
+ if((tmp = (prefetchpile_t *) calloc(1, sizeof(prefetchpile_t))) == NULL) {
+ printf("Calloc error: %s %d\n", __FILE__, __LINE__);
+ return NULL;
+ }
+ tmp->mid = myIpAddr;
+ tmp->next = head;
+ head = tmp;
+ } else {
+ head->mid = myIpAddr;
+ }
continue;
+ }
/* For each tuple make piles */
if ((machinenum = lhashSearch(oid[i])) == 0) {
printf("Error: No such Machine %s, %d\n", __FILE__, __LINE__);
return NULL;
}
/* Insert into machine pile */
- offset = &arryfields[endoffsets[i-1]];
- insertPile(machinenum, oid[i], numoffset[i], offset, head);
+ if(i == 0){
+ offset = &arryfields[0];
+ } else {
+ offset = &arryfields[endoffsets[i-1]];
+ }
+
+ if((head = insertPile(machinenum, oid[i], numoffset[i], offset, head)) == NULL){
+ printf("Error: Couldn't create a pile %s, %d\n", __FILE__, __LINE__);
+ return NULL;
+ }
}
return head;
}
-
-/* This function checks if the oids within the prefetch tuples are available locally.
- * If yes then makes the tuple invalid. If no then rearranges oid and offset values in
- * the prefetchqelem_t node to represent a new prefetch tuple */
prefetchpile_t *foundLocal(prefetchqelem_t *node) {
- int ntuples,i, j, k, oidnfound = 0, index, flag;
+ int ntuples,i, j, k, oidnfound = 0, arryfieldindex,nextarryfieldindex, flag = 0, val;
unsigned int *oid;
unsigned int objoid;
+ int isArray = 0;
char *ptr, *tmp;
objheader_t *objheader;
short *endoffsets, *arryfields;
oid = GET_PTR_OID(ptr);
endoffsets = GET_PTR_EOFF(ptr, ntuples);
arryfields = GET_PTR_ARRYFLD(ptr, ntuples);
+
/* Find offset length for each tuple */
int numoffset[ntuples];//Number of offsets for each tuple
numoffset[0] = endoffsets[0];
numoffset[i] = endoffsets[i] - endoffsets[i-1];
}
for(i = 0; i < ntuples; i++) {
- if(oid[i] == -1)
+ if(oid[i] == 0){
+ if(i == 0) {
+ arryfieldindex = 0;
+ nextarryfieldindex = endoffsets[0];
+ }else {
+ arryfieldindex = endoffsets[i-1];
+ nextarryfieldindex = endoffsets[i];
+ }
+ numoffset[i] = 0;
+ endoffsets[0] = val = numoffset[0];
+ for(k = 1; k < ntuples; k++) {
+ val = val + numoffset[k];
+ endoffsets[k] = val;
+ }
+
+ for(k = 0; k<endoffsets[ntuples-1]; k++) {
+ arryfields[arryfieldindex+k] = arryfields[nextarryfieldindex+k];
+ }
continue;
+ }
/* If object found locally */
if((objheader = (objheader_t*) mhashSearch(oid[i])) != NULL) {
- oidnfound = 0;
tmp = (char *) objheader;
- /* Find the oid of its offset value */
- if(i == 0)
- index = 0;
- else
- index = endoffsets[i - 1];
- for(j = 0 ; j < numoffset[i] ; j++) {
- objoid = *(tmp + sizeof(objheader_t) + arryfields[index]);
- /*If oid found locally then
- *assign the latest oid found as the new oid
- *and copy left over offsets into the arrayoffsetfieldarray*/
+ int orgnumoffset = numoffset[i];
+ if(i == 0) {
+ arryfieldindex = 0;
+ }else {
+ arryfieldindex = endoffsets[i-1];
+ }
+
+ for(j = 0; j<orgnumoffset; j++) {
+ /* Check for arrays */
+ if(TYPE(objheader) > NUMCLASSES) {
+ isArray = 1;
+ }
+ if(isArray == 1) {
+ int elementsize = classsize[TYPE(objheader)];
+ objoid = *((unsigned int *)(tmp + sizeof(objheader_t) + sizeof(struct ArrayObject) + (elementsize*arryfields[arryfieldindex])));
+ } else {
+ objoid = *((unsigned int *)(tmp + sizeof(objheader_t) + arryfields[arryfieldindex]));
+ }
+ //Update numoffset array
+ numoffset[i] = numoffset[i] - 1;
+ //Update oid array
oid[i] = objoid;
- numoffset[i] = numoffset[i] - (j+1);
- for(k = 0; k < numoffset[i]; k++)
- arryfields[endoffsets[j]+ k] = arryfields[endoffsets[j]+k+1];
- index++;
- /*New offset oid not found */
- if((objheader = (objheader_t*) mhashSearch(objoid)) == NULL) {
+ //Update endoffset array
+ endoffsets[0] = val = numoffset[0];
+ for(k = 1; k < ntuples; k++) {
+ val = val + numoffset[k];
+ endoffsets[k] = val;
+ }
+ //Update arrayfields array
+ for(k = 0; k < endoffsets[ntuples-1]; k++) {
+ arryfields[arryfieldindex+k] = arryfields[arryfieldindex+k+1];
+ }
+ if((objheader = (objheader_t*) mhashSearch(oid[i])) == NULL) {
flag = 1;
- checkPreCache(node, numoffset, j, numoffset[i], objoid, index, i, oidnfound);
+ checkPreCache(node, numoffset, oid[i], i);
break;
- } else
- flag = 0;
+ }
+ tmp = (char *) objheader;
+ isArray = 0;
}
-
/*If all offset oids are found locally,make the prefetch tuple invalid */
if(flag == 0) {
- oid[i] = -1;
- numoffset[i] = 0;
+ oid[i] = 0;
}
} else {
- oidnfound = 1;
/* Look in Prefetch cache */
- checkPreCache(node, numoffset, 0, numoffset[i], oid[i], 0, i, oidnfound);
+ checkPreCache(node, numoffset, oid[i],i);
}
-
}
+
/* Make machine groups */
- head = makePreGroups(node, numoffset);
+ if((head = makePreGroups(node, numoffset)) == NULL) {
+ printf("Error in makePreGroups() %s %d\n", __FILE__, __LINE__);
+ return NULL;
+ }
+
return head;
}
+void checkPreCache(prefetchqelem_t *node, int *numoffset, unsigned int objoid, int index) {
+ char *ptr, *tmp;
+ int ntuples, i, k, flag=0, isArray =0, arryfieldindex, val;
+ unsigned int * oid;
+ short *endoffsets, *arryfields;
+ objheader_t *header;
+
+ ptr = (char *) node;
+ ntuples = *(GET_NTUPLES(ptr));
+ oid = GET_PTR_OID(ptr);
+ endoffsets = GET_PTR_EOFF(ptr, ntuples);
+ arryfields = GET_PTR_ARRYFLD(ptr, ntuples);
+
+ if((header = (objheader_t *) prehashSearch(objoid)) == NULL) {
+ return;
+ } else { //Found in Prefetch Cache
+ //TODO Decide if object is too old, if old remove from cache
+ tmp = (char *) header;
+ int loopcount = numoffset[index];
+ if(index == 0)
+ arryfieldindex = 0;
+ else
+ arryfieldindex = endoffsets[(index - 1)];
+ // Check if any of the offset oid is available in the Prefetch cache
+ for(i = 0; i < loopcount; i++) {
+ /* Check for arrays */
+ if(TYPE(header) > NUMCLASSES) {
+ isArray = 1;
+ }
+ if(isArray == 1) {
+ int elementsize = classsize[TYPE(header)];
+ objoid = *((unsigned int *)(tmp + sizeof(objheader_t) + sizeof(struct ArrayObject) + (elementsize*arryfields[arryfieldindex])));
+ } else {
+ objoid = *((unsigned int *)(tmp + sizeof(objheader_t) + arryfields[arryfieldindex]));
+ }
+ //Update numoffset array
+ numoffset[index] = numoffset[index] - 1;
+ //Update oid array
+ oid[index] = objoid;
+ //Update endoffset array
+ endoffsets[0] = val = numoffset[0];
+ for(k = 1; k < ntuples; k++) {
+ val = val + numoffset[k];
+ endoffsets[k] = val;
+ }
+ //Update arrayfields array
+ for(k = 0; k < endoffsets[ntuples-1]; k++) {
+ arryfields[arryfieldindex+k] = arryfields[arryfieldindex+k+1];
+ }
+ if((header = (objheader_t *)prehashSearch(oid[index])) != NULL) {
+ tmp = (char *) header;
+ isArray = 0;
+ } else {
+ flag = 1;
+ break;
+ }
+ }
+ }
+ //Found in the prefetch cache
+ if(flag == 0 && (numoffset[index] == 0)) {
+ oid[index] = 0;
+ }
+}
+
+
+
/* This function is called by the thread calling transPrefetch */
void *transPrefetch(void *t) {
- //int *offstarray = NULL;
prefetchqelem_t *qnode;
prefetchpile_t *pilehead = NULL;
+ prefetchpile_t *ptr = NULL, *piletail = NULL;
while(1) {
/* lock mutex of primary prefetch queue */
}
/* dequeue node to create a machine piles and finally unlock mutex */
- if((qnode = dequeue()) == NULL) {
+ if((qnode = pre_dequeue()) == NULL) {
printf("Error: No node returned %s, %d\n", __FILE__, __LINE__);
- return NULL;
+ pthread_mutex_unlock(&pqueue.qlock);
+ pthread_exit(NULL);
}
pthread_mutex_unlock(&pqueue.qlock);
+
/* Reduce redundant prefetch requests */
checkPrefetchTuples(qnode);
/* Check if the tuples are found locally, if yes then reduce them further*/
/* and group requests by remote machine ids by calling the makePreGroups() */
- pilehead = foundLocal(qnode);
+ if((pilehead = foundLocal(qnode)) == NULL) {
+ printf("Error: No node created for serving prefetch request %s %d\n", __FILE__, __LINE__);
+ pthread_exit(NULL);
+ }
+
+ ptr = pilehead;
+ while(ptr != NULL) {
+ if(ptr->next == NULL) {
+ piletail = ptr;
+ }
+ ptr = ptr->next;
+ }
/* Lock mutex of pool queue */
pthread_mutex_lock(&mcqueue.qlock);
/* Update the pool queue with the new remote machine piles generated per prefetch call */
- mcpileenqueue(pilehead);
+ mcpileenqueue(pilehead, piletail);
/* Broadcast signal on machine pile queue */
pthread_cond_broadcast(&mcqueue.qcond);
/* Unlock mutex of machine pile queue */
pthread_mutex_unlock(&mcqueue.qlock);
/* Deallocate the prefetch queue pile node */
predealloc(qnode);
-
}
}
-/*The pool of threads work on this function to establish connection with
- * remote machines */
+/* Each thread in the pool of threads calls this function to establish connection with
+ * remote machines, send the prefetch requests and process the reponses from
+ * the remote machines .
+ * The thread is active throughout the period of runtime */
void *mcqProcess(void *threadid) {
int tid;
/* Dequeue node to send remote machine connections*/
if((mcpilenode = mcpiledequeue()) == NULL) {
printf("Dequeue Error: No node returned %s %d\n", __FILE__, __LINE__);
- return NULL;
+ pthread_mutex_unlock(&mcqueue.qlock);
+ pthread_exit(NULL);
}
/* Unlock mutex */
pthread_mutex_unlock(&mcqueue.qlock);
/*Initiate connection to remote host and send request */
/* Process Request */
- sendPrefetchReq(mcpilenode, tid);
- /* TODO: For each object not found query DHT for new location and retrieve the object */
+ if(mcpilenode->mid != myIpAddr)
+ sendPrefetchReq(mcpilenode);
/* Deallocate the machine queue pile node */
mcdealloc(mcpilenode);
}
}
-/*This function is called by the thread that processes the
- * prefetch request makes piles to prefetch records and prefetches the oids from remote machines */
-int transPrefetchProcess(transrecord_t *record, int *arrayofoffset[], short numoids){
- int i, k = 0, rc;
- int arraylength[numoids];
- unsigned int machinenumber;
- objheader_t *tmp, *objheader;
- void *objcopy;
- int size;
- pthread_attr_t attr;
-
- /* Given tuple find length of tuple*/
- for(i = 0; i < numoids ; i++) {
- arraylength[i] = arrayLength(arrayofoffset[i]);
- }
-
- /* Initialize and set thread attributes
- * Spawn a thread for each prefetch request sent*/
- pthread_t thread[numoids];
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- /* Create Machine Piles to send prefetch requests use threads*/
- for( i = 0 ; i< numoids ; i++) {
- if(arrayofoffset[i][0] == -1)
- continue;
- else{
- /* For each Pile in the machine send TRANS_PREFETCH */
- //makePiles(arrayofoffset, numoids);
- /* Fill thread data structure */
- //rc = pthread_create(&thread[i] , &attr, sendPrefetchReq, (void *) arrayofoffset[i]);
- if (rc) {
- perror("Error in pthread create at transPrefetchProcess()\n");
- return 1;
- }
-
- }
- }
-
- /* Free attribute and wait to join other threads */
- for (i = 0 ;i < numoids ; i++) {
- rc = pthread_join(thread[i], NULL);
- if (rc) {
- perror("Error pthread_join() in transPrefetchProcess()\n");
- return 1;
- }
- }
- pthread_attr_destroy(&attr);
-
- return 0;
-
-}
-
-void sendPrefetchReq(prefetchpile_t *mcpilenode, int threadid) {
- int sd, i, offset, off, len, endpair, numoffsets, count = 0;
- struct sockaddr_in serv_addr;
- struct hostent *server;
+void sendPrefetchReq(prefetchpile_t *mcpilenode) {
+ int sd, i, off, len, endpair, count = 0;
+ struct sockaddr_in remoteAddr;
char machineip[16], control;
objpile_t *tmp;
-
+ unsigned int mid;
/* Send Trans Prefetch Request */
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("Error in socket for TRANS_REQUEST\n");
+ perror("Error in socket for SEND_PREFETCH_REQUEST\n");
return;
}
- bzero((char*) &serv_addr, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(LISTEN_PORT);
- //serv_addr.sin_addr.s_addr = inet_addr(MACHINE_IP);
- midtoIP(mcpilenode->mid ,machineip);
- machineip[15] = '\0';
- serv_addr.sin_addr.s_addr = inet_addr(machineip);
+
+ mid = mcpilenode->mid;
+
+ bzero(&remoteAddr, sizeof(remoteAddr));
+ remoteAddr.sin_family = AF_INET;
+ remoteAddr.sin_port = htons(LISTEN_PORT);
+ remoteAddr.sin_addr.s_addr = htonl(mid);
/* Open Connection */
- if (connect(sd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr)) < 0) {
- perror("Error in connect for TRANS_REQUEST\n");
+ if (connect(sd, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr)) < 0) {
+ printf("%s():error %d connecting to %s:%d\n", __func__, errno,
+ inet_ntoa(remoteAddr.sin_addr), LISTEN_PORT);
+ close(sd);
return;
}
control = TRANS_PREFETCH;
if(send(sd, &control, sizeof(char), MSG_NOSIGNAL) < sizeof(char)) {
perror("Error in sending prefetch control\n");
+ close(sd);
return;
}
/* Send Oids and offsets in pairs */
tmp = mcpilenode->objpiles;
while(tmp != NULL) {
- off = offset = 0;
- count++; // Keeps track of the number of oid and offset tuples sent per remote machine
- len = sizeof(int) + sizeof(unsigned int) + ((tmp->numoffset) * sizeof(short));
+ off = 0;
+ count++; /* Keeps track of the number of oid and offset tuples sent per remote machine */
+ len = sizeof(int) + sizeof(unsigned int) + ((tmp->numoffset) * sizeof(unsigned short));
char oidnoffset[len];
- memcpy(oidnoffset, &len, sizeof(int));
+ bzero(oidnoffset, len);
+ *((unsigned int*)oidnoffset) = len;
off = sizeof(int);
- memcpy(oidnoffset + off, &tmp->oid, sizeof(unsigned int));
+ *((unsigned int *)((char *)oidnoffset + off)) = tmp->oid;
off += sizeof(unsigned int);
- for(i = 0; i < numoffsets; i++) {
- offset = off + (i * sizeof(short));
- memcpy(oidnoffset + offset, tmp->offset, sizeof(short));
+ for(i = 0; i < tmp->numoffset; i++) {
+ *((unsigned short*)((char *)oidnoffset + off)) = tmp->offset[i];
+ off+=sizeof(unsigned short);
}
- if (send(sd, &oidnoffset, sizeof(oidnoffset),MSG_NOSIGNAL) < sizeof(oidnoffset)) {
+
+ if (send(sd, oidnoffset, len , MSG_NOSIGNAL) < len) {
perror("Error sending fixed bytes for thread\n");
+ close(sd);
return;
}
+
tmp = tmp->next;
}
endpair = -1;
if (send(sd, &endpair, sizeof(int), MSG_NOSIGNAL) < sizeof(int)) {
perror("Error sending fixed bytes for thread\n");
+ close(sd);
return;
}
/* Get Response from the remote machine */
getPrefetchResponse(count,sd);
close(sd);
+ return;
}
void getPrefetchResponse(int count, int sd) {
int i = 0, val, n, N, sum, index, objsize;
unsigned int bufsize,oid;
- char buffer[RECEIVE_BUFFER_SIZE], control;
+ char *buffer;
+ char control;
char *ptr;
- void *modptr;
+ void *modptr, *oldptr;
/* Read prefetch response from the Remote machine */
if((val = read(sd, &control, sizeof(char))) <= 0) {
perror("No control response for Prefetch request sent\n");
return;
}
+
if(control == TRANS_PREFETCH_RESPONSE) {
/*For each oid and offset tuple sent as prefetch request to remote machine*/
- while(i < count) {
- /* Clear contents of buffer */
- memset(buffer, 0, RECEIVE_BUFFER_SIZE);
- sum = 0;
- index = 0;
- /* Read the size of buffer to be received */
- if((N = read(sd, buffer, sizeof(unsigned int))) <= 0) {
- perror("Size of buffer not recv\n");
+ while(N = recv((int)sd, &bufsize, sizeof(unsigned int), 0) != 0) {
+ if((buffer = calloc(1, bufsize)) == NULL) {
+ printf("Calloc Error in %s() at %s, %d\n", __func__, __FILE__, __LINE__);
return;
}
- memcpy(&bufsize, buffer, sizeof(unsigned int));
- ptr = buffer + sizeof(unsigned int);
+ sum = 0;
+ index = 0;
+ ptr = buffer;
/* Keep receiving the buffer containing oid info */
do {
n = recv((int)sd, (void *)ptr+sum, bufsize-sum, 0);
sum +=n;
} while(sum < bufsize && n != 0);
+
/* Decode the contents of the buffer */
- index = sizeof(unsigned int);
- while(index < (bufsize - sizeof(unsigned int))) {
+ while(index < bufsize ) {
if(buffer[index] == OBJECT_FOUND) {
/* Increment it to get the object */
index += sizeof(char);
- memcpy(&oid, buffer + index, sizeof(unsigned int));
+ oid = *((unsigned int *)(buffer+index));
index += sizeof(unsigned int);
- /* Lock the Prefetch Cache look up table*/
- pthread_mutex_lock(&pflookup.lock);
/* For each object found add to Prefetch Cache */
- memcpy(&objsize, buffer + index, sizeof(int));
+ objsize = *((int *)(buffer+index));
+ index+=sizeof(int);
+ pthread_mutex_lock(&prefetchcache_mutex);
if ((modptr = objstrAlloc(prefetchcache, objsize)) == NULL) {
- printf("objstrAlloc error for copying into prefetch cache %s, %d\n", __FILE__, __LINE__);
+ printf("Error: objstrAlloc error for copying into prefetch cache %s, %d\n", __FILE__, __LINE__);
+ pthread_mutex_unlock(&prefetchcache_mutex);
+ free(buffer);
return;
}
+ pthread_mutex_unlock(&prefetchcache_mutex);
memcpy(modptr, buffer+index, objsize);
- index += sizeof(int);
- /* Add pointer and oid to hash table */
- //TODO Do we need a version comparison here??
- prehashInsert(oid, modptr);
+ index += objsize;
+ /* Insert the oid and its address into the prefetch hash lookup table */
+ /* Do a version comparison if the oid exists */
+ if((oldptr = prehashSearch(oid)) != NULL) {
+ /* If older version then update with new object ptr */
+ if(((objheader_t *)oldptr)->version < ((objheader_t *)modptr)->version) {
+ prehashRemove(oid);
+ prehashInsert(oid, modptr);
+ } else if(((objheader_t *)oldptr)->version == ((objheader_t *)modptr)->version) {
+ /* Add the new object ptr to hash table */
+ prehashRemove(oid);
+ prehashInsert(oid, modptr);
+ } else { /* Do nothing: TODO modptr should be reference counted */
+ ;
+ }
+ } else {/*If doesn't no match found in hashtable, add the object ptr to hash table*/
+ prehashInsert(oid, modptr);
+ }
+ /* Lock the Prefetch Cache look up table*/
+ pthread_mutex_lock(&pflookup.lock);
/* Broadcast signal on prefetch cache condition variable */
pthread_cond_broadcast(&pflookup.cond);
/* Unlock the Prefetch Cache look up table*/
pthread_mutex_unlock(&pflookup.lock);
} else if(buffer[index] == OBJECT_NOT_FOUND) {
/* Increment it to get the object */
- // TODO If object not found, local machine takes inventory
+ /* TODO: For each object not found query DHT for new location and retrieve the object */
index += sizeof(char);
- memcpy(&oid, buffer + index, sizeof(unsigned int));
+ oid = *((unsigned int *)(buffer + index));
index += sizeof(unsigned int);
- } else
- printf("Error in decoding the index value %s, %d\n",__FILE__, __LINE__);
+ /* Throw an error */
+ printf("OBJECT NOT FOUND.... THIS SHOULD NOT HAPPEN...TERMINATE PROGRAM\n");
+ exit(-1);
+ } else {
+ printf("Error in decoding the index value %d, %s, %d\n",index, __FILE__, __LINE__);
+ free(buffer);
+ return;
+ }
}
-
- i++;
+ free(buffer);
}
} else
printf("Error in receving response for prefetch request %s, %d\n",__FILE__, __LINE__);
+ return;
+}
+
+unsigned short getObjType(unsigned int oid)
+{
+ objheader_t *objheader;
+ unsigned short numoffset[] ={0};
+ short fieldoffset[] ={};
+
+ if ((objheader = (objheader_t *) mhashSearch(oid)) == NULL)
+ {
+ if ((objheader = (objheader_t *) prehashSearch(oid)) == NULL)
+ {
+ prefetch(1, &oid, numoffset, fieldoffset);
+ pthread_mutex_lock(&pflookup.lock);
+ while ((objheader = (objheader_t *) prehashSearch(oid)) == NULL)
+ {
+ pthread_cond_wait(&pflookup.cond, &pflookup.lock);
+ }
+ pthread_mutex_unlock(&pflookup.lock);
+ }
+ }
+
+ return TYPE(objheader);
+}
+
+int startRemoteThread(unsigned int oid, unsigned int mid)
+{
+ int sock;
+ struct sockaddr_in remoteAddr;
+ char msg[1 + sizeof(unsigned int)];
+ int bytesSent;
+ int status;
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ perror("startRemoteThread():socket()");
+ return -1;
+ }
+
+ bzero(&remoteAddr, sizeof(remoteAddr));
+ remoteAddr.sin_family = AF_INET;
+ remoteAddr.sin_port = htons(LISTEN_PORT);
+ remoteAddr.sin_addr.s_addr = htonl(mid);
+
+ if (connect(sock, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr)) < 0)
+ {
+ printf("startRemoteThread():error %d connecting to %s:%d\n", errno,
+ inet_ntoa(remoteAddr.sin_addr), LISTEN_PORT);
+ status = -1;
+ }
+ else
+ {
+ msg[0] = START_REMOTE_THREAD;
+ memcpy(&msg[1], &oid, sizeof(unsigned int));
+
+ bytesSent = send(sock, msg, 1 + sizeof(unsigned int), 0);
+ if (bytesSent < 0)
+ {
+ perror("startRemoteThread():send()");
+ status = -1;
+ }
+ else if (bytesSent != 1 + sizeof(unsigned int))
+ {
+ printf("startRemoteThread(): error, sent %d bytes\n", bytesSent);
+ status = -1;
+ }
+ else
+ {
+ status = 0;
+ }
+ }
+
+ close(sock);
+ return status;
+}
+
+//TODO: when reusing oids, make sure they are not already in use!
+unsigned int getNewOID(void) {
+ static unsigned int id = 0xFFFFFFFF;
+
+ id += 2;
+ if (id > oidMax || id < oidMin)
+ {
+ id = (oidMin | 1);
+ }
+ return id;
+}
+
+int processConfigFile()
+{
+ FILE *configFile;
+ const int maxLineLength = 200;
+ char lineBuffer[maxLineLength];
+ char *token;
+ const char *delimiters = " \t\n";
+ char *commentBegin;
+ in_addr_t tmpAddr;
+
+ configFile = fopen(CONFIG_FILENAME, "r");
+ if (configFile == NULL)
+ {
+ printf("error opening %s:\n", CONFIG_FILENAME);
+ perror("");
+ return -1;
+ }
+
+ numHostsInSystem = 0;
+ sizeOfHostArray = 8;
+ hostIpAddrs = calloc(sizeOfHostArray, sizeof(unsigned int));
+
+ while(fgets(lineBuffer, maxLineLength, configFile) != NULL)
+ {
+ commentBegin = strchr(lineBuffer, '#');
+ if (commentBegin != NULL)
+ *commentBegin = '\0';
+ token = strtok(lineBuffer, delimiters);
+ while (token != NULL)
+ {
+ tmpAddr = inet_addr(token);
+ if ((int)tmpAddr == -1)
+ {
+ printf("error in %s: bad token:%s\n", CONFIG_FILENAME, token);
+ fclose(configFile);
+ return -1;
+ }
+ else
+ addHost(htonl(tmpAddr));
+ token = strtok(NULL, delimiters);
+ }
+ }
+
+ fclose(configFile);
+
+ if (numHostsInSystem < 1)
+ {
+ printf("error in %s: no IP Adresses found\n", CONFIG_FILENAME);
+ return -1;
+ }
+#ifdef MAC
+ myIpAddr = getMyIpAddr("en1");
+#else
+ myIpAddr = getMyIpAddr("eth0");
+#endif
+ myIndexInHostArray = findHost(myIpAddr);
+ if (myIndexInHostArray == -1)
+ {
+ printf("error in %s: IP Address of eth0 not found\n", CONFIG_FILENAME);
+ return -1;
+ }
+ oidsPerBlock = (0xFFFFFFFF / numHostsInSystem) + 1;
+ oidMin = oidsPerBlock * myIndexInHostArray;
+ if (myIndexInHostArray == numHostsInSystem - 1)
+ oidMax = 0xFFFFFFFF;
+ else
+ oidMax = oidsPerBlock * (myIndexInHostArray + 1) - 1;
+
+ return 0;
+}
+
+void addHost(unsigned int hostIp)
+{
+ unsigned int *tmpArray;
+
+ if (findHost(hostIp) != -1)
+ return;
+
+ if (numHostsInSystem == sizeOfHostArray)
+ {
+ tmpArray = calloc(sizeOfHostArray * 2, sizeof(unsigned int));
+ memcpy(tmpArray, hostIpAddrs, sizeof(unsigned int) * numHostsInSystem);
+ free(hostIpAddrs);
+ hostIpAddrs = tmpArray;
+ }
+
+ hostIpAddrs[numHostsInSystem++] = hostIp;
+
+ return;
+}
+
+int findHost(unsigned int hostIp)
+{
+ int i;
+ for (i = 0; i < numHostsInSystem; i++)
+ if (hostIpAddrs[i] == hostIp)
+ return i;
+
+ //not found
+ return -1;
+}
+
+/* This function sends notification request per thread waiting on object(s) whose version
+ * changes */
+int reqNotify(unsigned int *oidarry, unsigned short *versionarry, unsigned int numoid) {
+ int sock,i;
+ objheader_t *objheader;
+ struct sockaddr_in remoteAddr;
+ char msg[1 + numoid * (sizeof(short) + sizeof(unsigned int)) + 3 * sizeof(unsigned int)];
+ char *ptr;
+ int bytesSent;
+ int status, size;
+ unsigned short version;
+ unsigned int oid,mid;
+ static unsigned int threadid = 0;
+ pthread_mutex_t threadnotify = PTHREAD_MUTEX_INITIALIZER; //Lock and condition var for threadjoin and notification
+ pthread_cond_t threadcond = PTHREAD_COND_INITIALIZER;
+ notifydata_t *ndata;
+
+ //FIXME currently all oids belong to one machine
+ oid = oidarry[0];
+ mid = lhashSearch(oid);
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
+ perror("reqNotify():socket()");
+ return -1;
+ }
+
+ bzero(&remoteAddr, sizeof(remoteAddr));
+ remoteAddr.sin_family = AF_INET;
+ remoteAddr.sin_port = htons(LISTEN_PORT);
+ remoteAddr.sin_addr.s_addr = htonl(mid);
+
+ /* Generate unique threadid */
+ threadid++;
+
+ /* Save threadid, numoid, oidarray, versionarray, pthread_cond_variable for later processing */
+ if((ndata = calloc(1, sizeof(notifydata_t))) == NULL) {
+ printf("Calloc Error %s, %d\n", __FILE__, __LINE__);
+ return -1;
+ }
+ ndata->numoid = numoid;
+ ndata->threadid = threadid;
+ ndata->oidarry = oidarry;
+ ndata->versionarry = versionarry;
+ ndata->threadcond = threadcond;
+ ndata->threadnotify = threadnotify;
+ if((status = notifyhashInsert(threadid, ndata)) != 0) {
+ printf("reqNotify(): Insert into notify hash table not successful %s, %d\n", __FILE__, __LINE__);
+ free(ndata);
+ return -1;
+ }
+
+ /* Send number of oids, oidarry, version array, machine id and threadid */
+ if (connect(sock, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr)) < 0){
+ printf("reqNotify():error %d connecting to %s:%d\n", errno,
+ inet_ntoa(remoteAddr.sin_addr), LISTEN_PORT);
+ free(ndata);
+ return -1;
+ } else {
+ msg[0] = THREAD_NOTIFY_REQUEST;
+ *((unsigned int *)(&msg[1])) = numoid;
+ /* Send array of oids */
+ size = sizeof(unsigned int);
+ {
+ i = 0;
+ while(i < numoid) {
+ oid = oidarry[i];
+ *((unsigned int *)(&msg[1] + size)) = oid;
+ size += sizeof(unsigned int);
+ i++;
+ }
+ }
+
+ /* Send array of version */
+ {
+ i = 0;
+ while(i < numoid) {
+ version = versionarry[i];
+ *((unsigned short *)(&msg[1] + size)) = version;
+ size += sizeof(unsigned short);
+ i++;
+ }
+ }
+
+ *((unsigned int *)(&msg[1] + size)) = myIpAddr;
+ size += sizeof(unsigned int);
+ *((unsigned int *)(&msg[1] + size)) = threadid;
+
+ pthread_mutex_lock(&(ndata->threadnotify));
+ bytesSent = send(sock, msg, 1 + numoid * (sizeof(unsigned int) + sizeof(unsigned short)) + 3 * sizeof(unsigned int) , 0);
+ if (bytesSent < 0){
+ perror("reqNotify():send()");
+ status = -1;
+ } else if (bytesSent != 1 + numoid*(sizeof(unsigned int) + sizeof(unsigned short)) + 3 * sizeof(unsigned int)){
+ printf("reNotify(): error, sent %d bytes %s, %d\n", bytesSent, __FILE__, __LINE__);
+ status = -1;
+ } else {
+ status = 0;
+ }
+
+ pthread_cond_wait(&(ndata->threadcond), &(ndata->threadnotify));
+ pthread_mutex_unlock(&(ndata->threadnotify));
+ }
+
+ pthread_cond_destroy(&threadcond);
+ pthread_mutex_destroy(&threadnotify);
+ free(ndata);
+ close(sock);
+ return status;
+}
+
+void threadNotify(unsigned int oid, unsigned short version, unsigned int tid) {
+ notifydata_t *ndata;
+ int i, objIsFound = 0, index;
+ void *ptr;
+
+ //Look up the tid and call the corresponding pthread_cond_signal
+ if((ndata = notifyhashSearch(tid)) == NULL) {
+ printf("threadnotify(): No such threadid is present %s, %d\n", __FILE__, __LINE__);
+ return;
+ } else {
+ for(i = 0; i < ndata->numoid; i++) {
+ if(ndata->oidarry[i] == oid){
+ objIsFound = 1;
+ index = i;
+ }
+ }
+ if(objIsFound == 0){
+ printf("threadNotify(): Oid not found %s, %d\n", __FILE__, __LINE__);
+ return;
+ } else {
+ if(version <= ndata->versionarry[index]){
+ printf("threadNotify(): New version %d has not changed since last version %s, %d\n", version, __FILE__, __LINE__);
+ return;
+ } else {
+ /* Clear from prefetch cache and free thread related data structure */
+ if((ptr = prehashSearch(oid)) != NULL) {
+ prehashRemove(oid);
+ }
+ pthread_cond_signal(&(ndata->threadcond));
+ }
+ }
+ }
+ return;
+}
+
+int notifyAll(threadlist_t **head, unsigned int oid, unsigned int version) {
+ threadlist_t *ptr;
+ unsigned int mid;
+ struct sockaddr_in remoteAddr;
+ char msg[1 + sizeof(unsigned short) + 2*sizeof(unsigned int)];
+ int sock, status, size, bytesSent;
+
+ while(*head != NULL) {
+ ptr = *head;
+ mid = ptr->mid;
+ //create a socket connection to that machine
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
+ perror("notifyAll():socket()");
+ return -1;
+ }
+
+ bzero(&remoteAddr, sizeof(remoteAddr));
+ remoteAddr.sin_family = AF_INET;
+ remoteAddr.sin_port = htons(LISTEN_PORT);
+ remoteAddr.sin_addr.s_addr = htonl(mid);
+ //send Thread Notify response and threadid to that machine
+ if (connect(sock, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr)) < 0){
+ printf("notifyAll():error %d connecting to %s:%d\n", errno,
+ inet_ntoa(remoteAddr.sin_addr), LISTEN_PORT);
+ status = -1;
+ } else {
+ bzero(msg, (1+sizeof(unsigned short) + 2*sizeof(unsigned int)));
+ msg[0] = THREAD_NOTIFY_RESPONSE;
+ *((unsigned int *)&msg[1]) = oid;
+ size = sizeof(unsigned int);
+ *((unsigned short *)(&msg[1]+ size)) = version;
+ size+= sizeof(unsigned short);
+ *((unsigned int *)(&msg[1]+ size)) = ptr->threadid;
+
+ bytesSent = send(sock, msg, (1 + 2*sizeof(unsigned int) + sizeof(unsigned short)), 0);
+ if (bytesSent < 0){
+ perror("notifyAll():send()");
+ status = -1;
+ } else if (bytesSent != 1 + 2*sizeof(unsigned int) + sizeof(unsigned short)){
+ printf("notifyAll(): error, sent %d bytes %s, %d\n",
+ bytesSent, __FILE__, __LINE__);
+ status = -1;
+ } else {
+ status = 0;
+ }
+ }
+ //close socket
+ close(sock);
+ // Update head
+ *head = ptr->next;
+ free(ptr);
+ }
+ return status;
+}
+
+void transAbort(transrecord_t *trans) {
+ objstrDelete(trans->cache);
+ chashDelete(trans->lookupTable);
+ free(trans);
}
+++ /dev/null
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <limits.h>
-
-#include "GenericHashtable.h"
-#include "mem.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-void * getfirstkey(struct genhashtable *ht) {
- return ht->list->src;
-}
-
-int genputtable(struct genhashtable *ht, void * key, void * object) {
- unsigned int bin=genhashfunction(ht,key);
- struct genpointerlist * newptrlist=(struct genpointerlist *) RUNMALLOC(sizeof(struct genpointerlist));
- newptrlist->src=key;
- newptrlist->object=object;
- newptrlist->next=ht->bins[bin];
- newptrlist->inext=NULL;
- /* maintain linked list of ht entries for iteration*/
- if (ht->last==NULL) {
- ht->last=newptrlist;
- ht->list=newptrlist;
- newptrlist->iprev=NULL;
- } else {
- ht->last->inext=newptrlist;
- newptrlist->iprev=ht->last;
- ht->last=newptrlist;
- }
- ht->bins[bin]=newptrlist;
- ht->counter++;
- if(ht->counter>ht->currentsize&&ht->currentsize!=INT_MAX) {
- /* Expand hashtable */
- long newcurrentsize=(ht->currentsize<(INT_MAX/2))?ht->currentsize*2:INT_MAX;
- long oldcurrentsize=ht->currentsize;
- struct genpointerlist **newbins=(struct genpointerlist **) RUNMALLOC(sizeof (struct genpointerlist *)*newcurrentsize);
- struct genpointerlist **oldbins=ht->bins;
- long j,i;
- for(j=0;j<newcurrentsize;j++) newbins[j]=NULL;
- ht->currentsize=newcurrentsize;
- for(i=0;i<oldcurrentsize;i++) {
- struct genpointerlist * tmpptr=oldbins[i];
- while(tmpptr!=NULL) {
- unsigned int hashcode=genhashfunction(ht, tmpptr->src);
- struct genpointerlist *nextptr=tmpptr->next;
- tmpptr->next=newbins[hashcode];
- newbins[hashcode]=tmpptr;
- tmpptr=nextptr;
- }
- }
- ht->bins=newbins;
- RUNFREE(oldbins);
- }
- return 1;
-}
-
-int hashsize(struct genhashtable *ht) {
- return ht->counter;
-}
-
-void genrehash(struct genhashtable * ht) {
- struct genpointerlist **newbins=(struct genpointerlist **) RUNMALLOC(sizeof (struct genpointerlist *)*ht->currentsize);
- struct genpointerlist **oldbins=ht->bins;
- long j,i;
-
- for(i=0;i<ht->currentsize;i++) {
- struct genpointerlist * tmpptr=oldbins[i];
- while(tmpptr!=NULL) {
- unsigned int hashcode=genhashfunction(ht, tmpptr->src);
- struct genpointerlist *nextptr=tmpptr->next;
- tmpptr->next=newbins[hashcode];
- newbins[hashcode]=tmpptr;
- tmpptr=nextptr;
- }
- }
- ht->bins=newbins;
- RUNFREE(oldbins);
-}
-
-void * gengettable(struct genhashtable *ht, void * key) {
- struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)];
- while(ptr!=NULL) {
- if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key)))
- return ptr->object;
- ptr=ptr->next;
- }
- printf("XXXXXXXXX: COULDN'T FIND ENTRY FOR KEY %p\n",key);
- return NULL;
-}
-
-void * getnext(struct genhashtable *ht, void * key) {
- struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)];
- while(ptr!=NULL) {
- if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key)))
- if (ptr->inext!=NULL) {
- return ptr->inext->src;
- } else
- return NULL;
- ptr=ptr->next;
- }
- printf("XXXXXXXXX: COULDN'T FIND ENTRY FOR KEY %p...\n Likely concurrent removal--bad user!!!\n",key);
- return NULL;
-}
-
-int gencontains(struct genhashtable *ht, void * key) {
- struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)];
- //printf("In gencontains2\n");fflush(NULL);
- while(ptr!=NULL) {
- if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key)))
- return 1;
- ptr=ptr->next;
- }
- return 0;
-}
-
-
-void genfreekey(struct genhashtable *ht, void * key) {
- struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)];
-
- if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key))) {
- ht->bins[genhashfunction(ht,key)]=ptr->next;
-
- if (ptr==ht->last)
- ht->last=ptr->iprev;
-
- if (ptr==ht->list)
- ht->list=ptr->inext;
-
- if (ptr->iprev!=NULL)
- ptr->iprev->inext=ptr->inext;
- if (ptr->inext!=NULL)
- ptr->inext->iprev=ptr->iprev;
-
- RUNFREE(ptr);
- ht->counter--;
- return;
- }
- while(ptr->next!=NULL) {
- if (((ht->comp_function==NULL)&&(ptr->next->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->next->src,key))) {
- struct genpointerlist *tmpptr=ptr->next;
- ptr->next=tmpptr->next;
- if (tmpptr==ht->list)
- ht->list=tmpptr->inext;
- if (tmpptr==ht->last)
- ht->last=tmpptr->iprev;
- if (tmpptr->iprev!=NULL)
- tmpptr->iprev->inext=tmpptr->inext;
- if (tmpptr->inext!=NULL)
- tmpptr->inext->iprev=tmpptr->iprev;
- RUNFREE(tmpptr);
- ht->counter--;
- return;
- }
- ptr=ptr->next;
- }
- printf("XXXXXXXXX: COULDN'T FIND ENTRY FOR KEY %p\n",key);
-}
-
-unsigned int genhashfunction(struct genhashtable *ht, void * key) {
- if (ht->hash_function==NULL)
- return ((long unsigned int)key) % ht->currentsize;
- else
- return ((*ht->hash_function)(key)) % ht->currentsize;
-}
-
-struct genhashtable * genallocatehashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *, void *)) {
- struct genhashtable *ght=(struct genhashtable *) RUNMALLOC(sizeof(struct genhashtable));
- struct genpointerlist **gpl=(struct genpointerlist **) RUNMALLOC(sizeof(struct genpointerlist *)*geninitialnumbins);
- int i;
- for(i=0;i<geninitialnumbins;i++)
- gpl[i]=NULL;
- ght->hash_function=hash_function;
- ght->comp_function=comp_function;
- ght->currentsize=geninitialnumbins;
- ght->bins=gpl;
- ght->counter=0;
- ght->list=NULL;
- ght->last=NULL;
- return ght;
-}
-
-void genfreehashtable(struct genhashtable * ht) {
- int i;
- for (i=0;i<ht->currentsize;i++) {
- if (ht->bins[i]!=NULL) {
- struct genpointerlist *genptr=ht->bins[i];
- while(genptr!=NULL) {
- struct genpointerlist *tmpptr=genptr->next;
- RUNFREE(genptr);
- genptr=tmpptr;
- }
- }
- }
- RUNFREE(ht->bins);
- RUNFREE(ht);
-}
-
-struct geniterator * gengetiterator(struct genhashtable *ht) {
- struct geniterator *gi=(struct geniterator*)RUNMALLOC(sizeof(struct geniterator));
- gi->ptr=ht->list;
- return gi;
-}
-
-void * gennext(struct geniterator *it) {
- struct genpointerlist *curr=it->ptr;
- if (curr==NULL)
- return NULL;
- if (it->finished&&(curr->inext==NULL))
- return NULL;
- if (it->finished) {
- it->ptr=curr->inext;
- return it->ptr->src;
- }
- if(curr->inext!=NULL)
- it->ptr=curr->inext;
- else
- it->finished=1; /* change offsetting scheme */
- return curr->src;
-}
-
-void genfreeiterator(struct geniterator *it) {
- RUNFREE(it);
-}
+++ /dev/null
-// implements a generic hash table
-
-#ifndef GENHASHTABLE
-#define GENHASHTABLE
-#define geninitialnumbins 10
-#define bool int
-
-struct genhashtable {
- unsigned int (*hash_function)(void *);
- int (*comp_function)(void *,void *);
- struct genpointerlist ** bins;
- long counter;
- int currentsize;
- struct genpointerlist *list;
- struct genpointerlist *last;
-};
-
-
-struct genpointerlist {
- void * src;
- void * object;
- struct genpointerlist * next;
-
- struct genpointerlist * inext;
- struct genpointerlist * iprev;
-};
-
-
-struct geniterator {
- struct genpointerlist * ptr;
- bool finished;
-};
-
-struct genhashtable * genallocatehashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *,void *));
-void * getfirstkey(struct genhashtable *ht);
-void genfreehashtable(struct genhashtable * ht);
-void genrehash(struct genhashtable * ht);
-void * getnext(struct genhashtable *,void *);
-int genputtable(struct genhashtable *, void *, void *);
-void * gengettable(struct genhashtable *, void *);
-int gencontains(struct genhashtable *, void *);
-unsigned int genhashfunction(struct genhashtable *,void *);
-
-int hashsize(struct genhashtable * ht);
-void genfreekey(struct genhashtable *ht, void *);
-struct geniterator * gengetiterator(struct genhashtable *ht);
-void * gennext(struct geniterator *it);
-void genfreeiterator(struct geniterator *it);
-#endif
-
-
-
+++ /dev/null
-#include "mem.h"
-#include "Queue.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-struct Queue * createQueue() {
- return RUNMALLOC(sizeof(struct Queue));
-}
-
-void freeQueue(struct Queue * q) {
- RUNFREE(q);
-}
-
-int isEmpty(struct Queue *queue) {
- return queue->head==NULL;
-}
-
-struct QueueItem * addNewItem(struct Queue * queue, void * ptr) {
- struct QueueItem * item=RUNMALLOC(sizeof(struct QueueItem));
- item->objectptr=ptr;
- item->queue=queue;
- if (queue->head==NULL) {
- queue->head=item;
- queue->tail=item;
- } else {
- item->next=queue->head;
- queue->head->prev=item;
- queue->head=item;
- }
- return item;
-}
-
-struct QueueItem * findItem(struct Queue * queue, void *ptr) {
- struct QueueItem * item=queue->head;
- while(item!=NULL) {
- if (item->objectptr==ptr)
- return item;
- item=item->next;
- }
- return NULL;
-}
-
-void removeItem(struct Queue * queue, struct QueueItem * item) {
- struct QueueItem * prev=item->prev;
- struct QueueItem * next=item->next;
- if (queue->head==item)
- queue->head=next;
- else
- prev->next=next;
- if (queue->tail==item)
- queue->tail=prev;
- else
- next->prev=prev;
- RUNFREE(item);
-}
-
-struct QueueItem * getTail(struct Queue * queue) {
- return queue->tail;
-}
-
-struct QueueItem * getNext(struct QueueItem * qi) {
- return qi->next;
-}
+++ /dev/null
-#ifndef QUEUE_H
-#define QUEUE_H
-
-struct Queue {
- struct QueueItem * head;
- struct QueueItem * tail;
-};
-
-struct QueueItem {
- void * objectptr;
- struct Queue * queue;
- struct QueueItem * next;
- struct QueueItem * prev;
-};
-
-void freeQueue(struct Queue * q);
-struct Queue * createQueue();
-struct QueueItem * addNewItem(struct Queue * queue, void * ptr);
-struct QueueItem * findItem(struct Queue * queue, void * ptr);
-void removeItem(struct Queue * queue, struct QueueItem * item);
-int isEmpty(struct Queue *queue);
-struct QueueItem * getTail(struct Queue * queue);
-
-
-#endif
+++ /dev/null
-#include "SimpleHash.h"
-#include <stdio.h>
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-/* SIMPLE HASH ********************************************************/
-struct RuntimeIterator* RuntimeHashcreateiterator(struct RuntimeHash * thisvar) {
- return allocateRuntimeIterator(thisvar->listhead);
-}
-
-void RuntimeHashiterator(struct RuntimeHash *thisvar, struct RuntimeIterator * it) {
- it->cur=thisvar->listhead;
-}
-
-struct RuntimeHash * noargallocateRuntimeHash() {
- return allocateRuntimeHash(100);
-}
-
-struct RuntimeHash * allocateRuntimeHash(int size) {
- struct RuntimeHash *thisvar=(struct RuntimeHash *)RUNMALLOC(sizeof(struct RuntimeHash));
- if (size <= 0) {
- printf("Negative Hashtable size Exception\n");
- exit(-1);
- }
- thisvar->size = size;
- thisvar->bucket = (struct RuntimeNode **) RUNMALLOC(sizeof(struct RuntimeNode *)*size);
- /* Set allocation blocks*/
- thisvar->listhead=NULL;
- thisvar->listtail=NULL;
- /*Set data counts*/
- thisvar->numelements = 0;
- return thisvar;
-}
-
-void freeRuntimeHash(struct RuntimeHash *thisvar) {
- struct RuntimeNode *ptr=thisvar->listhead;
- RUNFREE(thisvar->bucket);
- while(ptr) {
- struct RuntimeNode *next=ptr->lnext;
- RUNFREE(ptr);
- ptr=next;
- }
- RUNFREE(thisvar);
-}
-
-inline int RuntimeHashcountset(struct RuntimeHash * thisvar) {
- return thisvar->numelements;
-}
-
-int RuntimeHashfirstkey(struct RuntimeHash *thisvar) {
- struct RuntimeNode *ptr=thisvar->listhead;
- return ptr->key;
-}
-
-int RuntimeHashremove(struct RuntimeHash *thisvar, int key, int data) {
- unsigned int hashkey = (unsigned int)key % thisvar->size;
-
- struct RuntimeNode **ptr = &thisvar->bucket[hashkey];
- int i;
-
- while (*ptr) {
- if ((*ptr)->key == key && (*ptr)->data == data) {
- struct RuntimeNode *toremove=*ptr;
- *ptr=(*ptr)->next;
-
- if (toremove->lprev!=NULL)
- toremove->lprev->lnext=toremove->lnext;
- else
- thisvar->listhead=toremove->lnext;
- if (toremove->lnext!=NULL)
- toremove->lnext->lprev=toremove->lprev;
- else
- thisvar->listtail=toremove->lprev;
- RUNFREE(toremove);
-
- thisvar->numelements--;
- return 1;
- }
- ptr = &((*ptr)->next);
- }
-
- return 0;
-}
-
-void RuntimeHashrehash(struct RuntimeHash * thisvar) {
- int newsize=thisvar->size;
- struct RuntimeNode ** newbucket = (struct RuntimeNode **) RUNMALLOC(sizeof(struct RuntimeNode *)*newsize);
- int i;
- for(i=thisvar->size-1;i>=0;i--) {
- struct RuntimeNode *ptr;
- for(ptr=thisvar->bucket[i];ptr!=NULL;) {
- struct RuntimeNode * nextptr=ptr->next;
- unsigned int newhashkey=(unsigned int)ptr->key % newsize;
- ptr->next=newbucket[newhashkey];
- newbucket[newhashkey]=ptr;
- ptr=nextptr;
- }
- }
- thisvar->size=newsize;
- RUNFREE(thisvar->bucket);
- thisvar->bucket=newbucket;
-}
-
-int RuntimeHashadd(struct RuntimeHash * thisvar,int key, int data) {
- /* Rehash code */
- unsigned int hashkey;
- struct RuntimeNode **ptr;
-
- if (thisvar->numelements>=thisvar->size) {
- int newsize=2*thisvar->size+1;
- struct RuntimeNode ** newbucket = (struct RuntimeNode **) RUNMALLOC(sizeof(struct RuntimeNode *)*newsize);
- int i;
- for(i=thisvar->size-1;i>=0;i--) {
- struct RuntimeNode *ptr;
- for(ptr=thisvar->bucket[i];ptr!=NULL;) {
- struct RuntimeNode * nextptr=ptr->next;
- unsigned int newhashkey=(unsigned int)ptr->key % newsize;
- ptr->next=newbucket[newhashkey];
- newbucket[newhashkey]=ptr;
- ptr=nextptr;
- }
- }
- thisvar->size=newsize;
- RUNFREE(thisvar->bucket);
- thisvar->bucket=newbucket;
- }
-
- hashkey = (unsigned int)key % thisvar->size;
- ptr = &thisvar->bucket[hashkey];
-
- /* check that thisvar key/object pair isn't already here */
- /* TBD can be optimized for set v. relation */
-
- while (*ptr) {
- if ((*ptr)->key == key && (*ptr)->data == data) {
- return 0;
- }
- ptr = &((*ptr)->next);
- }
-
- {
- struct RuntimeNode *node=RUNMALLOC(sizeof(struct RuntimeNode));
- node->data=data;
- node->key=key;
- node->next=(*ptr);
- *ptr=node;
- if (thisvar->listhead==NULL) {
- thisvar->listhead=node;
- thisvar->listtail=node;
- node->lnext=NULL;
- node->lprev=NULL;
- } else {
- node->lprev=NULL;
- node->lnext=thisvar->listhead;
- thisvar->listhead->lprev=node;
- thisvar->listhead=node;
- }
- }
-
- thisvar->numelements++;
- return 1;
-}
-
-bool RuntimeHashcontainskey(struct RuntimeHash *thisvar,int key) {
- unsigned int hashkey = (unsigned int)key % thisvar->size;
-
- struct RuntimeNode *ptr = thisvar->bucket[hashkey];
- while (ptr) {
- if (ptr->key == key) {
- /* we already have thisvar object
- stored in the hash so just return */
- return true;
- }
- ptr = ptr->next;
- }
- return false;
-}
-
-bool RuntimeHashcontainskeydata(struct RuntimeHash *thisvar, int key, int data) {
- unsigned int hashkey = (unsigned int)key % thisvar->size;
-
- struct RuntimeNode *ptr = thisvar->bucket[hashkey];
- while (ptr) {
- if (ptr->key == key && ptr->data == data) {
- /* we already have thisvar object
- stored in the hash so just return*/
- return true;
- }
- ptr = ptr->next;
- }
- return false;
-}
-
-int RuntimeHashcount(struct RuntimeHash *thisvar,int key) {
- unsigned int hashkey = (unsigned int)key % thisvar->size;
- int count = 0;
-
- struct RuntimeNode *ptr = thisvar->bucket[hashkey];
- while (ptr) {
- if (ptr->key == key) {
- count++;
- }
- ptr = ptr->next;
- }
- return count;
-}
-
-struct RuntimeHash * RuntimeHashimageSet(struct RuntimeHash *thisvar, int key) {
- struct RuntimeHash * newset=allocateRuntimeHash(2*RuntimeHashcount(thisvar,key)+4);
- unsigned int hashkey = (unsigned int)key % thisvar->size;
-
- struct RuntimeNode *ptr = thisvar->bucket[hashkey];
- while (ptr) {
- if (ptr->key == key) {
- RuntimeHashadd(newset,ptr->data,ptr->data);
- }
- ptr = ptr->next;
- }
- return newset;
-}
-
-int RuntimeHashget(struct RuntimeHash *thisvar, int key, int *data) {
- unsigned int hashkey = (unsigned int)key % thisvar->size;
-
- struct RuntimeNode *ptr = thisvar->bucket[hashkey];
- while (ptr) {
- if (ptr->key == key) {
- *data = ptr->data;
- return 1; /* success */
- }
- ptr = ptr->next;
- }
-
- return 0; /* failure */
-}
-
-inline struct RuntimeIterator * noargallocateRuntimeIterator() {
- return (struct RuntimeIterator*)RUNMALLOC(sizeof(struct RuntimeIterator));
-}
-
-inline struct RuntimeIterator * allocateRuntimeIterator(struct RuntimeNode *start) {
- struct RuntimeIterator *thisvar=(struct RuntimeIterator*)RUNMALLOC(sizeof(struct RuntimeIterator));
- thisvar->cur = start;
- return thisvar;
-}
-
-inline int RunhasNext(struct RuntimeIterator *thisvar) {
- return (thisvar->cur!=NULL);
-}
-
-inline int Runnext(struct RuntimeIterator *thisvar) {
- int curr=thisvar->cur->data;
- thisvar->cur=thisvar->cur->next;
-}
-
-inline int Runkey(struct RuntimeIterator *thisvar) {
- return thisvar->cur->key;
-}
+++ /dev/null
-#ifndef SIMPLEHASH_H
-#define SIMPLEHASH_H
-
-#ifndef bool
-#define bool int
-#endif
-
-#ifndef true
-#define true 1
-#endif
-
-#ifndef false
-#define false 0
-#endif
-
-#include "mem.h"
-
-/* SimpleHash *********************************************************/
-
-struct RuntimeHash * noargallocateRuntimeHash();
-struct RuntimeHash * allocateRuntimeHash(int size);
-void RuntimeHashaddChild(struct RuntimeHash *thisvar, struct RuntimeHash * child);
-void freeRuntimeHash(struct RuntimeHash *);
-
-void RuntimeHashrehash(struct RuntimeHash * thisvar);
-int RuntimeHashadd(struct RuntimeHash *, int key, int data);
-int RuntimeHashremove(struct RuntimeHash *,int key, int data);
-bool RuntimeHashcontainskey(struct RuntimeHash *,int key);
-bool RuntimeHashcontainskeydata(struct RuntimeHash *,int key, int data);
-int RuntimeHashget(struct RuntimeHash *,int key, int* data);
-void RuntimeHashaddParent(struct RuntimeHash *,struct RuntimeHash* parent);
-int RuntimeHashfirstkey(struct RuntimeHash *);
-struct RuntimeIterator* RuntimeHashcreateiterator(struct RuntimeHash *);
-void RuntimeHashiterator(struct RuntimeHash *, struct RuntimeIterator * it);
-int RuntimeHashcount(struct RuntimeHash *, int key);
-struct RuntimeHash * RuntimeHashimageSet(struct RuntimeHash *, int key);
-
-struct RuntimeHash {
- int numelements;
- int size;
- struct RuntimeNode **bucket;
- struct RuntimeNode *listhead;
- struct RuntimeNode *listtail;
-};
-
-inline int RuntimeHashcountset(struct RuntimeHash * thisvar);
-
-/* RuntimeHashException *************************************************/
-
-
-/* RuntimeIterator *****************************************************/
-#define ARRAYSIZE 100
-
-struct RuntimeNode {
- struct RuntimeNode *next;
- struct RuntimeNode *lnext;
- struct RuntimeNode *lprev;
- int data;
- int key;
-};
-
-struct RuntimeIterator {
- struct RuntimeNode *cur;
-};
-
-inline struct RuntimeIterator * noargallocateRuntimeIterator();
-
-inline struct RuntimeIterator * allocateRuntimeIterator(struct RuntimeNode *start);
-
-inline int RunhasNext(struct RuntimeIterator *thisvar);
-
-inline int Runnext(struct RuntimeIterator *thisvar);
-
-inline int Runkey(struct RuntimeIterator *thisvar);
-
-#endif
+++ /dev/null
-#include "checkpoint.h"
-#include "runtime.h"
-#include "structdefs.h"
-#include <string.h>
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-#define MALLOCSIZE 20*1024
-
-struct malloclist {
- struct malloclist *next;
- int size;
- char space[];
-};
-
-struct malloclist * top=NULL;
-int offset=0;
-
-void * cpmalloc(int size) {
- int endoffset=offset+size;
- if (top==NULL||endoffset>top->size) {
- int basesize=MALLOCSIZE;
- struct malloclist *tmp;
- if (size>basesize)
- basesize=size;
- tmp=RUNMALLOC(sizeof(struct malloclist)+basesize);
- tmp->next=top;
- top=tmp;
- top->size=basesize;
- offset=0;
- }
- int tmpoffset=offset;
- offset+=size;
- return &top->space[tmpoffset];
-}
-
-void freemalloc() {
- while(top!=NULL) {
- struct malloclist *next=top->next;
- RUNFREE(top);
- top=next;
- }
-}
-
-
-void ** makecheckpoint(int numparams, void ** srcpointer, struct RuntimeHash * forward, struct RuntimeHash * reverse) {
-#ifdef PRECISE_GC
- void **newarray=cpmalloc(sizeof(void *)*numparams);
-#else
- void **newarray=RUNMALLOC(sizeof(void *)*numparams);
-#endif
- struct RuntimeHash *todo=allocateRuntimeHash(100);
- int i;
- for(i=0;i<numparams;i++) {
- void * objptr=srcpointer[i];
- if (RuntimeHashcontainskey(forward, (int) objptr))
- RuntimeHashget(forward,(int) objptr,(int *) &newarray[i]);
- else {
- void * copy=createcopy(objptr);
- RuntimeHashadd(forward, (int) objptr, (int)copy);
- RuntimeHashadd(reverse, (int) copy, (int) objptr);
- RuntimeHashadd(todo, (int) objptr, (int) objptr);
- newarray[i]=copy;
- }
- }
- while(RuntimeHashcountset(todo)!=0) {
- void * ptr=(void *) RuntimeHashfirstkey(todo);
- int type=((int *)ptr)[0];
- RuntimeHashremove(todo, (int) ptr, (int) ptr);
- {
- void *cpy;
- RuntimeHashget(forward, (int) ptr, (int *) &cpy);
- int * pointer=pointerarray[type];
- if (pointer==0) {
- /* Array of primitives */
- /* Do nothing */
- } else if (((int)pointer)==1) {
- /* Array of pointers */
- struct ArrayObject *ao=(struct ArrayObject *) ptr;
- struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
- int length=ao->___length___;
- int i;
- for(i=0;i<length;i++) {
- void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
- if (objptr==NULL) {
- ((void **)(((char *)& ao->___length___)+sizeof(int)))[i]=NULL;
- } else if (RuntimeHashcontainskey(forward, (int) objptr))
- RuntimeHashget(forward,(int) objptr,(int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
- else {
- void * copy=createcopy(objptr);
- RuntimeHashadd(forward, (int) objptr, (int)copy);
- RuntimeHashadd(reverse, (int) copy, (int) objptr);
- RuntimeHashadd(todo, (int) objptr, (int) objptr);
- ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=copy;
- }
- }
- } else {
- int size=pointer[0];
- int i;
- for(i=1;i<=size;i++) {
- int offset=pointer[i];
- void * objptr=*((void **)(((int)ptr)+offset));
- if (objptr==NULL) {
- *((void **) (((int)cpy)+offset))=NULL;
- } else if (RuntimeHashcontainskey(forward, (int) objptr))
- RuntimeHashget(forward, (int) objptr, (int *) &(((char *)cpy)[offset]));
- else {
- void * copy=createcopy(objptr);
- RuntimeHashadd(forward, (int) objptr, (int) copy);
- RuntimeHashadd(reverse, (int) copy, (int) objptr);
- RuntimeHashadd(todo, (int) objptr, (int) objptr);
- *((void **) (((int)cpy)+offset))=copy;
- }
- }
- }
- }
- }
- freeRuntimeHash(todo);
- return newarray;
-}
-
-void * createcopy(void * orig) {
- if (orig==0)
- return 0;
- else {
- int type=((int *)orig)[0];
- if (type<NUMCLASSES) {
- /* We have a normal object */
- int size=classsize[type];
-#ifdef PRECISE_GC
- void *newobj=cpmalloc(size);
-#else
- void *newobj=RUNMALLOC(size);
-#endif
- memcpy(newobj, orig, size);
- return newobj;
- } else {
- /* We have an array */
- struct ArrayObject *ao=(struct ArrayObject *)orig;
- int elementsize=classsize[type];
- int length=ao->___length___;
- int size=sizeof(struct ArrayObject)+length*elementsize;
-#ifdef PRECISE_GC
- void *newobj=cpmalloc(size);
-#else
- void *newobj=RUNMALLOC(size);
-#endif
- memcpy(newobj, orig, size);
- return newobj;
- }
- }
-}
-
-void restorecheckpoint(int numparams, void ** original, void ** checkpoint, struct RuntimeHash *forward, struct RuntimeHash * reverse) {
- struct RuntimeHash *todo=allocateRuntimeHash(100);
- struct RuntimeHash *visited=allocateRuntimeHash(100);
- int i;
-
- for(i=0;i<numparams;i++) {
- if (checkpoint[i]!=NULL) {
- RuntimeHashadd(todo, (int) checkpoint[i], (int) checkpoint[i]);
- RuntimeHashadd(visited, (int) checkpoint[i], (int) checkpoint[i]);
- }
- }
-
- while(RuntimeHashcountset(todo)!=0) {
- void * ptr=(void *) RuntimeHashfirstkey(todo);
- int type=((int *)ptr)[0];
- RuntimeHashremove(todo, (int) ptr, (int) ptr);
-
- {
- void *cpy;
- int *pointer;
- int size;
- RuntimeHashget(reverse, (int) ptr, (int *) &cpy);
- pointer=pointerarray[type];
- size=classsize[type];
-
- if (pointer==0) {
- /* Array of primitives */
- struct ArrayObject *ao=(struct ArrayObject *) ptr;
- int length=ao->___length___;
- int cpysize=sizeof(struct ArrayObject)+length*size;
- memcpy(cpy, ptr, cpysize);
-
- } else if ((int)pointer==1) {
- /* Array of pointers */
- struct ArrayObject *ao=(struct ArrayObject *) ptr;
- struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
- int length=ao->___length___;
- int i;
- int cpysize=sizeof(struct ArrayObject)+length*size;
- memcpy(ao_cpy, ao, cpysize);
-
- for(i=0;i<length;i++) {
- void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
- if (objptr==NULL)
- ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=NULL;
- else {
- if (!RuntimeHashcontainskey(visited, (int) objptr)) {
- RuntimeHashadd(visited, (int) objptr, (int) objptr);
- RuntimeHashadd(todo, (int) objptr, (int) objptr);
- }
- RuntimeHashget(reverse, (int) objptr, (int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
- }
- }
- } else {
- int numptr=pointer[0];
- int i;
- void *flagptr;
- if (hasflags[type]) {
- flagptr=(void *) (((int *)cpy)[2]);
- }
- memcpy(cpy, ptr, size);
- for(i=1;i<=numptr;i++) {
- int offset=pointer[i];
- void * objptr=*((void **)(((int)ptr)+offset));
- if (objptr==NULL)
- *((void **) (((int)cpy)+offset))=NULL;
- else {
- if (!RuntimeHashcontainskey(visited, (int) objptr)) {
- RuntimeHashadd(visited, (int) objptr, (int) objptr);
- RuntimeHashadd(todo, (int) objptr, (int) objptr);
- }
- RuntimeHashget(reverse, (int) objptr, (int *) &(((char *)cpy)[offset]));
- }
- }
- if (hasflags[type]) {
- (((void **)cpy)[2])=flagptr;
- flagorandinit(cpy, 0, 0xFFFFFFFF);
- }
- }
- }
- }
- freeRuntimeHash(todo);
- freeRuntimeHash(visited);
-}
+++ /dev/null
-#ifndef CHECKPOINT_H
-#define CHECKPOINT_H
-#include "SimpleHash.h"
-
-void ** makecheckpoint(int numparams, void ** pointerarray, struct RuntimeHash * forward, struct RuntimeHash * reverse);
-
-void restorecheckpoint(int numparams, void ** original, void ** checkpoint, struct RuntimeHash *forward, struct RuntimeHash * reverse);
-
-void * createcopy(void * orig);
-void freemalloc();
-#endif
+++ /dev/null
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include "structdefs.h"
-#include "mem.h"
-#include "runtime.h"
-
-void CALL12(___FileOutputStream______nativeWrite____I__AR_B, int fd, int fd, struct ArrayObject * ___array___) {
- int length=VAR(___array___)->___length___;
- char * string= (((char *)& VAR(___array___)->___length___)+sizeof(int));
- int status=write(fd, string, length);
-}
-
-void CALL11(___FileOutputStream______nativeClose____I, int fd, int fd) {
- close(fd);
-}
-
-void CALL11(___FileOutputStream______nativeFlush____I, int fd, int fd) {
- fsync(fd);
-}
-
-int CALL01(___FileOutputStream______nativeOpen_____AR_B, struct ArrayObject * ___filename___) {
- int length=VAR(___filename___)->___length___;
- char* filename= (((char *)& VAR(___filename___)->___length___)+sizeof(int));
- int fd=open(filename, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
- return fd;
-}
-
-int CALL01(___FileOutputStream______nativeAppend_____AR_B, struct ArrayObject * ___filename___) {
- int length=VAR(___filename___)->___length___;
- char* filename= (((char *)& VAR(___filename___)->___length___)+sizeof(int));
- int fd=open(filename, O_WRONLY|O_CREAT|O_APPEND, S_IRWXU);
- return fd;
-}
-
-int CALL01(___FileInputStream______nativeOpen_____AR_B, struct ArrayObject * ___filename___) {
- int length=VAR(___filename___)->___length___;
- char* filename= (((char *)& VAR(___filename___)->___length___)+sizeof(int));
- int fd=open(filename, O_RDONLY, 0);
- return fd;
-}
-
-void CALL11(___FileInputStream______nativeClose____I, int fd, int fd) {
- close(fd);
-}
-
-int CALL23(___FileInputStream______nativeRead____I__AR_B_I, int fd, int numBytes, int fd, struct ArrayObject * ___array___, int numBytes) {
- int toread=VAR(___array___)->___length___;
- char* string= (((char *)& VAR(___array___)->___length___)+sizeof(int));
- int status;
-
- if (numBytes<toread)
- toread=numBytes;
-
- status=read(fd, string, toread);
- return status;
-}
-
-long long CALL01(___File______nativeLength_____AR_B, struct ArrayObject * ___pathname___) {
- int length=VAR(___pathname___)->___length___;
- char* filename= (((char *)& VAR(___pathname___)->___length___)+sizeof(int));
- struct stat st;
- stat(filename, &st);
- return st.st_size;
-}
+++ /dev/null
-#include "garbage.h"
-#include "runtime.h"
-#include "structdefs.h"
-#include "Queue.h"
-#include "SimpleHash.h"
-#include "GenericHashtable.h"
-#include <string.h>
-#ifdef THREADS
-#include "thread.h"
-#endif
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-
-#define NUMPTRS 100
-
-#define INITIALHEAPSIZE 10*1024
-#define GCPOINT(x) ((int)((x)*0.9))
-/* This define takes in how full the heap is initially and returns a new heap size to use */
-#define HEAPSIZE(x,y) (((int)((x)/0.6))+y)
-
-#ifdef TASK
-extern struct genhashtable * activetasks;
-extern struct parameterwrapper * objectqueues[NUMCLASSES];
-extern struct genhashtable * failedtasks;
-extern struct taskparamdescriptor *currtpd;
-extern struct RuntimeHash *forward;
-extern struct RuntimeHash *reverse;
-extern struct RuntimeHash *fdtoobject;
-#endif
-
-#ifdef THREADS
-int needtocollect=0;
-struct listitem * list=NULL;
-int listcount=0;
-#endif
-
-struct pointerblock {
- void * ptrs[NUMPTRS];
- struct pointerblock *next;
-};
-
-struct pointerblock *head=NULL;
-int headindex=0;
-struct pointerblock *tail=NULL;
-int tailindex=0;
-struct pointerblock *spare=NULL;
-
-void enqueue(void *ptr) {
- if (headindex==NUMPTRS) {
- struct pointerblock * tmp;
- if (spare!=NULL) {
- tmp=spare;
- spare=NULL;
- } else
- tmp=malloc(sizeof(struct pointerblock));
- head->next=tmp;
- head=tmp;
- headindex=0;
- }
- head->ptrs[headindex++]=ptr;
-}
-
-void * dequeue() {
- if (tailindex==NUMPTRS) {
- struct pointerblock *tmp=tail;
- tail=tail->next;
- tailindex=0;
- if (spare!=NULL)
- free(tmp);
- else
- spare=tmp;
- }
- return tail->ptrs[tailindex++];
-}
-
-int moreItems() {
- if ((head==tail)&&(tailindex==headindex))
- return 0;
- return 1;
-}
-
-#ifdef TASK
-struct pointerblock *taghead=NULL;
-int tagindex=0;
-
-void enqueuetag(struct ___TagDescriptor___ *ptr) {
- if (tagindex==NUMPTRS) {
- struct pointerblock * tmp=malloc(sizeof(struct pointerblock));
- tmp->next=taghead;
- taghead=tmp;
- tagindex=0;
- }
- taghead->ptrs[tagindex++]=ptr;
-}
-#endif
-
-
-void collect(struct garbagelist * stackptr) {
-#ifdef THREADS
- needtocollect=1;
- pthread_mutex_lock(&gclistlock);
- while(1) {
- if ((listcount+1)==threadcount) {
- break; /* Have all other threads stopped */
- }
- pthread_cond_wait(&gccond, &gclistlock);
- }
-#endif
-
- if (head==NULL) {
- headindex=0;
- tailindex=0;
- head=tail=malloc(sizeof(struct pointerblock));
- }
-
-#ifdef TASK
- if (taghead==NULL) {
- tagindex=0;
- taghead=malloc(sizeof(struct pointerblock));
- taghead->next=NULL;
- }
-#endif
-
- /* Check current stack */
-#ifdef THREADS
- {
- struct listitem *listptr=list;
- while(1) {
-#endif
-
- while(stackptr!=NULL) {
- int i;
- for(i=0;i<stackptr->size;i++) {
- void * orig=stackptr->array[i];
- void * copy;
- if (gc_createcopy(orig,©))
- enqueue(orig);
- stackptr->array[i]=copy;
- }
- stackptr=stackptr->next;
- }
-#ifdef THREADS
- /* Go to next thread */
- if (listptr!=NULL) {
- void * orig=listptr->locklist;
- void * copy;
- if (gc_createcopy(orig,©))
- enqueue(orig);
- listptr->locklist=copy;
- stackptr=listptr->stackptr;
- listptr=listptr->next;
- } else
- break;
- }
- }
-#endif
-
-#ifdef TASK
- {
- /* Update objectsets */
- int i;
- for(i=0;i<NUMCLASSES;i++) {
- struct parameterwrapper * p=objectqueues[i];
- while(p!=NULL) {
- struct RuntimeHash * set=p->objectset;
- struct RuntimeNode * ptr=set->listhead;
- while(ptr!=NULL) {
- void *orig=(void *)ptr->key;
- void *copy;
- if (gc_createcopy(orig, ©))
- enqueue(orig);
- ptr->key=(int)copy;
-
- ptr=ptr->lnext;
- }
- RuntimeHashrehash(set); /* Rehash the table */
- p=p->next;
- }
- }
- }
-
- if (forward!=NULL) {
- struct RuntimeNode * ptr=forward->listhead;
- while(ptr!=NULL) {
- void * orig=(void *)ptr->key;
- void *copy;
- if (gc_createcopy(orig, ©))
- enqueue(orig);
- ptr->key=(int)copy;
-
- ptr=ptr->lnext;
- }
- RuntimeHashrehash(forward); /* Rehash the table */
- }
-
- if (reverse!=NULL) {
- struct RuntimeNode * ptr=reverse->listhead;
- while(ptr!=NULL) {
- void *orig=(void *)ptr->data;
- void *copy;
- if (gc_createcopy(orig, ©))
- enqueue(orig);
- ptr->data=(int)copy;
-
- ptr=ptr->lnext;
- }
- }
-
- {
- struct RuntimeNode * ptr=fdtoobject->listhead;
- while(ptr!=NULL) {
- void *orig=(void *)ptr->data;
- void *copy;
- if (gc_createcopy(orig, ©))
- enqueue(orig);
- ptr->data=(int)copy;
-
- ptr=ptr->lnext;
- }
- }
-
- {
- /* Update current task descriptor */
- int i;
- for(i=0;i<currtpd->numParameters;i++) {
- void *orig=currtpd->parameterArray[i];
- void *copy;
- if (gc_createcopy(orig, ©))
- enqueue(orig);
- currtpd->parameterArray[i]=copy;
- }
-
- }
-
- /* Update active tasks */
- {
- struct genpointerlist * ptr=activetasks->list;
- while(ptr!=NULL) {
- struct taskparamdescriptor *tpd=ptr->src;
- int i;
- for(i=0;i<tpd->numParameters;i++) {
- void * orig=tpd->parameterArray[i];
- void * copy;
- if (gc_createcopy(orig, ©))
- enqueue(orig);
- tpd->parameterArray[i]=copy;
- }
- ptr=ptr->inext;
- }
- genrehash(activetasks);
- }
-
- /* Update failed tasks */
- {
- struct genpointerlist * ptr=failedtasks->list;
- while(ptr!=NULL) {
- struct taskparamdescriptor *tpd=ptr->src;
- int i;
- for(i=0;i<tpd->numParameters;i++) {
- void * orig=tpd->parameterArray[i];
- void * copy;
- if (gc_createcopy(orig, ©))
- enqueue(orig);
- tpd->parameterArray[i]=copy;
- }
- ptr=ptr->inext;
- }
- genrehash(failedtasks);
- }
-#endif
-
- while(moreItems()) {
- void * ptr=dequeue();
- void *cpy=((void **)ptr)[1];
- int type=((int *)cpy)[0];
- int * pointer;
-#ifdef TASK
- if(type==TAGTYPE) {
- /* Enqueue Tag */
- /* Nothing is inside */
- enqueuetag(ptr);
- continue;
- }
-#endif
- pointer=pointerarray[type];
- if (pointer==0) {
- /* Array of primitives */
- /* Do nothing */
- } else if (((int)pointer)==1) {
- /* Array of pointers */
- struct ArrayObject *ao=(struct ArrayObject *) ptr;
- struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
- int length=ao->___length___;
- int i;
- for(i=0;i<length;i++) {
- void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
- void * copy;
- if (gc_createcopy(objptr, ©))
- enqueue(objptr);
- ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=copy;
- }
- } else {
- int size=pointer[0];
- int i;
- for(i=1;i<=size;i++) {
- int offset=pointer[i];
- void * objptr=*((void **)(((int)ptr)+offset));
- void * copy;
- if (gc_createcopy(objptr, ©))
- enqueue(objptr);
- *((void **) (((int)cpy)+offset))=copy;
- }
- }
- }
-#ifdef TASK
- fixtags();
-#endif
-
-#ifdef THREADS
- needtocollect=0;
- pthread_mutex_unlock(&gclistlock);
-#endif
-}
-
-#ifdef TASK
-void fixtags() {
- while(taghead!=NULL) {
- int i;
- struct pointerblock *tmp=taghead->next;
- for(i=0;i<tagindex;i++) {
- struct ___TagDescriptor___ *tagd=taghead->ptrs[i];
- struct ___Object___ *obj=tagd->flagptr;
- struct ___TagDescriptor___ *copy=((struct ___TagDescriptor___**)tagd)[1];
- if (obj->type==-1) {
- /* Single object case */
- copy->flagptr=((struct ___Object___**)obj)[1];
- } else if (obj->type==OBJECTARRAYTYPE) {
- /* Array case */
- struct ArrayObject *ao=(struct ArrayObject *) obj;
- int livecount=0;
- int j;
- int k=0;
- struct ArrayObject *aonew;
-
- /* Count live objects */
- for(j=0;j<ao->___cachedCode___;j++) {
- struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, j);
- if (tobj->type==-1)
- livecount++;
- }
-
- livecount=((livecount-1)/OBJECTARRAYINTERVAL+1)*OBJECTARRAYINTERVAL;
- aonew=(struct ArrayObject *) tomalloc(sizeof(struct ArrayObject)+sizeof(struct ___Object___*)*livecount);
- aonew->type=OBJECTARRAYTYPE;
- aonew->___length___=livecount;
- copy->flagptr=aonew;
- for(j=0;j<ao->___cachedCode___;j++) {
- struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, j);
- if (tobj->type==-1) {
- struct ___Object___ * tobjcpy=((struct ___Object___**)tobj)[1];
- ARRAYSET(aonew, struct ___Object___*, k++,tobjcpy);
- }
- }
- aonew->___cachedCode___=k;
-
- } else {
- /* No object live anymore */
- copy->flagptr=NULL;
- }
- }
- free(taghead);
- taghead=tmp;
- tagindex=NUMPTRS;
- }
-}
-#endif
-
-void * curr_heapbase=0;
-void * curr_heapptr=0;
-void * curr_heapgcpoint=0;
-void * curr_heaptop=0;
-
-void * to_heapbase=0;
-void * to_heapptr=0;
-void * to_heaptop=0;
-long lastgcsize=0;
-
-void * tomalloc(int size) {
- void * ptr=to_heapptr;
- if ((size%4)!=0)
- size+=(4-(size%4));
- to_heapptr+=size;
- return ptr;
-}
-
-#ifdef THREADS
-
-void checkcollect(void * ptr) {
- if (needtocollect) {
- struct listitem * tmp=stopforgc((struct garbagelist *)ptr);
- pthread_mutex_lock(&gclock); // Wait for GC
- restartaftergc(tmp);
- pthread_mutex_unlock(&gclock);
-
- }
-}
-
-struct listitem * stopforgc(struct garbagelist * ptr) {
- struct listitem * litem=malloc(sizeof(struct listitem));
- litem->stackptr=ptr;
- litem->locklist=pthread_getspecific(threadlocks);
- litem->prev=NULL;
- pthread_mutex_lock(&gclistlock);
- litem->next=list;
- if(list!=NULL)
- list->prev=litem;
- list=litem;
- listcount++;
- pthread_cond_signal(&gccond);
- pthread_mutex_unlock(&gclistlock);
- return litem;
-}
-
-void restartaftergc(struct listitem * litem) {
- pthread_mutex_lock(&gclistlock);
- pthread_setspecific(threadlocks, litem->locklist);
- if (litem->prev==NULL) {
- list=litem->next;
- } else {
- litem->prev->next=litem->next;
- }
- if (litem->next!=NULL) {
- litem->next->prev=litem->prev;
- }
- listcount--;
- pthread_mutex_unlock(&gclistlock);
- free(litem);
-}
-#endif
-
-void * mygcmalloc(struct garbagelist * stackptr, int size) {
- void *ptr;
-#ifdef THREADS
- if (pthread_mutex_trylock(&gclock)!=0) {
- struct listitem *tmp=stopforgc(stackptr);
- pthread_mutex_lock(&gclock);
- restartaftergc(tmp);
- }
-#endif
- ptr=curr_heapptr;
- if ((size%4)!=0)
- size+=(4-(size%4));
- curr_heapptr+=size;
- if (curr_heapptr>curr_heapgcpoint) {
- if (curr_heapbase==0) {
- /* Need to allocate base heap */
- curr_heapbase=malloc(INITIALHEAPSIZE);
- bzero(curr_heapbase, INITIALHEAPSIZE);
- curr_heaptop=curr_heapbase+INITIALHEAPSIZE;
- curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(INITIALHEAPSIZE);
- curr_heapptr=curr_heapbase+size;
-
- to_heapbase=malloc(INITIALHEAPSIZE);
- to_heaptop=to_heapbase+INITIALHEAPSIZE;
- to_heapptr=to_heapbase;
- ptr=curr_heapbase;
-#ifdef THREADS
- pthread_mutex_unlock(&gclock);
-#endif
- return ptr;
- }
-
- /* Grow the to heap if necessary */
- {
- int curr_heapsize=curr_heaptop-curr_heapbase;
- int to_heapsize=to_heaptop-to_heapbase;
- int last_heapsize=0;
- if (lastgcsize>0) {
- last_heapsize=HEAPSIZE(lastgcsize, size);
- if ((last_heapsize%4)!=0)
- last_heapsize+=(4-(last_heapsize%4));
- }
- if (curr_heapsize>last_heapsize)
- last_heapsize=curr_heapsize;
- if (last_heapsize>to_heapsize) {
- free(to_heapbase);
- to_heapbase=malloc(last_heapsize);
- to_heaptop=to_heapbase+last_heapsize;
- to_heapptr=to_heapbase;
- }
- }
-
- /* Do our collection */
- collect(stackptr);
-
- /* Update stat on previous gc size */
- lastgcsize=(to_heapptr-to_heapbase)+size;
-
- /* Flip to/curr heaps */
- {
- void * tmp=to_heapbase;
- to_heapbase=curr_heapbase;
- curr_heapbase=tmp;
-
- tmp=to_heaptop;
- to_heaptop=curr_heaptop;
- curr_heaptop=tmp;
-
- tmp=to_heapptr;
- curr_heapptr=to_heapptr+size;
- curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(curr_heaptop-curr_heapbase);
- to_heapptr=to_heapbase;
-
- /* Not enough room :(, redo gc */
- if (curr_heapptr>curr_heapgcpoint) {
-#ifdef THREADS
- pthread_mutex_unlock(&gclock);
-#endif
- return mygcmalloc(stackptr, size);
- }
-
- bzero(tmp, curr_heaptop-tmp);
-#ifdef THREADS
- pthread_mutex_unlock(&gclock);
-#endif
- return tmp;
- }
- } else {
-#ifdef THREADS
- pthread_mutex_unlock(&gclock);
-#endif
- return ptr;
- }
-}
-
-
-int gc_createcopy(void * orig, void ** copy_ptr) {
- if (orig==0) {
- *copy_ptr=NULL;
- return 0;
- } else {
- int type=((int *)orig)[0];
- if (type==-1) {
- *copy_ptr=((void **)orig)[1];
- return 0;
- } if (type<NUMCLASSES) {
- /* We have a normal object */
- int size=classsize[type];
- void *newobj=tomalloc(size);
- memcpy(newobj, orig, size);
- ((int *)orig)[0]=-1;
- ((void **)orig)[1]=newobj;
- *copy_ptr=newobj;
- return 1;
- } else {
- /* We have an array */
- struct ArrayObject *ao=(struct ArrayObject *)orig;
- int elementsize=classsize[type];
- int length=ao->___length___;
- int size=sizeof(struct ArrayObject)+length*elementsize;
- void *newobj=tomalloc(size);
- memcpy(newobj, orig, size);
- ((int *)orig)[0]=-1;
- ((void **)orig)[1]=newobj;
- *copy_ptr=newobj;
- return 1;
- }
- }
-}
+++ /dev/null
-#ifndef GARBAGE_H
-#define GARBAGE_H
-struct garbagelist {
- int size;
- struct garbagelist *next;
- void * array[];
-};
-
-struct listitem {
- struct listitem * prev;
- struct listitem * next;
- struct garbagelist * stackptr;
- struct ___Object___ * locklist;
-};
-
-#ifdef TASK
-void fixtags();
-#endif
-
-#ifdef THREADS
-void checkcollect(void * ptr);
-struct listitem * stopforgc(struct garbagelist * ptr);
-void restartaftergc(struct listitem * litem);
-#endif
-void * tomalloc(int size);
-void collect(struct garbagelist *stackptr);
-int gc_createcopy(void * orig, void **);
-void * mygcmalloc(struct garbagelist * ptr, int size);
-#endif
+++ /dev/null
-#ifndef MEMH
-#define MEMH
-#include<stdlib.h>
-#include<stdio.h>
-
-#ifdef BOEHM_GC
-#include "gc.h"
-#define FREEMALLOC(x) GC_malloc(x)
-#define RUNMALLOC(x) GC_malloc(x)
-#define RUNFREE(x)
-#else
-#ifdef PRECISE_GC
-#include "garbage.h"
-#define RUNMALLOC(x) calloc(1,x)
-#define RUNFREE(x) free(x)
-#else
-#define FREEMALLOC(x) calloc(1,x)
-#define RUNMALLOC(x) calloc(1,x)
-#define RUNFREE(x) free(x)
-#endif
-#endif
-#endif
+++ /dev/null
-#include "object.h"
-#include "stdio.h"
-#include "stdlib.h"
-
-#ifdef THREADS
-#include "thread.h"
-#endif
-
-int CALL01(___Object______nativehashCode____, struct ___Object___ * ___this___) {
- return (int) VAR(___this___);
-}
-
-int CALL01(___Object______getType____, struct ___Object___ * ___this___) {
- return ((int *)VAR(___this___))[0];
-}
-
-#ifdef THREADS
-int CALL01(___Object______MonitorEnter____, struct ___Object___ * ___this___) {
- pthread_t self=pthread_self();
- if (self==VAR(___this___)->tid) {
- VAR(___this___)->lockcount++;
- } else {
-#ifdef PRECISE_GC
- struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
-#endif
- pthread_mutex_lock(&objlock);
-#ifdef PRECISE_GC
- restartaftergc(tmp);
-#endif
- while(1) {
- if (VAR(___this___)->tid==0) {
- VAR(___this___)->___prevlockobject___=NULL;
- VAR(___this___)->___nextlockobject___=(struct ___Object___ *)pthread_getspecific(threadlocks);
- if (VAR(___this___)->___nextlockobject___!=NULL)
- VAR(___this___)->___nextlockobject___->___prevlockobject___=VAR(___this___);
- pthread_setspecific(threadlocks, VAR(___this___));
- VAR(___this___)->lockcount=1;
- VAR(___this___)->tid=self;
- pthread_mutex_unlock(&objlock);
- break;
- }
- {
-#ifdef PRECISE_GC
- struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
-#endif
- pthread_cond_wait(&objcond, &objlock);
-#ifdef PRECISE_GC
- restartaftergc(tmp);
-#endif
- }
- }
- }
-}
-
-int CALL01(___Object______MonitorExit____, struct ___Object___ * ___this___) {
- pthread_t self=pthread_self();
- if (self==VAR(___this___)->tid) {
- VAR(___this___)->lockcount--;
- if (VAR(___this___)->lockcount==0) {
- if (VAR(___this___)->___prevlockobject___==NULL) {
- pthread_setspecific(threadlocks, VAR(___this___)->___nextlockobject___);
- } else
- VAR(___this___)->___prevlockobject___->___nextlockobject___=VAR(___this___)->___nextlockobject___;
- if (VAR(___this___)->___nextlockobject___!=NULL)
- VAR(___this___)->___nextlockobject___->___prevlockobject___=VAR(___this___)->___prevlockobject___;
- VAR(___this___)->lockentry=NULL;
- VAR(___this___)->tid=0;
- }
- pthread_mutex_lock(&objlock);
- pthread_cond_broadcast(&objcond);
- pthread_mutex_unlock(&objlock);
- } else {
- printf("ERROR...UNLOCKING LOCK WE DON'T HAVE\n");
- exit(-1);
- }
-}
-#endif
+++ /dev/null
-#ifndef OBJECT_H
-#define OBJECT_H
-#include "runtime.h"
-#include "structdefs.h"
-
-int CALL01(___Object______nativehashCode____, struct ___Object___ * ___this___);int CALL01(___Object______getType____, struct ___Object___ * ___this___);
-#ifdef THREADS
-int CALL01(___Object______MonitorEnter____, struct ___Object___ * ___this___);
-int CALL01(___Object______MonitorExit____, struct ___Object___ * ___this___);
-#endif
-#endif
+++ /dev/null
-#include "option.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "runtime.h"
-#include <stdlib.h>
-
-extern char *options;
-extern int injectfailures;
-extern float failurechance;
-extern int debugtask;
-extern int injectinstructionfailures;
-extern int failurecount;
-extern float instfailurechance;
-extern int numfailures;
-extern int instaccum;
-extern char ** environ;
-
-void processOptions() {
- int i;
- options=NULL;
- for(i=0;environ[i]!=0;i++) {
- if (strncmp(environ[i],"BRISTLECONE=",12)==0) {
- options=environ[i]+12;
- break;
- }
- }
-
- while(options!=NULL) {
- if (strncmp(options,"-injectfailures",sizeof("-injectfailures")-1)==0) {
- options=strchr(options,' ');
- if (options!=NULL) options++;
- if (options==NULL)
- break;
- sscanf(options, "%f", &failurechance);
- injectfailures=1;
- printf("Injecting errors with chance=%f\n",failurechance);
- options=strchr(options,' ');
- if (options!=NULL) options++;
- } else if (strncmp(options,"-injectinstructionfailures",sizeof("-injectinstructionfailures")-1)==0) {
- options=strchr(options,' ');
- if (options!=NULL) options++;
- if (options==NULL)
- break;
- sscanf(options, "%d", &failurecount);
- options=strchr(options,' ');
- if (options!=NULL) options++;
- if (options==NULL)
- break;
-
- sscanf(options, "%f", &instfailurechance);
- options=strchr(options,' ');
- if (options!=NULL) options++;
- if (options==NULL)
- break;
-
- sscanf(options, "%d", &numfailures);
- options=strchr(options,' ');
- if (options!=NULL) options++;
-
- instaccum=failurecount;
- instructioncount=failurecount;
- injectinstructionfailures=1;
- printf("Number of failures=%d\n",numfailures);
- printf("Injecting errors with count=%d\n",failurecount);
- printf("Injecting errors with chance=%f\n",instfailurechance);
- } else if (strncmp(options, "-debugtask",sizeof("-debugtask")-1)==0) {
- options=strchr(options,' ');
- if (options!=NULL) options++;
- debugtask=1;
- printf("Debug task option on.\n");
- } else if (strncmp(options, "-initializerandom", sizeof("-initializerandom")-1)==0) {
- options=strchr(options,' ');
- if (options!=NULL) options++;
- printf("Initializing random number generator.\n");
- srandom(time(NULL));
- } else
- break;
- }
-}
+++ /dev/null
-#ifdef OPTION_H
-#define OPTION_H
-void processOptions();
-#endif
+++ /dev/null
-#include "runtime.h"
-#include "structdefs.h"
-#include <signal.h>
-#include "mem.h"
-#include<fcntl.h>
-#include<errno.h>
-#include<signal.h>
-#include<stdio.h>
-#include "option.h"
-
-extern int classsize[];
-jmp_buf error_handler;
-int instructioncount;
-
-char *options;
-int injectfailures=0;
-float failurechance=0;
-int debugtask=0;
-int injectinstructionfailures;
-int failurecount;
-float instfailurechance=0;
-int numfailures;
-int instaccum=0;
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-
-
-
-void exithandler(int sig, siginfo_t *info, void * uap) {
- exit(0);
-}
-
-void initializeexithandler() {
- struct sigaction sig;
- sig.sa_sigaction=&exithandler;
- sig.sa_flags=SA_SIGINFO;
- sigemptyset(&sig.sa_mask);
- sigaction(SIGUSR2, &sig, 0);
-}
-
-
-/* This function inject failures */
-
-void injectinstructionfailure() {
-#ifdef TASK
- if (injectinstructionfailures) {
- if (numfailures==0)
- return;
- instructioncount=failurecount;
- instaccum+=failurecount;
- if ((((double)random())/RAND_MAX)<instfailurechance) {
- if (numfailures>0)
- numfailures--;
- printf("FAILURE!!! %d\n",numfailures);
- longjmp(error_handler,11);
- }
- }
-#else
-#ifdef THREADS
- if (injectinstructionfailures) {
- if (numfailures==0)
- return;
- instaccum+=failurecount;
- if ((((double)random())/RAND_MAX)<instfailurechance) {
- if (numfailures>0)
- numfailures--;
- printf("FAILURE!!! %d\n",numfailures);
- threadexit();
- }
- }
-#endif
-#endif
-}
-
-void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
- struct ArrayObject * chararray=VAR(___s___)->___value___;
- int i;
- int offset=VAR(___s___)->___offset___;
- for(i=0;i<VAR(___s___)->___count___;i++) {
- short sc=((short *)(((char *)& chararray->___length___)+sizeof(int)))[i+offset];
- putchar(sc);
- }
-}
-
-/* Object allocation function */
-
-#ifdef PRECISE_GC
-void * allocate_new(void * ptr, int type) {
- struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
- v->type=type;
-#ifdef THREADS
- v->tid=0;
- v->lockentry=0;
- v->lockcount=0;
-#endif
- return v;
-}
-
-/* Array allocation function */
-
-struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
- struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
- v->type=type;
- if (length<0) {
- printf("ERROR: negative array\n");
- return NULL;
- }
- v->___length___=length;
-#ifdef THREADS
- v->tid=0;
- v->lockentry=0;
- v->lockcount=0;
-#endif
- return v;
-}
-
-#else
-void * allocate_new(int type) {
- void * v=FREEMALLOC(classsize[type]);
- *((int *)v)=type;
- return v;
-}
-
-/* Array allocation function */
-
-struct ArrayObject * allocate_newarray(int type, int length) {
- struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
- v->type=type;
- v->___length___=length;
- return v;
-}
-#endif
-
-
-/* Converts C character arrays into Java strings */
-#ifdef PRECISE_GC
-struct ___String___ * NewString(void * ptr, const char *str,int length) {
-#else
-struct ___String___ * NewString(const char *str,int length) {
-#endif
- int i;
-#ifdef PRECISE_GC
- struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
- int ptrarray[]={1, (int) ptr, (int) chararray};
- struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
- chararray=(struct ArrayObject *) ptrarray[2];
-#else
- struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
- struct ___String___ * strobj=allocate_new(STRINGTYPE);
-#endif
- strobj->___value___=chararray;
- strobj->___count___=length;
- strobj->___offset___=0;
-
- for(i=0;i<length;i++) {
- ((short *)(((char *)& chararray->___length___)+sizeof(int)))[i]=(short)str[i]; }
- return strobj;
-}
-
-/* Generated code calls this if we fail a bounds check */
-
-void failedboundschk() {
-#ifndef TASK
- printf("Array out of bounds\n");
-#ifdef THREADS
- threadexit();
-#else
- exit(-1);
-#endif
-#else
- longjmp(error_handler,2);
-#endif
-}
-
-/* Abort task call */
-void abort_task() {
-#ifdef TASK
- longjmp(error_handler,4);
-#else
- printf("Aborting\n");
- exit(-1);
-#endif
-}
+++ /dev/null
-#ifndef RUNTIME
-#define RUNTIME
-#include <setjmp.h>
-extern jmp_buf error_handler;
-extern int instructioncount;
-extern int failurecount;
-
-#define TAGARRAYINTERVAL 10
-#define OBJECTARRAYINTERVAL 10
-
-#define ARRAYSET(array, type, index, value) \
-((type *)(&(& array->___length___)[1]))[index]=value
-
-#define ARRAYGET(array, type, index) \
-((type *)(&(& array->___length___)[1]))[index]
-
-#ifdef PRECISE_GC
-#include "garbage.h"
-void * allocate_new(void *, int type);
-struct ArrayObject * allocate_newarray(void *, int type, int length);
-struct ___String___ * NewString(void *, const char *str,int length);
-struct ___TagDescriptor___ * allocate_tag(void *ptr, int index);
-#else
-void * allocate_new(int type);
-struct ArrayObject * allocate_newarray(int type, int length);
-struct ___String___ * NewString(const char *str,int length);
-struct ___TagDescriptor___ * allocate_tag(int index);
-#endif
-
-
-
-void initializeexithandler();
-void failedboundschk();
-void failednullptr();
-void abort_task();
-void injectinstructionfailure();
-void createstartupobject();
-
-#ifdef PRECISE_GC
-#define VAR(name) ___params___->name
-#define CALL00(name) name(struct name ## _params * ___params___)
-#define CALL01(name, alt) name(struct name ## _params * ___params___)
-#define CALL02(name, alt1, alt2) name(struct name ## _params * ___params___)
-#define CALL11(name,rest, alt) name(struct name ## _params * ___params___, rest)
-#define CALL12(name,rest, alt1, alt2) name(struct name ## _params * ___params___, rest)
-#define CALL23(name, rest, rest2, alt1, alt2, alt3) name(struct name ## _params * ___params___, rest, rest2)
-#define CALL24(name, rest, rest2, alt1, alt2, alt3, alt4) name(struct name ## _params * ___params___, rest, rest2)
-#else
-#define VAR(name) name
-#define CALL00(name) name()
-#define CALL01(name, alt) name(alt)
-#define CALL02(name, alt1, alt2) name(alt1, alt2)
-#define CALL11(name,rest, alt) name(alt)
-#define CALL12(name,rest, alt1, alt2) name(alt1, alt2)
-#define CALL23(name, rest, rest2, alt1, alt2, alt3) name(alt1, alt2, alt3)
-#define CALL24(name, rest, rest2, alt1, alt2, alt3, alt4) name(alt1, alt2, alt3, alt4)
-#endif
-
-#ifdef TASK
-#include "SimpleHash.h"
-#include "task.h"
-#include "structdefs.h"
-
-void flagorand(void * ptr, int ormask, int andmask);
-void flagorandinit(void * ptr, int ormask, int andmask);
-void executetasks();
-void processtasks();
-
-struct tagobjectiterator {
- int istag; /* 0 if object iterator, 1 if tag iterator */
- struct RuntimeIterator it; /* Object iterator */
- struct RuntimeHash * objectset;
- int slot;
- int tagobjindex; /* Index for tag or object depending on use */
- /*if tag we have an object binding */
- int tagid;
- int tagobjectslot;
- /*if object, we may have one or more tag bindings */
- int numtags;
- int tagbindings[MAXTASKPARAMS-1]; /* list slots */
-};
-
-struct parameterwrapper {
- struct parameterwrapper *next;
- struct RuntimeHash * objectset;
- int numberofterms;
- int * intarray;
- int numbertags;
- int * tagarray;
- struct taskdescriptor * task;
- int slot;
- struct tagobjectiterator iterators[MAXTASKPARAMS-1];
-};
-
-struct taskparamdescriptor {
- struct taskdescriptor * task;
- int numParameters;
- void ** parameterArray;
-};
-
-int hashCodetpd(struct taskparamdescriptor *);
-int comparetpd(struct taskparamdescriptor *, struct taskparamdescriptor *);
-
-void toiReset(struct tagobjectiterator * it);
-int toiHasNext(struct tagobjectiterator *it, void ** objectarray);
-void toiNext(struct tagobjectiterator *it , void ** objectarray);
-void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams);
-void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams);
-void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter);
-void enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr);
-
-#endif
-
-#endif
+++ /dev/null
-#include "runtime.h"
-#include "structdefs.h"
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <arpa/inet.h>
-#include <strings.h>
-#include <errno.h>
-#include <netdb.h>
-#include "SimpleHash.h"
-#include "GenericHashtable.h"
-
-extern struct RuntimeHash *fdtoobject;
-
-int CALL24(___Socket______nativeConnect____I__AR_B_I, int ___fd___, int ___port___, struct ___Socket___ * ___this___, int ___fd___, struct ArrayObject * ___address___ ,int ___port___) {
- struct sockaddr_in sin;
- int rc;
-
- bzero(&sin, sizeof(sin));
- sin.sin_family= AF_INET;
- sin.sin_port=htons(___port___);
- sin.sin_addr.s_addr=htonl(*(int *)(((char *)&VAR(___address___)->___length___)+sizeof(int)));
-#ifdef THREADS
-#ifdef PRECISE_GC
- struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
-#endif
-#endif
- do {
- rc = connect(___fd___, (struct sockaddr *) &sin, sizeof(sin));
- } while (rc<0 && errno==EINTR); /* repeat if interrupted */
-#ifdef THREADS
-#ifdef PRECISE_GC
- restartaftergc(tmp);
-#endif
-#endif
-
-
- if (rc<0) goto error;
-
-#ifdef TASK
- //Make non-blocking
- fcntl(___fd___, F_SETFD, 1);
- fcntl(___fd___, F_SETFL, fcntl(___fd___, F_GETFL)|O_NONBLOCK);
- RuntimeHashadd(fdtoobject, ___fd___, (int) VAR(___this___));
- addreadfd(___fd___);
-#endif
-
- return 0;
-
- error:
- close(___fd___);
- return -1;
-}
-
-
-int CALL12(___Socket______nativeBind_____AR_B_I, int ___port___, struct ArrayObject * ___address___, int ___port___) {
- int fd;
- int rc;
- socklen_t sa_size;
- struct sockaddr_in sin;
- bzero(&sin, sizeof(sin));
- sin.sin_family= AF_INET;
- sin.sin_port=0;
- sin.sin_addr.s_addr=INADDR_ANY;
-
- fd=socket(AF_INET, SOCK_STREAM, 0);
- if (fd<0) {
-#ifdef DEBUG
- perror(NULL);
- printf("createSocket error in nativeBind\n");
-#endif
-#ifdef TASK
- longjmp(error_handler,12);
-#else
-#ifdef THREADS
- threadexit();
-#else
- exit(-1);
-#endif
-#endif
- }
-
- rc = bind(fd, (struct sockaddr *) &sin, sizeof(sin));
- if (rc<0) goto error;
-
- sa_size = sizeof(sin);
- rc = getsockname(fd, (struct sockaddr *) &sin, &sa_size);
- if (rc<0) goto error;
-
- return fd;
-
- error:
- close(fd);
-#ifdef DEBUG
- perror(NULL);
- printf("createSocket error #2 in nativeBind\n");
-#endif
-#ifdef TASK
- longjmp(error_handler,13);
-#else
-#ifdef THREADS
- threadexit();
-#else
- exit(-1);
-#endif
-#endif
-}
-
-struct ArrayObject * CALL01(___InetAddress______getHostByName_____AR_B, struct ___ArrayObject___ * ___hostname___) {
- int length=VAR(___hostname___)->___length___;
- int i,j,n;
- char * str=malloc(length+1);
- struct hostent *h;
- struct ArrayObject * arraybytearray;
-
- for(i=0;i<length;i++) {
- str[i]=(((char *)&VAR(___hostname___)->___length___)+sizeof(int))[i];
- }
- str[length]=0;
- h=gethostbyname(str);
- free(str);
-
- for (n=0; h->h_addr_list[n]; n++) /* do nothing */ ;
-
-#ifdef PRECISE_GC
- arraybytearray=allocate_newarray(___params___,BYTEARRAYARRAYTYPE,n);
-#else
- arraybytearray=allocate_newarray(BYTEARRAYARRAYTYPE,n);
-#endif
- for(i=0;i<n;i++) {
- struct ArrayObject *bytearray;
-#ifdef PRECISE_GC
- {
- int ptrarray[]={1, (int) ___params___, (int)arraybytearray};
- bytearray=allocate_newarray(&ptrarray,BYTEARRAYTYPE,h->h_length);
- arraybytearray=(struct ArrayObject *) ptrarray[2];
- }
-#else
- bytearray=allocate_newarray(BYTEARRAYTYPE,h->h_length);
-#endif
- ((void **)&((&arraybytearray->___length___)[1]))[i]=bytearray;
- {
- int ha=ntohl(*(int *)h->h_addr_list[i]);
- (&bytearray->___length___)[1]=ha;
- }
- }
-
- return arraybytearray;
-}
-
-
-int CALL12(___ServerSocket______createSocket____I, int port, struct ___ServerSocket___ * ___this___, int port) {
- int fd;
-
- int n=1;
- struct sockaddr_in sin;
-
- bzero(&sin, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = htons (port);
- sin.sin_addr.s_addr = htonl (INADDR_ANY);
- fd=socket(AF_INET, SOCK_STREAM, 0);
- if (fd<0) {
-#ifdef DEBUG
- perror(NULL);
- printf("createSocket error #1\n");
-#endif
-#ifdef TASK
- longjmp(error_handler,5);
-#else
-#ifdef THREADS
- threadexit();
-#else
- exit(-1);
-#endif
-#endif
- }
-
- if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof (n)) < 0) {
- close(fd);
-#ifdef DEBUG
- perror("");
- printf("createSocket error #2\n");
-#endif
-#ifdef TASK
- longjmp(error_handler,6);
-#else
-#ifdef THREADS
- threadexit();
-#else
- exit(-1);
-#endif
-#endif
- }
-
-#ifdef TASK
- fcntl(fd, F_SETFD, 1);
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
-#endif
-
- /* bind to port */
- if (bind(fd, (struct sockaddr *) &sin, sizeof(sin))<0) {
- close(fd);
-#ifdef DEBUG
- perror("");
- printf("createSocket error #3\n");
-#endif
-#ifdef TASK
- longjmp(error_handler,7);
-#else
-#ifdef THREADS
- threadexit();
-#else
- exit(-1);
-#endif
-#endif
- }
-
- /* listen */
- if (listen(fd, 5)<0) {
- close (fd);
-#ifdef DEBUG
- perror("");
- printf("createSocket error #4\n");
-#endif
-#ifdef TASK
- longjmp(error_handler,8);
-#else
-#ifdef THREADS
- threadexit();
-#else
- exit(-1);
-#endif
-#endif
- }
-
- /* Store the fd/socket object mapping */
-#ifdef TASK
- RuntimeHashadd(fdtoobject, fd, (int) VAR(___this___));
- addreadfd(fd);
-#endif
- return fd;
-}
-
-int CALL02(___ServerSocket______nativeaccept____L___Socket___,struct ___ServerSocket___ * ___this___, struct ___Socket___ * ___s___) {
- struct sockaddr_in sin;
- unsigned int sinlen=sizeof(sin);
- int fd=VAR(___this___)->___fd___;
- int newfd;
-#ifdef THREADS
-#ifdef PRECISE_GC
- struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
-#endif
-#endif
- newfd=accept(fd, (struct sockaddr *)&sin, &sinlen);
-#ifdef THREADS
-#ifdef PRECISE_GC
- restartaftergc(tmp);
-#endif
-#endif
- if (newfd<0) {
-#ifdef DEBUG
- perror(NULL);
- printf("acceptSocket error #1\n");
-#endif
-#ifdef TASK
- longjmp(error_handler,9);
-#else
-#ifdef THREADS
- threadexit();
-#else
- exit(-1);
-#endif
-#endif
- }
-#ifdef TASK
- fcntl(newfd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
- RuntimeHashadd(fdtoobject, newfd, (int) VAR(___s___));
- addreadfd(newfd);
- flagorand(VAR(___this___),0,0xFFFFFFFE);
-#endif
- return newfd;
-}
-
-void CALL02(___Socket______nativeWrite_____AR_B, struct ___Socket___ * ___this___, struct ArrayObject * ___b___) {
- int fd=VAR(___this___)->___fd___;
- int length=VAR(___b___)->___length___;
- char * charstr=((char *)& VAR(___b___)->___length___)+sizeof(int);
- while(1) {
- int bytewritten=write(fd, charstr, length);
- if (bytewritten==-1&&errno==EAGAIN)
- continue;
-
- if (bytewritten!=length) {
- perror("ERROR IN NATIVEWRITE");
- printf("Supposed to write %d, wrote %d\n", length, bytewritten);
- }
- break;
- }
-}
-
-int CALL02(___Socket______nativeRead_____AR_B, struct ___Socket___ * ___this___, struct ArrayObject * ___b___) {
- int fd=VAR(___this___)->___fd___;
- int length=VAR(___b___)->___length___;
-
- char * charstr=malloc(length);
-
-#ifdef THREADS
-#ifdef PRECISE_GC
- struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
-#endif
-#endif
- int byteread;
-
- // printf("Doing read on %d\n",fd);
- while(1) {
- byteread=read(fd, charstr, length);
-
- break;
- }
-#ifdef THREADS
-#ifdef PRECISE_GC
- restartaftergc(tmp);
-#endif
-#endif
-
- {
- int i;
- for(i=0;i<byteread;i++) {
- (((char *)& VAR(___b___)->___length___)+sizeof(int))[i]=charstr[i];
- }
- free(charstr);
- }
-
-
- if (byteread<0) {
- printf("ERROR IN NATIVEREAD\n");
- perror("");
- byteread=0;
- }
-#ifdef TASK
- flagorand(VAR(___this___),0,0xFFFFFFFE);
-#endif
- return byteread;
-}
-
-void CALL01(___Socket______nativeClose____, struct ___Socket___ * ___this___) {
- int fd=VAR(___this___)->___fd___;
- int data;
-#ifdef TASK
- RuntimeHashget(fdtoobject, fd, &data);
- RuntimeHashremove(fdtoobject, fd, data);
- removereadfd(fd);
- flagorand(VAR(___this___),0,0xFFFFFFFE);
-#endif
- close(fd);
-}
+++ /dev/null
-#ifdef TASK
-#include "runtime.h"
-#include "structdefs.h"
-#include "mem.h"
-#include "checkpoint.h"
-#include "Queue.h"
-#include "SimpleHash.h"
-#include "GenericHashtable.h"
-#include "optionalstruct.h"
-#include <sys/select.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <string.h>
-#include <signal.h>
-
-extern int injectfailures;
-extern float failurechance;
-extern int debugtask;
-extern int instaccum;
-
-#ifdef CONSCHECK
-#include "instrument.h"
-#endif
-
-struct genhashtable * activetasks;
-struct parameterwrapper * objectqueues[NUMCLASSES];
-struct genhashtable * failedtasks;
-struct taskparamdescriptor * currtpd;
-struct RuntimeHash * forward;
-struct RuntimeHash * reverse;
-
-
-int main(int argc, char **argv) {
-#ifdef BOEHM_GC
- GC_init(); // Initialize the garbage collector
-#endif
-#ifdef CONSCHECK
- initializemmap();
-#endif
- processOptions();
- initializeexithandler();
- /* Create table for failed tasks */
- failedtasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
- (int (*)(void *,void *)) &comparetpd);
- /* Create queue of active tasks */
- activetasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
- (int (*)(void *,void *)) &comparetpd);
-
-
- /* Process task information */
- processtasks();
-
- /* Create startup object */
- createstartupobject(argc, argv);
-
- /* Start executing the tasks */
- executetasks();
-}
-
-void createstartupobject(int argc, char ** argv) {
- int i;
-
- /* Allocate startup object */
-#ifdef PRECISE_GC
- struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(NULL, STARTUPTYPE);
- struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);
-#else
- struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
- struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);
-#endif
- /* Build array of strings */
- startupobject->___parameters___=stringarray;
- for(i=1;i<argc;i++) {
- int length=strlen(argv[i]);
-#ifdef PRECISE_GC
- struct ___String___ *newstring=NewString(NULL, argv[i],length);
-#else
- struct ___String___ *newstring=NewString(argv[i],length);
-#endif
- ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;
- }
-
- /* Set initialized flag for startup object */
- flagorand(startupobject,1,0xFFFFFFFF);
-}
-
-int hashCodetpd(struct taskparamdescriptor *ftd) {
- int hash=(int)ftd->task;
- int i;
- for(i=0;i<ftd->numParameters;i++) {
- hash^=(int)ftd->parameterArray[i];
- }
- return hash;
-}
-
-int comparetpd(struct taskparamdescriptor *ftd1, struct taskparamdescriptor *ftd2) {
- int i;
- if (ftd1->task!=ftd2->task)
- return 0;
- for(i=0;i<ftd1->numParameters;i++)
- if (ftd1->parameterArray[i]!=ftd2->parameterArray[i])
- return 0;
- return 1;
-}
-
-
-/* This function sets a tag. */
-#ifdef PRECISE_GC
-void tagset(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
-#else
-void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
-#endif
- struct ___Object___ * tagptr=obj->___tags___;
- if (tagptr==NULL) {
- obj->___tags___=(struct ___Object___ *)tagd;
- } else {
- /* Have to check if it is already set */
- if (tagptr->type==TAGTYPE) {
- struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
- if (td==tagd)
- return;
-#ifdef PRECISE_GC
- int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
- struct ArrayObject * ao=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
- obj=(struct ___Object___ *)ptrarray[2];
- tagd=(struct ___TagDescriptor___ *)ptrarray[3];
- td=(struct ___TagDescriptor___ *) obj->___tags___;
-#else
- struct ArrayObject * ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
-#endif
- ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
- ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
- obj->___tags___=(struct ___Object___ *) ao;
- ao->___cachedCode___=2;
- } else {
- /* Array Case */
- int i;
- struct ArrayObject *ao=(struct ArrayObject *) tagptr;
- for(i=0;i<ao->___cachedCode___;i++) {
- struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___*, i);
- if (td==tagd)
- return;
- }
- if (ao->___cachedCode___<ao->___length___) {
- ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
- ao->___cachedCode___++;
- } else {
-#ifdef PRECISE_GC
- int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
- struct ArrayObject * aonew=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
- obj=(struct ___Object___ *)ptrarray[2];
- tagd=(struct ___TagDescriptor___ *) ptrarray[3];
- ao=(struct ArrayObject *)obj->___tags___;
-#else
- struct ArrayObject * aonew=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
-#endif
- aonew->___cachedCode___=ao->___length___+1;
- for(i=0;i<ao->___length___;i++) {
- ARRAYSET(aonew, struct ___TagDescriptor___*, i, ARRAYGET(ao, struct ___TagDescriptor___*, i));
- }
- ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
- }
- }
- }
-
- {
- struct ___Object___ * tagset=tagd->flagptr;
-
- if(tagset==NULL) {
- tagd->flagptr=obj;
- } else if (tagset->type!=OBJECTARRAYTYPE) {
-#ifdef PRECISE_GC
- int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
- struct ArrayObject * ao=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
- obj=(struct ___Object___ *)ptrarray[2];
- tagd=(struct ___TagDescriptor___ *)ptrarray[3];
-#else
- struct ArrayObject * ao=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
-#endif
- ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
- ARRAYSET(ao, struct ___Object___ *, 1, obj);
- ao->___cachedCode___=2;
- tagd->flagptr=(struct ___Object___ *)ao;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) tagset;
- if (ao->___cachedCode___<ao->___length___) {
- ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
- } else {
- int i;
-#ifdef PRECISE_GC
- int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
- struct ArrayObject * aonew=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
- obj=(struct ___Object___ *)ptrarray[2];
- tagd=(struct ___TagDescriptor___ *)ptrarray[3];
- ao=(struct ArrayObject *)tagd->flagptr;
-#else
- struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
-#endif
- aonew->___cachedCode___=ao->___cachedCode___+1;
- for(i=0;i<ao->___length___;i++) {
- ARRAYSET(aonew, struct ___Object___*, i, ARRAYGET(ao, struct ___Object___*, i));
- }
- ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
- tagd->flagptr=(struct ___Object___ *) ao;
- }
- }
- }
-}
-
-/* This function clears a tag. */
-#ifdef PRECISE_GC
-void tagclear(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
-#else
-void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
-#endif
- /* We'll assume that tag is alway there.
- Need to statically check for this of course. */
- struct ___Object___ * tagptr=obj->___tags___;
-
- if (tagptr->type==TAGTYPE) {
- if ((struct ___TagDescriptor___ *)tagptr==tagd)
- obj->___tags___=NULL;
- else
- printf("ERROR 1 in tagclear\n");
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) tagptr;
- int i;
- for(i=0;i<ao->___cachedCode___;i++) {
- struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___ *, i);
- if (td==tagd) {
- ao->___cachedCode___--;
- if (i<ao->___cachedCode___)
- ARRAYSET(ao, struct ___TagDescriptor___ *, i, ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
- ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
- if (ao->___cachedCode___==0)
- obj->___tags___=NULL;
- goto PROCESSCLEAR;
- }
- }
- printf("ERROR 2 in tagclear\n");
- }
- PROCESSCLEAR:
- {
- struct ___Object___ *tagset=tagd->flagptr;
- if (tagset->type!=OBJECTARRAYTYPE) {
- if (tagset==obj)
- tagd->flagptr=NULL;
- else
- printf("ERROR 3 in tagclear\n");
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) tagset;
- int i;
- for(i=0;i<ao->___cachedCode___;i++) {
- struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
- if (tobj==obj) {
- ao->___cachedCode___--;
- if (i<ao->___cachedCode___)
- ARRAYSET(ao, struct ___Object___ *, i, ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
- ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
- if (ao->___cachedCode___==0)
- tagd->flagptr=NULL;
- goto ENDCLEAR;
- }
- }
- printf("ERROR 4 in tagclear\n");
- }
- }
- ENDCLEAR:
- return;
-
-}
-
-/* This function allocates a new tag. */
-#ifdef PRECISE_GC
-struct ___TagDescriptor___ * allocate_tag(void *ptr, int index) {
- struct ___TagDescriptor___ * v=(struct ___TagDescriptor___ *) mygcmalloc((struct garbagelist *) ptr, classsize[TAGTYPE]);
-#else
-struct ___TagDescriptor___ * allocate_tag(int index) {
- struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
-#endif
- v->type=TAGTYPE;
- v->flag=index;
- return v;
-}
-
-
-
-/* This function updates the flag for object ptr. It or's the flag
- with the or mask and and's it with the andmask. */
-
-void flagbody(struct ___Object___ *ptr, int flag);
-
-void flagorand(void * ptr, int ormask, int andmask) {
- int oldflag=((int *)ptr)[1];
- int flag=ormask|oldflag;
- flag&=andmask;
- // Not sure why this was necessary
- // if (flag==oldflag) /* Don't do anything */
- // return;
- //else
- flagbody(ptr, flag);
-}
-
-void intflagorand(void * ptr, int ormask, int andmask) {
- int oldflag=((int *)ptr)[1];
- int flag=ormask|oldflag;
- flag&=andmask;
- if (flag==oldflag) /* Don't do anything */
- return;
- else flagbody(ptr, flag);
-}
-
-void flagorandinit(void * ptr, int ormask, int andmask) {
- int oldflag=((int *)ptr)[1];
- int flag=ormask|oldflag;
- flag&=andmask;
- flagbody(ptr,flag);
-}
-
-void flagbody(struct ___Object___ *ptr, int flag) {
- struct parameterwrapper *flagptr=(struct parameterwrapper *)ptr->flagptr;
- ptr->flag=flag;
-
- /*Remove object from all queues */
- while(flagptr!=NULL) {
- struct parameterwrapper *next;
- struct ___Object___ * tag=ptr->___tags___;
- RuntimeHashget(flagptr->objectset, (int) ptr, (int *) &next);
- RuntimeHashremove(flagptr->objectset, (int)ptr, (int) next);
- flagptr=next;
- }
-
- {
- struct QueueItem *tmpptr;
- struct parameterwrapper * parameter=objectqueues[ptr->type];
- int i;
- struct parameterwrapper * prevptr=NULL;
- struct ___Object___ *tagptr=ptr->___tags___;
-
- /* Outer loop iterates through all parameter queues an object of
- this type could be in. */
-
- while(parameter!=NULL) {
- /* Check tags */
- if (parameter->numbertags>0) {
- if (tagptr==NULL)
- goto nextloop;//that means the object has no tag but that param needs tag
- else if(tagptr->type==TAGTYPE) {//one tag
- struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
- for(i=0;i<parameter->numbertags;i++) {
- //slotid is parameter->tagarray[2*i];
- int tagid=parameter->tagarray[2*i+1];
- if (tagid!=tagptr->flag)
- goto nextloop; /*We don't have this tag */
- }
- } else {//multiple tags
- struct ArrayObject * ao=(struct ArrayObject *) tagptr;
- for(i=0;i<parameter->numbertags;i++) {
- //slotid is parameter->tagarray[2*i];
- int tagid=parameter->tagarray[2*i+1];
- int j;
- for(j=0;j<ao->___cachedCode___;j++) {
- if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, i)->flag)
- goto foundtag;
- }
- goto nextloop;
- foundtag:
- ;
- }
- }
- }
-
- /* Check flags */
- for(i=0;i<parameter->numberofterms;i++) {
- int andmask=parameter->intarray[i*2];
- int checkmask=parameter->intarray[i*2+1];
- if ((flag&andmask)==checkmask) {
- enqueuetasks(parameter, prevptr, ptr);
- prevptr=parameter;
- break;
- }
- }
- nextloop:
- parameter=parameter->next;
- }
- ptr->flagptr=prevptr;
- }
-}
-
-void enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr) {
- void * taskpointerarray[MAXTASKPARAMS];
- int j;
- int numparams=parameter->task->numParameters;
- int numiterators=parameter->task->numTotal-1;
-
- struct taskdescriptor * task=parameter->task;
-
- RuntimeHashadd(parameter->objectset, (int) ptr, (int) prevptr);//this add the object to parameterwrapper
-
- /* Add enqueued object to parameter vector */
- taskpointerarray[parameter->slot]=ptr;
-
- /* Reset iterators */
- for(j=0;j<numiterators;j++) {
- toiReset(¶meter->iterators[j]);
- }
-
- /* Find initial state */
- for(j=0;j<numiterators;j++) {
- backtrackinit:
- if(toiHasNext(¶meter->iterators[j], taskpointerarray))
- toiNext(¶meter->iterators[j], taskpointerarray);
- else if (j>0) {
- /* Need to backtrack */
- toiReset(¶meter->iterators[j]);
- j--;
- goto backtrackinit;
- } else {
- /* Nothing to enqueue */
- return;
- }
- }
-
-
- while(1) {
- /* Enqueue current state */
- struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
- tpd->task=task;
- tpd->numParameters=numiterators+1;
- tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
- for(j=0;j<=numiterators;j++)
- tpd->parameterArray[j]=taskpointerarray[j];//store the actual parameters
-
- /* Enqueue task */
- if (!gencontains(failedtasks, tpd)&&!gencontains(activetasks,tpd)) {
- genputtable(activetasks, tpd, tpd);
- } else {
- RUNFREE(tpd->parameterArray);
- RUNFREE(tpd);
- }
-
- /* This loop iterates to the next parameter combination */
- if (numiterators==0)
- return;
-
- for(j=numiterators-1; j<numiterators;j++) {
- backtrackinc:
- if(toiHasNext(¶meter->iterators[j], taskpointerarray))
- toiNext(¶meter->iterators[j], taskpointerarray);
- else if (j>0) {
- /* Need to backtrack */
- toiReset(¶meter->iterators[j]);
- j--;
- goto backtrackinc;
- } else {
- /* Nothing more to enqueue */
- return;
- }
- }
- }
-}
-
-/* Handler for signals. The signals catch null pointer errors and
- arithmatic errors. */
-
-void myhandler(int sig, siginfo_t *info, void *uap) {
-#ifdef DEBUG
- printf("sig=%d\n",sig);
- printf("signal\n");
-#endif
- longjmp(error_handler,1);
-}
-
-fd_set readfds;
-int maxreadfd;
-struct RuntimeHash *fdtoobject;
-
-void addreadfd(int fd) {
- if (fd>=maxreadfd)
- maxreadfd=fd+1;
- FD_SET(fd, &readfds);
-}
-
-void removereadfd(int fd) {
- FD_CLR(fd, &readfds);
- if (maxreadfd==(fd+1)) {
- maxreadfd--;
- while(maxreadfd>0&&!FD_ISSET(maxreadfd-1, &readfds))
- maxreadfd--;
- }
-}
-
-#ifdef PRECISE_GC
-#define OFFSET 2
-#else
-#define OFFSET 0
-#endif
-
-void executetasks() {
- void * taskpointerarray[MAXTASKPARAMS+OFFSET];
-
- /* Set up signal handlers */
- struct sigaction sig;
- sig.sa_sigaction=&myhandler;
- sig.sa_flags=SA_SIGINFO;
- sigemptyset(&sig.sa_mask);
-
- /* Catch bus errors, segmentation faults, and floating point exceptions*/
- sigaction(SIGBUS,&sig,0);
- sigaction(SIGSEGV,&sig,0);
- sigaction(SIGFPE,&sig,0);
- sigaction(SIGPIPE,&sig,0);
-
- /* Zero fd set */
- FD_ZERO(&readfds);
- maxreadfd=0;
- fdtoobject=allocateRuntimeHash(100);
-
- /* Map first block of memory to protected, anonymous page */
- mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0);
-
- newtask:
- while((hashsize(activetasks)>0)||(maxreadfd>0)) {
-
- /* Check if any filedescriptors have IO pending */
- if (maxreadfd>0) {
- int i;
- struct timeval timeout={0,0};
- fd_set tmpreadfds;
- int numselect;
- tmpreadfds=readfds;
- numselect=select(maxreadfd, &tmpreadfds, NULL, NULL, &timeout);
- if (numselect>0) {
- /* Process ready fd's */
- int fd;
- for(fd=0;fd<maxreadfd;fd++) {
- if (FD_ISSET(fd, &tmpreadfds)) {
- /* Set ready flag on object */
- void * objptr;
- // printf("Setting fd %d\n",fd);
- if (RuntimeHashget(fdtoobject, fd,(int *) &objptr)) {
- intflagorand(objptr,1,0xFFFFFFFF); /* Set the first flag to 1 */
- }
- }
- }
- }
- }
-
- /* See if there are any active tasks */
- if (hashsize(activetasks)>0) {
- int i;
- currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
- genfreekey(activetasks, currtpd);
-
- /* Check if this task has failed */
- if (gencontains(failedtasks, currtpd)) {
- // Free up task parameter descriptor
- RUNFREE(currtpd->parameterArray);
- RUNFREE(currtpd);
- goto newtask;
- }
- int numparams=currtpd->task->numParameters;
- int numtotal=currtpd->task->numTotal;
-
- /* Make sure that the parameters are still in the queues */
- for(i=0;i<numparams;i++) {
- void * parameter=currtpd->parameterArray[i];
- struct parameterdescriptor * pd=currtpd->task->descriptorarray[i];
- struct parameterwrapper *pw=(struct parameterwrapper *) pd->queue;
- int j;
- /* Check that object is still in queue */
- if (!RuntimeHashcontainskey(pw->objectset, (int) parameter)) {
- RUNFREE(currtpd->parameterArray);
- RUNFREE(currtpd);
- goto newtask;
- }
- /* Check that object still has necessary tags */
- for(j=0;j<pd->numbertags;j++) {
- int slotid=pd->tagarray[2*j]+numparams;
- struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
- if (!containstag(parameter, tagd)) {
- RUNFREE(currtpd->parameterArray);
- RUNFREE(currtpd);
- goto newtask;
- }
- }
-
- taskpointerarray[i+OFFSET]=parameter;
- }
- /* Copy the tags */
- for(;i<numtotal;i++) {
- taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
- }
-
- {
- /* Checkpoint the state */
- forward=allocateRuntimeHash(100);
- reverse=allocateRuntimeHash(100);
- void ** checkpoint=makecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, forward, reverse);
- int x;
- if (x=setjmp(error_handler)) {
- /* Recover */
- int h;
-#ifdef DEBUG
- printf("Fatal Error=%d, Recovering!\n",x);
-#endif
- genputtable(failedtasks,currtpd,currtpd);
- restorecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, checkpoint, forward, reverse);
- /*where we have to insert the code for optional tasks
- all the pointers I need are in currtpd->parameterArray */
- freeRuntimeHash(forward);
- freeRuntimeHash(reverse);
- freemalloc();
- forward=NULL;
- reverse=NULL;
- } else {
- if (injectfailures) {
- if ((((double)random())/RAND_MAX)<failurechance) {
- printf("\nINJECTING TASK FAILURE to %s\n", currtpd->task->name);
- longjmp(error_handler,10);
- }
- }
- /* Actually call task */
-#ifdef PRECISE_GC
- ((int *)taskpointerarray)[0]=currtpd->task->numParameters;
- taskpointerarray[1]=NULL;
-#endif
-
- if (debugtask) {
- printf("ENTER %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
- ((void (*) (void **)) currtpd->task->taskptr)(taskpointerarray);
- printf("EXIT %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
- } else
- ((void (*) (void **)) currtpd->task->taskptr)(taskpointerarray);
- freeRuntimeHash(forward);
- freeRuntimeHash(reverse);
- freemalloc();
- // Free up task parameter descriptor
- RUNFREE(currtpd->parameterArray);
- RUNFREE(currtpd);
- forward=NULL;
- reverse=NULL;
- }
- }
- }
- }
-}
-
-/* This function processes an objects tags */
-void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams) {
- int i;
-
- for(i=0;i<pd->numbertags;i++) {
- int slotid=pd->tagarray[2*i];
- int tagid=pd->tagarray[2*i+1];
-
- if (statusarray[slotid+numparams]==0) {
- parameter->iterators[*iteratorcount].istag=1;
- parameter->iterators[*iteratorcount].tagid=tagid;
- parameter->iterators[*iteratorcount].slot=slotid+numparams;
- parameter->iterators[*iteratorcount].tagobjectslot=index;
- statusarray[slotid+numparams]=1;
- (*iteratorcount)++;
- }
- }
-}
-
-
-void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams) {
- int i;
- int tagcount=0;
- struct RuntimeHash * objectset=((struct parameterwrapper *)pd->queue)->objectset;
-
- parameter->iterators[*iteratorcount].istag=0;
- parameter->iterators[*iteratorcount].slot=index;
- parameter->iterators[*iteratorcount].objectset=objectset;
- statusarray[index]=1;
-
- for(i=0;i<pd->numbertags;i++) {
- int slotid=pd->tagarray[2*i];
- int tagid=pd->tagarray[2*i+1];
- if (statusarray[slotid+numparams]!=0) {
- /* This tag has already been enqueued, use it to narrow search */
- parameter->iterators[*iteratorcount].tagbindings[tagcount]=slotid+numparams;
- tagcount++;
- }
- }
- parameter->iterators[*iteratorcount].numtags=tagcount;
-
- (*iteratorcount)++;
-}
-
-/* This function builds the iterators for a task & parameter */
-
-void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter) {
- int statusarray[MAXTASKPARAMS];
- int i;
- int numparams=task->numParameters;
- int iteratorcount=0;
- for(i=0;i<MAXTASKPARAMS;i++) statusarray[i]=0;
-
- statusarray[index]=1; /* Initial parameter */
- /* Process tags for initial iterator */
-
- processtags(task->descriptorarray[index], index, parameter, & iteratorcount, statusarray, numparams);
-
- while(1) {
- loopstart:
- /* Check for objects with existing tags */
- for(i=0;i<numparams;i++) {
- if (statusarray[i]==0) {
- struct parameterdescriptor *pd=task->descriptorarray[i];
- int j;
- for(j=0;j<pd->numbertags;j++) {
- int slotid=pd->tagarray[2*j];
- if(statusarray[slotid+numparams]!=0) {
- processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
- processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
- goto loopstart;
- }
- }
- }
- }
-
- /* Next do objects w/ unbound tags*/
-
- for(i=0;i<numparams;i++) {
- if (statusarray[i]==0) {
- struct parameterdescriptor *pd=task->descriptorarray[i];
- if (pd->numbertags>0) {
- processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
- processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
- goto loopstart;
- }
- }
- }
-
- /* Nothing with a tag enqueued */
-
- for(i=0;i<numparams;i++) {
- if (statusarray[i]==0) {
- struct parameterdescriptor *pd=task->descriptorarray[i];
- processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
- processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
- goto loopstart;
- }
- }
-
- /* Nothing left */
- return;
- }
-}
-
-
-
-
-/* This function processes the task information to create queues for
- each parameter type. */
-
-void processtasks() {
- int i;
- for(i=0;i<numtasks;i++) {
- struct taskdescriptor * task=taskarray[i];
- int j;
-
- for(j=0;j<task->numParameters;j++) {
- struct parameterdescriptor *param=task->descriptorarray[j];
- struct parameterwrapper * parameter=RUNMALLOC(sizeof(struct parameterwrapper));
- struct parameterwrapper ** ptr=&objectqueues[param->type];
-
- param->queue=parameter;
- parameter->objectset=allocateRuntimeHash(10);
- parameter->numberofterms=param->numberterms;
- parameter->intarray=param->intarray;
- parameter->numbertags=param->numbertags;
- parameter->tagarray=param->tagarray;
- parameter->task=task;
- /* Link new queue in */
- while((*ptr)!=NULL)
- ptr=&((*ptr)->next);
- (*ptr)=parameter;
- }
-
- /* Build iterators for parameters */
- for(j=0;j<task->numParameters;j++) {
- struct parameterdescriptor *param=task->descriptorarray[j];
- struct parameterwrapper *parameter=param->queue;
- parameter->slot=j;
- builditerators(task, j, parameter);
- }
- }
-}
-
-void toiReset(struct tagobjectiterator * it) {
- if (it->istag) {
- it->tagobjindex=0;
- } else if (it->numtags>0) {
- it->tagobjindex=0;
- } else {
- RuntimeHashiterator(it->objectset, &it->it);
- }
-}
-
-int toiHasNext(struct tagobjectiterator *it, void ** objectarray) {
- if (it->istag) {
- /* Iterate tag */
- /* Get object with tags */
- struct ___Object___ *obj=objectarray[it->tagobjectslot];
- struct ___Object___ *tagptr=obj->___tags___;
- if (tagptr->type==TAGTYPE) {
- if ((it->tagobjindex==0)&& /* First object */
- (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
- return 1;
- else
- return 0;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) tagptr;
- int tagindex=it->tagobjindex;
- for(;tagindex<ao->___cachedCode___;tagindex++) {
- struct ___TagDescriptor___ *td=ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
- if (td->flag==it->tagid) {
- it->tagobjindex=tagindex; /* Found right type of tag */
- return 1;
- }
- }
- return 0;
- }
- } else if (it->numtags>0) {
- /* Use tags to locate appropriate objects */
- struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
- struct ___Object___ *objptr=tag->flagptr;
- int i;
- if (objptr->type!=OBJECTARRAYTYPE) {
- if (it->tagobjindex>0)
- return 0;
- if (!RuntimeHashcontainskey(it->objectset, (int) objptr))
- return 0;
- for(i=1;i<it->numtags;i++) {
- struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
- if (!containstag(objptr,tag2))
- return 0;
- }
- return 1;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) objptr;
- int tagindex;
- int i;
- for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
- struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
- if (!RuntimeHashcontainskey(it->objectset, (int) objptr))
- continue;
- for(i=1;i<it->numtags;i++) {
- struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
- if (!containstag(objptr,tag2))
- goto nexttag;
- }
- return 1;
- nexttag:
- ;
- }
- it->tagobjindex=tagindex;
- return 0;
- }
- } else {
- return RunhasNext(&it->it);
- }
-}
-
-int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) {
- int j;
- struct ___Object___ * objptr=tag->flagptr;
- if (objptr->type==OBJECTARRAYTYPE) {
- struct ArrayObject *ao=(struct ArrayObject *)objptr;
- for(j=0;j<ao->___cachedCode___;j++) {
- if (ptr==ARRAYGET(ao, struct ___Object___*, j))
- return 1;
- }
- return 0;
- } else
- return objptr==ptr;
-}
-
-void toiNext(struct tagobjectiterator *it , void ** objectarray) {
- /* hasNext has all of the intelligence */
- if(it->istag) {
- /* Iterate tag */
- /* Get object with tags */
- struct ___Object___ *obj=objectarray[it->tagobjectslot];
- struct ___Object___ *tagptr=obj->___tags___;
- if (tagptr->type==TAGTYPE) {
- it->tagobjindex++;
- objectarray[it->slot]=tagptr;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) tagptr;
- objectarray[it->slot]=ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
- }
- } else if (it->numtags>0) {
- /* Use tags to locate appropriate objects */
- struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
- struct ___Object___ *objptr=tag->flagptr;
- if (objptr->type!=OBJECTARRAYTYPE) {
- it->tagobjindex++;
- objectarray[it->slot]=objptr;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) objptr;
- objectarray[it->slot]=ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
- }
- } else {
- /* Iterate object */
- objectarray[it->slot]=(void *)Runkey(&it->it);
- Runnext(&it->it);
- }
-}
-
-
-#endif
+++ /dev/null
-#include "runtime.h"
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdlib.h>
-#include "thread.h"
-#include "option.h"
-#include <signal.h>
-
-#include <stdio.h>
-int threadcount;
-pthread_mutex_t gclock;
-pthread_mutex_t gclistlock;
-pthread_cond_t gccond;
-pthread_mutex_t objlock;
-pthread_cond_t objcond;
-pthread_key_t threadlocks;
-
-void threadexit() {
- struct ___Object___ *ll=pthread_getspecific(threadlocks);
- while(ll!=NULL) {
- struct ___Object___ *llnext=ll->___nextlockobject___;
- ll->___nextlockobject___=NULL;
- ll->___prevlockobject___=NULL;
- ll->lockcount=0;
- ll->tid=0; //unlock it
- ll=llnext;
- }
- pthread_mutex_lock(&objlock);//wake everyone up
- pthread_cond_broadcast(&objcond);
- pthread_mutex_unlock(&objlock);
- pthread_mutex_lock(&gclistlock);
- threadcount--;
- pthread_cond_signal(&gccond);
- pthread_mutex_unlock(&gclistlock);
- pthread_exit(NULL);
-}
-
-void threadhandler(int sig, siginfo_t *info, void *uap) {
-#ifdef DEBUG
- printf("sig=%d\n",sig);
- printf("signal\n");
-#endif
- threadexit();
-}
-
-void initializethreads() {
- struct sigaction sig;
- threadcount=1;
- pthread_mutex_init(&gclock, NULL);
- pthread_mutex_init(&gclistlock, NULL);
- pthread_cond_init(&gccond, NULL);
- pthread_mutex_init(&objlock,NULL);
- pthread_cond_init(&objcond,NULL);
- pthread_key_create(&threadlocks, NULL);
- processOptions();
- initializeexithandler();
-
- sig.sa_sigaction=&threadhandler;
- sig.sa_flags=SA_SIGINFO;
- sigemptyset(&sig.sa_mask);
-
- /* Catch bus errors, segmentation faults, and floating point exceptions*/
- sigaction(SIGBUS,&sig,0);
- sigaction(SIGSEGV,&sig,0);
- sigaction(SIGFPE,&sig,0);
-}
-
-void initthread(struct ___Thread___ * ___this___) {
-#ifdef PRECISE_GC
- struct ___Thread______staticStart____L___Thread____params p={1, NULL, ___this___};
- ___Thread______staticStart____L___Thread___(&p);
-#else
- ___Thread______staticStart____L___Thread___(___this___);
-#endif
- pthread_mutex_lock(&gclistlock);
- threadcount--;
- pthread_cond_signal(&gccond);
- pthread_mutex_unlock(&gclistlock);
-}
-
-void CALL11(___Thread______sleep____J, long long ___millis___, long long ___millis___) {
-#ifdef THREADS
-#ifdef PRECISE_GC
- struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
-#endif
-#endif
- usleep(___millis___);
-#ifdef THREADS
-#ifdef PRECISE_GC
- restartaftergc(tmp);
-#endif
-#endif
-}
-
-void CALL01(___Thread______nativeCreate____, struct ___Thread___ * ___this___) {
- pthread_t thread;
- int retval;
- pthread_attr_t nattr;
-
- pthread_mutex_lock(&gclistlock);
- threadcount++;
- pthread_mutex_unlock(&gclistlock);
- pthread_attr_init(&nattr);
- pthread_attr_setdetachstate(&nattr, PTHREAD_CREATE_DETACHED);
-
- do {
- retval=pthread_create(&thread, &nattr, (void * (*)(void *)) &initthread, VAR(___this___));
- if (retval!=0)
- usleep(1);
- } while(retval!=0);
-
- pthread_attr_destroy(&nattr);
-}
+++ /dev/null
-#ifndef THREAD_H
-#define THREAD_H
-#include "methodheaders.h"
-#include <pthread.h>
-
-extern int threadcount;
-extern pthread_mutex_t gclock;
-extern pthread_mutex_t gclistlock;
-extern pthread_cond_t gccond;
-extern pthread_mutex_t objlock;
-extern pthread_cond_t objcond;
-extern pthread_key_t threadlocks;
-void initthread(struct ___Thread___ * ___this___);
-
-struct locklist {
- struct locklist * next;
- struct locklist * prev;
- struct ___Object___ * object;
-};
-#endif
+++ /dev/null
-public class Array {
- int a;
- public static void main(String[] st) {
- int a[]=new int[10];
- int i=2;
- a[i]=4;
- System.printInt(a[2]);
- System.printString("\n");
- System.printInt(a.length);
- System.printString("\n");
- }
-}
+++ /dev/null
-public class Array2 {
- int a;
- public static void main(String str[]) {
- int a[][]=new int[10][20];
- for(int i=0;i<10;i++) {
- for(int j=0;j<20;j++) {
- a[i][j]=i*100+j;
- }
- }
-
- for(int i=0;i<10;i++) {
- for(int j=0;j<20;j++) {
- System.printInt(a[i][j]);
- System.printString(" ");
- }
- System.printString("\n");
- }
- }
-}
+++ /dev/null
-public class BoundsFail {
- int a;
- public static void main(String str[]) {
- int a[]=new int[10];
- a[-1]=2;
- }
-}
+++ /dev/null
-public class BoundsFail2 {
- int a;
- public static void main(String str[]) {
- int a[]=new int[10];
- a[10]=2;
- }
-}
+++ /dev/null
-public class BoundsFail3 {
- int a;
- public static void main(String str[]) {
- int a[]=new int[10];
- int b=a[-1];
- }
-}
+++ /dev/null
-public class BoundsFail4 {
- int a;
- public static void main(String str[]) {
- int a[]=new int[10];
- int b=a[10];
- }
-}
+++ /dev/null
-class CommandLineTest {
- public static void main(String str[]) {
- for(int i=0;i<str.length;i++) {
- System.printString(str[i]);
- System.printString("\n");
- }
- }
-}
+++ /dev/null
-#!/bin/bash
-export PATH=$PATH:./
-dotest Array Array.java
-dotest Array2 Array2.java
-dotest BoundsFail BoundsFail.java
-dotest BoundsFail2 BoundsFail2.java
-dotest BoundsFail3 BoundsFail3.java
-dotest BoundsFail4 BoundsFail4.java
-dotest StringTest StringTest.java
-dotest StringBufferTest StringBufferTest.java
-dotest Test Test.java
-dotest virtualcalltest virtualcalltest.java
-dotest IncTest IncTest.java
-dotest CommandLineTest CommandLineTest.java hello hi
-dotest WriteFile WriteFile.java
-dotest ReadFile ReadFile.java
-dotest FileLength FileLength.java
-dotest IntegerTest IntegerTest.java
\ No newline at end of file
+++ /dev/null
-public class FileLength {
- public static void main(String []str) {
- String filename="testfile000";
- File fi=new File(filename);
- long length=fi.length();
- String st=String.valueOf((int)length);
- System.printString(st);
- }
-
-}
+++ /dev/null
-public class IncTest {
-
- public static void main(String str[]) {
- int x[]=new int[20];
- for(int i=0;i<10;) {
- x[i++]++;
- }
- for(int i=0;i<20;i++) {
- System.printInt(x[i]);
- System.printString("\n");
- }
- System.printString("----------------\n");
-
- x=new int[20];
- for(int i=0;i<10;) {
- x[++i]+=1;
- }
- for(int i=0;i<20;i++) {
- System.printInt(x[i]);
- System.printString("\n");
- }
-
-
- }
-
-
-
-}
+++ /dev/null
-public class IntegerTest {
- public static void main(String[] str) {
- Integer i=new Integer("312");
- System.printString(i.toString());
- System.printString("\n");
- System.printInt(Integer.parseInt("-34"));
- System.printString("\n");
- }
-
-
-}
+++ /dev/null
-public class ReadFile {
- public static void main(String []str) {
- String filename="testfile000";
- FileInputStream fis=new FileInputStream(filename);
- byte x[]=new byte[9];
- fis.read(x);
- fis.close();
- String st=new String(x);
- System.printString(st);
- }
-
-}
+++ /dev/null
-/* Startup object is generated with the initialstate flag set by the
- * system to start the computation up */
-
-task Startup(StartupObject s {initialstate}) {
- System.printString("Starting\n");
- ServerSocket ss=new ServerSocket(8000);
- System.printString("Creating ServerSocket\n");
- taskexit(s {!initialstate}); /* Turns initial state flag off, so this task won't refire */
-}
-
-task AcceptConnection(ServerSocket ss{SocketPending}) {
- Socket s=ss.accept();
- System.printString("Creating Socket\n");
-}
-
-task IncomingIO(Socket s{IOPending}) {
- byte[] b=new byte[10];
- int length=s.read(b);
- byte[] b2=new byte[length];
- int i;
- for(i=0;i<length;i++) {
- b2[i]=b[i];
- }
- System.printString("receiving input\n");
- s.write(b2);
-}
-
+++ /dev/null
-class StringBufferTest {
- public static void main(String str[]) {
- String a="hello world";
- StringBuffer b=new StringBuffer(a);
- b.append(a);
- System.printString(b.toString());
- }
-}
+++ /dev/null
-class StringTest {
- public static void main(String str[]) {
- String a="hello world\n";
- System.printString(a);
- System.printInt(a.indexOf('e'));
- System.printString("\n");
- System.printInt(a.indexOf("world"));
- System.printString("\n");
- System.printString(a.subString(3));
- System.printString(a.subString(3,6));
- System.printString("\n");
- }
-}
+++ /dev/null
-public class Test {
-
-
- flag A;
- flag B;
- flag C;
- flag D;
- flag E;
- flag F;
- flag G;
- flag H;
- flag I;
- flag J;
- flag K;
- flag L;
- flag M;
-
- public void Test(){
- }
-
- public boolean is(){
- return true;
- }
-
-}
-
+++ /dev/null
-
-
-task Startup(StartupObject s {initialstate}){
- tag t =new tag(link);
- Test o = new Test() {A}{t};
- taskexit(s {!initialstate});
-
-}
-
-task ONE(Test o{A}{link l}){
-
- taskexit(o {!A, B});
-}
-
-task TWO(Test o{B}{link l}){
-
- taskexit(o {!B, C});
-
-}
-
-task THREE(Test o{B}{link l}){
-
- taskexit(o {!B, D});
-}
-
-task FOUR(Test o{C}{link l}){
- tag f =new tag(link);
- taskexit(o {!C, E}{!l, f});
-
-
-}
-
-task FIVE(Test o{D}{link l}){
- tag h =new tag(link);
- taskexit(o {!D, F}{!l, h});
-
-}
-
-task SIX(optional Test o{E}{link l}){
-
- taskexit(o {!E, G});
-
-}
-
-task SEVEN(Test o{F}{link l}){
-
- taskexit(o {!F, G});
-
-}
-
-task EIGHT(optional Test o{G}{link l}){
-
- taskexit(o {!G, H});
-
-}
-
+++ /dev/null
-class Example {
- flag needoperation;
- flag needprinting;
- public Example() {}
-
-
- int operation;
- int x;
- int y;
- int z;
-}
-
-/* Startup object is generated with the initialstate flag set by the
- * system to start the computation up */
-
-task Startup(StartupObject s {initialstate}) {
- for(int i=0;i<10;i++) {
- Example e=new Example() {needoperation};
- e.x=i;
- e.y=2;
- e.operation=i%2;
- }
-
- taskexit(s {!initialstate}); /* Turns initial state flag off, so this task won't refire */
-
-}
-
-/* Fails for x=1 */
-
-task DoOperation(Example e{needoperation}) {
- e.z=10*e.y/(e.x-1);
-
- if (e.operation==0)
- /* Print the result */
- taskexit(e {!needoperation, needprinting});
- else
- /* Don't print the result */
- taskexit(e {!needoperation});
-}
-
-/* Note that we can write arbitrary boolean expressions for flag
- * expressions. For example, needprinting && ! needoperation would
- * also be a legal flag expression */
-
-task DoPrint(Example e{needprinting}) {
- System.printInt(e.z);
- System.printString("\n");
- taskexit(e {!needprinting});
-}
+++ /dev/null
-public class Test {
- public Test() {
- ;
- }
- int a;
- public static void main(String str[]) {
- Test t=new Test();
- for(int i=3;i<10000;i++) {
- boolean flagx=true;
- for(int j=2;flagx&&j<i;j++) {
- if ((i%j)==0)
- flagx=false;
- }
- if (flagx) {
- System.printInt(i);
- System.printString("\n");
- }
- }
- }
-}
+++ /dev/null
-public class Foo {
- Foo x;
- Foo() {}
-
-}
-
-public class ThreadTest extends Thread {
- public ThreadTest() {
- }
-
- public static void main(String[] st) {
- System.printString("hello");
- ThreadTest tt=new ThreadTest();
- tt.start();
- tt=new ThreadTest();
- tt.start();
- System.printString("main\n");
- System.printString("main\n");
- System.printString("main\n");
- System.printString("main\n");
- }
- public void run() {
- System.printString("thread\n");
- Foo x=null;
- for(int i=0;i<1000;i++) {
- Foo y=new Foo();
- y.x=x;
- x=y;
- }
- }
-}
+++ /dev/null
-public class PrintObject {
- PrintObject() {}
- synchronized void print(String n) {
- System.printString(n);
- }
-}
-
-public class ThreadTest2 extends Thread {
- String name;
- PrintObject a;
- public ThreadTest2(String name, PrintObject a) {
- this.name=name;
- this.a=a;
- }
-
- public static void main(String[] st) {
- PrintObject po=new PrintObject();
- System.printString("hello");
- ThreadTest2 tt=new ThreadTest2("AAAAAA\n",po);
- tt.start();
- tt=new ThreadTest2("BBBBBB\n",po);
- tt.start();
- }
- public void run() {
- while(true) {
- a.print(name);
- }
- }
-}
+++ /dev/null
-public class WriteFile {
- public static void main(String []str) {
- String filename="testfile000";
- FileOutputStream fos=new FileOutputStream(filename);
- String st=new String("adsasdasd");
- fos.write(st.getBytes());
- fos.close();
- }
-
-}
+++ /dev/null
-#!/bin/bash
-ARG1=$1
-ARG2=$2
-shift
-shift
-
-echo Doing Test $ARG1
-../buildscript -mainclass $ARG1 $ARG2 -o $ARG1 &>/dev/null
-$ARG1.bin $@ &> output/$ARG1.output
-diff output/$ARG1.output output/$ARG1.output.goal
-rm $ARG1.bin
+++ /dev/null
-0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
-100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
-200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
-300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
-400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
-500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
-600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
-700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
-800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
-900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919
+++ /dev/null
-Array out of bounds
+++ /dev/null
-Array out of bounds
+++ /dev/null
-Array out of bounds
+++ /dev/null
-Array out of bounds
+++ /dev/null
-9
\ No newline at end of file
+++ /dev/null
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-----------------
-0
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
+++ /dev/null
-adsasdasd
\ No newline at end of file
+++ /dev/null
-hello worldhello world
\ No newline at end of file
+++ /dev/null
-hello world
-1
-6
-lo world
-lo
+++ /dev/null
-3
-5
-7
-11
-13
-17
-19
-23
-29
-31
-37
-41
-43
-47
-53
-59
-61
-67
-71
-73
-79
-83
-89
-97
-101
-103
-107
-109
-113
-127
-131
-137
-139
-149
-151
-157
-163
-167
-173
-179
-181
-191
-193
-197
-199
-211
-223
-227
-229
-233
-239
-241
-251
-257
-263
-269
-271
-277
-281
-283
-293
-307
-311
-313
-317
-331
-337
-347
-349
-353
-359
-367
-373
-379
-383
-389
-397
-401
-409
-419
-421
-431
-433
-439
-443
-449
-457
-461
-463
-467
-479
-487
-491
-499
-503
-509
-521
-523
-541
-547
-557
-563
-569
-571
-577
-587
-593
-599
-601
-607
-613
-617
-619
-631
-641
-643
-647
-653
-659
-661
-673
-677
-683
-691
-701
-709
-719
-727
-733
-739
-743
-751
-757
-761
-769
-773
-787
-797
-809
-811
-821
-823
-827
-829
-839
-853
-857
-859
-863
-877
-881
-883
-887
-907
-911
-919
-929
-937
-941
-947
-953
-967
-971
-977
-983
-991
-997
-1009
-1013
-1019
-1021
-1031
-1033
-1039
-1049
-1051
-1061
-1063
-1069
-1087
-1091
-1093
-1097
-1103
-1109
-1117
-1123
-1129
-1151
-1153
-1163
-1171
-1181
-1187
-1193
-1201
-1213
-1217
-1223
-1229
-1231
-1237
-1249
-1259
-1277
-1279
-1283
-1289
-1291
-1297
-1301
-1303
-1307
-1319
-1321
-1327
-1361
-1367
-1373
-1381
-1399
-1409
-1423
-1427
-1429
-1433
-1439
-1447
-1451
-1453
-1459
-1471
-1481
-1483
-1487
-1489
-1493
-1499
-1511
-1523
-1531
-1543
-1549
-1553
-1559
-1567
-1571
-1579
-1583
-1597
-1601
-1607
-1609
-1613
-1619
-1621
-1627
-1637
-1657
-1663
-1667
-1669
-1693
-1697
-1699
-1709
-1721
-1723
-1733
-1741
-1747
-1753
-1759
-1777
-1783
-1787
-1789
-1801
-1811
-1823
-1831
-1847
-1861
-1867
-1871
-1873
-1877
-1879
-1889
-1901
-1907
-1913
-1931
-1933
-1949
-1951
-1973
-1979
-1987
-1993
-1997
-1999
-2003
-2011
-2017
-2027
-2029
-2039
-2053
-2063
-2069
-2081
-2083
-2087
-2089
-2099
-2111
-2113
-2129
-2131
-2137
-2141
-2143
-2153
-2161
-2179
-2203
-2207
-2213
-2221
-2237
-2239
-2243
-2251
-2267
-2269
-2273
-2281
-2287
-2293
-2297
-2309
-2311
-2333
-2339
-2341
-2347
-2351
-2357
-2371
-2377
-2381
-2383
-2389
-2393
-2399
-2411
-2417
-2423
-2437
-2441
-2447
-2459
-2467
-2473
-2477
-2503
-2521
-2531
-2539
-2543
-2549
-2551
-2557
-2579
-2591
-2593
-2609
-2617
-2621
-2633
-2647
-2657
-2659
-2663
-2671
-2677
-2683
-2687
-2689
-2693
-2699
-2707
-2711
-2713
-2719
-2729
-2731
-2741
-2749
-2753
-2767
-2777
-2789
-2791
-2797
-2801
-2803
-2819
-2833
-2837
-2843
-2851
-2857
-2861
-2879
-2887
-2897
-2903
-2909
-2917
-2927
-2939
-2953
-2957
-2963
-2969
-2971
-2999
-3001
-3011
-3019
-3023
-3037
-3041
-3049
-3061
-3067
-3079
-3083
-3089
-3109
-3119
-3121
-3137
-3163
-3167
-3169
-3181
-3187
-3191
-3203
-3209
-3217
-3221
-3229
-3251
-3253
-3257
-3259
-3271
-3299
-3301
-3307
-3313
-3319
-3323
-3329
-3331
-3343
-3347
-3359
-3361
-3371
-3373
-3389
-3391
-3407
-3413
-3433
-3449
-3457
-3461
-3463
-3467
-3469
-3491
-3499
-3511
-3517
-3527
-3529
-3533
-3539
-3541
-3547
-3557
-3559
-3571
-3581
-3583
-3593
-3607
-3613
-3617
-3623
-3631
-3637
-3643
-3659
-3671
-3673
-3677
-3691
-3697
-3701
-3709
-3719
-3727
-3733
-3739
-3761
-3767
-3769
-3779
-3793
-3797
-3803
-3821
-3823
-3833
-3847
-3851
-3853
-3863
-3877
-3881
-3889
-3907
-3911
-3917
-3919
-3923
-3929
-3931
-3943
-3947
-3967
-3989
-4001
-4003
-4007
-4013
-4019
-4021
-4027
-4049
-4051
-4057
-4073
-4079
-4091
-4093
-4099
-4111
-4127
-4129
-4133
-4139
-4153
-4157
-4159
-4177
-4201
-4211
-4217
-4219
-4229
-4231
-4241
-4243
-4253
-4259
-4261
-4271
-4273
-4283
-4289
-4297
-4327
-4337
-4339
-4349
-4357
-4363
-4373
-4391
-4397
-4409
-4421
-4423
-4441
-4447
-4451
-4457
-4463
-4481
-4483
-4493
-4507
-4513
-4517
-4519
-4523
-4547
-4549
-4561
-4567
-4583
-4591
-4597
-4603
-4621
-4637
-4639
-4643
-4649
-4651
-4657
-4663
-4673
-4679
-4691
-4703
-4721
-4723
-4729
-4733
-4751
-4759
-4783
-4787
-4789
-4793
-4799
-4801
-4813
-4817
-4831
-4861
-4871
-4877
-4889
-4903
-4909
-4919
-4931
-4933
-4937
-4943
-4951
-4957
-4967
-4969
-4973
-4987
-4993
-4999
-5003
-5009
-5011
-5021
-5023
-5039
-5051
-5059
-5077
-5081
-5087
-5099
-5101
-5107
-5113
-5119
-5147
-5153
-5167
-5171
-5179
-5189
-5197
-5209
-5227
-5231
-5233
-5237
-5261
-5273
-5279
-5281
-5297
-5303
-5309
-5323
-5333
-5347
-5351
-5381
-5387
-5393
-5399
-5407
-5413
-5417
-5419
-5431
-5437
-5441
-5443
-5449
-5471
-5477
-5479
-5483
-5501
-5503
-5507
-5519
-5521
-5527
-5531
-5557
-5563
-5569
-5573
-5581
-5591
-5623
-5639
-5641
-5647
-5651
-5653
-5657
-5659
-5669
-5683
-5689
-5693
-5701
-5711
-5717
-5737
-5741
-5743
-5749
-5779
-5783
-5791
-5801
-5807
-5813
-5821
-5827
-5839
-5843
-5849
-5851
-5857
-5861
-5867
-5869
-5879
-5881
-5897
-5903
-5923
-5927
-5939
-5953
-5981
-5987
-6007
-6011
-6029
-6037
-6043
-6047
-6053
-6067
-6073
-6079
-6089
-6091
-6101
-6113
-6121
-6131
-6133
-6143
-6151
-6163
-6173
-6197
-6199
-6203
-6211
-6217
-6221
-6229
-6247
-6257
-6263
-6269
-6271
-6277
-6287
-6299
-6301
-6311
-6317
-6323
-6329
-6337
-6343
-6353
-6359
-6361
-6367
-6373
-6379
-6389
-6397
-6421
-6427
-6449
-6451
-6469
-6473
-6481
-6491
-6521
-6529
-6547
-6551
-6553
-6563
-6569
-6571
-6577
-6581
-6599
-6607
-6619
-6637
-6653
-6659
-6661
-6673
-6679
-6689
-6691
-6701
-6703
-6709
-6719
-6733
-6737
-6761
-6763
-6779
-6781
-6791
-6793
-6803
-6823
-6827
-6829
-6833
-6841
-6857
-6863
-6869
-6871
-6883
-6899
-6907
-6911
-6917
-6947
-6949
-6959
-6961
-6967
-6971
-6977
-6983
-6991
-6997
-7001
-7013
-7019
-7027
-7039
-7043
-7057
-7069
-7079
-7103
-7109
-7121
-7127
-7129
-7151
-7159
-7177
-7187
-7193
-7207
-7211
-7213
-7219
-7229
-7237
-7243
-7247
-7253
-7283
-7297
-7307
-7309
-7321
-7331
-7333
-7349
-7351
-7369
-7393
-7411
-7417
-7433
-7451
-7457
-7459
-7477
-7481
-7487
-7489
-7499
-7507
-7517
-7523
-7529
-7537
-7541
-7547
-7549
-7559
-7561
-7573
-7577
-7583
-7589
-7591
-7603
-7607
-7621
-7639
-7643
-7649
-7669
-7673
-7681
-7687
-7691
-7699
-7703
-7717
-7723
-7727
-7741
-7753
-7757
-7759
-7789
-7793
-7817
-7823
-7829
-7841
-7853
-7867
-7873
-7877
-7879
-7883
-7901
-7907
-7919
-7927
-7933
-7937
-7949
-7951
-7963
-7993
-8009
-8011
-8017
-8039
-8053
-8059
-8069
-8081
-8087
-8089
-8093
-8101
-8111
-8117
-8123
-8147
-8161
-8167
-8171
-8179
-8191
-8209
-8219
-8221
-8231
-8233
-8237
-8243
-8263
-8269
-8273
-8287
-8291
-8293
-8297
-8311
-8317
-8329
-8353
-8363
-8369
-8377
-8387
-8389
-8419
-8423
-8429
-8431
-8443
-8447
-8461
-8467
-8501
-8513
-8521
-8527
-8537
-8539
-8543
-8563
-8573
-8581
-8597
-8599
-8609
-8623
-8627
-8629
-8641
-8647
-8663
-8669
-8677
-8681
-8689
-8693
-8699
-8707
-8713
-8719
-8731
-8737
-8741
-8747
-8753
-8761
-8779
-8783
-8803
-8807
-8819
-8821
-8831
-8837
-8839
-8849
-8861
-8863
-8867
-8887
-8893
-8923
-8929
-8933
-8941
-8951
-8963
-8969
-8971
-8999
-9001
-9007
-9011
-9013
-9029
-9041
-9043
-9049
-9059
-9067
-9091
-9103
-9109
-9127
-9133
-9137
-9151
-9157
-9161
-9173
-9181
-9187
-9199
-9203
-9209
-9221
-9227
-9239
-9241
-9257
-9277
-9281
-9283
-9293
-9311
-9319
-9323
-9337
-9341
-9343
-9349
-9371
-9377
-9391
-9397
-9403
-9413
-9419
-9421
-9431
-9433
-9437
-9439
-9461
-9463
-9467
-9473
-9479
-9491
-9497
-9511
-9521
-9533
-9539
-9547
-9551
-9587
-9601
-9613
-9619
-9623
-9629
-9631
-9643
-9649
-9661
-9677
-9679
-9689
-9697
-9719
-9721
-9733
-9739
-9743
-9749
-9767
-9769
-9781
-9787
-9791
-9803
-9811
-9817
-9829
-9833
-9839
-9851
-9857
-9859
-9871
-9883
-9887
-9901
-9907
-9923
-9929
-9931
-9941
-9949
-9967
-9973
+++ /dev/null
-class A {
- A() {
- ;
- }
-
- void foo(int x) {
- System.printInt(x);
- System.printString("\n");
- }
-}
-
-
-class B extends A {
- B() {
- ;
- }
-
- void foo(int x) {
- }
-}
-
-
-class C extends A {
- C() {
- ;
- }
-
- void foo(int x) {
- }
-}
-
-public class virtualcalltest {
- public static void main(String str[]) {
-
- A a=null;
- B b=new B();
- C c=new C();
- for(int i=0;i<1000000;i++) {
- if (i%2==0)
- a=b;
- else
- a=c;
-
- a.foo(20);
- }
- }
-}
+++ /dev/null
-package Util;
-
-/* Edge *****************/
-
-public class Edge {
- protected GraphNode target;
- protected GraphNode source;
- protected boolean processed = false;
-
-
- protected String dotnodeparams = new String();
-
- public Edge(GraphNode target) {
- this.target = target;
- }
-
- public String getLabel() {
- return "";
- }
-
- public void setSource(GraphNode s) {
- this.source=s;
- }
-
- public GraphNode getSource() {
- return source;
- }
-
- public GraphNode getTarget() {
- return target;
- }
-
- public void setProcessed() {
- processed = true;
- }
-
- public boolean isProcessed(){
- return processed;
- }
-
- public void setDotNodeParameters(String param) {
- if (param == null) {
- throw new NullPointerException();
- }
- if (dotnodeparams.length() > 0) {
- dotnodeparams += "," + param;
- } else {
- dotnodeparams = param;
- }
- }
-}
+++ /dev/null
-package Util;
-
-import java.util.*;
-import java.io.*;
-
-public class GraphNode {
- /* NodeStatus enumeration pattern ***********/
-
- public static final NodeStatus UNVISITED = new NodeStatus("UNVISITED");
- public static final NodeStatus PROCESSING = new NodeStatus("PROCESSING");
- public static final NodeStatus FINISHED = new NodeStatus("FINISHED");
-
- public static class NodeStatus {
- private static String name;
- private NodeStatus(String name) { this.name = name; }
- public String toString() { return name; }
- }
-
- int discoverytime = -1;
- int finishingtime = -1; /* used for searches */
-
- protected Vector edges = new Vector();
- protected Vector inedges = new Vector();
-
- NodeStatus status = UNVISITED;
- String dotnodeparams = new String();
- public boolean merge=false;
-
- public void setMerge() {
- merge=true;
- }
-
- public static void computeclosure(Collection nodes, Collection removed) {
- Stack tovisit=new Stack();
- tovisit.addAll(nodes);
- while(!tovisit.isEmpty()) {
- GraphNode gn=(GraphNode)tovisit.pop();
- for(Iterator it=gn.edges();it.hasNext();) {
- Edge edge=(Edge)it.next();
- GraphNode target=edge.getTarget();
- if (!nodes.contains(target)) {
- if ((removed==null)||
- (!removed.contains(target))) {
- nodes.add(target);
- tovisit.push(target);
- }
- }
- }
- }
- }
-
- public static void boundedcomputeclosure(Collection nodes, Collection removed,int depth) {
- Stack tovisit=new Stack();
- Stack newvisit=new Stack();
- tovisit.addAll(nodes);
- for(int i=0;i<depth&&!tovisit.isEmpty();i++) {
- while(!tovisit.isEmpty()) {
- GraphNode gn=(GraphNode)tovisit.pop();
- for(Iterator it=gn.edges();it.hasNext();) {
- Edge edge=(Edge)it.next();
- GraphNode target=edge.getTarget();
- if (!nodes.contains(target)) {
- if ((removed==null)||
- (!removed.contains(target))) {
- nodes.add(target);
- newvisit.push(target);
- }
- }
- }
- }
- tovisit=newvisit;
- newvisit=new Stack();
- }
- }
-
- public void setDotNodeParameters(String param) {
- if (param == null) {
- throw new NullPointerException();
- }
- if (dotnodeparams.length() > 0) {
- dotnodeparams += "," + param;
- } else {
- dotnodeparams = param;
- }
- }
-
- public void setStatus(NodeStatus status) {
- if (status == null) {
- throw new NullPointerException();
- }
- this.status = status;
- }
-
- public String getLabel() {
- return "";
- }
-
- public String getTextLabel() {
- return "";
- }
-
- public String getName(){
- return "";
- }
-
- public NodeStatus getStatus() {
- return this.status;
- }
-
- public int numedges() {
- return edges.size();
- }
-
- public int numinedges() {
- return inedges.size();
- }
-
- public Edge getedge(int i) {
- return (Edge) edges.get(i);
- }
-
- public Edge getinedge(int i) {
- return (Edge) inedges.get(i);
- }
-
- public Vector getEdgeVector() {
- return edges;
- }
-
- public Vector getInedgeVector() {
- return inedges;
- }
-
- public Iterator edges() {
- return edges.iterator();
- }
-
- public Iterator inedges() {
- return inedges.iterator();
- }
-
- public void addEdge(Edge newedge) {
- newedge.setSource(this);
- edges.addElement(newedge);
- GraphNode tonode=newedge.getTarget();
- tonode.inedges.addElement(newedge);
- }
-
- public void addEdge(Vector v) {
- for (Iterator it = v.iterator(); it.hasNext();)
- addEdge((Edge)it.next());
- }
-
- public void removeEdge(Edge edge) {
- edges.remove(edge);
- }
-
- public void removeInedge(Edge edge) {
- inedges.remove(edge);
- }
-
- public void removeAllEdges() {
- edges.removeAllElements();
- }
-
- public void removeAllInedges() {
- inedges.removeAllElements();
- }
- void reset() {
- discoverytime = -1;
- finishingtime = -1;
- status = UNVISITED;
- }
-
- void resetscc() {
- status = UNVISITED;
- }
-
- void discover(int time) {
- discoverytime = time;
- status = PROCESSING;
- }
-
- void finish(int time) {
- assert status == PROCESSING;
- finishingtime = time;
- status = FINISHED;
- }
-
- /** Returns finishing time for dfs */
-
- public int getFinishingTime() {
- return finishingtime;
- }
-
-
- public static class DOTVisitor {
-
- java.io.PrintWriter output;
- int tokennumber;
- int color;
- Vector namers;
-
- private DOTVisitor(java.io.OutputStream output, Vector namers) {
- tokennumber = 0;
- color = 0;
- this.output = new java.io.PrintWriter(output, true);
- this.namers=namers;
- }
-
- private String getNewID(String name) {
- tokennumber = tokennumber + 1;
- return new String (name+tokennumber);
- }
-
- Collection nodes;
-
-
- public static void visit(java.io.OutputStream output, Collection nodes, Vector namers) {
- DOTVisitor visitor = new DOTVisitor(output, namers);
- visitor.nodes = nodes;
- visitor.make();
- }
-
- public static void visit(java.io.OutputStream output, Collection nodes) {
- Vector v=new Vector();
- v.add(new Namer());
- DOTVisitor visitor = new DOTVisitor(output, v);
- visitor.nodes = nodes;
- visitor.make();
- }
-
- private void make() {
- output.println("digraph dotvisitor {");
- /* output.println("\tpage=\"8.5,11\";");
- output.println("\tnslimit=1000.0;");
- output.println("\tnslimit1=1000.0;");
- output.println("\tmclimit=1000.0;");
- output.println("\tremincross=true;");*/
- output.println("\tnode [fontsize=10,height=\"0.1\", width=\"0.1\"];");
- output.println("\tedge [fontsize=6];");
- traverse();
- output.println("}\n");
- }
-
-
-
- private void traverse() {
- Set cycleset=GraphNode.findcycles(nodes);
-
- Iterator it = nodes.iterator();
- while (it.hasNext()) {
- GraphNode gn = (GraphNode) it.next();
- Iterator edges = gn.edges();
- String label = "";
- String dotnodeparams="";
-
- for(int i=0;i<namers.size();i++) {
- Namer name=(Namer) namers.get(i);
- String newlabel=name.nodeLabel(gn);
- String newparams=name.nodeOption(gn);
-
- if (!newlabel.equals("") && !label.equals("")) {
- label+=", ";
- }
- if (!newparams.equals("")) {
- dotnodeparams+=", " + name.nodeOption(gn);
- }
- label+=name.nodeLabel(gn);
- }
-
- if (!gn.merge)
- output.println("\t" + gn.getLabel() + " [label=\"" + label + "\"" + dotnodeparams + "];");
-
- if (!gn.merge)
- while (edges.hasNext()) {
- Edge edge = (Edge) edges.next();
- GraphNode node = edge.getTarget();
- if (nodes.contains(node)) {
- for(Iterator nodeit=nonmerge(node).iterator();nodeit.hasNext();) {
- GraphNode node2=(GraphNode)nodeit.next();
- String edgelabel = "";
- String edgedotnodeparams="";
-
- for(int i=0;i<namers.size();i++) {
- Namer name=(Namer) namers.get(i);
- String newlabel=name.edgeLabel(edge);
- String newoption=name.edgeOption(edge);
- if (!newlabel.equals("")&& ! edgelabel.equals(""))
- edgelabel+=", ";
- edgelabel+=newlabel;
- if (!newoption.equals(""))
- edgedotnodeparams+=", "+newoption;
- }
-
- output.println("\t" + gn.getLabel() + " -> " + node2.getLabel() + " [" + "label=\"" + edgelabel + "\"" + edgedotnodeparams + "];");
- }
- }
- }
- }
- }
-
- Set nonmerge(GraphNode gn) {
- HashSet newset=new HashSet();
- HashSet toprocess=new HashSet();
- toprocess.add(gn);
- while(!toprocess.isEmpty()) {
- GraphNode gn2=(GraphNode)toprocess.iterator().next();
- toprocess.remove(gn2);
- if (!gn2.merge)
- newset.add(gn2);
- else {
- Iterator edges = gn2.edges();
- while (edges.hasNext()) {
- Edge edge = (Edge) edges.next();
- GraphNode node = edge.getTarget();
- if (!newset.contains(node)&&nodes.contains(node))
- toprocess.add(node);
- }
- }
- }
- return newset;
- }
-
- }
-
- /** This function returns the set of nodes involved in cycles.
- * It only considers cycles containing nodes in the set 'nodes'.
- */
- public static Set findcycles(Collection nodes) {
- HashSet cycleset=new HashSet();
- SCC scc=DFS.computeSCC(nodes);
- if (!scc.hasCycles())
- return cycleset;
- for(int i=0;i<scc.numSCC();i++) {
- if (scc.hasCycle(i))
- cycleset.addAll(scc.getSCC(i));
- }
- return cycleset;
- }
-
- public static class SCC {
- boolean acyclic;
- HashMap map,revmap;
- int numscc;
- public SCC(boolean acyclic, HashMap map,HashMap revmap,int numscc) {
- this.acyclic=acyclic;
- this.map=map;
- this.revmap=revmap;
- this.numscc=numscc;
- }
-
- /** Returns whether the graph has any cycles */
- public boolean hasCycles() {
- return !acyclic;
- }
-
- /** Returns the number of Strongly Connected Components */
- public int numSCC() {
- return numscc;
- }
-
- /** Returns the strongly connected component number for the GraphNode gn*/
- public int getComponent(GraphNode gn) {
- return ((Integer)revmap.get(gn)).intValue();
- }
-
- /** Returns the set of nodes in the strongly connected component i*/
- public Set getSCC(int i) {
- Integer scc=new Integer(i);
- return (Set)map.get(scc);
- }
-
- /** Returns whether the strongly connected component i contains a cycle */
- boolean hasCycle(int i) {
- Integer scc=new Integer(i);
- Set s=(Set)map.get(scc);
- if (s.size()>1)
- return true;
- Object [] array=s.toArray();
- GraphNode gn=(GraphNode)array[0];
- for(Iterator it=gn.edges();it.hasNext();) {
- Edge e=(Edge)it.next();
- if (e.getTarget()==gn)
- return true; /* Self Cycle */
- }
- return false;
- }
- }
-
- /**
- * DFS encapsulates the depth first search algorithm
- */
- public static class DFS {
-
- int time = 0;
- int sccindex = 0;
- Collection nodes;
- Vector finishingorder=null;
- HashMap sccmap;
- HashMap sccmaprev;
-
- private DFS(Collection nodes) {
- this.nodes = nodes;
- }
- /** Calculates the strong connected components for the graph composed
- * of the set of nodes 'nodes'*/
- public static SCC computeSCC(Collection nodes) {
- if (nodes==null) {
- throw new NullPointerException();
- }
- DFS dfs=new DFS(nodes);
- dfs.sccmap=new HashMap();
- dfs.sccmaprev=new HashMap();
- dfs.finishingorder=new Vector();
- boolean acyclic=dfs.go();
- for (Iterator it = nodes.iterator();it.hasNext();) {
- GraphNode gn = (GraphNode) it.next();
- gn.resetscc();
- }
- for(int i=dfs.finishingorder.size()-1;i>=0;i--) {
- GraphNode gn=(GraphNode)dfs.finishingorder.get(i);
- if (gn.getStatus() == UNVISITED) {
- dfs.dfsprev(gn);
- dfs.sccindex++; /* Increment scc index */
- }
- }
- return new SCC(acyclic,dfs.sccmap,dfs.sccmaprev,dfs.sccindex);
- }
-
- void dfsprev(GraphNode gn) {
- if (gn.getStatus()==FINISHED||!nodes.contains(gn))
- return;
- gn.setStatus(FINISHED);
- Integer i=new Integer(sccindex);
- if (!sccmap.containsKey(i))
- sccmap.put(i,new HashSet());
- ((Set)sccmap.get(i)).add(gn);
- sccmaprev.put(gn,i);
- for(Iterator edgeit=gn.inedges();edgeit.hasNext();) {
- Edge e=(Edge)edgeit.next();
- GraphNode gn2=e.getSource();
- dfsprev(gn2);
- }
- }
-
- public static boolean depthFirstSearch(Collection nodes) {
- if (nodes == null) {
- throw new NullPointerException();
- }
-
- DFS dfs = new DFS(nodes);
- return dfs.go();
- }
-
- private boolean go() {
- Iterator i;
- time = 0;
- boolean acyclic=true;
- i = nodes.iterator();
- while (i.hasNext()) {
- GraphNode gn = (GraphNode) i.next();
- gn.reset();
- }
-
- i = nodes.iterator();
- while (i.hasNext()) {
- GraphNode gn = (GraphNode) i.next();
- assert gn.getStatus() != PROCESSING;
- if (gn.getStatus() == UNVISITED) {
- if (!dfs(gn))
- acyclic=false;
- }
- }
- return acyclic;
- }
-
- private boolean dfs(GraphNode gn) {
- boolean acyclic=true;
- gn.discover(time++);
- Iterator edges = gn.edges();
-
- while (edges.hasNext()) {
- Edge edge = (Edge) edges.next();
- GraphNode node = edge.getTarget();
- if (!nodes.contains(node)) /* Skip nodes which aren't in the set */
- continue;
- if (node.getStatus() == UNVISITED) {
- if (!dfs(node))
- acyclic=false;
- } else if (node.getStatus()==PROCESSING) {
- acyclic=false;
- }
- }
- if (finishingorder!=null)
- finishingorder.add(gn);
- gn.finish(time++);
- return acyclic;
- }
-
- } /* end DFS */
-
-}
+++ /dev/null
-package Util;
-
-public class Namer {
- public Namer() {}
-
- public String nodeLabel(GraphNode gn) {
- return gn.getTextLabel();
- }
-
- public String nodeOption(GraphNode gn) {
- return gn.dotnodeparams;
- }
-
- public String edgeLabel(Edge e) {
- return e.getLabel();
- }
-
- public String edgeOption(Edge e) {
- return e.dotnodeparams;
- }
-}
+++ /dev/null
-package Util;
-import java.util.*;
-
-
-public class Relation {
- private Hashtable table;
- int size;
-
- public Relation() {
- table=new Hashtable();
- size=0;
- }
-
- public int size() {
- return size;
- }
-
- public boolean containsKey(Object o) {
- return table.containsKey(o);
- }
-
- public Set keySet() {
- return table.keySet();
- }
-
- public synchronized boolean put(Object key, Object value) {
- HashSet s;
- if (table.containsKey(key)) {
- s=(HashSet) table.get(key);
- } else {
- s=new HashSet();
- table.put(key,s);
- }
- if (!s.contains(value)) {
- size++;
- s.add(value);
- return true;
- } else
- return false;
- }
-
- public Set get(Object key) {
- return (Set)table.get(key);
- }
-}
#!/bin/bash
printhelp() {
+echo -robustroot set up the ROBUSTROOT to directory other than default one
echo -dsm distributed shared memory
+echo -trueprob double - probabiltiy of true branch
+echo -dsmcaching -enable caching in dsm runtime
+echo -mac distributed shared memory mac support
echo -check generate check code
echo -dmalloc link in dmalloc
echo -recover compile task code
echo -specdir directory
+echo -printflat print out flat representation
+echo -selfloop task - this task cannot self loop forever
+echo "-excprefetch methoddescriptor - exclude prefetches for this method (specified as class.method)"
echo -taskstate do task state analysis
+echo -tagstate do tag state analysis
+echo -scheduling do task scheduling
+echo -multicore generate multi-core version binary
+echo "-numcore set the number of cores (should be used together with -multicore), defaultly set as 1"
+echo "-raw generate raw version binary (should be used together with -multicore)"
+echo "-interrupt generate raw version binary with interruption (should be used togethere with -raw)"
+echo "-rawconfig config raw simulator as 4xn (should be used together with -raw)"
+echo "-rawpath print out execute path information for raw version (should be used together with -raw)"
+echo "-useprofile use profiling data for scheduling (should be used together with -raw)"
+echo -threadsimulate generate multi-thread simulate version binary
+echo -printscheduling print out scheduling graphs
+echo -printschedulesim print out scheduling simulator result graphs
echo -optional enable optional
echo -debug generate debug symbols
+echo -prefetch do prefetch analysis
+echo -transstats generates transaction stats on commits and aborts
echo -webinterface enable web interface
echo -runtimedebug printout runtime debug messages
echo "-thread use support for multiple threads"
echo -curdir directory
echo -mainclass class with main method
echo -o binary
+echo -nojava do not run bristlecone compiler
echo -instructionfailures inject code for instructionfailures
+echo -profile build with profile options
+echo "-rawuseio use standard io to output profiling data (should be used together with -raw and -profile), it only works with single core version"
+echo "-enable-assertions execute assert statements during compilation"
echo -help help
}
ROBUSTROOT=~/research/Robust/src
+DSMRUNTIME=$ROBUSTROOT/Runtime/DSTM/interface/
REPAIRROOT=~/research/Repair/RepairCompiler/
CURDIR=`pwd`
+DSMFLAG=false
+NOJAVA=false
CHECKFLAG=false
RECOVERFLAG=false
+MULTICOREFLAG=false
+TRANSSTATSFLAG=false
+RAWFLAG=false
+RAWCONFIG=''
+RAWDEBUGFLAG=false
+RAWPATHFLAG=false
+RAWPROFILEFLAG=false
+RAWUSEIOFLAG=false
+INTERRUPTFLAG=false
+THREADSIMULATEFLAG=false;
USEDMALLOC=false
THREADFLAG=false
SPECDIR=`pwd`
SRCFILES=''
EXTRAOPTIONS=''
MAINFILE='a'
+JAVAFORWARDOPTS=''
JAVAOPTS=''
+OPTIONALFLAG=false
if [[ -z $1 ]]
then
then
printhelp
exit
+elif [[ $1 = '-robustroot' ]]
+then
+ROBUSTROOT="$2"
+shift
+elif [[ $1 = '-nojava' ]]
+then
+NOJAVA=true
elif [[ $1 = '-o' ]]
then
MAINFILE="$2"
then
JAVAOPTS="$JAVAOPTS -mainclass $2"
shift
+elif [[ $1 = '-selfloop' ]]
+then
+JAVAOPTS="$JAVAOPTS -selfloop $2"
+shift
+elif [[ $1 = '-excprefetch' ]]
+then
+JAVAOPTS="$JAVAOPTS -excprefetch $2"
+shift
elif [[ $1 = '-dsm' ]]
then
JAVAOPTS="$JAVAOPTS -dsm"
+DSMFLAG=true
+elif [[ $1 = '-prefetch' ]]
+then
+JAVAOPTS="$JAVAOPTS -prefetch"
+elif [[ $1 = '-transstats' ]]
+then
+TRANSSTATSFLAG=true
+elif [[ $1 = '-printflat' ]]
+then
+JAVAOPTS="$JAVAOPTS -printflat"
+elif [[ $1 = '-trueprob' ]]
+then
+JAVAOPTS="$JAVAOPTS -trueprob $2"
+shift
+elif [[ $1 = '-mac' ]]
+then
+EXTRAOPTIONS="$EXTRAOPTIONS -DMAC"
+elif [[ $1 = '-profile' ]]
+then
+RAWPROFILEFLAG=true
+EXTRAOPTIONS="$EXTRAOPTIONS -pg"
+elif [[ $1 = '-rawuseio' ]]
+then
+RAWUSEIOFLAG=true
elif [[ $1 = '-taskstate' ]]
then
JAVAOPTS="$JAVAOPTS -taskstate"
+elif [[ $1 = '-tagstate' ]]
+then
+JAVAOPTS="$JAVAOPTS -tagstate"
+elif [[ $1 = '-scheduling' ]]
+then
+JAVAOPTS="$JAVAOPTS -scheduling"
+elif [[ $1 = '-multicore' ]]
+then
+MULTICOREFLAG=true
+JAVAOPTS="$JAVAOPTS -multicore"
+elif [[ $1 = '-numcore' ]]
+then
+JAVAOPTS="$JAVAOPTS -numcore $2"
+shift
+elif [[ $1 = '-raw' ]]
+then
+RAWFLAG=true
+JAVAOPTS="$JAVAOPTS -raw"
+elif [[ $1 = '-rawconfig' ]]
+then
+RAWCONFIG="$2"
+shift
+elif [[ $1 = '-interrupt' ]]
+then
+INTERRUPTFLAG=true
+elif [[ $1 = '-threadsimulate' ]]
+then
+THREADSIMULATEFLAG=true
elif [[ $1 = '-optional' ]]
then
JAVAOPTS="$JAVAOPTS -optional"
+OPTIONALFLAG=true
elif [[ $1 = '-dmalloc' ]]
then
USEDMALLOC=true
then
RECOVERFLAG=true
JAVAOPTS="$JAVAOPTS -task"
+elif [[ $1 = '-useprofile' ]]
+then
+JAVAOPTS="$JAVAOPTS -useprofile"
elif [[ $1 = '-webinterface' ]]
then
JAVAOPTS="$JAVAOPTS -webinterface"
then
CHECKFLAG=true
JAVAOPTS="$JAVAOPTS -conscheck"
+elif [[ $1 = '-enable-assertions' ]]
+then
+JAVAFORWARDOPTS="$JAVAFORWARDOPTS -ea"
elif [[ $1 = '-specdir' ]]
then
cd $2
shift
elif [[ $1 = '-debug' ]]
then
+RAWDEBUGFLAG=true
EXTRAOPTIONS="$EXTRAOPTIONS -g"
+elif [[ $1 = '-rawpath' ]]
+then
+RAWPATHFLAG=true
elif [[ $1 = '-runtimedebug' ]]
then
EXTRAOPTIONS="$EXTRAOPTIONS -DDEBUG"
+elif [[ $1 = '-dsmcaching' ]]
+then
+EXTRAOPTIONS="$EXTRAOPTIONS -DCACHE"
elif [[ $1 = '-nooptimize' ]]
then
EXTRAOPTIONS="$EXTRAOPTIONS -O0"
# Build bristlecone/java sources
-java -cp $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary \
+if $MULTICOREFLAG
+then
+if ! ./ourjava -Xms50m -Xmx800m $JAVAFORWARDOPTS -classpath $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary \
+$ROBUSTROOT/ClassLibrary/ -dir $BUILDDIR \
+$JAVAOPTS $SRCFILES
+then exit $?
+fi
+else
+#if ! ourjava -Xms5m -Xmx100m $JAVAFORWARDOPTS -classpath $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary \
+if ! $NOJAVA
+then
+if ! ./ourjava -Xms50m -Xmx600m $JAVAFORWARDOPTS -classpath $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary \
$ROBUSTROOT/ClassLibrary/ -dir $BUILDDIR -precise \
$JAVAOPTS $SRCFILES
+then exit $?
+fi
+fi
+fi
# Build all of the consistency specs
echo > $BUILDDIR/checkers.h
for i in `cat $BUILDDIR/specs`
do
-gcc -O0 -g -c $i\_aux.c
+gcc -O0 -g -fbounds-check -c $i\_aux.c
echo \#include \"specdir\/$i\_aux.h\" >> $BUILDDIR/checkers.h
done
fi # CHECKFLAG
#build and link everything
+if $RAWFLAG
+then # RAWFLAG
+RAWDIR="$CURDIR/raw"
+MAKEFILE="../Makefile.raw"
+mkdir $RAWDIR
+cd $RAWDIR
+make clean
+rm ./*
+
+export RAWRGCCFLAGS="-DTASK -DMULTICORE -DRAW"
+
+if $RAWPATHFLAG
+then # print path
+RAWRGCCFLAGS="${RAWRGCCFLAGS} -DRAWPATH"
+fi
+
+if $RAWDEBUGFLAG
+then #debug version
+RAWRGCCFLAGS="${RAWRGCCFLAGS} -DRAWDEBUG"
+fi
+
+if $RAWPROFILEFLAG
+then # profile version
+RAWRGCCFLAGS="${RAWRGCCFLAGS} -DRAWPROFILE"
+fi
+
+if $RAWUSEIOFLAG
+then # useio version
+RAWRGCCFLAGS="${RAWRGCCFLAGS} -DRAWUSEIO"
+fi
+
+if $INTERRUPTFLAG
+then #INTERRUPT version
+RAWRGCCFLAGS="${RAWRGCCFLAGS} -DINTERRUPT"
+fi #INTERRUPT version
+
+if $RAWUSEIOFLAG
+then # useio version
+MAKEFILE="$MAKEFILE.io"
+echo "+++++++++++use Makefile.raw.io++++++++++++++++"
+else
+MAKEFILE="$MAKEFILE.$RAWCONFIG"
+fi #useio version
+
+cp $MAKEFILE ./Makefile
+cp ../Runtime/*.c ./
+cp ../Runtime/*.h ./
+cp ../Runtime/*.S ./
+cp ../Runtime/*.s ./
+cp ../tmpbuilddirectory/*.c ./
+cp ../tmpbuilddirectory/*.h ./
+
+make
+
+else #!RAWFLAG
cd $CURDIR
INCLUDES="$INCLUDES -I$ROBUSTROOT/Runtime -I. -IRuntime/include \
-I$BUILDDIR"
-FILES="$ROBUSTROOT/Runtime/runtime.c $ROBUSTROOT/Runtime/task.c \
+if $MULTICOREFLAG
+then
+RUNTIMEFILE="$ROBUSTROOT/Runtime/multicoreruntime.c $ROBUSTROOT/Runtime/multicoretask.c"
+else
+RUNTIMEFILE="$ROBUSTROOT/Runtime/runtime.c $ROBUSTROOT/Runtime/task.c"
+fi
+
+FILES="$RUNTIMEFILE \
$ROBUSTROOT/Runtime/file.c $ROBUSTROOT/Runtime/Queue.c \
$ROBUSTROOT/Runtime/SimpleHash.c $ROBUSTROOT/Runtime/option.c \
+$ROBUSTROOT/Runtime/ObjectHash.c \
$ROBUSTROOT/Runtime/garbage.c $ROBUSTROOT/Runtime/socket.c \
+$ROBUSTROOT/Runtime/math.c \
$ROBUSTROOT/Runtime/GenericHashtable.c $ROBUSTROOT/Runtime/object.c"
+if $DSMFLAG
+then
+EXTRAOPTIONS="$EXTRAOPTIONS -lpthread -DCOMPILER -DDSTM -I$DSMRUNTIME"
+if $TRANSSTATSFLAG
+then
+EXTRAOPTIONS="$EXTRAOPTIONS -lpthread -DTRANSSTATS -DCOMPILER -DDSTM -I$DSMRUNTIME"
+fi
+FILES="$FILES $DSMRUNTIME/trans.c $DSMRUNTIME/mcpileq.c $DSMRUNTIME/objstr.c $DSMRUNTIME/dstm.c $DSMRUNTIME/mlookup.c $DSMRUNTIME/clookup.c $DSMRUNTIME/llookup.c $DSMRUNTIME/threadnotify.c $DSMRUNTIME/dstmserver.c $DSMRUNTIME/plookup.c $DSMRUNTIME/ip.c $DSMRUNTIME/queue.c $DSMRUNTIME/prelookup.c $DSMRUNTIME/machinepile.c $DSMRUNTIME/localobjects.c $ROBUSTROOT/Runtime/thread.c $DSMRUNTIME/sockpool.c $DSMRUNTIME/addUdpEnhance.c $DSMRUNTIME/signal.c $DSMRUNTIME/gCollect.c $DSMRUNTIME/addPrefetchEnhance.c $DSMRUNTIME/dsmlock.c"
+fi
+
if $RECOVERFLAG
then
EXTRAOPTIONS="$EXTRAOPTIONS -DTASK"
-FILES="$FILES tmpbuilddirectory/taskdefs.c $ROBUSTROOT/Runtime/checkpoint.c"
+if $MULTICOREFLAG
+then
+EXTRAOPTIONS="$EXTRAOPTIONS -DMULTICORE"
+fi
+FILES="$FILES tmpbuilddirectory/taskdefs.c $ROBUSTROOT/Runtime/checkpoint.c $ROBUSTROOT/Runtime/chash.c"
+if $RAWFLAG
+then
+EXTRAOPTIONS="$EXTRAOPTIONS -DRAW"
+fi
+if $THREADSIMULATEFLAG
+then
+# -lpthread for pthread functions, -lrt for message queue functions
+EXTRAOPTIONS="$EXTRAOPTIONS -DTHREADSIMULATE -lpthread -lrt"
+fi
+fi
+
+if $OPTIONALFLAG
+then
+EXTRAOPTIONS="$EXTRAOPTIONS -DOPTIONAL"
+FILES="$FILES tmpbuilddirectory/optionalarrays.c"
fi
if $THREADFLAG
EXTRAOPTIONS="$EXTRAOPTIONS -ldmalloc -DDMALLOC"
fi
+if $MULTICOREFLAG
+then
+gcc $INCLUDES $EXTRAOPTIONS \
+tmpbuilddirectory/methods.c $FILES -lm -o $MAINFILE.bin
+else
gcc $INCLUDES $EXTRAOPTIONS -DPRECISE_GC \
-tmpbuilddirectory/methods.c $FILES -o $MAINFILE.bin
+tmpbuilddirectory/methods.c $FILES -lm -o $MAINFILE.bin
+fi
+
+fi #!RAWFLAG
exit
+++ /dev/null
-#!/bin/bash
-echo THIS FILE IS DEPRECATED. DO NOT USE IT.
-./buildscript -recover -o $@
-
+++ /dev/null
-#!/bin/bash
-echo THIS FILE IS DEPRECATED. DO NOT USE IT.
-./buildscript -recover -debug -instructionfailures -o $@
+++ /dev/null
-Objects have:
-Collection of Flags
- Flags have type/name associated with them
- Are either present or not present
-
-Assumptions:
-Task parameters can't be modified
-
-How do we handle new object allocation?
-Idea #1: Set flags at allocation
- Only allow flag setting at exit for parameters
-
-Non parameter variables:
-1) Type must contain flags
-2) Apply flag additions to all states
-
-Tags operations:
-create_tag operation(type)
-
-tag name=new tag(type);
-
-associate_with_tag operation(object, tag)
-
-Dispatch:
-after flag status, allow tag status...
-each tag state is of the form: Type(name)
-
-Other approach:
-Tag sets: {x, y, z, ... in R
-
-Allow additions/removals of tuples in taskexit:
-remove <x, y, z, ...> from R
-add <x, y> to R
-
-Allow addition of new tuples in object allocation
-add <new, y> to R
-------------------------------------------------------------------------------
-
-
-
-
-Collection of Tags
- Tags have type/name associated with them
- Also have UID associated with them
- Two basic types:
- Ordered: Initial/Next / Preserves Sequencing
- Non-ordered: New / Groups items together
-
-----------------------------------------------------------------------
-Tasks:
-Have list of parameters w/ flag/tag specifications
-Flag/Tag transitions at task exit
------------------------------------------------------------------------
-Problems:
-How do we efficiently do task dispatch?
-
-Idea:
-Flags - efficiently
-Build static state transition diagram : explore full space for now
-Then for each state transition we consider:
-1) What task activations have we added
-2) What task activations have we removed
-Collapse state transition diagram to
-
-
-Tags - search once we match a flag
-
-
-
-Input:
-trigger role specification for tasks:
-role mutator operation:
-role definition:
-
-Generate:
-Role transition diagram
-
-
-Initial features:
-methods
-structs
-type system
-
-Language features:
-Single Inheritance
-Virtual methods
-Objects
-
-object metastate:
-1. flags: flag role1
-2. tags: tag tag1
-
-tag operations:
-tag tag1=new tag;
-tag tag2=incrementtag(tag tag1);
-tag tag3=no tag;
-
-metastate operations:
-
-task foo(type1 o1{role1||role2}, type2 o2{role3}) {
-
- exit(o1{role1'=false},o2{role3'=false},onew{role4=true});
-}
-----------------------------------------------------------------
-----------------------------------------------------------------
-
-Initial design:
-----------------------------------------------------------------
-
-Provide runtime with:
-1) List of tasks
- a) Task names
- b) Parameter types
- c) Flag settings
-
-2) List of flags for each type
-
-3) Flag transition calls
+++ /dev/null
-Basic design of scheduler:
-
-activetask: Queue of active tasks
-failedtasks: Hashtable of failed task/parameter combinations
-objectqueues: For each class we have a list of parameterwrapper objects
-
-1. ObjectQueues
-
-Each parameterwrapper object is a set of objects that can serve as a
-specific parameter for a specific task. This set is stored in the
-hashtable referenced by the objectset field. A reference to the
-relevant taskdescriptor is stored in the task field.
-
-Each parameterwrapper object has an array of ints: intarray This array
-contains numberofterms pairs of integere: i*2 and i*2+1. The first
-integer in a pair contains an "and" mask of the flags that the task
-cares about. The second integer in the pair contains the flag
-settings. If the flag of an object matches any of these masks, then
-the object should be placed in the object set.
-
-1.1 Objectsets
-
-Each objectset is implemented using a hashtable. If an object is in
-the objectset, the objectset hashtable maps that object to either NULL
-or the next objectset the object is a member of.
-
-1.2
-
-Each object with a flag contains a flagptr field ((struct RuntimeHash
-*) ptr)[2]. This field points to the first objectset hashtable that
-the object is a member of.
-
+++ /dev/null
-Example:
-task test(Baz a {}{tag Foo x}, Bar b {}{tag Foo x, Tag Far y}) {
-}
-
-Idea: Each parameter with a tag has its own queue and a hashtable that
-is indexed by the tag
-
-When adding the object to the queue, the runtime:
-
-1) cycles through each tag of the appropriate type in that object and
-index into the other queues for that tag
-
-2) if multiple objects have that tag, have to search each possible
-one...
-
-3) if the parameter is specified to have a second tag, search through
-each possible second tag
-
-Each flag object has tag pointer - it can either point to a tag object
-or a list of tags...