# 1 "parse.c" # 1 "d.h" 1 # 1 "/usr/include/assert.h" 1 # 1 "/usr/include/sys/cdefs.h" 1 # 106 "/usr/include/sys/cdefs.h" # 216 "/usr/include/sys/cdefs.h" # 295 "/usr/include/sys/cdefs.h" # 324 "/usr/include/sys/cdefs.h" # 61 "/usr/include/assert.h" 2 void __assert (const char *, int, const char *) ; # 12 "d.h" 2 # 1 "/usr/include/stdarg.h" 1 typedef char *va_list; # 13 "d.h" 2 # 1 "/usr/include/stdlib.h" 1 # 1 "/usr/include/machine/ansi.h" 1 typedef long long __int64_t; typedef unsigned long long __uint64_t; typedef signed char __int8_t; typedef unsigned char __uint8_t; typedef short __int16_t; typedef unsigned short __uint16_t; typedef int __int32_t; typedef unsigned int __uint32_t; typedef int __intptr_t; typedef unsigned int __uintptr_t; typedef union { char __mbstate8[128]; __int64_t _mbstateL; } __mbstate_t; # 42 "/usr/include/stdlib.h" 2 typedef int rune_t; typedef unsigned int size_t; typedef int wchar_t; typedef struct { int quot; int rem; } div_t; typedef struct { long quot; long rem; } ldiv_t; extern int __mb_cur_max; void abort (void) ; int abs (int) ; int atexit (void (*)(void)) ; double atof (const char *) ; int atoi (const char *) ; long atol (const char *) ; void *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *)) ; void *calloc (size_t, size_t) ; div_t div (int, int) ; void exit (int) ; void free (void *) ; char *getenv (const char *) ; long labs (long) ; ldiv_t ldiv (long, long) ; void *malloc (size_t) ; void qsort (void *, size_t, size_t, int (*)(const void *, const void *)) ; int rand (void) ; void *realloc (void *, size_t) ; void srand (unsigned) ; double strtod (const char *, char **) ; long strtol (const char *, char **, int) ; long long strtoll (const char *, char **, int) ; unsigned long strtoul (const char *, char **, int) ; unsigned long long strtoull (const char *, char **, int) ; int system (const char *) ; int mblen (const char *, size_t) ; size_t mbstowcs (wchar_t *, const char *, size_t) ; int wctomb (char *, wchar_t) ; int mbtowc (wchar_t *, const char *, size_t) ; size_t wcstombs (char *, const wchar_t *, size_t) ; int putenv (const char *) ; int setenv (const char *, const char *, int) ; double drand48 (void) ; double erand48 (unsigned short[3]) ; long jrand48 (unsigned short[3]) ; void lcong48 (unsigned short[7]) ; long lrand48 (void) ; long mrand48 (void) ; long nrand48 (unsigned short[3]) ; unsigned short *seed48 (unsigned short[3]) ; void srand48 (long) ; void *alloca (size_t) ; __uint32_t arc4random (void) ; void arc4random_addrandom (unsigned char *dat, int datlen) ; void arc4random_stir (void) ; char *getbsize (int *, long *) ; char *cgetcap (char *, char *, int) ; int cgetclose (void) ; int cgetent (char **, char **, char *) ; int cgetfirst (char **, char **) ; int cgetmatch (char *, char *) ; int cgetnext (char **, char **) ; int cgetnum (char *, char *, long *) ; int cgetset (char *) ; int cgetstr (char *, char *, char **) ; int cgetustr (char *, char *, char **) ; int daemon (int, int) ; char *devname (int, int) ; int getloadavg (double [], int) ; const char * getprogname (void) ; char *group_from_gid (unsigned long, int) ; int heapsort (void *, size_t, size_t, int (*)(const void *, const void *)) ; char *initstate (unsigned long, char *, long) ; int mergesort (void *, size_t, size_t, int (*)(const void *, const void *)) ; int radixsort (const unsigned char **, int, const unsigned char *, unsigned) ; int sradixsort (const unsigned char **, int, const unsigned char *, unsigned) ; int rand_r (unsigned *) ; long random (void) ; void *reallocf (void *, size_t) ; char *realpath (const char *, char resolved_path[]) ; void setprogname (const char *) ; char *setstate (char *) ; void srandom (unsigned long) ; void srandomdev (void) ; char *user_from_uid (unsigned long, int) ; __int64_t strtoq (const char *, char **, int) ; __uint64_t strtouq (const char *, char **, int) ; void unsetenv (const char *) ; # 14 "d.h" 2 # 1 "/usr/include/stdio.h" 1 typedef __int64_t fpos_t; struct __sbuf { unsigned char *_base; int _size; }; typedef struct __sFILE { unsigned char *_p; int _r; int _w; short _flags; short _file; struct __sbuf _bf; int _lbfsize; void *_cookie; int (*_close) (void *) ; int (*_read) (void *, char *, int) ; fpos_t (*_seek) (void *, fpos_t, int) ; int (*_write) (void *, const char *, int) ; struct __sbuf _ub; unsigned char *_up; int _ur; unsigned char _ubuf[3]; unsigned char _nbuf[1]; struct __sbuf _lb; int _blksize; fpos_t _offset; } FILE; extern FILE __sF[]; void clearerr (FILE *) ; int fclose (FILE *) ; int feof (FILE *) ; int ferror (FILE *) ; int fflush (FILE *) ; int fgetc (FILE *) ; int fgetpos (FILE *, fpos_t *) ; char *fgets (char *, int, FILE *) ; FILE *fopen (const char *, const char *) ; int fprintf (FILE *, const char *, ...) ; int fputc (int, FILE *) ; int fputs (const char *, FILE *) ; size_t fread (void *, size_t, size_t, FILE *) ; FILE *freopen (const char *, const char *, FILE *) ; int fscanf (FILE *, const char *, ...) ; int fseek (FILE *, long, int) ; int fsetpos (FILE *, const fpos_t *) ; long ftell (FILE *) ; size_t fwrite (const void *, size_t, size_t, FILE *) ; int getc (FILE *) ; int getchar (void) ; char *gets (char *) ; extern const int sys_nerr; extern const char * const sys_errlist[]; void perror (const char *) ; int printf (const char *, ...) ; int putc (int, FILE *) ; int putchar (int) ; int puts (const char *) ; int remove (const char *) ; int rename (const char *, const char *) ; void rewind (FILE *) ; int scanf (const char *, ...) ; void setbuf (FILE *, char *) ; int setvbuf (FILE *, char *, int, size_t) ; int sprintf (char *, const char *, ...) ; int sscanf (const char *, const char *, ...) ; FILE *tmpfile (void) ; char *tmpnam (char *) ; int ungetc (int, FILE *) ; int vfprintf (FILE *, const char *, char * ) ; int vprintf (const char *, char * ) ; int vsprintf (char *, const char *, char * ) ; char *ctermid (char *) ; FILE *fdopen (int, const char *) ; int fileno (FILE *) ; int ftrylockfile (FILE *) ; void flockfile (FILE *) ; void funlockfile (FILE *) ; int ftruncate (int, __int64_t ) ; __int64_t lseek (int, __int64_t , int) ; void *mmap (void *, size_t, int, int, int, __int64_t ) ; int truncate (const char *, __int64_t ) ; int asprintf (char **, const char *, ...) ; char *ctermid_r (char *) ; char *fgetln (FILE *, size_t *) ; const char *fmtcheck (const char *, const char *) ; int fpurge (FILE *) ; int fseeko (FILE *, __int64_t , int) ; __int64_t ftello (FILE *) ; int getw (FILE *) ; int pclose (FILE *) ; FILE *popen (const char *, const char *) ; int putw (int, FILE *) ; void setbuffer (FILE *, char *, int) ; int setlinebuf (FILE *) ; char *tempnam (const char *, const char *) ; int snprintf (char *, size_t, const char *, ...) ; int vasprintf (char **, const char *, char * ) ; int vsnprintf (char *, size_t, const char *, char * ) ; int vscanf (const char *, char * ) ; int vsscanf (const char *, const char *, char * ) ; FILE *funopen (const void *, int (*)(void *, char *, int), int (*)(void *, const char *, int), fpos_t (*)(void *, fpos_t, int), int (*)(void *)) ; int __srget (FILE *) ; int __svfscanf (FILE *, const char *, char * ) ; int __swbuf (int, FILE *) ; # 443 "/usr/include/stdio.h" # 15 "d.h" 2 # 1 "/usr/include/limits.h" 1 # 1 "/usr/include/sys/_posix.h" 1 # 70 "/usr/include/sys/_posix.h" # 39 "/usr/include/limits.h" 2 # 1 "/usr/include/machine/limits.h" 1 # 94 "/usr/include/limits.h" 2 # 1 "/usr/include/sys/syslimits.h" 1 # 96 "/usr/include/limits.h" 2 # 16 "d.h" 2 # 1 "/usr/include/sys/types.h" 1 # 1 "/usr/include/sys/inttypes.h" 1 typedef __int8_t int8_t; typedef __int16_t int16_t; typedef __int32_t int32_t; typedef __int64_t int64_t; typedef __uint8_t uint8_t; typedef __uint16_t uint16_t; typedef __uint32_t uint32_t; typedef __uint64_t uint64_t; typedef __intptr_t intptr_t; typedef __uintptr_t uintptr_t; # 48 "/usr/include/sys/types.h" 2 # 1 "/usr/include/machine/types.h" 1 typedef struct _physadr { int r[1]; } *physadr; typedef struct label_t { int val[6]; } label_t; typedef unsigned int vm_offset_t; typedef __int64_t vm_ooffset_t; typedef unsigned int vm_pindex_t; typedef unsigned int vm_size_t; typedef __int32_t register_t; typedef __uint32_t u_register_t; typedef __uint32_t intrmask_t; typedef void inthand2_t (void *_cookie) ; typedef void ointhand2_t (int _device_id) ; # 49 "/usr/include/sys/types.h" 2 typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; typedef unsigned short ushort; typedef unsigned int uint; typedef __uint8_t u_int8_t; typedef __uint16_t u_int16_t; typedef __uint32_t u_int32_t; typedef __uint64_t u_int64_t; typedef u_int64_t u_quad_t; typedef int64_t quad_t; typedef quad_t * qaddr_t; typedef char * caddr_t; typedef const char * c_caddr_t; typedef volatile char *v_caddr_t; typedef int32_t daddr_t; typedef u_int32_t u_daddr_t; typedef u_int32_t fixpt_t; typedef u_int32_t gid_t; typedef u_int32_t in_addr_t; typedef u_int16_t in_port_t; typedef u_int32_t ino_t; typedef long key_t; typedef u_int16_t mode_t; typedef u_int16_t nlink_t; typedef __int64_t off_t; typedef int pid_t; typedef quad_t rlim_t; typedef int32_t segsz_t; typedef int32_t swblk_t; typedef int32_t ufs_daddr_t; typedef u_int32_t uid_t; # 106 "/usr/include/sys/types.h" typedef u_int32_t dev_t; # 1 "/usr/include/machine/endian.h" 1 unsigned long htonl (unsigned long) ; unsigned short htons (unsigned short) ; unsigned long ntohl (unsigned long) ; unsigned short ntohs (unsigned short) ; # 84 "/usr/include/machine/endian.h" # 126 "/usr/include/sys/types.h" 2 typedef unsigned long clock_t; typedef int clockid_t; typedef int ssize_t; typedef long time_t; typedef int timer_t; typedef unsigned long fd_mask; typedef struct fd_set { fd_mask fds_bits[((( 1024 ) + (( (sizeof(fd_mask) * 8 ) ) - 1)) / ( (sizeof(fd_mask) * 8 ) )) ]; } fd_set; # 17 "d.h" 2 # 1 "/usr/include/sys/mman.h" 1 int mlockall (int) ; int munlockall (void) ; int shm_open (const char *, int, mode_t) ; int shm_unlink (const char *) ; int mlock (const void *, size_t) ; int mprotect (const void *, size_t, int) ; int msync (void *, size_t, int) ; int munlock (const void *, size_t) ; int munmap (void *, size_t) ; int madvise (void *, size_t, int) ; int mincore (const void *, size_t, char *) ; int minherit (void *, size_t, int) ; # 18 "d.h" 2 # 1 "/usr/include/sys/uio.h" 1 struct iovec { char *iov_base; size_t iov_len; }; enum uio_rw { UIO_READ, UIO_WRITE }; enum uio_seg { UIO_USERSPACE, UIO_SYSSPACE, UIO_USERISPACE, UIO_NOCOPY }; # 84 "/usr/include/sys/uio.h" ssize_t readv (int, const struct iovec *, int) ; ssize_t writev (int, const struct iovec *, int) ; # 19 "d.h" 2 # 1 "/usr/include/unistd.h" 1 # 1 "/usr/include/sys/unistd.h" 1 # 42 "/usr/include/unistd.h" 2 void _exit (int) ; int access (const char *, int) ; unsigned int alarm (unsigned int) ; int chdir (const char *) ; int chown (const char *, uid_t, gid_t) ; int close (int) ; int dup (int) ; int dup2 (int, int) ; int execl (const char *, const char *, ...) ; int execle (const char *, const char *, ...) ; int execlp (const char *, const char *, ...) ; int execv (const char *, char * const *) ; int execve (const char *, char * const *, char * const *) ; int execvp (const char *, char * const *) ; pid_t fork (void) ; long fpathconf (int, int) ; char *getcwd (char *, size_t) ; gid_t getegid (void) ; uid_t geteuid (void) ; gid_t getgid (void) ; int getgroups (int, gid_t []) ; char *getlogin (void) ; pid_t getpgrp (void) ; pid_t getpid (void) ; pid_t getppid (void) ; uid_t getuid (void) ; int isatty (int) ; int link (const char *, const char *) ; long pathconf (const char *, int) ; int pause (void) ; int pipe (int *) ; ssize_t read (int, void *, size_t) ; int rmdir (const char *) ; int setgid (gid_t) ; int setpgid (pid_t, pid_t) ; pid_t setsid (void) ; int setuid (uid_t) ; unsigned int sleep (unsigned int) ; long sysconf (int) ; pid_t tcgetpgrp (int) ; int tcsetpgrp (int, pid_t) ; char *ttyname (int) ; int unlink (const char *) ; ssize_t write (int, const void *, size_t) ; extern char *optarg; extern int optind, opterr, optopt; int getopt (int, char * const [], const char *) ; struct timeval; int acct (const char *) ; int async_daemon (void) ; int brk (const void *) ; int chroot (const char *) ; size_t confstr (int, char *, size_t) ; char *crypt (const char *, const char *) ; const char * crypt_get_format (void) ; int crypt_set_format (const char *) ; int des_cipher (const char *, char *, long, int) ; int des_setkey (const char *key) ; int encrypt (char *, int) ; void endusershell (void) ; int exect (const char *, char * const *, char * const *) ; int fchdir (int) ; int fchown (int, uid_t, gid_t) ; char *fflagstostr (u_long) ; int fsync (int) ; int getdomainname (char *, int) ; int getdtablesize (void) ; int getgrouplist (const char *, int, int *, int *) ; long gethostid (void) ; int gethostname (char *, int) ; int getlogin_r (char *, int) ; mode_t getmode (const void *, mode_t) ; int getpagesize (void) ; char *getpass (const char *) ; int getpeereid (int, uid_t *, gid_t *) ; int getpgid (pid_t _pid) ; int getresgid (gid_t *, gid_t *, gid_t *) ; int getresuid (uid_t *, uid_t *, uid_t *) ; int getsid (pid_t _pid) ; char *getusershell (void) ; char *getwd (char *) ; int initgroups (const char *, int) ; int iruserok (unsigned long, int, const char *, const char *) ; int iruserok_sa (const void *, int, int, const char *, const char *) ; int issetugid (void) ; int lchown (const char *, uid_t, gid_t) ; int lockf (int, int, off_t) ; char *mkdtemp (char *) ; int mknod (const char *, mode_t, dev_t) ; int mkstemp (char *) ; int mkstemps (char *, int) ; char *mktemp (char *) ; int nfssvc (int, void *) ; int nice (int) ; ssize_t pread (int, void *, size_t, off_t) ; int profil (char *, size_t, vm_offset_t, int) ; ssize_t pwrite (int, const void *, size_t, off_t) ; int rcmd (char **, int, const char *, const char *, const char *, int *) ; int rcmd_af (char **, int, const char *, const char *, const char *, int *, int) ; int rcmdsh (char **, int, const char *, const char *, const char *, const char *) ; char *re_comp (const char *) ; int re_exec (const char *) ; int readlink (const char *, char *, int) ; int reboot (int) ; int revoke (const char *) ; pid_t rfork (int) ; pid_t rfork_thread (int, void *, int (*) (void *) , void *) ; int rresvport (int *) ; int rresvport_af (int *, int) ; int ruserok (const char *, int, const char *, const char *) ; void *sbrk (intptr_t) ; int select (int, fd_set *, fd_set *, fd_set *, struct timeval *) ; int setdomainname (const char *, int) ; int setegid (gid_t) ; int seteuid (uid_t) ; int setgroups (int, const gid_t *) ; void sethostid (long) ; int sethostname (const char *, int) ; int setkey (const char *) ; int setlogin (const char *) ; void *setmode (const char *) ; int setpgrp (pid_t _pid, pid_t _pgrp) ; int setregid (gid_t, gid_t) ; int setresgid (gid_t, gid_t, gid_t) ; int setresuid (uid_t, uid_t, uid_t) ; int setreuid (uid_t, uid_t) ; int setrgid (gid_t) ; int setruid (uid_t) ; void setusershell (void) ; int strtofflags (char **, u_long *, u_long *) ; int swapon (const char *) ; int symlink (const char *, const char *) ; void sync (void) ; int syscall (int, ...) ; off_t __syscall (quad_t, ...) ; int ttyslot (void) ; unsigned int ualarm (unsigned int, unsigned int) ; int undelete (const char *) ; int unwhiteout (const char *) ; int usleep (unsigned int) ; void *valloc (size_t) ; pid_t vfork (void) ; extern char *suboptarg; int getsubopt (char **, char * const *, char **) ; extern int optreset; # 20 "d.h" 2 # 1 "/usr/include/fcntl.h" 1 # 113 "/usr/include/fcntl.h" struct flock { off_t l_start; off_t l_len; pid_t l_pid; short l_type; short l_whence; }; int open (const char *, int, ...) ; int creat (const char *, mode_t) ; int fcntl (int, int, ...) ; int flock (int, int) ; # 21 "d.h" 2 # 1 "/usr/include/time.h" 1 struct timespec { time_t tv_sec; long tv_nsec; }; struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; long tm_gmtoff; char *tm_zone; }; extern char *tzname[]; char *asctime (const struct tm *) ; clock_t clock (void) ; char *ctime (const time_t *) ; double difftime (time_t, time_t) ; struct tm *gmtime (const time_t *) ; struct tm *localtime (const time_t *) ; time_t mktime (struct tm *) ; size_t strftime (char *, size_t, const char *, const struct tm *) ; time_t time (time_t *) ; void tzset (void) ; char *asctime_r (const struct tm *, char *) ; char *ctime_r (const time_t *, char *) ; struct tm *gmtime_r (const time_t *, struct tm *) ; struct tm *localtime_r (const time_t *, struct tm *) ; char *strptime (const char *, const char *, struct tm *) ; char *timezone (int, int) ; void tzsetwall (void) ; time_t timelocal (struct tm * const) ; time_t timegm (struct tm * const) ; int clock_getres (clockid_t, struct timespec *) ; int clock_gettime (clockid_t, struct timespec *) ; int clock_settime (clockid_t, const struct timespec *) ; int nanosleep (const struct timespec *, struct timespec *) ; # 22 "d.h" 2 # 1 "/usr/include/sys/time.h" 1 struct timeval { long tv_sec; long tv_usec; }; struct timezone { int tz_minuteswest; int tz_dsttime; }; struct timecounter; typedef unsigned timecounter_get_t (struct timecounter *) ; typedef void timecounter_pps_t (struct timecounter *) ; struct timecounter { timecounter_get_t *tc_get_timecount; timecounter_pps_t *tc_poll_pps; unsigned tc_counter_mask; u_int32_t tc_frequency; char *tc_name; void *tc_priv; int64_t tc_adjustment; u_int32_t tc_scale_micro; u_int32_t tc_scale_nano_i; u_int32_t tc_scale_nano_f; unsigned tc_offset_count; u_int32_t tc_offset_sec; u_int32_t tc_offset_micro; u_int64_t tc_offset_nano; struct timeval tc_microtime; struct timespec tc_nanotime; struct timecounter *tc_avail; struct timecounter *tc_other; struct timecounter *tc_tweak; }; # 201 "/usr/include/sys/time.h" # 220 "/usr/include/sys/time.h" # 229 "/usr/include/sys/time.h" struct itimerval { struct timeval it_interval; struct timeval it_value; }; struct clockinfo { int hz; int tick; int tickadj; int stathz; int profhz; }; # 288 "/usr/include/sys/time.h" int adjtime (const struct timeval *, struct timeval *) ; int futimes (int, const struct timeval *) ; int getitimer (int, struct itimerval *) ; int gettimeofday (struct timeval *, struct timezone *) ; int lutimes (const char *, const struct timeval *) ; int setitimer (int, const struct itimerval *, struct itimerval *) ; int settimeofday (const struct timeval *, const struct timezone *) ; int utimes (const char *, const struct timeval *) ; # 23 "d.h" 2 # 1 "/usr/include/sys/stat.h" 1 struct ostat { u_int16_t st_dev; ino_t st_ino; mode_t st_mode; nlink_t st_nlink; u_int16_t st_uid; u_int16_t st_gid; u_int16_t st_rdev; int32_t st_size; struct timespec st_atimespec; struct timespec st_mtimespec; struct timespec st_ctimespec; int32_t st_blksize; int32_t st_blocks; u_int32_t st_flags; u_int32_t st_gen; }; struct stat { dev_t st_dev; ino_t st_ino; mode_t st_mode; nlink_t st_nlink; uid_t st_uid; gid_t st_gid; dev_t st_rdev; struct timespec st_atimespec; struct timespec st_mtimespec; struct timespec st_ctimespec; off_t st_size; int64_t st_blocks; u_int32_t st_blksize; u_int32_t st_flags; u_int32_t st_gen; int32_t st_lspare; int64_t st_qspare[2]; }; struct nstat { dev_t st_dev; ino_t st_ino; u_int32_t st_mode; u_int32_t st_nlink; uid_t st_uid; gid_t st_gid; dev_t st_rdev; struct timespec st_atimespec; struct timespec st_mtimespec; struct timespec st_ctimespec; off_t st_size; int64_t st_blocks; u_int32_t st_blksize; u_int32_t st_flags; u_int32_t st_gen; int64_t st_qspare[2]; }; # 234 "/usr/include/sys/stat.h" int chmod (const char *, mode_t) ; int fstat (int, struct stat *) ; int mkdir (const char *, mode_t) ; int mkfifo (const char *, mode_t) ; int stat (const char *, struct stat *) ; mode_t umask (mode_t) ; int chflags (const char *, u_long) ; int fchflags (int, u_long) ; int fchmod (int, mode_t) ; int lchmod (const char *, mode_t) ; int lstat (const char *, struct stat *) ; # 24 "d.h" 2 # 1 "/usr/include/dirent.h" 1 # 1 "/usr/include/sys/dirent.h" 1 struct dirent { __uint32_t d_fileno; __uint16_t d_reclen; __uint8_t d_type; __uint8_t d_namlen; char d_name[255 + 1]; }; # 44 "/usr/include/dirent.h" 2 typedef struct _dirdesc { int dd_fd; long dd_loc; long dd_size; char *dd_buf; int dd_len; long dd_seek; long dd_rewind; int dd_flags; } DIR; DIR *opendir (const char *) ; struct dirent *readdir (DIR *) ; void rewinddir (DIR *) ; int closedir (DIR *) ; DIR *__opendir2 (const char *, int) ; long telldir (const DIR *) ; void seekdir (DIR *, long) ; int scandir (const char *, struct dirent ***, int (*)(struct dirent *), int (*)(const void *, const void *)) ; int alphasort (const void *, const void *) ; int getdents (int, char *, int) ; int getdirentries (int, char *, int, long *) ; int readdir_r (DIR *, struct dirent *, struct dirent **) ; # 25 "d.h" 2 # 1 "/usr/include/ctype.h" 1 # 1 "/usr/include/runetype.h" 1 typedef struct { rune_t min; rune_t max; rune_t map; unsigned long *types; } _RuneEntry; typedef struct { int nranges; _RuneEntry *ranges; } _RuneRange; typedef struct { char magic[8]; char encoding[32]; rune_t (*sgetrune) (const char *, size_t, char const **) ; int (*sputrune) (rune_t, char *, size_t, char **) ; rune_t invalid_rune; unsigned long runetype[(1 <<8 ) ]; rune_t maplower[(1 <<8 ) ]; rune_t mapupper[(1 <<8 ) ]; _RuneRange runetype_ext; _RuneRange maplower_ext; _RuneRange mapupper_ext; void *variable; int variable_len; } _RuneLocale; extern _RuneLocale _DefaultRuneLocale; extern _RuneLocale *_CurrentRuneLocale; # 52 "/usr/include/ctype.h" 2 int isalnum (int) ; int isalpha (int) ; int iscntrl (int) ; int isdigit (int) ; int isgraph (int) ; int islower (int) ; int isprint (int) ; int ispunct (int) ; int isspace (int) ; int isupper (int) ; int isxdigit (int) ; int tolower (int) ; int toupper (int) ; int digittoint (int) ; int isascii (int) ; int isblank (int) ; int ishexnumber (int) ; int isideogram (int) ; int isnumber (int) ; int isphonogram (int) ; int isrune (int) ; int isspecial (int) ; int toascii (int) ; unsigned long ___runetype (int ) ; int ___tolower (int ) ; int ___toupper (int ) ; # 177 "/usr/include/ctype.h" int __maskrune (int , unsigned long) ; int __isctype (int , unsigned long) ; int __toupper (int ) ; int __tolower (int ) ; # 26 "d.h" 2 # 1 "/usr/include/string.h" 1 void *memchr (const void *, int, size_t) ; int memcmp (const void *, const void *, size_t) ; void *memcpy (void *, const void *, size_t) ; void *memmove (void *, const void *, size_t) ; void *memset (void *, int, size_t) ; char *strcat (char *, const char *) ; char *strchr (const char *, int) ; int strcmp (const char *, const char *) ; int strcoll (const char *, const char *) ; char *strcpy (char *, const char *) ; size_t strcspn (const char *, const char *) ; char *strerror (int) ; size_t strlen (const char *) ; char *strncat (char *, const char *, size_t) ; int strncmp (const char *, const char *, size_t) ; char *strncpy (char *, const char *, size_t) ; char *strpbrk (const char *, const char *) ; char *strrchr (const char *, int) ; size_t strspn (const char *, const char *) ; char *strstr (const char *, const char *) ; char *strtok (char *, const char *) ; size_t strxfrm (char *, const char *, size_t) ; int bcmp (const void *, const void *, size_t) ; void bcopy (const void *, void *, size_t) ; void bzero (void *, size_t) ; int ffs (int) ; char *index (const char *, int) ; void *memccpy (void *, const void *, int, size_t) ; char *rindex (const char *, int) ; int strcasecmp (const char *, const char *) ; char *strcasestr (const char *, const char *) ; char *strdup (const char *) ; int strerror_r (int, char *, size_t) ; size_t strlcat (char *, const char *, size_t) ; size_t strlcpy (char *, const char *, size_t) ; void strmode (int, char *) ; int strncasecmp (const char *, const char *, size_t) ; char *strnstr (const char *, const char *, size_t) ; char *strsep (char **, const char *) ; char *strsignal (int) ; char *strtok_r (char *, const char *, char **) ; void swab (const void *, void *, size_t) ; # 27 "d.h" 2 # 37 "d.h" typedef char int8; typedef unsigned char uint8; typedef int int32; typedef unsigned int uint32; typedef long long int64; typedef unsigned long long uint64; typedef short int16; typedef unsigned short uint16; # 1 "dparse.h" 1 # 1 "dparse_tables.h" 1 struct D_ShiftTable; typedef int (*D_ScanCode)( char **s, int *col, int *line, unsigned short *symbol, int *term_priority, unsigned short *op_assoc, int *op_priority); typedef int (*D_ReductionCode)( void *new_ps, void **children, int n_children, int pn_offset); typedef struct D_Reduction { unsigned short nelements; unsigned short symbol; D_ReductionCode speculative_code; D_ReductionCode final_code; unsigned short op_assoc; unsigned short rule_assoc; int op_priority; int rule_priority; } D_Reduction; typedef struct D_RightEpsilonHint { unsigned short depth; unsigned short preceeding_state; D_Reduction *reduction; } D_RightEpsilonHint; typedef struct D_ErrorRecoveryHint { unsigned short depth; unsigned short symbol; char *string; } D_ErrorRecoveryHint; typedef struct D_Shift { unsigned short symbol; unsigned short op_assoc; int op_priority; int term_priority; } D_Shift; typedef struct D_State { unsigned char *goto_valid; int goto_table_offset; struct { unsigned int n; D_Reduction **v; } reductions; struct { unsigned int n; D_RightEpsilonHint *v; } right_epsilon_hints; struct { unsigned int n; D_ErrorRecoveryHint *v; } error_recovery_hints; D_Shift **shifts; D_ScanCode scanner_code; void* scanner_table; unsigned char scanner_size; unsigned char accept; } D_State; typedef struct D_ParserTables { unsigned int nstates; D_State *state; unsigned short *goto_table; unsigned int nproductions; } D_ParserTables; typedef struct SB_uint8 { D_Shift **shift; unsigned char *scanner_block[(1 << 2 ) ]; } SB_uint8; typedef struct SB_uint16 { D_Shift **shift; unsigned short *scanner_block[(1 << 2 ) ]; } SB_uint16; typedef struct SB_uint32 { D_Shift **shift; unsigned int *scanner_block[(1 << 2 ) ]; } SB_uint32; # 8 "dparse.h" 2 # 1 "dsymtab.h" 1 struct D_Scope; typedef struct D_Sym { char *name; int len; unsigned int hash; unsigned int index; unsigned int user; struct D_Sym *update_of; struct D_Sym *next; } D_Sym; struct D_Scope *new_scope(struct D_Scope *st); D_Sym *new_sym(struct D_Scope *st, char *name, char *end); D_Sym *find_sym(struct D_Scope *st, char *name, char *end); D_Sym *update_sym(struct D_Scope *st, D_Sym *sym); D_Sym *current_sym(struct D_Scope *st, D_Sym *sym); # 9 "dparse.h" 2 struct D_Parser; struct D_ParserTables; struct D_Scope; typedef void *d_voidp; typedef struct d_loc_t { char *s, *filename; int last_col, col, line; } d_loc_t; typedef void (*D_SkipSpaceFn)(d_loc_t *loc, void ** p_globals); typedef void (*D_SyntaxErrorFn)(struct D_Parser *); typedef struct D_Parser { void *initial_globals; D_SyntaxErrorFn syntax_error_fn; d_loc_t loc; int sizeof_user_parse_node; int save_parse_tree; int syntax_errors; int last_syntax_error_line; } D_Parser; typedef struct D_ParseNode { char *start, *end; int line; struct D_Scope *scope; D_SkipSpaceFn skip_space; void *globals; d_voidp user; } D_ParseNode; D_Parser *new_D_Parser(struct D_ParserTables *t); D_ParseNode *dparse(D_Parser *p, char *buf, int buf_len); void free_D_ParseNode(D_ParseNode *pn); # 69 "d.h" 2 # 1 "arg.h" 1 struct ArgumentState; typedef void ArgumentFunction(struct ArgumentState *arg_state, char *arg); typedef struct { char *name; char key; char *description; char *type; void *location; char *env; ArgumentFunction *pfn; } ArgumentDescription; typedef struct ArgumentState { char **file_argument; int nfile_arguments; char *program_name; ArgumentDescription *desc; } ArgumentState; void usage(ArgumentState *arg_state, char *arg_unused); void process_args(ArgumentState *arg_state, char **argv); void free_args(ArgumentState *arg_state); # 70 "d.h" 2 # 1 "util.h" 1 typedef struct AbstractVec { uint n; uint i; void **v; void *e[3 ]; } AbstractVec; typedef struct AbstractStack { void **start; void **end; void **cur; void *initial[8 ]; } AbstractStack; struct hash_fns_t; typedef uint32 (*hash_fn_t)(void *, struct hash_fns_t*); typedef int (*cmp_fn_t)(void *, void *, struct hash_fns_t*); typedef struct hash_fns_t { hash_fn_t hash_fn; cmp_fn_t cmp_fn; void *data[2]; } hash_fns_t; void skip_space(d_loc_t *loc, void **p_user_globals); # 78 "util.h" void vec_add_internal(void *v, void *elem); int set_add(void *v, void *t); int set_union(void *v, void *vv); void *set_add_fn(void *v, void *t, hash_fns_t *fns); void set_union_fn(void *v, void *vv, hash_fns_t *fns); void set_to_vec(void *av); void * stack_push_internal(AbstractStack*, void*); int buf_read(char *pathname, char **buf, int *len); char *sbuf_read(char *pathname); void fail(char *str, ...); char *tmp_str(char *str, char *end); char *dup_filename_str(char *str); char *dup_str(char *str, char *end); uint strhashl(char *s, int len); extern uint prime2[]; extern int verbose_level; extern int debug_level; # 71 "d.h" 2 # 1 "lr.h" 1 struct Elem; struct Grammar; typedef struct Elem Item; void build_LR_tables(struct Grammar *g); # 72 "d.h" 2 # 1 "gram.h" 1 struct Production; struct Rule; struct Elem; struct Term; struct State; struct ScanState; typedef struct { uint n; uint i; struct ScanState * *v; struct ScanState * e[3 ]; } VecScanState; typedef struct Code { char *code; int line; } Code; typedef struct Goto { struct Elem *elem; struct State *state; } Goto; typedef enum ActionKind { ACTION_ACCEPT, ACTION_SHIFT, ACTION_REDUCE } ActionKind; typedef struct Action { ActionKind kind; struct Term *term; struct Rule *rule; struct State *state; char *temp_string; } Action; typedef struct { uint n; uint i; Action * *v; Action * e[3 ]; } VecAction; typedef struct Hint { uint depth; struct State *state; struct Rule *rule; } Hint; typedef struct { uint n; uint i; Hint * *v; Hint * e[3 ]; } VecHint; typedef struct State { uint index; uint64 hash; struct { uint n; uint i; Item* *v; Item* e[3 ]; } items; struct { uint n; uint i; Item* *v; Item* e[3 ]; } items_hash; struct { uint n; uint i; Goto* *v; Goto* e[3 ]; } gotos; VecAction shift_actions; VecAction reduce_actions; VecHint right_epsilon_hints; VecHint error_recovery_hints; VecScanState scanner; uint accept:1; uint scanner_code:1; uint goto_on_token:1; uint8 *goto_valid; int goto_table_offset; struct State *same_shifts; } State; typedef enum AssocKind { ASSOC_NONE = 0, ASSOC_NARY_LEFT = (0x0004 | 0x0001 ), ASSOC_NARY_RIGHT = (0x0004 | 0x0002 ), ASSOC_UNARY_LEFT = (0x0008 | 0x0001 ), ASSOC_UNARY_RIGHT = (0x0008 | 0x0002 ), ASSOC_BINARY_LEFT = (0x0010 | 0x0001 ), ASSOC_BINARY_RIGHT = (0x0010 | 0x0002 ), ASSOC_NO = 0x0020 } AssocKind; typedef struct Rule { uint index; struct Production *prod; int op_priority; AssocKind op_assoc; int rule_priority; AssocKind rule_assoc; struct { uint n; uint i; struct Elem* *v; struct Elem* e[3 ]; } elems; struct Elem *end; Code speculative_code; Code final_code; struct Rule *same_reduction; } Rule; typedef enum TermKind { TERM_STRING, TERM_REGEX, TERM_CODE, TERM_TOKEN } TermKind; typedef struct Term { TermKind kind; uint index; int term_priority; AssocKind op_assoc; int op_priority; char *string; int string_len; } Term; typedef struct { uint n; uint i; Term * *v; Term * e[3 ]; } TermVec; typedef struct Production { char *name; uint name_len; uint index; Rule *nullable; struct { uint n; uint i; Rule * *v; Rule * e[3 ]; } rules; struct Production *next; } Production; typedef enum ElemKind { ELEM_NTERM, ELEM_TERM, ELEM_UNRESOLVED, ELEM_END } ElemKind; typedef struct Elem { ElemKind kind; uint index; Rule *rule; union { Production *nterm; Term *term; void *term_or_nterm; struct Unresolved { char *string; uint len; } unresolved; } e; } Elem; typedef struct Grammar { char *pathname; struct { uint n; uint i; Production * *v; Production * e[3 ]; } productions; struct { uint n; uint i; Term * *v; Term * e[3 ]; } terminals; struct { uint n; uint i; State * *v; State * e[3 ]; } states; Code scanner; Code *code; int ncode; } Grammar; extern int set_op_priority_from_rule; Grammar *load_grammar(char *grammar_filename); Grammar * parse_gram(char *pathname); void print_grammar(Grammar *g); void print_states(Grammar *g); void print_rule(Rule *r); void print_term(Term *t); # 73 "d.h" 2 # 1 "scan.h" 1 struct Grammar; typedef struct ScanState { uint index; struct ScanState *chars[256]; VecAction accepts; } ScanState; void build_scanner(struct Grammar *g); # 74 "d.h" 2 extern int verbose_level; extern int debug_level; void d_version(char *); # 5 "parse.c" 2 struct PNode; struct SNode; struct ZNode; struct Parser; static void free_SNode(struct Parser *p, struct SNode *s); typedef struct { uint n; uint i; struct ZNode* *v; struct ZNode* e[3 ]; } VecZNode; typedef struct { uint n; uint i; VecZNode * *v; VecZNode * e[3 ]; } VecVecZNode; typedef struct { uint n; uint i; struct SNode* *v; struct SNode* e[3 ]; } VecSNode; typedef struct { uint n; uint i; struct PNode* *v; struct PNode* e[3 ]; } VecPNode; typedef struct PNodeHash { struct PNode **v; uint i; uint m; uint n; struct PNode *all; } PNodeHash; typedef struct SNodeHash { struct SNode **s; struct SNode *all; struct SNode *last_all; } SNodeHash; typedef struct Reduction { struct ZNode *znode; struct SNode *snode; struct D_Reduction *reduction; struct SNode *new_snode; int new_depth; struct Reduction *next; } Reduction; typedef struct Shift { struct SNode *snode; struct Shift *next; } Shift; typedef struct Parser { D_Parser user; char *start, *end; struct D_ParserTables *t; int states, pnodes, scans, shifts, reductions, compares, ambiguities; PNodeHash pnode_hash; SNodeHash snode_hash; Reduction *reductions_todo; Shift *shifts_todo; VecSNode accepts; Reduction *free_reductions; Shift *free_shifts; struct PNode *free_pnodes; struct SNode *free_snodes; struct ZNode *free_znodes; struct { uint n; uint i; D_Reduction * *v; D_Reduction * e[3 ]; } error_reductions; } Parser; typedef struct PNode { int symbol; AssocKind assoc; int priority; AssocKind op_assoc; int op_priority; D_Reduction *reduction; D_Shift *shift; uint32 refcount; VecPNode children; uint height; uint8 evaluated; struct PNode *all_next; struct PNode *bucket_next; struct PNode *ambiguities; D_ParseNode parse_node; } PNode; typedef struct SNode { D_State *state; d_loc_t loc; uint depth; PNode *last_pn; VecZNode zns; uint32 refcount; struct SNode *all_next; } SNode; typedef struct ZNode { PNode *pn; VecSNode sns; } ZNode; typedef struct { struct PNode* *start; struct PNode* *end; struct PNode* *cur; struct PNode* initial[8 ]; } StackPNode; typedef struct { struct SNode* *start; struct SNode* *end; struct SNode* *cur; struct SNode* initial[8 ]; } StackSNode; typedef struct { int *start; int *end; int *cur; int initial[8 ]; } StackInt; int dummy_col, dummy_line; void print_paren(PNode *p) { int i; char *c; if (p->children.n) { if (p->children.n > 1) printf("("); for (i = 0; i < p->children.n; i++) print_paren(p->children.v[i]); if (p->children.n > 1) printf(")"); } else if (p->parse_node.start != p->parse_node.end) { printf(" "); for (c = p->parse_node.start; c < p->parse_node.end; c++) printf("%c", *c); printf(" "); } } void pp(PNode *p) { print_paren(p); printf("\n"); } static SNode * new_SNode(Parser *p) { SNode *ps = p->free_snodes; if (!ps) ps = malloc (sizeof *ps); else p->free_snodes = ps->all_next; ps->depth = 0; do { ( &ps->zns )->n = 0; ( &ps->zns )->v = 0; } while(0) ; ps->refcount = 0; ps->all_next = 0; p->states++; return ps; } static ZNode * new_ZNode(Parser *p, PNode *pn) { ZNode *z = p->free_znodes; if (!z) z = malloc (sizeof *z); else p->free_znodes = (*(ZNode**)&(( z )->pn)) ; z->pn = pn; do { ( &z->sns )->n = 0; ( &z->sns )->v = 0; } while(0) ; return z; } static void free_PNode(Parser *p, PNode *pn) { PNode *amb; int i; for (i = 0; i < pn->children.n; i++) do { if (!--( pn->children.v[i] )->refcount) free_PNode( p , pn->children.v[i] ); } while (0) ; do { if (( &pn->children )->v && ( &pn->children )->v != ( &pn->children )->e) free (( &pn->children )->v); do { ( &pn->children )->n = 0; ( &pn->children )->v = 0; } while(0) ; } while(0) ; for (;pn->ambiguities;pn->ambiguities = amb) { amb = pn->ambiguities->all_next; free (pn->ambiguities); } if (!p) free (pn); else { pn->all_next = p->free_pnodes; p->free_pnodes = pn; } } static void free_ZNode(Parser *p, ZNode *z, SNode *s) { int i; do { if (!--( z->pn )->refcount) free_PNode( p , z->pn ); } while (0) ; for (i = 0; i < z->sns.n; i++) if (s != z->sns.v[i]) do { if (!--( z->sns.v[i] )->refcount) free_SNode( p , z->sns.v[i] ); } while (0) ; do { if (( &z->sns )->v && ( &z->sns )->v != ( &z->sns )->e) free (( &z->sns )->v); do { ( &z->sns )->n = 0; ( &z->sns )->v = 0; } while(0) ; } while(0) ; if (!p) free (z); else { (*(ZNode**)&(( z )->pn)) = p->free_znodes; p->free_znodes = z; } } static void free_SNode(Parser *p, struct SNode *s) { int i; for (i = 0; i < s->zns.n; i++) if (s->zns.v[i]) free_ZNode(p, s->zns.v[i], s); do { if (( &s->zns )->v && ( &s->zns )->v != ( &s->zns )->e) free (( &s->zns )->v); do { ( &s->zns )->n = 0; ( &s->zns )->v = 0; } while(0) ; } while(0) ; if (!p) free (s); else { s->all_next = p->free_snodes; p->free_snodes = s; } } PNode * find_PNode(Parser *p, char *start, char *end, int symbol) { PNodeHash *ph = &p->pnode_hash; PNode *pn; uint h = ((((uint) start ) << 8) + (((uint) end ) << 16) + (((uint) symbol ))) ; if (ph->v) for (pn = ph->v[h % ph->m]; pn; pn = pn->bucket_next) if (pn->symbol == symbol && pn->parse_node.start == start && pn->parse_node.end == end) return pn; return 0 ; } void insert_PNode_internal(Parser *p, PNode *pn) { PNodeHash *ph = &p->pnode_hash; uint h = ((((uint) pn->parse_node.start ) << 8) + (((uint) pn->parse_node.end ) << 16) + (((uint) pn->symbol ))) , i; PNode *t; if (ph->n + 1 > ph->m) { PNode **v = ph->v; int m = ph->m; ph->i++; ph->m = prime2[ph->i]; ph->v = (PNode**)malloc (ph->m * sizeof(*ph->v)); memset(ph->v, 0, ph->m * sizeof(*ph->v)); for (i = 0; i < m; i++) while ((t = v[i])) { v[i] = v[i]->bucket_next; insert_PNode_internal(p, t); } free (v); } pn->bucket_next = ph->v[h % ph->m]; ph->v[h % ph->m] = pn; ph->n++; } void insert_PNode(Parser *p, PNode *pn) { insert_PNode_internal(p, pn); do { ( pn )->refcount++; } while (0) ; pn->all_next = p->pnode_hash.all; p->pnode_hash.all = pn; } static void free_old_nodes(Parser *p) { PNode *pn = p->pnode_hash.all, *tpn, **lpn; SNode *sn = p->snode_hash.all, *tsn; while (sn) { p->snode_hash.s[sn->state - p->t->state] = 0; tsn = sn; sn = sn->all_next; } sn = p->snode_hash.last_all; while (sn) { tsn = sn; sn = sn->all_next; do { if (!--( tsn )->refcount) free_SNode( p , tsn ); } while (0) ; } p->snode_hash.last_all = p->snode_hash.all; p->snode_hash.all = 0 ; while (pn) { lpn = &p->pnode_hash.v[ ((((uint) pn->parse_node.start ) << 8) + (((uint) pn->parse_node.end ) << 16) + (((uint) pn->symbol ))) % p->pnode_hash.m]; tpn = pn; pn = pn->all_next; while (*lpn != tpn) lpn = &(*lpn)->bucket_next; *lpn = (*lpn)->bucket_next; do { if (!--( tpn )->refcount) free_PNode( p , tpn ); } while (0) ; } p->pnode_hash.n = 0; p->pnode_hash.all = 0 ; } static void alloc_parser_working_data(Parser *p) { p->pnode_hash.i = 10 ; p->pnode_hash.m = prime2[p->pnode_hash.i]; p->pnode_hash.v = (PNode**)malloc (p->pnode_hash.m * sizeof(*p->pnode_hash.v)); memset(p->pnode_hash.v, 0, p->pnode_hash.m * sizeof(*p->pnode_hash.v)); p->snode_hash.s = malloc (p->t->nstates * sizeof(SNode *)); memset(p->snode_hash.s, 0, p->t->nstates * sizeof(SNode *)); } static void free_parser_working_data(Parser *p) { int i; free_old_nodes(p); free_old_nodes(p); free (p->pnode_hash.v); free (p->snode_hash.s); memset(&p->pnode_hash, 0, sizeof(p->pnode_hash)); memset(&p->snode_hash, 0, sizeof(p->snode_hash)); while (p->free_reductions) { Reduction *r = p->free_reductions->next; free (p->free_reductions); p->free_reductions = r; } while (p->free_shifts) { Shift *s = p->free_shifts->next; free (p->free_shifts); p->free_shifts = s; } while (p->free_pnodes) { PNode *pn = p->free_pnodes->all_next; free (p->free_pnodes); p->free_pnodes = pn; } for (i = 0; i < p->error_reductions.n; i++) free (p->error_reductions.v[i]); do { if (( &p->error_reductions )->v && ( &p->error_reductions )->v != ( &p->error_reductions )->e) free (( &p->error_reductions )->v); do { ( &p->error_reductions )->n = 0; ( &p->error_reductions )->v = 0; } while(0) ; } while(0) ; } static int znode_depth(ZNode *z) { int i, d = 0; if (!z) return 0x7fffffff ; for (i = 0; i < z->sns.n; i++) d = d < z->sns.v[i]->depth ? z->sns.v[i]->depth : d; return d; } static Reduction * add_Reduction(Parser *p, ZNode *z, SNode *sn, D_Reduction *reduction) { Reduction *x, **l = &p->reductions_todo; int d = znode_depth(z), dd; for (x = p->reductions_todo; x; l = &x->next, x = x->next) { if (sn->loc.s < x->snode->loc.s) break; dd = znode_depth(x->znode); if ((sn->loc.s == x->snode->loc.s && d >= dd)) { if (d == dd) while (x) { if (sn == x->snode && z == x->znode && reduction == x->reduction) return 0 ; x = x->next; } break; } } { Reduction *r = p->free_reductions; if (!r) r = malloc (sizeof *r); else p->free_reductions = r->next; r->znode = z; r->snode = sn; r->new_snode = 0 ; do { ( sn )->refcount++; } while (0) ; r->reduction = reduction; r->next = *l; *l = r; return r; } } static void add_Shift(Parser *p, SNode *snode) { Shift *x, **l = &p->shifts_todo; Shift *s = p->free_shifts; if (!s) s = malloc (sizeof *s); else p->free_shifts = s->next; s->snode = snode; do { ( s->snode )->refcount++; } while (0) ; for (x = p->shifts_todo; x; l = &x->next, x = x->next) if (snode->loc.s <= x->snode->loc.s) break; s->next = *l; *l = s; } static SNode * add_SNode(Parser *p, D_State *state, d_loc_t *loc) { int i; SNode *sn = p->snode_hash.s[state - p->t->state]; if (sn) return sn; sn = new_SNode(p); sn->state = state; sn->loc = *loc; p->snode_hash.s[state - p->t->state] = sn; do { ( sn )->refcount++; } while (0) ; sn->all_next = p->snode_hash.all; p->snode_hash.all = sn; if (sn->state->accept && !*sn->loc.s) { do { if (!( &p->accepts )->v) { (( &p->accepts )->v = ( &p->accepts )->e)[( &p->accepts )->n++] = ( sn ); break; } else if (( &p->accepts )->v == (( &p->accepts )->e)) { if ((( &p->accepts )->n < 3 )) { ( &p->accepts )->v[( &p->accepts )->n++] = ( sn ); break; } } else if (( &p->accepts )->n & ((1 << 3 ) - 1)) { ( &p->accepts )->v[( &p->accepts )->n++] = ( sn ); break; } vec_add_internal(( &p->accepts ), sn ); } while (0) ; do { ( sn )->refcount++; } while (0) ; } if (sn->state->scanner_code || sn->state->scanner_table) add_Shift(p, sn); for (i = 0; i < sn->state->reductions.n; i++) if (!sn->state->reductions.v[i]->nelements) add_Reduction(p, 0, sn, sn->state->reductions.v[i]); return sn; } static int reduce_actions(Parser *p, PNode *pn, D_Reduction *r) { int i, height = 0; PNode *c; for (i = 0; i < pn->children.n; i++) { c = pn->children.v[i]; if (c->op_assoc) { pn->assoc = c->op_assoc; pn->priority = c->op_priority; } if (c->height >= height) height = c->height + 1; } pn->op_assoc = r->op_assoc; pn->op_priority = r->op_priority; pn->height = height; if (r->rule_assoc) { pn->assoc = r->rule_assoc; pn->priority = r->rule_priority; } if (r->speculative_code) return r->speculative_code(pn, (void**)&pn->children.v[0], pn->children.n, (int)&((PNode*)(0 ))->parse_node); return 0; } static D_Shift ** scan_buf(d_loc_t *loc, int scanner_size, void *scanner_table) { char *s = loc->s, *scol = 0; int col = loc->col, collast = col, line = loc->line; switch (scanner_size) { case 1: { SB_uint8 *st = (SB_uint8*)scanner_table; uint8 state = 0, last = state, c; c = (uint8)*s++; while ((state = st[state].scanner_block[c >> (8 - 2 ) ] [c & ((1 << (8 - 2 ) ) - 1) ])) { state -= 1; if (st[state].shift) { last = state; loc->s = s; collast = col; loc->line = line; } if (c == '\n') { line++; col = 0; scol = s; } else col++; c = (uint8)*s++; } loc->col = scol ? s - scol : -1; if (last) return st[last].shift; return 0 ; } case 2: { SB_uint16 *st = (SB_uint16*)scanner_table; uint16 state = 0, last = state, c; c = (uint8)*s++; while ((state = st[state].scanner_block[c >> (8 - 2 ) ] [c & ((1 << (8 - 2 ) ) - 1) ])) { state -= 1; if (st[state].shift) { last = state; loc->s = s; collast = col; loc->line = line; } if (c == '\n') { line++; col = 0; scol = s; } else col++; c = (uint8)*s++; } loc->col = scol ? s - scol : -1; if (last) return st[last].shift; return 0 ; } case 4: { SB_uint32 *st = (SB_uint32*)scanner_table; uint32 state = 0, last = state, c; c = (uint8)*s++; while ((state = st[state].scanner_block[c >> (8 - 2 ) ] [c & ((1 << (8 - 2 ) ) - 1) ])) { state -= 1; if (st[state].shift) { last = state; loc->s = s; collast = col; loc->line = line; } if (c == '\n') { line++; col = 0; scol = s; } else col++; c = (uint8)*s++; } loc->col = scol ? s - scol : -1; if (last) return st[last].shift; return 0 ; } } return 0; } static int child_table[4][3][6] = { { { 1, 0, 1, 1, 0, 0}, { 1, 1, 1, 1, 666 , 666 }, { 1, 0, 666 , 666 , 1, 1} }, { { 1, 0, 0, 0, 1, 1}, { 1, 0, 1, 1, 666 , 666 }, { 1, 1, 666 , 666 , 1, 1} }, { { 1, 0, 0, 666 , 0, 666 }, { 1, 0, 1, 666 , 666 , 666 }, { 1, 1, 666 , 666 , 1, 666 } }, { { 1, 0, 666 , 0, 666 , 0}, { 1, 1, 666 , 1, 666 , 666 }, { 1, 0, 666 , 666 , 666 , 1} } }; static int check_child(int ppri, AssocKind passoc, int cpri, AssocKind cassoc, int left, int right) { int p = ((( passoc ) & 0x0010 ) || (( passoc ) & 0x0004 ) ) ? (right ? 1 : 0) : (passoc == ASSOC_UNARY_LEFT ? 2 : 3); int c = ((( cassoc ) & 0x0010 ) || (( cassoc ) & 0x0004 ) ) ? 0 : (cassoc == ASSOC_UNARY_LEFT ? 1 : 2); int r = cpri > ppri ? 0 : ( cpri < ppri ? 1 : ( 2 + ( ((( cassoc ) & 0x0002 ) ? 2 : 0) + ((( passoc ) & 0x0002 ) ? 1 : 0)))); return child_table[p][c][r]; } static int check_assoc_priority(PNode *pn0, PNode *pn1, PNode *pn2) { if (! ((( pn0->op_assoc ) & 0x0010 ) || (( pn0->op_assoc ) & 0x0008 ) ) ) { if (((( pn1->op_assoc ) & 0x0010 ) || (( pn1->op_assoc ) & 0x0008 ) ) ) { if (pn0->assoc) { if (!check_child(pn1->op_priority, pn1->op_assoc, pn0->priority, pn0->assoc, 0, 1)) return -1; } } } else { if (pn1->op_assoc) { if (!check_child(pn1->op_priority, pn1->op_assoc, pn0->op_priority, pn0->op_assoc, 0, 1)) return -1; } else if (pn2) { if (pn2->op_assoc && !check_child(pn2->op_priority, pn2->op_assoc, pn0->op_priority, pn0->op_assoc, 0, 1)) return -1; } if (pn1->assoc) { if (!check_child(pn0->op_priority, pn0->op_assoc, pn1->priority, pn1->assoc, 1, 0)) return -1; } } return 0; } static int check_path_priorities_internal(VecZNode *path) { int i = 0, j, k, jj, kk, one = 0; ZNode *z, *zz, *zzz; PNode *pn0, *pn1; if (path->n < i + 1) return 0; pn0 = path->v[i]->pn; if (!pn0->op_assoc) { i = 1; if (path->n < i + 1) return 0; pn1 = path->v[i]->pn; if (!pn1->op_assoc) return 0; if (pn0->assoc) { if (!check_child(pn1->op_priority, pn1->op_assoc, pn0->priority, pn0->assoc, 0, 1)) return -1; } pn0 = pn1; } if (path->n > i + 1) { pn1 = path->v[i + 1]->pn; if (path->n > i + 2) return check_assoc_priority(pn0, pn1, path->v[i + 2]->pn); else { z = path->v[i + 1]; for (k = 0; k < z->sns.n; k++) for (j = 0; j < z->sns.v[k]->zns.n; j++) { one = 1; zz = z->sns.v[k]->zns.v[j]; if (zz && !check_assoc_priority(pn0, pn1, zz->pn)) return 0; } if (!one) return check_assoc_priority(pn0, pn1, 0 ); } } else { z = path->v[i]; for (k = 0; k < z->sns.n; k++) for (j = 0; j < z->sns.v[k]->zns.n; j++) { zz = z->sns.v[k]->zns.v[j]; if (zz) for (kk = 0; kk < zz->sns.n; kk++) for (jj = 0; jj < zz->sns.v[kk]->zns.n; jj++) { one = 1; zzz = zz->sns.v[kk]->zns.v[jj]; if (zzz && !check_assoc_priority(pn0, zz->pn, zzz->pn)) return 0; } } return 0; } return -1; } static int cmp_priorities(int xpri[], int xn, int ypri[], int yn) { int i = 0; while (i < xn && i < yn) { if (xpri[i] > ypri[i]) return -1; if (xpri[i] < ypri[i]) return 1; i++; } return 0; } static void intsort(int *xp, int n) { int again = 1, i, t; while (again) { again = 0; for (i = 0; i < n - 1; i++) { if (xp[i] > xp[i+1]) { t = xp[i]; xp[i] = xp[i + 1]; xp[i + 1] = t; again = 1; } } } } static int cmp_eagerness(PNode *x, PNode *y) { int i, n; n = x->children.n < y->children.n ? x->children.n : y->children.n; for (i = 0; i < n; i++) { if (x->children.v[i]->parse_node.end > y->children.v[i]->parse_node.end) return -1; if (x->children.v[i]->parse_node.end < y->children.v[i]->parse_node.end) return 1; } return 0; } static void priority_insert(StackPNode *psx, PNode *x) { PNode *t, **start, **cur; (( psx )->cur == ( psx )->end ? stack_push_internal((AbstractStack*)(( psx )), (void*) x ) : (void*)(*(( psx )->cur)++ = ( x ))) ; start = psx->start; cur = psx->cur; for (;cur > start + 1;cur--) { if (cur[-1]->height > cur[-2]->height) continue; if (cur[-1]->height == cur[-2]->height && cur[-1] > cur[-2]) continue; t = cur[-1]; cur[-1] = cur[-2]; cur[-2] = t; } } static void get_exp_all(PNode *x, StackInt *psx) { int i; if (x->assoc) (( psx )->cur == ( psx )->end ? stack_push_internal((AbstractStack*)(( psx )), (void*) x->priority ) : (void*)(*(( psx )->cur)++ = ( x->priority ))) ; for (i = 0; i < x->children.n; i++) get_exp_all(x->children.v[i], psx); } static void get_exp_one(PNode *x, StackPNode *psx, StackInt *isx) { int i; if (! (( x->assoc ) & 0x0004 ) ) priority_insert(psx, x); else { (( isx )->cur == ( isx )->end ? stack_push_internal((AbstractStack*)(( isx )), (void*) x->priority ) : (void*)(*(( isx )->cur)++ = ( x->priority ))) ; for (i = 0; i < x->children.n; i++) if (x->children.v[i]->assoc) get_exp_one(x->children.v[i], psx, isx); } } static void get_exp_one_down(PNode *x, StackPNode *psx, StackInt *isx) { int i; (( isx )->cur == ( isx )->end ? stack_push_internal((AbstractStack*)(( isx )), (void*) x->priority ) : (void*)(*(( isx )->cur)++ = ( x->priority ))) ; for (i = 0; i < x->children.n; i++) if (x->children.v[i]->assoc) get_exp_one(x->children.v[i], psx, isx); } static void get_unshared_priorities(StackPNode *psx, StackPNode *psy, StackInt *isx, StackInt *isy) { StackPNode *psr; PNode *t; while (1) { if ((( psx )->cur == ( psx )->start) ) { psr = psy; break; } else if ((( psy )->cur == ( psy )->start) ) { psr = psx; break; } if ((( psx )->cur[-1]) ->height > (( psy )->cur[-1]) ->height) psr = psx; else if ((( psx )->cur[-1]) ->height < (( psy )->cur[-1]) ->height) psr = psy; else if ((( psx )->cur[-1]) > (( psy )->cur[-1]) ) psr = psx; else if ((( psx )->cur[-1]) < (( psy )->cur[-1]) ) psr = psy; else { (void)(*--(( psx )->cur)) ; (void)(*--(( psy )->cur)) ; continue; } t = (*--(( psr )->cur)) ; if (psr == psx) get_exp_one_down(t, psx, isx); else get_exp_one_down(t, psy, isy); } while (! (( psr )->cur == ( psr )->start) ) { t = (*--(( psr )->cur)) ; if (psr == psx) get_exp_all(t, isx); else get_exp_all(t, isy); } return; } static int cmp_reduction_priorities(Parser *p, PNode *x, PNode *y) { StackPNode psx, psy; StackInt isx, isy; int r; if (!x->assoc || !y->assoc) return 0; if (! (( x->assoc ) & 0x0004 ) && ! (( y->assoc ) & 0x0004 ) ) { if (x->priority > y->priority) return -1; if (x->priority < y->priority) return 1; } do { ( &psx )->start = ( &psx )->cur = ( &psx )->end = ( &psx )->initial; ( &psx )->end += 8 ; } while(0) ; do { ( &psy )->start = ( &psy )->cur = ( &psy )->end = ( &psy )->initial; ( &psy )->end += 8 ; } while(0) ; do { ( &isx )->start = ( &isx )->cur = ( &isx )->end = ( &isx )->initial; ( &isx )->end += 8 ; } while(0) ; do { ( &isy )->start = ( &isy )->cur = ( &isy )->end = ( &isy )->initial; ( &isy )->end += 8 ; } while(0) ; get_exp_one(x, &psx, &isx); get_exp_one(y, &psy, &isy); get_unshared_priorities(&psx, &psy, &isx, &isy); intsort(isx.start, (( &isx )->cur - ( &isx )->start) ); intsort(isy.start, (( &isy )->cur - ( &isy )->start) ); p->compares += (( &isx )->cur - ( &isx )->start) + (( &isy )->cur - ( &isy )->start) ; r = cmp_priorities(isx.start, (( &isx )->cur - ( &isx )->start) , isy.start, (( &isy )->cur - ( &isy )->start) ); do { if (( &psx )->start != ( &psx )->initial) free (( &psx )->start); do { ( &psx )->start = ( &psx )->cur = ( &psx )->end = ( &psx )->initial; ( &psx )->end += 8 ; } while(0) ; } while(0) ; do { if (( &psy )->start != ( &psy )->initial) free (( &psy )->start); do { ( &psy )->start = ( &psy )->cur = ( &psy )->end = ( &psy )->initial; ( &psy )->end += 8 ; } while(0) ; } while(0) ; do { if (( &isx )->start != ( &isx )->initial) free (( &isx )->start); do { ( &isx )->start = ( &isx )->cur = ( &isx )->end = ( &isx )->initial; ( &isx )->end += 8 ; } while(0) ; } while(0) ; do { if (( &isy )->start != ( &isy )->initial) free (( &isy )->start); do { ( &isy )->start = ( &isy )->cur = ( &isy )->end = ( &isy )->initial; ( &isy )->end += 8 ; } while(0) ; } while(0) ; if (r) return r; return cmp_eagerness(x, y); } static PNode * make_PNode(Parser *p, int symbol, char *s, int line, char *e, PNode *pn, D_Reduction *r, VecZNode *path, D_Shift *sh) { int i, l = sizeof(PNode) - sizeof(d_voidp) + p->user.sizeof_user_parse_node; PNode *new_pn = p->free_pnodes; if (!new_pn) new_pn = malloc (l); else p->free_pnodes = new_pn->all_next; p->pnodes++; memset(new_pn, 0, l); new_pn->symbol = symbol; new_pn->parse_node.start = s; new_pn->parse_node.end = e; new_pn->parse_node.line = line; new_pn->shift = sh; new_pn->reduction = r; new_pn->parse_node.scope = pn->parse_node.scope; new_pn->parse_node.skip_space = pn->parse_node.skip_space; new_pn->parse_node.globals = pn->parse_node.globals; if (sh) { new_pn->op_assoc = sh->op_assoc; new_pn->op_priority = sh->op_priority; } else if (r) { if (path) for (i = path->n - 1; i >= 0; i--) { do { if (!( &new_pn->children )->v) { (( &new_pn->children )->v = ( &new_pn->children )->e)[( &new_pn->children )->n++] = ( path->v[i]->pn ); break; } else if (( &new_pn->children )->v == (( &new_pn->children )->e)) { if ((( &new_pn->children )->n < 3 )) { ( &new_pn->children )->v[( &new_pn->children )->n++] = ( path->v[i]->pn ); break; } } else if (( &new_pn->children )->n & ((1 << 3 ) - 1)) { ( &new_pn->children )->v[( &new_pn->children )->n++] = ( path->v[i]->pn ); break; } vec_add_internal(( &new_pn->children ), path->v[i]->pn ); } while (0) ; do { ( path->v[i]->pn )->refcount++; } while (0) ; } if (reduce_actions(p, new_pn, r)) { free_PNode(p, new_pn); return 0 ; } if (path && path->n > 1) { int n = path->n; for (i = 0; i < n; i += n-1) { PNode *child = new_pn->children.v[i]; if (child->assoc && !check_child(new_pn->priority, new_pn->assoc, child->priority, child->assoc, i == 0, i == n - 1)) { free_PNode(p, new_pn); return 0 ; } } } } return new_pn; } static int PNode_equal(PNode *pn, D_Reduction *r, VecZNode *path, D_Shift *sh) { int i, n = pn->children.n; if (sh) return sh == pn->shift; if (r != pn->reduction) return 0; if (!path && !n) return 1; if (n == path->n) { for (i = 0; i < n; i++) if (pn->children.v[i] != path->v[n - i - 1]->pn) return 0; return 1; } return 0; } static void move_PNode(PNode *dest, PNode *src) { PNode *next = dest->bucket_next, *all = dest->all_next, *amb = dest->ambiguities; int refcount = dest->refcount; do { if (( &dest->children )->v && ( &dest->children )->v != ( &dest->children )->e) free (( &dest->children )->v); do { ( &dest->children )->n = 0; ( &dest->children )->v = 0; } while(0) ; } while(0) ; memcpy(dest, src, sizeof(*src)); do { ( &dest->children )->n = ( &src->children )->n; if (( &src->children )->v == ( &src->children )->e) { memcpy(&( &dest->children )->e[0], &( &src->children )->e[0], sizeof(( &dest->children )->e)); ( &dest->children )->v = ( &dest->children )->e; } else ( &dest->children )->v = ( &src->children )->v; do { ( &src->children )->n = 0; ( &src->children )->v = 0; } while(0) ; } while (0) ; dest->bucket_next = next; dest->all_next = all; dest->ambiguities = amb; dest->refcount = refcount; } static PNode * add_PNode(Parser *p, int symbol, char *s, int line, char *e, PNode *pn, D_Reduction *r, VecZNode *path, D_Shift *sh) { PNode *old_pn = find_PNode(p, s, e, symbol), *new_pn; if (old_pn && PNode_equal(old_pn, r, path, sh)) return old_pn; new_pn = make_PNode(p, symbol, s, line, e, pn, r, path, sh); if (!old_pn) { old_pn = new_pn; if (!new_pn) return 0 ; insert_PNode(p, new_pn); goto Lreturn; } if (!new_pn) goto Lreturn; switch (cmp_reduction_priorities(p, new_pn, old_pn)) { case 0: new_pn->all_next = old_pn->ambiguities; old_pn->ambiguities = new_pn; break; case -1: move_PNode(old_pn, new_pn); free_PNode(p, new_pn); break; case 1: break; } Lreturn: return old_pn; } static void set_add_znode(VecZNode *v, ZNode *z); static void set_union_znode(VecZNode *v, VecZNode *vv) { int i; for (i = 0; i < vv->n; i++) if (vv->v[i]) set_add_znode(v, vv->v[i]); } static ZNode * set_find_znode(VecZNode *v, PNode *pn) { uint i, j, n = v->n, h; if (n <= 3 ) { for (i = 0; i < n; i++) if (v->v[i]->pn == pn) return v->v[i]; return 0 ; } h = ((uint)pn) % 10147031 ; h = h % n; for (i = h, j = 0; i < v->n && j < 3 ; i = ((i + 1) % n), j++) { if (!v->v[i]) return 0 ; else if (v->v[i]->pn == pn) return v->v[i]; } return 0 ; } static void set_add_znode_hash(VecZNode *v, ZNode *z) { VecZNode vv; int i, j, n = v->n; if (n) { uint h = ((uint)z->pn) % 10147031 ; h = h % n; for (i = h, j = 0; i < v->n && j < 3 ; i = ((i + 1) % n), j++) { if (!v->v[i]) { v->v[i] = z; return; } } } if (!n) { vv.v = 0 ; v->i = 2 ; } else { vv.v = (void*)v->v; vv.n = v->n; v->i = v->i + 2; } v->n = prime2[v->i]; v->v = malloc (v->n * sizeof(void *)); memset(v->v, 0, v->n * sizeof(void *)); if (vv.v) { set_union_znode(v, &vv); free (vv.v); } set_add_znode(v, z); } static void set_add_znode(VecZNode *v, ZNode *z) { VecZNode vv; int i, n = v->n; if (n < 3 ) { do { if (!( v )->v) { (( v )->v = ( v )->e)[( v )->n++] = ( z ); break; } else if (( v )->v == (( v )->e)) { if ((( v )->n < 3 )) { ( v )->v[( v )->n++] = ( z ); break; } } else if (( v )->n & ((1 << 3 ) - 1)) { ( v )->v[( v )->n++] = ( z ); break; } vec_add_internal(( v ), z ); } while (0) ; return; } if (n == 3 ) { vv = *v; do { ( v )->n = 0; ( v )->v = 0; } while(0) ; for (i = 0; i < n; i++) set_add_znode_hash(v, vv.v[i]); } set_add_znode_hash(v, z); } static SNode * goto_PNode(Parser *p, d_loc_t *loc, PNode *pn, SNode *ps) { SNode *new_ps, *pre_ps; ZNode *z = 0 ; D_State *state; int i, j, k, state_index; if (! (( ps->state->goto_valid )[( pn->symbol ) / 8] & 1 << (( pn->symbol ) % 8)) ) return 0 ; state_index = (( p )->t->goto_table[( pn )->symbol - ( ps )->state->goto_table_offset] - 1) ; state = &p->t->state[state_index]; new_ps = add_SNode(p, state, loc); new_ps->last_pn = pn; if (debug_level) { printf("goto %d -> %d %X\n", ps->state - p->t->state, state_index, (uint)new_ps) ; } ; if (ps != new_ps && new_ps->depth < ps->depth + 1) new_ps->depth = ps->depth + 1; z = set_find_znode(&new_ps->zns, pn); if (!z) { set_add_znode(&new_ps->zns, (z = new_ZNode(p, pn))); do { ( pn )->refcount++; } while (0) ; for (j = 0; j < new_ps->state->reductions.n; j++) if (new_ps->state->reductions.v[j]->nelements) add_Reduction(p, z, new_ps, new_ps->state->reductions.v[j]); if (!pn->shift) for (j = 0; j < new_ps->state->right_epsilon_hints.n; j++) { D_RightEpsilonHint *h = &new_ps->state->right_epsilon_hints.v[j]; pre_ps = p->snode_hash.s[h->preceeding_state]; if (!pre_ps) continue; for (k = 0; k < pre_ps->zns.n; k++) if (pre_ps->zns.v[k]) { Reduction *r = add_Reduction(p, pre_ps->zns.v[k], pre_ps, h->reduction); if (r) { r->new_snode = new_ps; r->new_depth = h->depth; } } } } for (i = 0; i < z->sns.n; i++) if (z->sns.v[i] == ps) break; if (i >= z->sns.n) { do { if (!( &z->sns )->v) { (( &z->sns )->v = ( &z->sns )->e)[( &z->sns )->n++] = ( ps ); break; } else if (( &z->sns )->v == (( &z->sns )->e)) { if ((( &z->sns )->n < 3 )) { ( &z->sns )->v[( &z->sns )->n++] = ( ps ); break; } } else if (( &z->sns )->n & ((1 << 3 ) - 1)) { ( &z->sns )->v[( &z->sns )->n++] = ( ps ); break; } vec_add_internal(( &z->sns ), ps ); } while (0) ; if (ps != new_ps) do { ( ps )->refcount++; } while (0) ; } return new_ps; } static void shift_one(Parser *p, Shift *s) { int skip = 0; d_loc_t loc, skip_loc; D_Shift *sh, **psh = 0, code_st; PNode *new_pn; D_State *state = s->snode->state; loc = s->snode->loc; p->scans++; if (state->scanner_table) psh = scan_buf(&loc, state->scanner_size, state->scanner_table); if (state->scanner_code) { code_st.term_priority = 0; code_st.op_assoc = 0; if ((state->scanner_code(&loc.s, &loc.col, &loc.line, &code_st.symbol, &code_st.term_priority, &code_st.op_assoc, &code_st.op_priority))) { sh = &code_st; psh--; goto Lcode; } } if (debug_level) { printf("shift %d %X\n", s->snode->state - p->t->state, (uint)s->snode) ; } ; for (; psh && *psh; psh++) { sh = *psh; Lcode: p->shifts++; new_pn = add_PNode(p, sh->symbol, s->snode->loc.s, loc.line, loc.s, s->snode->last_pn, 0 , 0 , sh); if (new_pn) { if (!skip) { skip = 1; skip_loc = loc; new_pn->parse_node.skip_space( &skip_loc, (void**)&new_pn->parse_node.globals); skip_loc.last_col = s->snode->loc.col >= 0 ? s->snode->loc.col : s->snode->loc.last_col; } goto_PNode(p, &skip_loc, new_pn, s->snode); } } do { if (!--( s->snode )->refcount) free_SNode( p , s->snode ); } while (0) ; s->next = p->free_shifts; p->free_shifts = s; } static VecZNode path1; static VecZNode * new_VecZNode(VecVecZNode *paths, int n, int parent) { int i; VecZNode *pv; if (!paths->n) pv = &path1; else pv = malloc (sizeof *pv); do { ( pv )->n = 0; ( pv )->v = 0; } while(0) ; if (parent >= 0) for (i = 0; i < n; i++) do { if (!( pv )->v) { (( pv )->v = ( pv )->e)[( pv )->n++] = ( paths->v[parent]->v[i] ); break; } else if (( pv )->v == (( pv )->e)) { if ((( pv )->n < 3 )) { ( pv )->v[( pv )->n++] = ( paths->v[parent]->v[i] ); break; } } else if (( pv )->n & ((1 << 3 ) - 1)) { ( pv )->v[( pv )->n++] = ( paths->v[parent]->v[i] ); break; } vec_add_internal(( pv ), paths->v[parent]->v[i] ); } while (0) ; return pv; } static void build_paths_internal(ZNode *z, VecVecZNode *paths, int parent, int n, int n_to_go) { int j, k, l; do { if (!( paths->v[parent] )->v) { (( paths->v[parent] )->v = ( paths->v[parent] )->e)[( paths->v[parent] )->n++] = ( z ); break; } else if (( paths->v[parent] )->v == (( paths->v[parent] )->e)) { if ((( paths->v[parent] )->n < 3 )) { ( paths->v[parent] )->v[( paths->v[parent] )->n++] = ( z ); break; } } else if (( paths->v[parent] )->n & ((1 << 3 ) - 1)) { ( paths->v[parent] )->v[( paths->v[parent] )->n++] = ( z ); break; } vec_add_internal(( paths->v[parent] ), z ); } while (0) ; if (n_to_go <= 1) return; for (k = 0; k < z->sns.n; k++) for (j = 0, l = 0; j < z->sns.v[k]->zns.n; j++) { if (z->sns.v[k]->zns.v[j]) { if (k + l) { do { if (!( paths )->v) { (( paths )->v = ( paths )->e)[( paths )->n++] = ( new_VecZNode(paths, n - (n_to_go - 1), parent) ); break; } else if (( paths )->v == (( paths )->e)) { if ((( paths )->n < 3 )) { ( paths )->v[( paths )->n++] = ( new_VecZNode(paths, n - (n_to_go - 1), parent) ); break; } } else if (( paths )->n & ((1 << 3 ) - 1)) { ( paths )->v[( paths )->n++] = ( new_VecZNode(paths, n - (n_to_go - 1), parent) ); break; } vec_add_internal(( paths ), new_VecZNode(paths, n - (n_to_go - 1), parent) ); } while (0) ; parent = paths->n - 1; } build_paths_internal(z->sns.v[k]->zns.v[j], paths, parent, n, n_to_go - 1); l++; } } } static void build_paths(ZNode *z, VecVecZNode *paths, int nchildren_to_go) { if (!nchildren_to_go) return; do { if (!( paths )->v) { (( paths )->v = ( paths )->e)[( paths )->n++] = ( new_VecZNode(paths, 0, -1) ); break; } else if (( paths )->v == (( paths )->e)) { if ((( paths )->n < 3 )) { ( paths )->v[( paths )->n++] = ( new_VecZNode(paths, 0, -1) ); break; } } else if (( paths )->n & ((1 << 3 ) - 1)) { ( paths )->v[( paths )->n++] = ( new_VecZNode(paths, 0, -1) ); break; } vec_add_internal(( paths ), new_VecZNode(paths, 0, -1) ); } while (0) ; build_paths_internal(z, paths, 0, nchildren_to_go, nchildren_to_go); } static void free_paths(VecVecZNode *paths) { int i; do { if (( &path1 )->v && ( &path1 )->v != ( &path1 )->e) free (( &path1 )->v); do { ( &path1 )->n = 0; ( &path1 )->v = 0; } while(0) ; } while(0) ; for (i = 1; i < paths->n; i++) { do { if (( paths->v[i] )->v && ( paths->v[i] )->v != ( paths->v[i] )->e) free (( paths->v[i] )->v); do { ( paths->v[i] )->n = 0; ( paths->v[i] )->v = 0; } while(0) ; } while(0) ; free (paths->v[i]); } do { if (( paths )->v && ( paths )->v != ( paths )->e) free (( paths )->v); do { ( paths )->n = 0; ( paths )->v = 0; } while(0) ; } while(0) ; } static void reduce_one(Parser *p, Reduction *r) { SNode *sn = r->snode; PNode *pn, *last_pn; ZNode *first_z; int i, j, n = r->reduction->nelements; VecVecZNode paths; VecZNode *path; if (!r->znode) { if ((pn = add_PNode(p, r->reduction->symbol, sn->loc.s, sn->loc.line, sn->loc.s, sn->last_pn, r->reduction, 0, 0))) goto_PNode(p, &sn->loc, pn, sn); } else { if (debug_level) { printf("reduce %d %X\n", r->snode->state - p->t->state, (uint)sn) ; } ; do { ( &paths )->n = 0; ( &paths )->v = 0; } while(0) ; build_paths(r->znode, &paths, n); for (i = 0; i < paths.n; i++) { path = paths.v[i]; if (r->new_snode) { for (j = 0; j < path->v[r->new_depth]->sns.n; j++) if (path->v[r->new_depth]->sns.v[j] == r->new_snode) break; if (j >= path->v[r->new_depth]->sns.n) continue; } if ((( path )->n > 1 && (( path )->v[0]->pn->op_assoc || ( path )->v[1]->pn->op_assoc) && check_path_priorities_internal( path )) ) continue; p->reductions++; last_pn = path->v[0]->pn; first_z = path->v[n - 1]; pn = add_PNode(p, r->reduction->symbol, first_z->pn->parse_node.start, first_z->pn->parse_node.line, last_pn->parse_node.end, last_pn, r->reduction, path, 0 ); if (pn) for (j = 0; j < first_z->sns.n; j++) goto_PNode(p, &sn->loc, pn, first_z->sns.v[j]); } free_paths(&paths); } do { if (!--( sn )->refcount) free_SNode( p , sn ); } while (0) ; r->next = p->free_reductions; p->free_reductions = r; } static int VecSNode_equal(VecSNode *vsn1, VecSNode *vsn2) { int i, j; if (vsn1->n != vsn2->n) return 0; for (i = 0; i < vsn1->n; i++) { for (j = 0; j < vsn2->n; j++) { if (vsn1->v[i] == vsn2->v[j]) break; } if (j >= vsn2->n) return 0; } return 1; } static ZNode * binary_op_ZNode(SNode *sn) { ZNode *z; if (sn->zns.n != 1) return 0 ; z = sn->zns.v[0]; if (z->pn->op_assoc == ASSOC_UNARY_RIGHT) { if (z->sns.n != 1) return 0 ; sn = z->sns.v[0]; if (sn->zns.n != 1) return 0 ; z = sn->zns.v[0]; } if (! (( z->pn->op_assoc ) & 0x0010 ) ) return 0 ; return z; } static void cmp_stacks(Parser *p) { char *pos; Shift *a, *b, **al, **bl; ZNode *az, *bz; if (!p->shifts_todo) return; pos = p->shifts_todo->snode->loc.s; for (al = &p->shifts_todo, a = *al; a && a->snode->loc.s == pos; al = &a->next, a = a->next) { if (!(az = binary_op_ZNode(a->snode))) continue; for (bl = &a->next, b = a->next; b && b->snode->loc.s == pos; bl = &b->next, b = b->next) { if (!(bz = binary_op_ZNode(b->snode))) continue; if (!VecSNode_equal(&az->sns, &bz->sns)) continue; if (az->pn->op_priority > bz->pn->op_priority) { *bl = b->next; do { if (!--( b->snode )->refcount) free_SNode( p , b->snode ); } while (0) ; free (b); b = *bl; break; } if (az->pn->op_priority < bz->pn->op_priority) { *al = a->next; do { if (!--( a->snode )->refcount) free_SNode( p , a->snode ); } while (0) ; free (a); a = *al; goto Lbreak2; } } Lbreak2:; } } static void commit_tree(Parser *p, PNode *pn) { int i; PNode *amb; if (pn->evaluated) return; if (! (( pn )->parse_node.start == ( pn )->parse_node.end && (( pn )->reduction && ( pn )->reduction->final_code)) ) pn->evaluated = 1; for (i = 0; i < pn->children.n; i++) commit_tree(p, pn->children.v[i]); if (pn->reduction && pn->reduction->final_code) pn->reduction->final_code(pn, (void**)&pn->children.v[0], pn->children.n, (int)&((PNode*)(0 ))->parse_node); if (pn->evaluated) { if (!p->user.save_parse_tree) { for (i = 0; i < pn->children.n; i++) do { if (!--( pn->children.v[i] )->refcount) free_PNode( p , pn->children.v[i] ); } while (0) ; do { if (( &pn->children )->v && ( &pn->children )->v != ( &pn->children )->e) free (( &pn->children )->v); do { ( &pn->children )->n = 0; ( &pn->children )->v = 0; } while(0) ; } while(0) ; for (;pn->ambiguities;pn->ambiguities = amb) { amb = pn->ambiguities->all_next; free (pn->ambiguities); p->ambiguities++; } } else { for (amb = pn->ambiguities; amb; amb = amb->all_next) p->ambiguities++; } } } static int commit_stack(Parser *p, SNode *sn) { int res = 0; if (sn->zns.n != 1) return -1; if (sn->zns.v[0]->sns.n > 1) return -2; if ((( sn->zns.v[0]->pn )->parse_node.start == ( sn->zns.v[0]->pn )->parse_node.end && (( sn->zns.v[0]->pn )->reduction && ( sn->zns.v[0]->pn )->reduction->final_code)) ) return -3; if (sn->zns.v[0]->sns.n) if ((res = commit_stack(p, sn->zns.v[0]->sns.v[0])) < 0) return res; commit_tree(p, sn->zns.v[0]->pn); return res; } static char * find_substr(char *str, char *s) { int len = strlen(s); if (len == 1) { while (*str && *str != *s) str++; if (*str == *s) return str + 1; } else while (*str) { if (!strncmp(s, str, len)) return str + len; str++; } return 0 ; } static int error_recovery(Parser *p) { SNode *sn, *best_sn = 0 ; char *best_s = 0 , *ss, *s; int i, j, head = 0, tail = 0, res = 1; D_ErrorRecoveryHint *best_er = 0 ; SNode **q = malloc (10000 * sizeof(SNode*)); if (p->user.loc.line > p->user.last_syntax_error_line) { p->user.last_syntax_error_line = p->user.loc.line; p->user.syntax_errors++; if (p->user.syntax_error_fn) p->user.syntax_error_fn((D_Parser*)p); else { char *fn = dup_filename_str(p->user.loc.filename); fprintf((&__sF[2]) , "syntax error, '%s' line %d\n", fn, p->user.loc.line); free (fn); } } for (sn = p->snode_hash.last_all; sn; sn = sn->all_next) { if (tail < 10000 - 1) q[tail++] = sn; } s = p->snode_hash.last_all->loc.s; while (tail > head) { sn = q[head++]; if (sn->state->error_recovery_hints.n) { for (i = 0; i < sn->state->error_recovery_hints.n; i++) { D_ErrorRecoveryHint *er = &sn->state->error_recovery_hints.v[i]; if ((ss = find_substr(s, er->string))) { if (!best_sn || ss < best_s || (best_sn && ss == best_s && (best_sn->depth < sn->depth || (best_sn->depth == sn->depth && best_er->depth < er->depth)))) { best_sn = sn; best_s = ss; best_er = er; } } } } for (i = 0; i < sn->zns.n; i++) if (sn->zns.v[i]) for (j = 0; j < sn->zns.v[i]->sns.n; j++) { if (tail < 10000 - 1) q[tail++] = sn->zns.v[i]->sns.v[j]; } } if (best_sn) { D_Reduction *rr = malloc (sizeof(*rr)); d_loc_t best_loc = p->user.loc; memset(rr, 0, sizeof(*rr)); do { if (!( &p->error_reductions )->v) { (( &p->error_reductions )->v = ( &p->error_reductions )->e)[( &p->error_reductions )->n++] = ( rr ); break; } else if (( &p->error_reductions )->v == (( &p->error_reductions )->e)) { if ((( &p->error_reductions )->n < 3 )) { ( &p->error_reductions )->v[( &p->error_reductions )->n++] = ( rr ); break; } } else if (( &p->error_reductions )->n & ((1 << 3 ) - 1)) { ( &p->error_reductions )->v[( &p->error_reductions )->n++] = ( rr ); break; } vec_add_internal(( &p->error_reductions ), rr ); } while (0) ; rr->nelements = best_er->depth; rr->symbol = best_er->symbol; best_loc.s = best_s; (( best_sn )->zns.v[0]->pn) ->parse_node.skip_space( &best_loc, (void**)& (( best_sn )->zns.v[0]->pn) ->parse_node.globals); do { ( best_sn )->refcount++; } while (0) ; if (rr->nelements) free_old_nodes(p); for (i = 0; i < (rr->nelements ? best_sn->zns.n : 1); i++) { Reduction *r = malloc (sizeof(*r)); best_sn->loc = best_loc; if (i) do { ( best_sn )->refcount++; } while (0) ; if (rr->nelements) r->znode = best_sn->zns.v[i]; else r->znode = 0 ; r->snode = best_sn; r->reduction = rr; r->new_snode = 0 ; r->next = 0 ; reduce_one(p, r); } if (p->shifts_todo || p->reductions_todo) res = 0; } free (q); return res; } static int exhaustive_parse(Parser *p) { Reduction *r; Shift *s; char *pos, *epos = 0 ; PNode *pn, tpn; SNode *sn; ZNode *z; int progress = 0; d_loc_t loc; p->reductions_todo = 0 ; p->shifts_todo = 0 ; loc = p->user.loc; loc.s = pos = p->start; skip_space(&loc, &p->user.initial_globals); sn = add_SNode(p, p->t->state, &loc); memset(&tpn, 0, sizeof(tpn)); tpn.parse_node.skip_space = &skip_space; tpn.parse_node.globals = p->user.initial_globals; pn = add_PNode(p, 0, p->start-1, loc.line, p->start-1, &tpn, 0, 0, 0); sn->last_pn = pn; set_add_znode(&sn->zns, (z = new_ZNode(p, pn))); do { ( pn )->refcount++; } while (0) ; while (1) { while (p->reductions_todo) { pos = p->reductions_todo->snode->loc.s; if (p->shifts_todo && p->shifts_todo->snode->loc.s < pos) break; if (pos > epos) { epos = pos; free_old_nodes(p); } for (;(r = p->reductions_todo) && r->snode->loc.s == pos;) { p->reductions_todo = p->reductions_todo->next; reduce_one(p, r); } } cmp_stacks(p); if (!p->shifts_todo) { if (p->accepts.n) return 0; else { if (p->snode_hash.last_all) p->user.loc = p->snode_hash.last_all->loc; if (error_recovery(p)) return 1; continue; } } progress++; if (progress > 100 && !p->shifts_todo->next) { commit_stack(p, p->shifts_todo->snode); progress = 0; } pos = p->shifts_todo->snode->loc.s; if (pos > epos) { epos = pos; free_old_nodes(p); } for (; (s = p->shifts_todo) && s->snode->loc.s == pos;) { p->shifts_todo = p->shifts_todo->next; shift_one(p, s); } } } D_Parser * new_D_Parser(D_ParserTables *t) { Parser *p = malloc (sizeof(Parser)); memset(p, 0, sizeof(Parser)); p->t = t; p->user.loc.line = 1; return (D_Parser*)p; } void free_D_ParseNode(D_ParseNode *dpn) { if (dpn != ((D_ParseNode*)0x1) ) do { if (!--( ((PNode *)(((char*)dpn)-(int)(&((PNode*)0)->parse_node))) )->refcount) free_PNode( 0 , ((PNode *)(((char*)dpn)-(int)(&((PNode*)0)->parse_node))) ); } while (0) ; } D_ParseNode * dparse(D_Parser *ap, char *buf, int buf_len) { int r, i; Parser *p = (Parser *)ap; SNode *ps; PNode *pn; D_ParseNode *res = 0 ; p->states = p->scans = p->shifts = p->reductions = p->compares = 0; p->start = buf; p->end = buf + buf_len; alloc_parser_working_data(p); r = exhaustive_parse(p); if (!r) { ps = p->accepts.v[0]; pn = ps->last_pn; commit_tree(p, pn); if (verbose_level) { printf( "%d states %d scans %d shifts %d reductions " "%d compares %d ambiguities\n", p->states, p->scans, p->shifts, p->reductions, p->compares, p->ambiguities); if (p->user.save_parse_tree) { print_paren(pn); printf("\n"); } } if (p->user.save_parse_tree) { do { ( pn )->refcount++; } while (0) ; res = &pn->parse_node; } else res = ((D_ParseNode*)0x1) ; for (i = 0; i < p->accepts.n; i++) do { if (!--( p->accepts.v[i] )->refcount) free_SNode( 0 , p->accepts.v[i] ); } while (0) ; do { if (( &p->accepts )->v && ( &p->accepts )->v != ( &p->accepts )->e) free (( &p->accepts )->v); do { ( &p->accepts )->n = 0; ( &p->accepts )->v = 0; } while(0) ; } while(0) ; } else do { if (( &p->accepts )->v && ( &p->accepts )->v != ( &p->accepts )->e) free (( &p->accepts )->v); do { ( &p->accepts )->n = 0; ( &p->accepts )->v = 0; } while(0) ; } while(0) ; free_parser_working_data(p); return res; }