Convert all the things to Unix format.
This commit is contained in:
parent
020c84db3d
commit
9519588f59
|
@ -1,4 +1,4 @@
|
||||||
---
|
---
|
||||||
AlignAfterOpenBracket: AlwaysBreak
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
AllowShortFunctionsOnASingleLine: false
|
AllowShortFunctionsOnASingleLine: false
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
|
|
@ -1,135 +1,135 @@
|
||||||
!File: lint.h
|
!File: lint.h
|
||||||
/*#define LINT 1 *//* if defined, 'lint' is produced */
|
/*#define LINT 1 *//* if defined, 'lint' is produced */
|
||||||
|
|
||||||
|
|
||||||
!File: pathlength.h
|
!File: pathlength.h
|
||||||
#define PATHLENGTH 1024 /* max. length of path to file */
|
#define PATHLENGTH 1024 /* max. length of path to file */
|
||||||
|
|
||||||
|
|
||||||
!File: errout.h
|
!File: errout.h
|
||||||
#define ERROUT STDERR /* file pointer for writing messages */
|
#define ERROUT STDERR /* file pointer for writing messages */
|
||||||
#define ERR_SHADOW 5 /* a syntax error overshadows error messages
|
#define ERR_SHADOW 5 /* a syntax error overshadows error messages
|
||||||
until ERR_SHADOW symbols have been
|
until ERR_SHADOW symbols have been
|
||||||
accepted without syntax error */
|
accepted without syntax error */
|
||||||
|
|
||||||
|
|
||||||
!File: idfsize.h
|
!File: idfsize.h
|
||||||
#define IDFSIZE 64 /* maximum significant length of an identifier */
|
#define IDFSIZE 64 /* maximum significant length of an identifier */
|
||||||
|
|
||||||
|
|
||||||
!File: numsize.h
|
!File: numsize.h
|
||||||
#define NUMSIZE 256 /* maximum length of a numeric constant */
|
#define NUMSIZE 256 /* maximum length of a numeric constant */
|
||||||
|
|
||||||
|
|
||||||
!File: nparams.h
|
!File: nparams.h
|
||||||
#define NPARAMS 32 /* maximum number of parameters */
|
#define NPARAMS 32 /* maximum number of parameters */
|
||||||
#define STDC_NPARAMS 31 /* ANSI limit on number of parameters */
|
#define STDC_NPARAMS 31 /* ANSI limit on number of parameters */
|
||||||
|
|
||||||
|
|
||||||
!File: ifdepth.h
|
!File: ifdepth.h
|
||||||
#define IFDEPTH 256 /* maximum number of nested if-constructions */
|
#define IFDEPTH 256 /* maximum number of nested if-constructions */
|
||||||
|
|
||||||
|
|
||||||
!File: density.h
|
!File: density.h
|
||||||
#define DENSITY 3 /* see switch.[ch] for an explanation */
|
#define DENSITY 3 /* see switch.[ch] for an explanation */
|
||||||
|
|
||||||
|
|
||||||
!File: macbuf.h
|
!File: macbuf.h
|
||||||
#define LAPBUF 128 /* initial size of macro replacement buffer */
|
#define LAPBUF 128 /* initial size of macro replacement buffer */
|
||||||
#define ARGBUF 128 /* initial size of macro parameter buffer(s) */
|
#define ARGBUF 128 /* initial size of macro parameter buffer(s) */
|
||||||
|
|
||||||
|
|
||||||
!File: strsize.h
|
!File: strsize.h
|
||||||
#define ISTRSIZE 32 /* minimum number of bytes allocated for
|
#define ISTRSIZE 32 /* minimum number of bytes allocated for
|
||||||
storing a string */
|
storing a string */
|
||||||
#define RSTRSIZE 16 /* step size in enlarging the memory for
|
#define RSTRSIZE 16 /* step size in enlarging the memory for
|
||||||
the storage of a string */
|
the storage of a string */
|
||||||
|
|
||||||
|
|
||||||
!File: trgt_sizes.h
|
!File: trgt_sizes.h
|
||||||
#define MAXSIZE 8 /* the maximum of the SZ_* constants */
|
#define MAXSIZE 8 /* the maximum of the SZ_* constants */
|
||||||
|
|
||||||
/* target machine sizes */
|
/* target machine sizes */
|
||||||
#define SZ_CHAR 1
|
#define SZ_CHAR 1
|
||||||
#define SZ_SHORT 2
|
#define SZ_SHORT 2
|
||||||
#define SZ_WORD 4
|
#define SZ_WORD 4
|
||||||
#define SZ_INT 4
|
#define SZ_INT 4
|
||||||
#define SZ_LONG 4
|
#define SZ_LONG 4
|
||||||
#define SZ_LNGLNG -1
|
#define SZ_LNGLNG -1
|
||||||
#define SZ_FLOAT 4
|
#define SZ_FLOAT 4
|
||||||
#define SZ_DOUBLE 8
|
#define SZ_DOUBLE 8
|
||||||
#define SZ_LNGDBL 8 /* for now */
|
#define SZ_LNGDBL 8 /* for now */
|
||||||
#define SZ_POINTER 4
|
#define SZ_POINTER 4
|
||||||
|
|
||||||
/* target machine alignment requirements */
|
/* target machine alignment requirements */
|
||||||
#define AL_CHAR 1
|
#define AL_CHAR 1
|
||||||
#define AL_SHORT SZ_SHORT
|
#define AL_SHORT SZ_SHORT
|
||||||
#define AL_WORD SZ_WORD
|
#define AL_WORD SZ_WORD
|
||||||
#define AL_INT SZ_WORD
|
#define AL_INT SZ_WORD
|
||||||
#define AL_LONG SZ_WORD
|
#define AL_LONG SZ_WORD
|
||||||
#define AL_LNGLNG SZ_WORD
|
#define AL_LNGLNG SZ_WORD
|
||||||
#define AL_FLOAT SZ_WORD
|
#define AL_FLOAT SZ_WORD
|
||||||
#define AL_DOUBLE SZ_WORD
|
#define AL_DOUBLE SZ_WORD
|
||||||
#define AL_LNGDBL SZ_WORD
|
#define AL_LNGDBL SZ_WORD
|
||||||
#define AL_POINTER SZ_WORD
|
#define AL_POINTER SZ_WORD
|
||||||
#define AL_STRUCT 1
|
#define AL_STRUCT 1
|
||||||
#define AL_UNION 1
|
#define AL_UNION 1
|
||||||
|
|
||||||
|
|
||||||
!File: botch_free.h
|
!File: botch_free.h
|
||||||
/*#define BOTCH_FREE 1* *//* when defined, botch freed memory, as a check */
|
/*#define BOTCH_FREE 1* *//* when defined, botch freed memory, as a check */
|
||||||
|
|
||||||
|
|
||||||
!File: dataflow.h
|
!File: dataflow.h
|
||||||
#define DATAFLOW 1 /* produce some compile-time xref */
|
#define DATAFLOW 1 /* produce some compile-time xref */
|
||||||
|
|
||||||
|
|
||||||
!File: debug.h
|
!File: debug.h
|
||||||
/*#define DEBUG 1 *//* perform various self-tests */
|
/*#define DEBUG 1 *//* perform various self-tests */
|
||||||
#define NDEBUG 1 /* disable assertions */
|
#define NDEBUG 1 /* disable assertions */
|
||||||
|
|
||||||
|
|
||||||
!File: use_tmp.h
|
!File: use_tmp.h
|
||||||
#define PREPEND_SCOPES 1 /* collect exa, exp, ina and inp commands
|
#define PREPEND_SCOPES 1 /* collect exa, exp, ina and inp commands
|
||||||
and if USE_TMP is defined let them
|
and if USE_TMP is defined let them
|
||||||
precede the rest of the generated
|
precede the rest of the generated
|
||||||
compact code */
|
compact code */
|
||||||
#define USE_TMP 1 /* use C_insertpart, C_endpart mechanism
|
#define USE_TMP 1 /* use C_insertpart, C_endpart mechanism
|
||||||
to generate EM-code in the order needed
|
to generate EM-code in the order needed
|
||||||
for the code-generators. If not defined,
|
for the code-generators. If not defined,
|
||||||
the old-style peephole optimizer is
|
the old-style peephole optimizer is
|
||||||
needed. */
|
needed. */
|
||||||
|
|
||||||
|
|
||||||
!File: parbufsize.h
|
!File: parbufsize.h
|
||||||
#define PARBUFSIZE 1024
|
#define PARBUFSIZE 1024
|
||||||
|
|
||||||
|
|
||||||
!File: textsize.h
|
!File: textsize.h
|
||||||
#define ITEXTSIZE 32 /* 1st piece of memory for repl. text */
|
#define ITEXTSIZE 32 /* 1st piece of memory for repl. text */
|
||||||
|
|
||||||
|
|
||||||
!File: inputtype.h
|
!File: inputtype.h
|
||||||
#define INP_READ_IN_ONE 1 /* read input file in one */
|
#define INP_READ_IN_ONE 1 /* read input file in one */
|
||||||
|
|
||||||
|
|
||||||
!File: nobitfield.h
|
!File: nobitfield.h
|
||||||
/*#define NOBITFIELD 1 *//* if NOT defined, implement bitfields */
|
/*#define NOBITFIELD 1 *//* if NOT defined, implement bitfields */
|
||||||
|
|
||||||
|
|
||||||
!File: static.h
|
!File: static.h
|
||||||
#define GSTATIC /* for large global "static" arrays */
|
#define GSTATIC /* for large global "static" arrays */
|
||||||
|
|
||||||
|
|
||||||
!File: nocross.h
|
!File: nocross.h
|
||||||
/*#define NOCROSS 1 *//* if NOT defined, cross compiler */
|
/*#define NOCROSS 1 *//* if NOT defined, cross compiler */
|
||||||
|
|
||||||
|
|
||||||
!File: regcount.h
|
!File: regcount.h
|
||||||
/*#define REGCOUNT 1 *//* count occurrences for register messages */
|
/*#define REGCOUNT 1 *//* count occurrences for register messages */
|
||||||
|
|
||||||
|
|
||||||
!File: dbsymtab.h
|
!File: dbsymtab.h
|
||||||
#define DBSYMTAB 1 /* ability to produce symbol table for debugger */
|
#define DBSYMTAB 1 /* ability to produce symbol table for debugger */
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,354 +1,354 @@
|
||||||
/*
|
/*
|
||||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/* EXPRESSION SYNTAX PARSER */
|
/* EXPRESSION SYNTAX PARSER */
|
||||||
|
|
||||||
{
|
{
|
||||||
#include <alloc.h>
|
#include <alloc.h>
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include <flt_arith.h>
|
#include <flt_arith.h>
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "code.h"
|
#include "code.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "ch3.h"
|
#include "ch3.h"
|
||||||
#include "ch3bin.h"
|
#include "ch3bin.h"
|
||||||
#include "ch3mon.h"
|
#include "ch3mon.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "sizes.h"
|
#include "sizes.h"
|
||||||
|
|
||||||
extern struct expr *intexpr();
|
extern struct expr *intexpr();
|
||||||
int InSizeof = 0; /* inside a sizeof- expression */
|
int InSizeof = 0; /* inside a sizeof- expression */
|
||||||
int ResultKnown = 0; /* result of the expression is already known */
|
int ResultKnown = 0; /* result of the expression is already known */
|
||||||
|
|
||||||
/* Since the grammar in the standard is not LL(n), it is modified so that
|
/* Since the grammar in the standard is not LL(n), it is modified so that
|
||||||
* it accepts basically the same grammar. This means that there is no 1-1
|
* it accepts basically the same grammar. This means that there is no 1-1
|
||||||
* mapping from the grammar in the standard to the grammar given here.
|
* mapping from the grammar in the standard to the grammar given here.
|
||||||
* Such is life.
|
* Such is life.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3.3.1 */
|
/* 3.3.1 */
|
||||||
primary(register struct expr **expp;) :
|
primary(register struct expr **expp;) :
|
||||||
IDENTIFIER
|
IDENTIFIER
|
||||||
{dot2expr(expp);}
|
{dot2expr(expp);}
|
||||||
|
|
|
|
||||||
constant(expp)
|
constant(expp)
|
||||||
|
|
|
|
||||||
string(expp)
|
string(expp)
|
||||||
|
|
|
|
||||||
'(' expression(expp) ')'
|
'(' expression(expp) ')'
|
||||||
{ (*expp)->ex_flags |= EX_PARENS; }
|
{ (*expp)->ex_flags |= EX_PARENS; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
/* Character string literals that are adjacent tokens
|
/* Character string literals that are adjacent tokens
|
||||||
* are concatenated into a single character string
|
* are concatenated into a single character string
|
||||||
* literal.
|
* literal.
|
||||||
*/
|
*/
|
||||||
string(register struct expr **expp;)
|
string(register struct expr **expp;)
|
||||||
{ register int i, len;
|
{ register int i, len;
|
||||||
register char *str;
|
register char *str;
|
||||||
register int fund;
|
register int fund;
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
STRING
|
STRING
|
||||||
{ str = dot.tk_bts;
|
{ str = dot.tk_bts;
|
||||||
len = dot.tk_len;
|
len = dot.tk_len;
|
||||||
fund = dot.tk_fund;
|
fund = dot.tk_fund;
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
STRING
|
STRING
|
||||||
{ /* A pasted string keeps the type of the first
|
{ /* A pasted string keeps the type of the first
|
||||||
* string literal.
|
* string literal.
|
||||||
* The pasting of normal strings and wide
|
* The pasting of normal strings and wide
|
||||||
* character strings are stated as having an
|
* character strings are stated as having an
|
||||||
* undefined behaviour.
|
* undefined behaviour.
|
||||||
*/
|
*/
|
||||||
if (dot.tk_fund != fund)
|
if (dot.tk_fund != fund)
|
||||||
warning("illegal pasting of string literals");
|
warning("illegal pasting of string literals");
|
||||||
str = Realloc(str, (unsigned) (--len + dot.tk_len));
|
str = Realloc(str, (unsigned) (--len + dot.tk_len));
|
||||||
for (i = 0; i < dot.tk_len; i++)
|
for (i = 0; i < dot.tk_len; i++)
|
||||||
str[len++] = dot.tk_bts[i];
|
str[len++] = dot.tk_bts[i];
|
||||||
}
|
}
|
||||||
]*
|
]*
|
||||||
{ string2expr(expp, str, len); }
|
{ string2expr(expp, str, len); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* 3.3.2 */
|
/* 3.3.2 */
|
||||||
postfix_expression(register struct expr **expp;)
|
postfix_expression(register struct expr **expp;)
|
||||||
{ int oper;
|
{ int oper;
|
||||||
struct expr *e1 = 0;
|
struct expr *e1 = 0;
|
||||||
struct idf *idf;
|
struct idf *idf;
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
primary(expp)
|
primary(expp)
|
||||||
[
|
[
|
||||||
'[' expression(&e1) ']'
|
'[' expression(&e1) ']'
|
||||||
{ ch3bin(expp, '[', e1); e1 = 0; }
|
{ ch3bin(expp, '[', e1); e1 = 0; }
|
||||||
|
|
|
|
||||||
'(' parameter_list(&e1)? ')'
|
'(' parameter_list(&e1)? ')'
|
||||||
{ ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; }
|
{ ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; }
|
||||||
|
|
|
|
||||||
[ '.' | ARROW ] { oper = DOT; }
|
[ '.' | ARROW ] { oper = DOT; }
|
||||||
identifier(&idf) { ch3sel(expp, oper, idf); }
|
identifier(&idf) { ch3sel(expp, oper, idf); }
|
||||||
|
|
|
|
||||||
[
|
[
|
||||||
PLUSPLUS { oper = POSTINCR; }
|
PLUSPLUS { oper = POSTINCR; }
|
||||||
|
|
|
|
||||||
MINMIN { oper = POSTDECR; }
|
MINMIN { oper = POSTDECR; }
|
||||||
]
|
]
|
||||||
{ ch3incr(expp, oper); }
|
{ ch3incr(expp, oper); }
|
||||||
]*
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
parameter_list(struct expr **expp;)
|
parameter_list(struct expr **expp;)
|
||||||
{struct expr *e1 = 0;}
|
{struct expr *e1 = 0;}
|
||||||
:
|
:
|
||||||
assignment_expression(expp)
|
assignment_expression(expp)
|
||||||
{any2opnd(expp, PARCOMMA);}
|
{any2opnd(expp, PARCOMMA);}
|
||||||
[ %persistent
|
[ %persistent
|
||||||
','
|
','
|
||||||
assignment_expression(&e1)
|
assignment_expression(&e1)
|
||||||
{any2opnd(&e1, PARCOMMA);}
|
{any2opnd(&e1, PARCOMMA);}
|
||||||
{ch3bin(expp, PARCOMMA, e1);}
|
{ch3bin(expp, PARCOMMA, e1);}
|
||||||
]*
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
%first first_of_type_specifier, type_specifier;
|
%first first_of_type_specifier, type_specifier;
|
||||||
|
|
||||||
/* 3.3.3 & 3.3.4 */
|
/* 3.3.3 & 3.3.4 */
|
||||||
unary(register struct expr **expp;)
|
unary(register struct expr **expp;)
|
||||||
{struct type *tp; int oper;}
|
{struct type *tp; int oper;}
|
||||||
:
|
:
|
||||||
%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
|
%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
|
||||||
cast(&tp) unary(expp)
|
cast(&tp) unary(expp)
|
||||||
{ ch3cast(expp, CAST, tp);
|
{ ch3cast(expp, CAST, tp);
|
||||||
(*expp)->ex_flags |= EX_CAST;
|
(*expp)->ex_flags |= EX_CAST;
|
||||||
if (int_size != pointer_size)
|
if (int_size != pointer_size)
|
||||||
(*expp)->ex_flags &= ~EX_PTRDIFF;
|
(*expp)->ex_flags &= ~EX_PTRDIFF;
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
postfix_expression(expp)
|
postfix_expression(expp)
|
||||||
|
|
|
|
||||||
unop(&oper) unary(expp)
|
unop(&oper) unary(expp)
|
||||||
{ch3mon(oper, expp);}
|
{ch3mon(oper, expp);}
|
||||||
|
|
|
|
||||||
size_of(expp)
|
size_of(expp)
|
||||||
;
|
;
|
||||||
|
|
||||||
/* When an identifier is used in a sizeof()-expression, we must stil not
|
/* When an identifier is used in a sizeof()-expression, we must stil not
|
||||||
* mark it as used.
|
* mark it as used.
|
||||||
* extern int i; .... sizeof(i) .... need not have a definition for i
|
* extern int i; .... sizeof(i) .... need not have a definition for i
|
||||||
*/
|
*/
|
||||||
size_of(register struct expr **expp;)
|
size_of(register struct expr **expp;)
|
||||||
{struct type *tp;}
|
{struct type *tp;}
|
||||||
:
|
:
|
||||||
SIZEOF { InSizeof++; } /* handle (sizeof(sizeof(int))) too */
|
SIZEOF { InSizeof++; } /* handle (sizeof(sizeof(int))) too */
|
||||||
[%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
|
[%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
|
||||||
cast(&tp)
|
cast(&tp)
|
||||||
{
|
{
|
||||||
*expp = intexpr(size_of_type(tp, "type"), UNSIGNED);
|
*expp = intexpr(size_of_type(tp, "type"), UNSIGNED);
|
||||||
(*expp)->ex_flags |= EX_SIZEOF;
|
(*expp)->ex_flags |= EX_SIZEOF;
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
unary(expp)
|
unary(expp)
|
||||||
{ch3mon(SIZEOF, expp);}
|
{ch3mon(SIZEOF, expp);}
|
||||||
]
|
]
|
||||||
{ InSizeof--; }
|
{ InSizeof--; }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* 3.3.5-3.3.17 */
|
/* 3.3.5-3.3.17 */
|
||||||
/* The set of operators in C is stratified in 15 levels, with level
|
/* The set of operators in C is stratified in 15 levels, with level
|
||||||
N being treated in RM 7.N (although this is not the standard
|
N being treated in RM 7.N (although this is not the standard
|
||||||
anymore). The standard describes this in phrase-structure-grammar,
|
anymore). The standard describes this in phrase-structure-grammar,
|
||||||
which we are unable to parse. The description that follows comes
|
which we are unable to parse. The description that follows comes
|
||||||
from the old C-compiler.
|
from the old C-compiler.
|
||||||
|
|
||||||
In principle each operator is assigned a rank, ranging
|
In principle each operator is assigned a rank, ranging
|
||||||
from 1 to 15. Such an expression can be parsed by a construct
|
from 1 to 15. Such an expression can be parsed by a construct
|
||||||
like:
|
like:
|
||||||
binary_expression(int maxrank;)
|
binary_expression(int maxrank;)
|
||||||
{int oper;}
|
{int oper;}
|
||||||
:
|
:
|
||||||
binary_expression(maxrank - 1)
|
binary_expression(maxrank - 1)
|
||||||
[%if (rank_of(DOT) <= maxrank)
|
[%if (rank_of(DOT) <= maxrank)
|
||||||
binop(&oper)
|
binop(&oper)
|
||||||
binary_expression(rank_of(oper)-1)
|
binary_expression(rank_of(oper)-1)
|
||||||
]?
|
]?
|
||||||
;
|
;
|
||||||
except that some call of 'unary' is necessary, depending on the
|
except that some call of 'unary' is necessary, depending on the
|
||||||
grammar.
|
grammar.
|
||||||
|
|
||||||
This simple view is marred by three complications:
|
This simple view is marred by three complications:
|
||||||
1. Level 15 (comma operator) is not allowed in many
|
1. Level 15 (comma operator) is not allowed in many
|
||||||
contexts and is different.
|
contexts and is different.
|
||||||
2. Level 13 (conditional operator) is a ternary operator,
|
2. Level 13 (conditional operator) is a ternary operator,
|
||||||
which does not fit this scheme at all.
|
which does not fit this scheme at all.
|
||||||
3. Level 14 (assignment operators) group right-to-left, as
|
3. Level 14 (assignment operators) group right-to-left, as
|
||||||
opposed to 2-12, which group left-to-right (or are
|
opposed to 2-12, which group left-to-right (or are
|
||||||
immaterial).
|
immaterial).
|
||||||
4. The operators in level 14 start with operators in levels
|
4. The operators in level 14 start with operators in levels
|
||||||
2-13 (RM 7.14: The two parts of a compound assignment
|
2-13 (RM 7.14: The two parts of a compound assignment
|
||||||
operator are separate tokens.) This causes LL1 problems.
|
operator are separate tokens.) This causes LL1 problems.
|
||||||
This forces us to have four rules:
|
This forces us to have four rules:
|
||||||
binary_expression for level 2-12
|
binary_expression for level 2-12
|
||||||
conditional_expression for level 13
|
conditional_expression for level 13
|
||||||
assignment_expression for level 14 and
|
assignment_expression for level 14 and
|
||||||
expression for the most general expression
|
expression for the most general expression
|
||||||
*/
|
*/
|
||||||
|
|
||||||
binary_expression(int maxrank; struct expr **expp;)
|
binary_expression(int maxrank; struct expr **expp;)
|
||||||
{int oper, OldResultKnown; struct expr *e1;}
|
{int oper, OldResultKnown; struct expr *e1;}
|
||||||
:
|
:
|
||||||
unary(expp)
|
unary(expp)
|
||||||
[%while (rank_of(DOT) <= maxrank )
|
[%while (rank_of(DOT) <= maxrank )
|
||||||
/* '?', '=', and ',' are no binops
|
/* '?', '=', and ',' are no binops
|
||||||
*/
|
*/
|
||||||
binop(&oper)
|
binop(&oper)
|
||||||
{ OldResultKnown = ResultKnown;
|
{ OldResultKnown = ResultKnown;
|
||||||
if (oper == OR || oper == AND) {
|
if (oper == OR || oper == AND) {
|
||||||
if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
|
if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
|
||||||
if (is_zero_cst(*expp)) {
|
if (is_zero_cst(*expp)) {
|
||||||
if (oper == AND) ResultKnown++;
|
if (oper == AND) ResultKnown++;
|
||||||
} else if (oper == OR) ResultKnown++;
|
} else if (oper == OR) ResultKnown++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binary_expression(rank_of(oper)-1, &e1)
|
binary_expression(rank_of(oper)-1, &e1)
|
||||||
{
|
{
|
||||||
ch3bin(expp, oper, e1);
|
ch3bin(expp, oper, e1);
|
||||||
ResultKnown = OldResultKnown;
|
ResultKnown = OldResultKnown;
|
||||||
}
|
}
|
||||||
]*
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
/* 3.3.15 */
|
/* 3.3.15 */
|
||||||
conditional_expression(struct expr **expp;)
|
conditional_expression(struct expr **expp;)
|
||||||
{struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;}
|
{struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;}
|
||||||
:
|
:
|
||||||
/* allow all binary operators */
|
/* allow all binary operators */
|
||||||
binary_expression(rank_of('?') - 1, expp)
|
binary_expression(rank_of('?') - 1, expp)
|
||||||
[ '?'
|
[ '?'
|
||||||
{ OldResultKnown = ResultKnown;
|
{ OldResultKnown = ResultKnown;
|
||||||
if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
|
if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
|
||||||
ConstExpr++;
|
ConstExpr++;
|
||||||
if (is_zero_cst(*expp)) ResultKnown++;
|
if (is_zero_cst(*expp)) ResultKnown++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expression(&e1)
|
expression(&e1)
|
||||||
':'
|
':'
|
||||||
{ if (ConstExpr) {
|
{ if (ConstExpr) {
|
||||||
if (OldResultKnown == ResultKnown) ResultKnown++;
|
if (OldResultKnown == ResultKnown) ResultKnown++;
|
||||||
else ResultKnown = OldResultKnown;
|
else ResultKnown = OldResultKnown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conditional_expression(&e2)
|
conditional_expression(&e2)
|
||||||
{
|
{
|
||||||
ResultKnown = OldResultKnown;
|
ResultKnown = OldResultKnown;
|
||||||
ch3bin(&e1, ':', e2);
|
ch3bin(&e1, ':', e2);
|
||||||
opnd2test(expp, '?');
|
opnd2test(expp, '?');
|
||||||
ch3bin(expp, '?', e1);
|
ch3bin(expp, '?', e1);
|
||||||
}
|
}
|
||||||
]?
|
]?
|
||||||
;
|
;
|
||||||
|
|
||||||
/* 3.3.16 */
|
/* 3.3.16 */
|
||||||
assignment_expression(struct expr **expp;)
|
assignment_expression(struct expr **expp;)
|
||||||
{ int oper;
|
{ int oper;
|
||||||
struct expr *e1 = 0;
|
struct expr *e1 = 0;
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
conditional_expression(expp)
|
conditional_expression(expp)
|
||||||
[
|
[
|
||||||
asgnop(&oper)
|
asgnop(&oper)
|
||||||
assignment_expression(&e1)
|
assignment_expression(&e1)
|
||||||
{ch3asgn(expp, oper, e1);}
|
{ch3asgn(expp, oper, e1);}
|
||||||
|
|
|
|
||||||
empty /* LLgen artefact ??? */
|
empty /* LLgen artefact ??? */
|
||||||
]
|
]
|
||||||
;
|
;
|
||||||
|
|
||||||
/* 3.3.17 */
|
/* 3.3.17 */
|
||||||
expression(struct expr **expp;)
|
expression(struct expr **expp;)
|
||||||
{struct expr *e1;}
|
{struct expr *e1;}
|
||||||
:
|
:
|
||||||
assignment_expression(expp)
|
assignment_expression(expp)
|
||||||
[ ','
|
[ ','
|
||||||
assignment_expression(&e1)
|
assignment_expression(&e1)
|
||||||
{
|
{
|
||||||
ch3bin(expp, ',', e1);
|
ch3bin(expp, ',', e1);
|
||||||
}
|
}
|
||||||
]*
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
unop(int *oper;) :
|
unop(int *oper;) :
|
||||||
['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN]
|
['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN]
|
||||||
{ if (DOT == '&') DOT = ADDRESSOF;
|
{ if (DOT == '&') DOT = ADDRESSOF;
|
||||||
*oper = DOT;
|
*oper = DOT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
multop:
|
multop:
|
||||||
'*' | '/' | '%'
|
'*' | '/' | '%'
|
||||||
;
|
;
|
||||||
|
|
||||||
addop:
|
addop:
|
||||||
'+' | '-'
|
'+' | '-'
|
||||||
;
|
;
|
||||||
|
|
||||||
shiftop:
|
shiftop:
|
||||||
LEFT | RIGHT
|
LEFT | RIGHT
|
||||||
;
|
;
|
||||||
|
|
||||||
relop:
|
relop:
|
||||||
'<' | '>' | LESSEQ | GREATEREQ
|
'<' | '>' | LESSEQ | GREATEREQ
|
||||||
;
|
;
|
||||||
|
|
||||||
eqop:
|
eqop:
|
||||||
EQUAL | NOTEQUAL
|
EQUAL | NOTEQUAL
|
||||||
;
|
;
|
||||||
|
|
||||||
arithop:
|
arithop:
|
||||||
multop | addop | shiftop
|
multop | addop | shiftop
|
||||||
|
|
|
|
||||||
'&' | '^' | '|'
|
'&' | '^' | '|'
|
||||||
;
|
;
|
||||||
|
|
||||||
binop(int *oper;) :
|
binop(int *oper;) :
|
||||||
[ arithop | relop | eqop | AND | OR ]
|
[ arithop | relop | eqop | AND | OR ]
|
||||||
{*oper = DOT;}
|
{*oper = DOT;}
|
||||||
;
|
;
|
||||||
|
|
||||||
asgnop(register int *oper;):
|
asgnop(register int *oper;):
|
||||||
[ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB
|
[ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB
|
||||||
| LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]
|
| LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]
|
||||||
{ *oper = DOT; }
|
{ *oper = DOT; }
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
constant(struct expr **expp;) :
|
constant(struct expr **expp;) :
|
||||||
[
|
[
|
||||||
INTEGER
|
INTEGER
|
||||||
|
|
|
|
||||||
FLOATING
|
FLOATING
|
||||||
] {dot2expr(expp);}
|
] {dot2expr(expp);}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* 3.4 */
|
/* 3.4 */
|
||||||
constant_expression (struct expr **expp;) :
|
constant_expression (struct expr **expp;) :
|
||||||
conditional_expression(expp)
|
conditional_expression(expp)
|
||||||
{ chk_cst_expr(expp); }
|
{ chk_cst_expr(expp); }
|
||||||
;
|
;
|
||||||
|
|
||||||
identifier(struct idf **idfp;) :
|
identifier(struct idf **idfp;) :
|
||||||
[ IDENTIFIER
|
[ IDENTIFIER
|
||||||
| TYPE_IDENTIFIER
|
| TYPE_IDENTIFIER
|
||||||
]
|
]
|
||||||
{ *idfp = dot.tk_idf; }
|
{ *idfp = dot.tk_idf; }
|
||||||
;
|
;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,227 +1,227 @@
|
||||||
/*
|
/*
|
||||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/* PROGRAM PARSER */
|
/* PROGRAM PARSER */
|
||||||
|
|
||||||
/* The presence of typedef declarations renders it impossible to
|
/* The presence of typedef declarations renders it impossible to
|
||||||
make a context-free grammar of C. Consequently we need
|
make a context-free grammar of C. Consequently we need
|
||||||
context-sensitive parsing techniques, the simplest one being
|
context-sensitive parsing techniques, the simplest one being
|
||||||
a subtle cooperation between the parser and the lexical scanner.
|
a subtle cooperation between the parser and the lexical scanner.
|
||||||
The lexical scanner has to know whether to return IDENTIFIER
|
The lexical scanner has to know whether to return IDENTIFIER
|
||||||
or TYPE_IDENTIFIER for a given tag, and it obtains this information
|
or TYPE_IDENTIFIER for a given tag, and it obtains this information
|
||||||
from the definition list, as constructed by the parser.
|
from the definition list, as constructed by the parser.
|
||||||
The present grammar is essentially LL(2), and is processed by
|
The present grammar is essentially LL(2), and is processed by
|
||||||
a parser generator which accepts LL(1) with tie breaking rules
|
a parser generator which accepts LL(1) with tie breaking rules
|
||||||
in C, of the form %if(cond) and %while(cond). To solve the LL(1)
|
in C, of the form %if(cond) and %while(cond). To solve the LL(1)
|
||||||
ambiguities, the lexical scanner does a one symbol look-ahead.
|
ambiguities, the lexical scanner does a one symbol look-ahead.
|
||||||
This symbol, however, cannot always be correctly assessed, since
|
This symbol, however, cannot always be correctly assessed, since
|
||||||
the present symbol may cause a change in the definition list
|
the present symbol may cause a change in the definition list
|
||||||
which causes the identification of the look-ahead symbol to be
|
which causes the identification of the look-ahead symbol to be
|
||||||
invalidated.
|
invalidated.
|
||||||
The lexical scanner relies on the parser (or its routines) to
|
The lexical scanner relies on the parser (or its routines) to
|
||||||
detect this situation and then update the look-ahead symbol.
|
detect this situation and then update the look-ahead symbol.
|
||||||
An alternative approach would be to reassess the look-ahead symbol
|
An alternative approach would be to reassess the look-ahead symbol
|
||||||
in the lexical scanner when it is promoted to dot symbol. This
|
in the lexical scanner when it is promoted to dot symbol. This
|
||||||
would be more beautiful but less correct, since then for a short
|
would be more beautiful but less correct, since then for a short
|
||||||
while there would be a discrepancy between the look-ahead symbol
|
while there would be a discrepancy between the look-ahead symbol
|
||||||
and the definition list; I think it would nevertheless work in
|
and the definition list; I think it would nevertheless work in
|
||||||
correct programs.
|
correct programs.
|
||||||
A third solution would be to enter the identifier as soon as it
|
A third solution would be to enter the identifier as soon as it
|
||||||
is found; its storage class is then known, although its full type
|
is found; its storage class is then known, although its full type
|
||||||
isn't. We would have to fill that in afterwards.
|
isn't. We would have to fill that in afterwards.
|
||||||
|
|
||||||
At block exit the situation is even worse. Upon reading the
|
At block exit the situation is even worse. Upon reading the
|
||||||
closing brace, the names declared inside the function are cleared
|
closing brace, the names declared inside the function are cleared
|
||||||
from the name list. This action may expose a type identifier that
|
from the name list. This action may expose a type identifier that
|
||||||
is the same as the identifier in the look-ahead symbol. This
|
is the same as the identifier in the look-ahead symbol. This
|
||||||
situation certainly invalidates the third solution, and casts
|
situation certainly invalidates the third solution, and casts
|
||||||
doubts upon the second.
|
doubts upon the second.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
%lexical LLlex;
|
%lexical LLlex;
|
||||||
%start C_program, program;
|
%start C_program, program;
|
||||||
%start If_expr, control_if_expression;
|
%start If_expr, control_if_expression;
|
||||||
|
|
||||||
{
|
{
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include <flt_arith.h>
|
#include <flt_arith.h>
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "declar.h"
|
#include "declar.h"
|
||||||
#include "decspecs.h"
|
#include "decspecs.h"
|
||||||
#include "code.h"
|
#include "code.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "declarator.h"
|
#include "declarator.h"
|
||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
#include "l_lint.h"
|
#include "l_lint.h"
|
||||||
#endif /* LINT */
|
#endif /* LINT */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
control_if_expression
|
control_if_expression
|
||||||
{
|
{
|
||||||
struct expr *exprX;
|
struct expr *exprX;
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
constant_expression(&exprX)
|
constant_expression(&exprX)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* 3.7 */
|
/* 3.7 */
|
||||||
program:
|
program:
|
||||||
[%persistent external_definition]*
|
[%persistent external_definition]*
|
||||||
{ unstack_world(); }
|
{ unstack_world(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* A C identifier definition is remarkable in that it formulates
|
/* A C identifier definition is remarkable in that it formulates
|
||||||
the declaration in a way different from most other languages:
|
the declaration in a way different from most other languages:
|
||||||
e.g., rather than defining x as a pointer-to-integer, it defines
|
e.g., rather than defining x as a pointer-to-integer, it defines
|
||||||
*x as an integer and lets the compiler deduce that x is actually
|
*x as an integer and lets the compiler deduce that x is actually
|
||||||
pointer-to-integer. This has profound consequences, both for the
|
pointer-to-integer. This has profound consequences, both for the
|
||||||
structure of an identifier definition and for the compiler.
|
structure of an identifier definition and for the compiler.
|
||||||
|
|
||||||
A definition starts with a decl_specifiers, which contains things
|
A definition starts with a decl_specifiers, which contains things
|
||||||
like
|
like
|
||||||
typedef int
|
typedef int
|
||||||
which is implicitly repeated for every definition in the list, and
|
which is implicitly repeated for every definition in the list, and
|
||||||
then for each identifier a declarator is given, of the form
|
then for each identifier a declarator is given, of the form
|
||||||
*a()
|
*a()
|
||||||
or so. The decl_specifiers is kept in a struct decspecs, to be
|
or so. The decl_specifiers is kept in a struct decspecs, to be
|
||||||
used again and again, while the declarator is stored in a struct
|
used again and again, while the declarator is stored in a struct
|
||||||
declarator, only to be passed to declare_idf together with the
|
declarator, only to be passed to declare_idf together with the
|
||||||
struct decspecs.
|
struct decspecs.
|
||||||
|
|
||||||
With the introduction of prototypes, extra problems for the scope
|
With the introduction of prototypes, extra problems for the scope
|
||||||
administration were introduced as well. We can have, for example,
|
administration were introduced as well. We can have, for example,
|
||||||
int x(double x);
|
int x(double x);
|
||||||
and
|
and
|
||||||
int x(double x) { ... use(x) ... }
|
int x(double x) { ... use(x) ... }
|
||||||
In the first case, the parameter name can be forgotten, whereas in
|
In the first case, the parameter name can be forgotten, whereas in
|
||||||
the second case, the parameter should have a block scope. The
|
the second case, the parameter should have a block scope. The
|
||||||
problem lies in the fact that the parameter's type is known before
|
problem lies in the fact that the parameter's type is known before
|
||||||
the type of the function, which causes the def structure to be on
|
the type of the function, which causes the def structure to be on
|
||||||
the end of the list. Our solution is as follows:
|
the end of the list. Our solution is as follows:
|
||||||
1- In case of a declaration, throw the parameter identifier away
|
1- In case of a declaration, throw the parameter identifier away
|
||||||
before the declaration of the outer x.
|
before the declaration of the outer x.
|
||||||
2- In case of a definition, the function begin_proc() changes the
|
2- In case of a definition, the function begin_proc() changes the
|
||||||
def list for the identifier. This means that declare_idf()
|
def list for the identifier. This means that declare_idf()
|
||||||
contains an extra test in case we already saw a declaration of
|
contains an extra test in case we already saw a declaration of
|
||||||
such a function, because this function is called before
|
such a function, because this function is called before
|
||||||
begin_proc().
|
begin_proc().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
external_definition
|
external_definition
|
||||||
{ struct decspecs Ds;
|
{ struct decspecs Ds;
|
||||||
struct declarator Dc;
|
struct declarator Dc;
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
{ Ds = null_decspecs;
|
{ Ds = null_decspecs;
|
||||||
Dc = null_declarator;
|
Dc = null_declarator;
|
||||||
}
|
}
|
||||||
[ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
|
[ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
|
||||||
decl_specifiers(&Ds)
|
decl_specifiers(&Ds)
|
||||||
|
|
|
|
||||||
{do_decspecs(&Ds);}
|
{do_decspecs(&Ds);}
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
declarator(&Dc)
|
declarator(&Dc)
|
||||||
{
|
{
|
||||||
declare_idf(&Ds, &Dc, level);
|
declare_idf(&Ds, &Dc, level);
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
lint_ext_def(Dc.dc_idf, Ds.ds_sc);
|
lint_ext_def(Dc.dc_idf, Ds.ds_sc);
|
||||||
#endif /* LINT */
|
#endif /* LINT */
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
function(&Ds, &Dc)
|
function(&Ds, &Dc)
|
||||||
|
|
|
|
||||||
{ if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
|
{ if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
|
||||||
Ds.ds_notypegiven) {
|
Ds.ds_notypegiven) {
|
||||||
strict("declaration specifiers missing");
|
strict("declaration specifiers missing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
non_function(&Ds, &Dc)
|
non_function(&Ds, &Dc)
|
||||||
]
|
]
|
||||||
|
|
|
|
||||||
{ if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
|
{ if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
|
||||||
Ds.ds_notypegiven) {
|
Ds.ds_notypegiven) {
|
||||||
strict("declaration missing");
|
strict("declaration missing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
';'
|
';'
|
||||||
]
|
]
|
||||||
{remove_declarator(&Dc); flush_strings(); }
|
{remove_declarator(&Dc); flush_strings(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
non_function(register struct decspecs *ds; register struct declarator *dc;)
|
non_function(register struct decspecs *ds; register struct declarator *dc;)
|
||||||
:
|
:
|
||||||
{ reject_params(dc);
|
{ reject_params(dc);
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
initializer(dc->dc_idf, ds->ds_sc)
|
initializer(dc->dc_idf, ds->ds_sc)
|
||||||
|
|
|
|
||||||
{ code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); }
|
{ code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); }
|
||||||
]
|
]
|
||||||
{
|
{
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
lint_non_function_decl(ds, dc);
|
lint_non_function_decl(ds, dc);
|
||||||
#endif /* LINT */
|
#endif /* LINT */
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
','
|
','
|
||||||
init_declarator(ds)
|
init_declarator(ds)
|
||||||
]*
|
]*
|
||||||
';'
|
';'
|
||||||
;
|
;
|
||||||
|
|
||||||
/* 3.7.1 */
|
/* 3.7.1 */
|
||||||
function(struct decspecs *ds; struct declarator *dc;)
|
function(struct decspecs *ds; struct declarator *dc;)
|
||||||
{
|
{
|
||||||
arith fbytes;
|
arith fbytes;
|
||||||
register struct idf *idf = dc->dc_idf;
|
register struct idf *idf = dc->dc_idf;
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
{
|
{
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
lint_start_function();
|
lint_start_function();
|
||||||
#endif /* LINT */
|
#endif /* LINT */
|
||||||
idf_initialized(idf);
|
idf_initialized(idf);
|
||||||
stack_level(); /* L_FORMAL1 declarations */
|
stack_level(); /* L_FORMAL1 declarations */
|
||||||
declare_params(dc);
|
declare_params(dc);
|
||||||
begin_proc(ds, idf); /* sets global function info */
|
begin_proc(ds, idf); /* sets global function info */
|
||||||
stack_level(); /* L_FORMAL2 declarations */
|
stack_level(); /* L_FORMAL2 declarations */
|
||||||
declare_protos(dc);
|
declare_protos(dc);
|
||||||
}
|
}
|
||||||
declaration*
|
declaration*
|
||||||
{
|
{
|
||||||
check_formals(idf, dc); /* check style-mixtures */
|
check_formals(idf, dc); /* check style-mixtures */
|
||||||
declare_formals(idf, &fbytes);
|
declare_formals(idf, &fbytes);
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
lint_formals();
|
lint_formals();
|
||||||
#endif /* LINT */
|
#endif /* LINT */
|
||||||
}
|
}
|
||||||
compound_statement
|
compound_statement
|
||||||
{
|
{
|
||||||
end_proc(fbytes);
|
end_proc(fbytes);
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
lint_implicit_return();
|
lint_implicit_return();
|
||||||
#endif /* LINT */
|
#endif /* LINT */
|
||||||
unstack_level(); /* L_FORMAL2 declarations */
|
unstack_level(); /* L_FORMAL2 declarations */
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
lint_end_formals();
|
lint_end_formals();
|
||||||
#endif /* LINT */
|
#endif /* LINT */
|
||||||
unstack_level(); /* L_FORMAL1 declarations */
|
unstack_level(); /* L_FORMAL1 declarations */
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
lint_end_function();
|
lint_end_function();
|
||||||
#endif /* LINT */
|
#endif /* LINT */
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,16 +1,16 @@
|
||||||
default:
|
default:
|
||||||
if (tok <= 0) return "end of file";
|
if (tok <= 0) return "end of file";
|
||||||
if (tok < 040 || tok >= 0177) {
|
if (tok < 040 || tok >= 0177) {
|
||||||
return "bad token";
|
return "bad token";
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\f':
|
case '\f':
|
||||||
case '\v':
|
case '\v':
|
||||||
case '\r':
|
case '\r':
|
||||||
case '\t':
|
case '\t':
|
||||||
index = (index+2) & (SIZBUF-1);
|
index = (index+2) & (SIZBUF-1);
|
||||||
buf[index] = tok;
|
buf[index] = tok;
|
||||||
return &buf[index];
|
return &buf[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
/* Generated by make.tokcase */
|
/* Generated by make.tokcase */
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
|
|
||||||
char *symbol2str(int tok)
|
char *symbol2str(int tok)
|
||||||
{
|
{
|
||||||
#define SIZBUF 8
|
#define SIZBUF 8
|
||||||
/* allow for a few invocations in f.i. an argument list */
|
/* allow for a few invocations in f.i. an argument list */
|
||||||
static char buf[SIZBUF];
|
static char buf[SIZBUF];
|
||||||
static int index;
|
static int index;
|
||||||
|
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
L_ACK_MODULES_ALLOC = {
|
L_ACK_MODULES_ALLOC = {
|
||||||
$PWD/Malloc.c,
|
$PWD/Malloc.c,
|
||||||
$PWD/Salloc.c,
|
$PWD/Salloc.c,
|
||||||
$PWD/Srealloc.c,
|
$PWD/Srealloc.c,
|
||||||
$PWD/Realloc.c,
|
$PWD/Realloc.c,
|
||||||
$PWD/botch.c,
|
$PWD/botch.c,
|
||||||
$PWD/clear.c,
|
$PWD/clear.c,
|
||||||
$PWD/st_alloc.c,
|
$PWD/st_alloc.c,
|
||||||
$PWD/std_alloc.c,
|
$PWD/std_alloc.c,
|
||||||
$PWD/No_Mem.c,
|
$PWD/No_Mem.c,
|
||||||
$PWD/alloc.h
|
$PWD/alloc.h
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,80 +1,80 @@
|
||||||
.TH ALLOC 3 "$Revision$"
|
.TH ALLOC 3 "$Revision$"
|
||||||
.ad
|
.ad
|
||||||
.SH NAME
|
.SH NAME
|
||||||
Malloc, Salloc, Realloc, Srealloc, st_alloc, st_free\ \-\ low level memory allocation routines
|
Malloc, Salloc, Realloc, Srealloc, st_alloc, st_free\ \-\ low level memory allocation routines
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B #include <alloc.h>
|
.B #include <alloc.h>
|
||||||
.PP
|
.PP
|
||||||
.B char *Malloc(unsigned int size)
|
.B char *Malloc(unsigned int size)
|
||||||
.PP
|
.PP
|
||||||
.B char *Salloc(char *str, unsigned int size)
|
.B char *Salloc(char *str, unsigned int size)
|
||||||
.PP
|
.PP
|
||||||
.B char *Realloc(char *buf, unsigned int size)
|
.B char *Realloc(char *buf, unsigned int size)
|
||||||
.PP
|
.PP
|
||||||
.B char *Srealloc(char *str, unsigned int size)
|
.B char *Srealloc(char *str, unsigned int size)
|
||||||
.PP
|
.PP
|
||||||
.B char *st_alloc(char **phead, unsigned int size, int count)
|
.B char *st_alloc(char **phead, unsigned int size, int count)
|
||||||
.PP
|
.PP
|
||||||
.B st_free(char *ptr, char **phead, unsigned int size)
|
.B st_free(char *ptr, char **phead, unsigned int size)
|
||||||
.PP
|
.PP
|
||||||
.B void clear(char *ptr, unsigned int size)
|
.B void clear(char *ptr, unsigned int size)
|
||||||
.PP
|
.PP
|
||||||
.void No_Mem()
|
.void No_Mem()
|
||||||
.PP
|
.PP
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This set of routines provides a checking memory allocation mechanism.
|
This set of routines provides a checking memory allocation mechanism.
|
||||||
.PP
|
.PP
|
||||||
\fIMalloc\fR returns a pointer to a block of at least \fIsize\fR
|
\fIMalloc\fR returns a pointer to a block of at least \fIsize\fR
|
||||||
bytes, beginning on a boundary suitable for any data type.
|
bytes, beginning on a boundary suitable for any data type.
|
||||||
.PP
|
.PP
|
||||||
\fISalloc\fR returns a pointer to a block of at least \fIsize\fR
|
\fISalloc\fR returns a pointer to a block of at least \fIsize\fR
|
||||||
bytes, initialized with the null-terminated string \fIstr\fR.
|
bytes, initialized with the null-terminated string \fIstr\fR.
|
||||||
.PP
|
.PP
|
||||||
\fIRealloc\fR changes the size of
|
\fIRealloc\fR changes the size of
|
||||||
the block at \fIbuf\fR to \fIsize\fR bytes, and returns a pointer to the
|
the block at \fIbuf\fR to \fIsize\fR bytes, and returns a pointer to the
|
||||||
(possibly moved) block. If \fIbuf\fP is a null pointer, \fIRealloc\fP
|
(possibly moved) block. If \fIbuf\fP is a null pointer, \fIRealloc\fP
|
||||||
behaves as \fIMalloc\fP.
|
behaves as \fIMalloc\fP.
|
||||||
.PP
|
.PP
|
||||||
\fISrealloc\fR reallocates
|
\fISrealloc\fR reallocates
|
||||||
the string at \fIstr\fR to \fIsize\fR bytes.
|
the string at \fIstr\fR to \fIsize\fR bytes.
|
||||||
It actually does the same as \fIRealloc\fP, and exists only for
|
It actually does the same as \fIRealloc\fP, and exists only for
|
||||||
backwards compatibility.
|
backwards compatibility.
|
||||||
.PP
|
.PP
|
||||||
All these routines use \fImalloc\fR and \fIrealloc\fR.
|
All these routines use \fImalloc\fR and \fIrealloc\fR.
|
||||||
The routine \fIfree\fR can be used on pointers returned by these routines.
|
The routine \fIfree\fR can be used on pointers returned by these routines.
|
||||||
.PP
|
.PP
|
||||||
\fISt_alloc\fR and \fIst_free\fR provide a mechanism for maintaining free lists
|
\fISt_alloc\fR and \fIst_free\fR provide a mechanism for maintaining free lists
|
||||||
of structures.
|
of structures.
|
||||||
\fISt_alloc\fR takes three parameters: \fIphead\fR is a pointer to a field
|
\fISt_alloc\fR takes three parameters: \fIphead\fR is a pointer to a field
|
||||||
containing the head of the free list, \fIsize\fR contains the size of the
|
containing the head of the free list, \fIsize\fR contains the size of the
|
||||||
structures, and \fIcount\fR indicates how many new structures must be allocated
|
structures, and \fIcount\fR indicates how many new structures must be allocated
|
||||||
in case the free list is exhausted.
|
in case the free list is exhausted.
|
||||||
It returns a pointer to a zero-initialized structure.
|
It returns a pointer to a zero-initialized structure.
|
||||||
\fISt_free\fR also takes three parameters: \fIptr\fR is a pointer to
|
\fISt_free\fR also takes three parameters: \fIptr\fR is a pointer to
|
||||||
the structure to be freed, \fIphead\fR is again a pointer to a field
|
the structure to be freed, \fIphead\fR is again a pointer to a field
|
||||||
containing the head of the free list, and \fIsize\fR again contains the size
|
containing the head of the free list, and \fIsize\fR again contains the size
|
||||||
of the structures.
|
of the structures.
|
||||||
These last two routines are best used in a macro.
|
These last two routines are best used in a macro.
|
||||||
.PP
|
.PP
|
||||||
\fIclear\fR clears \fIsize\fR bytes, starting at \fIptr\fR.
|
\fIclear\fR clears \fIsize\fR bytes, starting at \fIptr\fR.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.nf
|
.nf
|
||||||
~em/modules/h/alloc.h
|
~em/modules/h/alloc.h
|
||||||
~em/modules/lib/liballoc.a
|
~em/modules/lib/liballoc.a
|
||||||
.fi
|
.fi
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
malloc(3)
|
malloc(3)
|
||||||
.SH DIAGNOSTICS
|
.SH DIAGNOSTICS
|
||||||
\fIMalloc\fR, \fISalloc\fR, \fIRealloc\fP, \fISrealloc\fR, and \fIst_alloc\fR
|
\fIMalloc\fR, \fISalloc\fR, \fIRealloc\fP, \fISrealloc\fR, and \fIst_alloc\fR
|
||||||
call a routine \fINo_Mem\fR if there is no memory available. This routine
|
call a routine \fINo_Mem\fR if there is no memory available. This routine
|
||||||
is not supposed to return. A default one, that
|
is not supposed to return. A default one, that
|
||||||
gives an error message and stops execution, is provided.
|
gives an error message and stops execution, is provided.
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
The
|
The
|
||||||
.I st_alloc
|
.I st_alloc
|
||||||
mechanism only works for structures that are large enough to contain one
|
mechanism only works for structures that are large enough to contain one
|
||||||
pointer.
|
pointer.
|
||||||
Also,
|
Also,
|
||||||
.I st_free
|
.I st_free
|
||||||
actually is a macro, and references its arguments more than once, so they
|
actually is a macro, and references its arguments more than once, so they
|
||||||
better not have side-effects.
|
better not have side-effects.
|
||||||
|
|
|
@ -1,116 +1,116 @@
|
||||||
#
|
#
|
||||||
.sect .text
|
.sect .text
|
||||||
.sect .rom
|
.sect .rom
|
||||||
.sect .data
|
.sect .data
|
||||||
.sect .bss
|
.sect .bss
|
||||||
|
|
||||||
.sect .text
|
.sect .text
|
||||||
|
|
||||||
bdos: ! BDOS entry point
|
bdos: ! BDOS entry point
|
||||||
out 0xff
|
out 0xff
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
COLDSTART: ! system startup entry point --- this needs to be four bytes after FBASE.
|
COLDSTART: ! system startup entry point --- this needs to be four bytes after FBASE.
|
||||||
jmp boot ! 0: Cold start routine
|
jmp boot ! 0: Cold start routine
|
||||||
bios:
|
bios:
|
||||||
jmp wboot ! 1: Warm boot - reload command processor
|
jmp wboot ! 1: Warm boot - reload command processor
|
||||||
jmp const ! 2: Console status
|
jmp const ! 2: Console status
|
||||||
jmp conin ! 3: Console input
|
jmp conin ! 3: Console input
|
||||||
jmp conout ! 4: Console output
|
jmp conout ! 4: Console output
|
||||||
jmp list ! 5: Printer output
|
jmp list ! 5: Printer output
|
||||||
jmp punch ! 6: Paper tape punch output
|
jmp punch ! 6: Paper tape punch output
|
||||||
jmp reader ! 7: Paper tape reader input
|
jmp reader ! 7: Paper tape reader input
|
||||||
jmp home ! 8: Move disc head to track 0
|
jmp home ! 8: Move disc head to track 0
|
||||||
jmp seldsk ! 9: Select disc drive
|
jmp seldsk ! 9: Select disc drive
|
||||||
jmp settrk !10: Set track number
|
jmp settrk !10: Set track number
|
||||||
jmp setsec !11: Set sector number
|
jmp setsec !11: Set sector number
|
||||||
jmp setdma !12: Set DMA address
|
jmp setdma !12: Set DMA address
|
||||||
jmp read !13: Read a sector
|
jmp read !13: Read a sector
|
||||||
jmp write !14: Write a sector
|
jmp write !14: Write a sector
|
||||||
|
|
||||||
boot:
|
boot:
|
||||||
xra a
|
xra a
|
||||||
sta 3 ! iobyte
|
sta 3 ! iobyte
|
||||||
sta 4 ! drive
|
sta 4 ! drive
|
||||||
! falls through
|
! falls through
|
||||||
wboot:
|
wboot:
|
||||||
mvi a, 0xc3 ! jmp
|
mvi a, 0xc3 ! jmp
|
||||||
sta 0
|
sta 0
|
||||||
sta 5
|
sta 5
|
||||||
|
|
||||||
lxi h, bios
|
lxi h, bios
|
||||||
shld 1
|
shld 1
|
||||||
|
|
||||||
lxi h, bdos
|
lxi h, bdos
|
||||||
shld 6
|
shld 6
|
||||||
|
|
||||||
lda 4 ! get the current drive/user
|
lda 4 ! get the current drive/user
|
||||||
mov c, a
|
mov c, a
|
||||||
out 1
|
out 1
|
||||||
|
|
||||||
const:
|
const:
|
||||||
out 2
|
out 2
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
conin:
|
conin:
|
||||||
out 3
|
out 3
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
conout:
|
conout:
|
||||||
out 4
|
out 4
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
list:
|
list:
|
||||||
out 5
|
out 5
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
punch:
|
punch:
|
||||||
out 6
|
out 6
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
reader:
|
reader:
|
||||||
out 7
|
out 7
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
home:
|
home:
|
||||||
out 8
|
out 8
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
seldsk:
|
seldsk:
|
||||||
out 9
|
out 9
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
settrk:
|
settrk:
|
||||||
out 10
|
out 10
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
setsec:
|
setsec:
|
||||||
out 11
|
out 11
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
setdma:
|
setdma:
|
||||||
out 12
|
out 12
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
read:
|
read:
|
||||||
out 13
|
out 13
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
write:
|
write:
|
||||||
out 14
|
out 14
|
||||||
ora a
|
ora a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,15 +1,15 @@
|
||||||
#ifndef SIM__HEADER
|
#ifndef SIM__HEADER
|
||||||
#define SIM__HEADER
|
#define SIM__HEADER
|
||||||
|
|
||||||
unsigned int cpu_read_byte(unsigned int address);
|
unsigned int cpu_read_byte(unsigned int address);
|
||||||
unsigned int cpu_read_word(unsigned int address);
|
unsigned int cpu_read_word(unsigned int address);
|
||||||
unsigned int cpu_read_long(unsigned int address);
|
unsigned int cpu_read_long(unsigned int address);
|
||||||
void cpu_write_byte(unsigned int address, unsigned int value);
|
void cpu_write_byte(unsigned int address, unsigned int value);
|
||||||
void cpu_write_word(unsigned int address, unsigned int value);
|
void cpu_write_word(unsigned int address, unsigned int value);
|
||||||
void cpu_write_long(unsigned int address, unsigned int value);
|
void cpu_write_long(unsigned int address, unsigned int value);
|
||||||
void cpu_pulse_reset(void);
|
void cpu_pulse_reset(void);
|
||||||
void cpu_set_fc(unsigned int fc);
|
void cpu_set_fc(unsigned int fc);
|
||||||
int cpu_irq_ack(int level);
|
int cpu_irq_ack(int level);
|
||||||
void cpu_instr_callback(int pc);
|
void cpu_instr_callback(int pc);
|
||||||
|
|
||||||
#endif /* SIM__HEADER */
|
#endif /* SIM__HEADER */
|
||||||
|
|
|
@ -1,45 +1,45 @@
|
||||||
Following is a repost of the public domain 'make' that I posted
|
Following is a repost of the public domain 'make' that I posted
|
||||||
to net.sources a couple of months ago. I have fixed a few bugs, and
|
to net.sources a couple of months ago. I have fixed a few bugs, and
|
||||||
added some more features, and the resulting changes amounted to
|
added some more features, and the resulting changes amounted to
|
||||||
about as much text as the whole program (hence the repost).
|
about as much text as the whole program (hence the repost).
|
||||||
|
|
||||||
For those that missed the net.sources posting, this is a public domain
|
For those that missed the net.sources posting, this is a public domain
|
||||||
re-implementation of the UNIX make program. There is no manual included;
|
re-implementation of the UNIX make program. There is no manual included;
|
||||||
for documentation, refer to a UNIX manual, or the source.
|
for documentation, refer to a UNIX manual, or the source.
|
||||||
|
|
||||||
Here is a list of the changes made:
|
Here is a list of the changes made:
|
||||||
|
|
||||||
i) If '-' (ignore) or '@' (silent) where used at the start
|
i) If '-' (ignore) or '@' (silent) where used at the start
|
||||||
of a command, their effect was not turned off for the following
|
of a command, their effect was not turned off for the following
|
||||||
commands.
|
commands.
|
||||||
ii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o),
|
ii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o),
|
||||||
if first in the file would be taken as the default target.
|
if first in the file would be taken as the default target.
|
||||||
This resulted in error messages like "Don't know how to
|
This resulted in error messages like "Don't know how to
|
||||||
make .c", because things like .SUFFIXES were being made.
|
make .c", because things like .SUFFIXES were being made.
|
||||||
This was further complicated by ---
|
This was further complicated by ---
|
||||||
iii) Special target lines with no dependents (ie. .SUFFIXES:\n)
|
iii) Special target lines with no dependents (ie. .SUFFIXES:\n)
|
||||||
were not clearing out the existing dependents like
|
were not clearing out the existing dependents like
|
||||||
they should.
|
they should.
|
||||||
iv) Default rules could not be redefined because of the error
|
iv) Default rules could not be redefined because of the error
|
||||||
checking for commands being defined twice. Now you are
|
checking for commands being defined twice. Now you are
|
||||||
allowed to define a target beinging with '.', having
|
allowed to define a target beinging with '.', having
|
||||||
no dependents with commands.
|
no dependents with commands.
|
||||||
v) The -q option didn't do the time comparison correctly,
|
v) The -q option didn't do the time comparison correctly,
|
||||||
or clear the variable used to keep track of this. Thus
|
or clear the variable used to keep track of this. Thus
|
||||||
it didn't work very well.
|
it didn't work very well.
|
||||||
vi) The syntax ${..} for macro's supported by UNIX make was
|
vi) The syntax ${..} for macro's supported by UNIX make was
|
||||||
not supported.
|
not supported.
|
||||||
vii) There wuz a couple of spelling errors.
|
vii) There wuz a couple of spelling errors.
|
||||||
viii) When make checked for implicit rules on targets without
|
viii) When make checked for implicit rules on targets without
|
||||||
a suffix, there were problems. (Note: The ~ feature of
|
a suffix, there were problems. (Note: The ~ feature of
|
||||||
UNIX make wasn't and still isn't supported)
|
UNIX make wasn't and still isn't supported)
|
||||||
ix) The -n option did not print @ lines like it was supposed to.
|
ix) The -n option did not print @ lines like it was supposed to.
|
||||||
x) :: added. (See UNIX manual)
|
x) :: added. (See UNIX manual)
|
||||||
xi) $? added. (see UNIX manual)
|
xi) $? added. (see UNIX manual)
|
||||||
|
|
||||||
Hacked further by Ceriel Jacobs to make it work better. Use this "make" to
|
Hacked further by Ceriel Jacobs to make it work better. Use this "make" to
|
||||||
install ACK under Microsoft Xenix V3.2. Some of the makefiles are just too
|
install ACK under Microsoft Xenix V3.2. Some of the makefiles are just too
|
||||||
big for the Xenix "make". Strange, they work on a PDP-11 ...
|
big for the Xenix "make". Strange, they work on a PDP-11 ...
|
||||||
|
|
||||||
Made it almost ISO C90 and POSIX portable by Carl Eric Codere, and
|
Made it almost ISO C90 and POSIX portable by Carl Eric Codere, and
|
||||||
also made it safer by using correct datatypes on some library calls.
|
also made it safer by using correct datatypes on some library calls.
|
||||||
|
|
|
@ -1,349 +1,349 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/*
|
/*
|
||||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
/* t o p g e n . g
|
/* t o p g e n . g
|
||||||
*
|
*
|
||||||
* Grammar of optimizer description, and some code generation
|
* Grammar of optimizer description, and some code generation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
%token LETTER, DIGIT, OTHER, SPACE;
|
%token LETTER, DIGIT, OTHER, SPACE;
|
||||||
%token LINE_TERMINATOR, OPERAND_SEPARATOR, INSTRUCTION_SEPARATOR,
|
%token LINE_TERMINATOR, OPERAND_SEPARATOR, INSTRUCTION_SEPARATOR,
|
||||||
PATTERN_SEPARATOR, OPEN_BRACKET, CLOSE_BRACKET;
|
PATTERN_SEPARATOR, OPEN_BRACKET, CLOSE_BRACKET;
|
||||||
%lexical LLlex;
|
%lexical LLlex;
|
||||||
%start LLparse, optim_description;
|
%start LLparse, optim_description;
|
||||||
|
|
||||||
{
|
{
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "pattern.h"
|
#include "pattern.h"
|
||||||
|
|
||||||
char idbuf[BUFSIZ], buf[BUFSIZ];
|
char idbuf[BUFSIZ], buf[BUFSIZ];
|
||||||
int countid; /* # of variables */
|
int countid; /* # of variables */
|
||||||
int countpat; /* # of patterns */
|
int countpat; /* # of patterns */
|
||||||
static int patlen; /* Maximum number of instructions in pattern */
|
static int patlen; /* Maximum number of instructions in pattern */
|
||||||
static int maxoperand; /* Maximum number of operands of instruction */
|
static int maxoperand; /* Maximum number of operands of instruction */
|
||||||
extern FILE *input; /* file descriptor of inputfile */
|
extern FILE *input; /* file descriptor of inputfile */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern int onlyspace(char* s);
|
extern int onlyspace(char* s);
|
||||||
extern void error(char *s, char* s1);
|
extern void error(char *s, char* s1);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
optim_description
|
optim_description
|
||||||
{ struct symtab *p; } :
|
{ struct symtab *p; } :
|
||||||
SPACE* parameters
|
SPACE* parameters
|
||||||
{ p = findident("MAXOP",LOOKING,&deftable);
|
{ p = findident("MAXOP",LOOKING,&deftable);
|
||||||
if (p == 0) maxoperand = 2; /* default */
|
if (p == 0) maxoperand = 2; /* default */
|
||||||
else maxoperand = p->s_num;
|
else maxoperand = p->s_num;
|
||||||
}
|
}
|
||||||
separator SPACE* mode_definitions
|
separator SPACE* mode_definitions
|
||||||
separator SPACE* patterns
|
separator SPACE* patterns
|
||||||
separator
|
separator
|
||||||
{ register int c;
|
{ register int c;
|
||||||
fprintf(genc, linedir, lineno, inpfile);
|
fprintf(genc, linedir, lineno, inpfile);
|
||||||
while ((c = getc(input)) != EOF) {
|
while ((c = getc(input)) != EOF) {
|
||||||
putc(c,genc);
|
putc(c,genc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
parameters :
|
parameters :
|
||||||
[ parameter_line | declaration_block ]*
|
[ parameter_line | declaration_block ]*
|
||||||
;
|
;
|
||||||
|
|
||||||
parameter_line
|
parameter_line
|
||||||
{ struct symtab *p;
|
{ struct symtab *p;
|
||||||
int lin;
|
int lin;
|
||||||
} :
|
} :
|
||||||
identifier
|
identifier
|
||||||
{ p = findident(idbuf,ENTERING,&deftable);}
|
{ p = findident(idbuf,ENTERING,&deftable);}
|
||||||
SPACE
|
SPACE
|
||||||
{ lin = lineno;}
|
{ lin = lineno;}
|
||||||
value
|
value
|
||||||
{ p->s_num = atoi(buf);}
|
{ p->s_num = atoi(buf);}
|
||||||
/* This action in fact only needed for MAXOP */
|
/* This action in fact only needed for MAXOP */
|
||||||
LINE_TERMINATOR
|
LINE_TERMINATOR
|
||||||
SPACE*
|
SPACE*
|
||||||
{ fprintf(genh, linedir, lin, inpfile);
|
{ fprintf(genh, linedir, lin, inpfile);
|
||||||
fprintf(genh,"#define %s %s\n",p->s_name,buf);}
|
fprintf(genh,"#define %s %s\n",p->s_name,buf);}
|
||||||
;
|
;
|
||||||
|
|
||||||
value
|
value
|
||||||
{ char *p1 = buf;} :
|
{ char *p1 = buf;} :
|
||||||
[
|
[
|
||||||
[ OPEN_BRACKET
|
[ OPEN_BRACKET
|
||||||
| CLOSE_BRACKET
|
| CLOSE_BRACKET
|
||||||
| OPERAND_SEPARATOR
|
| OPERAND_SEPARATOR
|
||||||
| PATTERN_SEPARATOR
|
| PATTERN_SEPARATOR
|
||||||
| INSTRUCTION_SEPARATOR
|
| INSTRUCTION_SEPARATOR
|
||||||
| SPACE
|
| SPACE
|
||||||
| LETTER
|
| LETTER
|
||||||
| DIGIT
|
| DIGIT
|
||||||
| OTHER
|
| OTHER
|
||||||
| '%'
|
| '%'
|
||||||
]
|
]
|
||||||
{ *p1++ = dot.t_attrib;}
|
{ *p1++ = dot.t_attrib;}
|
||||||
]*
|
]*
|
||||||
{ *p1 = '\0';}
|
{ *p1 = '\0';}
|
||||||
;
|
;
|
||||||
|
|
||||||
declaration_block :
|
declaration_block :
|
||||||
OPEN_BRACKET
|
OPEN_BRACKET
|
||||||
{ fprintf(genh, linedir, lineno, inpfile);}
|
{ fprintf(genh, linedir, lineno, inpfile);}
|
||||||
[
|
[
|
||||||
[ LINE_TERMINATOR
|
[ LINE_TERMINATOR
|
||||||
| OPERAND_SEPARATOR
|
| OPERAND_SEPARATOR
|
||||||
| PATTERN_SEPARATOR
|
| PATTERN_SEPARATOR
|
||||||
| INSTRUCTION_SEPARATOR
|
| INSTRUCTION_SEPARATOR
|
||||||
| SPACE
|
| SPACE
|
||||||
| LETTER
|
| LETTER
|
||||||
| DIGIT
|
| DIGIT
|
||||||
| OTHER
|
| OTHER
|
||||||
| '%'
|
| '%'
|
||||||
]
|
]
|
||||||
{ putc(dot.t_attrib, genh);}
|
{ putc(dot.t_attrib, genh);}
|
||||||
]*
|
]*
|
||||||
CLOSE_BRACKET
|
CLOSE_BRACKET
|
||||||
SPACE*
|
SPACE*
|
||||||
{ putc('\n', genh);}
|
{ putc('\n', genh);}
|
||||||
;
|
;
|
||||||
|
|
||||||
mode_definitions
|
mode_definitions
|
||||||
{ int lin; } :
|
{ int lin; } :
|
||||||
{ fputs("int tok_chk(int varno) {\n\tint r;\n", genc);
|
{ fputs("int tok_chk(int varno) {\n\tint r;\n", genc);
|
||||||
fputs("\tchar *VAL;\n\n",genc);
|
fputs("\tchar *VAL;\n\n",genc);
|
||||||
fputs("\tVAL = var[varno].value;\n",genc);
|
fputs("\tVAL = var[varno].value;\n",genc);
|
||||||
fputs("\tswitch(varno) {\n",genc);
|
fputs("\tswitch(varno) {\n",genc);
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
token_list
|
token_list
|
||||||
constraint(&lin)
|
constraint(&lin)
|
||||||
{ fprintf(genc,linedir,lin,inpfile);
|
{ fprintf(genc,linedir,lin,inpfile);
|
||||||
fprintf(genc,"\t\tr = (%s); break;\n",buf);
|
fprintf(genc,"\t\tr = (%s); break;\n",buf);
|
||||||
}
|
}
|
||||||
LINE_TERMINATOR
|
LINE_TERMINATOR
|
||||||
SPACE*
|
SPACE*
|
||||||
]*
|
]*
|
||||||
{ fputs("\tdefault :\n\t\tassert(0);\n",genc);
|
{ fputs("\tdefault :\n\t\tassert(0);\n",genc);
|
||||||
fputs("\t}\n\treturn r;\n}\n\n",genc);
|
fputs("\t}\n\treturn r;\n}\n\n",genc);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
token_list :
|
token_list :
|
||||||
new_identifier
|
new_identifier
|
||||||
SPACE*
|
SPACE*
|
||||||
[
|
[
|
||||||
OPERAND_SEPARATOR
|
OPERAND_SEPARATOR
|
||||||
SPACE*
|
SPACE*
|
||||||
new_identifier
|
new_identifier
|
||||||
SPACE*
|
SPACE*
|
||||||
]*
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
new_identifier
|
new_identifier
|
||||||
{ struct symtab *p;} :
|
{ struct symtab *p;} :
|
||||||
identifier
|
identifier
|
||||||
{ p = findident(idbuf,ENTERING,&idtable);
|
{ p = findident(idbuf,ENTERING,&idtable);
|
||||||
p->s_num = ++countid;
|
p->s_num = ++countid;
|
||||||
fprintf(genc,"\tcase %d:\n", countid);
|
fprintf(genc,"\tcase %d:\n", countid);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
constraint (int *lin;)
|
constraint (int *lin;)
|
||||||
{ char *p = buf; } :
|
{ char *p = buf; } :
|
||||||
OPEN_BRACKET
|
OPEN_BRACKET
|
||||||
{ *lin = lineno;}
|
{ *lin = lineno;}
|
||||||
[
|
[
|
||||||
[ LINE_TERMINATOR
|
[ LINE_TERMINATOR
|
||||||
| OPERAND_SEPARATOR
|
| OPERAND_SEPARATOR
|
||||||
| PATTERN_SEPARATOR
|
| PATTERN_SEPARATOR
|
||||||
| INSTRUCTION_SEPARATOR
|
| INSTRUCTION_SEPARATOR
|
||||||
| LETTER
|
| LETTER
|
||||||
| DIGIT
|
| DIGIT
|
||||||
| SPACE
|
| SPACE
|
||||||
| OTHER
|
| OTHER
|
||||||
| '%'
|
| '%'
|
||||||
]
|
]
|
||||||
{ *p++ = dot.t_attrib;}
|
{ *p++ = dot.t_attrib;}
|
||||||
]*
|
]*
|
||||||
{ *p = '\0';
|
{ *p = '\0';
|
||||||
if (onlyspace(buf)) strcpy(buf,"TRUE");
|
if (onlyspace(buf)) strcpy(buf,"TRUE");
|
||||||
}
|
}
|
||||||
CLOSE_BRACKET
|
CLOSE_BRACKET
|
||||||
SPACE*
|
SPACE*
|
||||||
;
|
;
|
||||||
|
|
||||||
patterns
|
patterns
|
||||||
{ int lin;
|
{ int lin;
|
||||||
char *constr;
|
char *constr;
|
||||||
int np, nr;
|
int np, nr;
|
||||||
} :
|
} :
|
||||||
[
|
[
|
||||||
{ countpat++;
|
{ countpat++;
|
||||||
constr = (char *) 0;
|
constr = (char *) 0;
|
||||||
fprintf(genc,"struct instr_descr pat%d[] = {\n",
|
fprintf(genc,"struct instr_descr pat%d[] = {\n",
|
||||||
countpat);
|
countpat);
|
||||||
}
|
}
|
||||||
instruction_list(&np)
|
instruction_list(&np)
|
||||||
{ if (np > patlen) patlen = np;
|
{ if (np > patlen) patlen = np;
|
||||||
fputs("\n};\n\n",genc);
|
fputs("\n};\n\n",genc);
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
constraint(&lin)
|
constraint(&lin)
|
||||||
{ /* Save the constraint, we need it later on */
|
{ /* Save the constraint, we need it later on */
|
||||||
constr = malloc((unsigned)(strlen(buf)+1));
|
constr = malloc((unsigned)(strlen(buf)+1));
|
||||||
strcpy(constr,buf);
|
strcpy(constr,buf);
|
||||||
}
|
}
|
||||||
]?
|
]?
|
||||||
PATTERN_SEPARATOR
|
PATTERN_SEPARATOR
|
||||||
{ fprintf(genc,"struct instr_descr rep%d[] = {\n",
|
{ fprintf(genc,"struct instr_descr rep%d[] = {\n",
|
||||||
countpat);
|
countpat);
|
||||||
}
|
}
|
||||||
replacement(&nr)
|
replacement(&nr)
|
||||||
{ fputs("\n};\n\n",genc);}
|
{ fputs("\n};\n\n",genc);}
|
||||||
LINE_TERMINATOR
|
LINE_TERMINATOR
|
||||||
SPACE*
|
SPACE*
|
||||||
{ addpattern(constr,lin,np,nr);}
|
{ addpattern(constr,lin,np,nr);}
|
||||||
]*
|
]*
|
||||||
{ printhashtable();
|
{ printhashtable();
|
||||||
printpatterns();
|
printpatterns();
|
||||||
fprintf(genh,"#define NRVARS %d\n",countid);
|
fprintf(genh,"#define NRVARS %d\n",countid);
|
||||||
fprintf(genh,"#define NRPATTERNS %d\n",countpat);
|
fprintf(genh,"#define NRPATTERNS %d\n",countpat);
|
||||||
fprintf(genh,"#define MIN_WINDOW_SIZE %d\n",
|
fprintf(genh,"#define MIN_WINDOW_SIZE %d\n",
|
||||||
patlen+3);
|
patlen+3);
|
||||||
fclose(genh);
|
fclose(genh);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
instruction_list(int *n;) :
|
instruction_list(int *n;) :
|
||||||
instruction(1)
|
instruction(1)
|
||||||
{ *n = 1;}
|
{ *n = 1;}
|
||||||
[
|
[
|
||||||
INSTRUCTION_SEPARATOR
|
INSTRUCTION_SEPARATOR
|
||||||
{ fputs(",\n",genc);}
|
{ fputs(",\n",genc);}
|
||||||
SPACE*
|
SPACE*
|
||||||
instruction(0)
|
instruction(0)
|
||||||
{ *n += 1;}
|
{ *n += 1;}
|
||||||
]*
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
instruction(int opt;)
|
instruction(int opt;)
|
||||||
{ int count = 0;} :
|
{ int count = 0;} :
|
||||||
opcode(opt)
|
opcode(opt)
|
||||||
{ if (strcmp(buf,"ANY") != 0) {
|
{ if (strcmp(buf,"ANY") != 0) {
|
||||||
fprintf(genc,"\t{\"%s\", {",buf);
|
fprintf(genc,"\t{\"%s\", {",buf);
|
||||||
}
|
}
|
||||||
else fputs("\t{(char *) 0, {",genc);
|
else fputs("\t{(char *) 0, {",genc);
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
operand(' ')
|
operand(' ')
|
||||||
{ count = 1;}
|
{ count = 1;}
|
||||||
[
|
[
|
||||||
OPERAND_SEPARATOR
|
OPERAND_SEPARATOR
|
||||||
{ count++;}
|
{ count++;}
|
||||||
SPACE*
|
SPACE*
|
||||||
operand(',')
|
operand(',')
|
||||||
]*
|
]*
|
||||||
{ if (count > maxoperand) {
|
{ if (count > maxoperand) {
|
||||||
error("Too many operands","");
|
error("Too many operands","");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]?
|
]?
|
||||||
{ while (count++ < maxoperand) {
|
{ while (count++ < maxoperand) {
|
||||||
fprintf(genc,"%c{\"\",-1,\"\"}",count == 1 ? ' ' : ',');
|
fprintf(genc,"%c{\"\",-1,\"\"}",count == 1 ? ' ' : ',');
|
||||||
}
|
}
|
||||||
putc('}',genc);
|
putc('}',genc);
|
||||||
putc('}',genc);
|
putc('}',genc);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
opcode(int opt;)
|
opcode(int opt;)
|
||||||
{ char *p = buf;} :
|
{ char *p = buf;} :
|
||||||
[
|
[
|
||||||
[ LETTER
|
[ LETTER
|
||||||
| DIGIT
|
| DIGIT
|
||||||
| OTHER
|
| OTHER
|
||||||
]
|
]
|
||||||
{ *p++ = dot.t_attrib;}
|
{ *p++ = dot.t_attrib;}
|
||||||
]+
|
]+
|
||||||
SPACE+
|
SPACE+
|
||||||
{ *p = '\0';
|
{ *p = '\0';
|
||||||
if (opt) addtohashtable(buf,countpat);
|
if (opt) addtohashtable(buf,countpat);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
operand(int c;)
|
operand(int c;)
|
||||||
{ register struct symtab *p = 0;} :
|
{ register struct symtab *p = 0;} :
|
||||||
{ fprintf(genc, "%c{\"", c);}
|
{ fprintf(genc, "%c{\"", c);}
|
||||||
[
|
[
|
||||||
identifier
|
identifier
|
||||||
{ if (!p) {
|
{ if (!p) {
|
||||||
p = findident(idbuf,LOOKING,&idtable);
|
p = findident(idbuf,LOOKING,&idtable);
|
||||||
if (p) fprintf(genc,"\",%d,\"",p->s_num);
|
if (p) fprintf(genc,"\",%d,\"",p->s_num);
|
||||||
else fputs(idbuf,genc);
|
else fputs(idbuf,genc);
|
||||||
}
|
}
|
||||||
else fputs(idbuf,genc);
|
else fputs(idbuf,genc);
|
||||||
}
|
}
|
||||||
| DIGIT
|
| DIGIT
|
||||||
{ putc(dot.t_attrib,genc);}
|
{ putc(dot.t_attrib,genc);}
|
||||||
| OTHER
|
| OTHER
|
||||||
{ putc(dot.t_attrib,genc);}
|
{ putc(dot.t_attrib,genc);}
|
||||||
]+
|
]+
|
||||||
{ if (p) fputs("\"}",genc);
|
{ if (p) fputs("\"}",genc);
|
||||||
else fputs("\",0,\"\"}",genc);
|
else fputs("\",0,\"\"}",genc);
|
||||||
}
|
}
|
||||||
SPACE*
|
SPACE*
|
||||||
;
|
;
|
||||||
|
|
||||||
replacement (int *n;)
|
replacement (int *n;)
|
||||||
{register int i;} :
|
{register int i;} :
|
||||||
SPACE*
|
SPACE*
|
||||||
{ *n = 0;}
|
{ *n = 0;}
|
||||||
[
|
[
|
||||||
instruction(0)
|
instruction(0)
|
||||||
{ *n = 1;}
|
{ *n = 1;}
|
||||||
[
|
[
|
||||||
INSTRUCTION_SEPARATOR
|
INSTRUCTION_SEPARATOR
|
||||||
{ fputs(",\n", genc);}
|
{ fputs(",\n", genc);}
|
||||||
SPACE*
|
SPACE*
|
||||||
instruction(0)
|
instruction(0)
|
||||||
{ *n += 1;}
|
{ *n += 1;}
|
||||||
]*
|
]*
|
||||||
| /* empty replacement, but there must be a
|
| /* empty replacement, but there must be a
|
||||||
* structure initializer anyway
|
* structure initializer anyway
|
||||||
*/
|
*/
|
||||||
{ fputs("\t{\"\", {",genc);
|
{ fputs("\t{\"\", {",genc);
|
||||||
for (i = 0; i < maxoperand; i++) {
|
for (i = 0; i < maxoperand; i++) {
|
||||||
fprintf(genc, "%c{\"\",-1,\"\"}",i?',':' ');
|
fprintf(genc, "%c{\"\",-1,\"\"}",i?',':' ');
|
||||||
}
|
}
|
||||||
fputs("}}",genc);
|
fputs("}}",genc);
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
identifier
|
identifier
|
||||||
{ char *p = idbuf; } :
|
{ char *p = idbuf; } :
|
||||||
LETTER
|
LETTER
|
||||||
{ *p++ = dot.t_attrib;}
|
{ *p++ = dot.t_attrib;}
|
||||||
[ %while (1)
|
[ %while (1)
|
||||||
LETTER { *p++ = dot.t_attrib;}
|
LETTER { *p++ = dot.t_attrib;}
|
||||||
| DIGIT { *p++ = dot.t_attrib;}
|
| DIGIT { *p++ = dot.t_attrib;}
|
||||||
]*
|
]*
|
||||||
{ *p = '\0';}
|
{ *p = '\0';}
|
||||||
;
|
;
|
||||||
|
|
||||||
separator :
|
separator :
|
||||||
'%' '%' SPACE* LINE_TERMINATOR
|
'%' '%' SPACE* LINE_TERMINATOR
|
||||||
;
|
;
|
||||||
|
|
Loading…
Reference in a new issue