newer version, partial parse trees

This commit is contained in:
ceriel 1986-04-06 17:42:56 +00:00
parent 0e4311490c
commit 376c47c98f
13 changed files with 418 additions and 220 deletions

View file

@ -17,7 +17,7 @@ LFLAGS = $(PROFILE)
LOBJ = tokenfile.o program.o declar.o expression.o statement.o
COBJ = LLlex.o LLmessage.o char.o error.o main.o \
symbol2str.o tokenname.o idf.o input.o type.o def.o \
scope.o misc.o enter.o defmodule.o typequiv.o
scope.o misc.o enter.o defmodule.o typequiv.o node.o
OBJ = $(COBJ) $(LOBJ) Lpars.o
GENFILES= tokenfile.c \
program.c declar.c expression.c statement.c \
@ -47,6 +47,7 @@ symbol2str.c: tokenname.c make.tokcase
misc.h: misc.H make.allocd
def.h: def.H make.allocd
type.h: type.H make.allocd
node.h: node.H make.allocd
scope.c: scope.C make.allocd
char.c: char.tab tab
@ -71,22 +72,23 @@ depend:
LLlex.o: LLlex.h Lpars.h class.h f_info.h idf.h input.h
LLmessage.o: LLlex.h Lpars.h idf.h
char.o: class.h
error.o: LLlex.h f_info.h input.h main.h
error.o: LLlex.h f_info.h input.h main.h node.h
main.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h main.h scope.h standards.h type.h
symbol2str.o: Lpars.h
tokenname.o: Lpars.h idf.h tokenname.h
idf.o: idf.h
input.o: f_info.h input.h
type.o: Lpars.h def.h def_sizes.h idf.h misc.h type.h
def.o: Lpars.h debug.h def.h idf.h main.h misc.h scope.h type.h
type.o: LLlex.h Lpars.h def.h def_sizes.h idf.h node.h type.h
def.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
scope.o: LLlex.h debug.h def.h idf.h scope.h type.h
misc.o: LLlex.h f_info.h idf.h misc.h
enter.o: def.h idf.h misc.h scope.h type.h
enter.o: LLlex.h def.h idf.h node.h scope.h type.h
defmodule.o: LLlex.h def.h f_info.h idf.h input.h scope.h
typequiv.o: Lpars.h def.h type.h
node.o: LLlex.h def.h node.h type.h
tokenfile.o: Lpars.h
program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h misc.h scope.h type.h
declar.o: LLlex.h Lpars.h def.h idf.h misc.h scope.h type.h
expression.o: LLlex.h Lpars.h def.h idf.h scope.h
program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
declar.o: LLlex.h Lpars.h def.h idf.h misc.h node.h scope.h type.h
expression.o: LLlex.h Lpars.h def.h idf.h node.h scope.h
statement.o: Lpars.h
Lpars.o: Lpars.h

View file

@ -7,11 +7,12 @@ static char *RcsId = "$Header$";
#include <em_label.h>
#include <assert.h>
#include "idf.h"
#include "misc.h"
#include "LLlex.h"
#include "def.h"
#include "type.h"
#include "scope.h"
#include "node.h"
#include "misc.h"
}
ProcedureDeclaration
@ -95,7 +96,7 @@ FormalParameters(int doparams; struct paramlist **pr; struct type **tp;)
]?
')'
{ *tp = 0; }
[ ':' qualident(D_TYPE | D_HTYPE, &df, "type")
[ ':' qualident(D_TYPE | D_HTYPE, &df, "type", (struct node **) 0)
{ *tp = df->df_type; }
]?
;
@ -108,7 +109,7 @@ FormalParameters(int doparams; struct paramlist **pr; struct type **tp;)
*/
FPSection(int doparams; struct paramlist **ppr;)
{
struct id_list *FPList;
struct node *FPList;
struct paramlist *ParamList();
struct type *tp;
int VARp = 0;
@ -122,7 +123,7 @@ FPSection(int doparams; struct paramlist **ppr;)
EnterIdList(FPList, D_VARIABLE, VARp, tp, CurrentScope);
}
*ppr = ParamList(FPList, tp);
FreeIdList(FPList);
FreeNode(FPList);
}
;
@ -133,7 +134,7 @@ FormalType(struct type **tp;)
} :
[ ARRAY OF { ARRAYflag = 1; }
]?
qualident(D_TYPE | D_HTYPE, &df, "type")
qualident(D_TYPE | D_HTYPE, &df, "type", (struct node **) 0)
{ if (ARRAYflag) {
*tp = construct_type(ARRAY, NULLTYPE);
(*tp)->arr_elem = df->df_type;
@ -182,7 +183,7 @@ SimpleType(struct type **ptp;)
struct def *df;
struct type *tp;
} :
qualident(D_TYPE | D_HTYPE, &df, "type")
qualident(D_TYPE | D_HTYPE, &df, "type", (struct node **) 0)
[
/* nothing */
|
@ -202,41 +203,44 @@ SimpleType(struct type **ptp;)
enumeration(struct type **ptp;)
{
struct id_list *EnumList;
struct node *EnumList;
} :
'(' IdentList(&EnumList) ')'
{
*ptp = standard_type(ENUMERATION,int_align,int_size);
EnterIdList(EnumList, D_ENUM, 0, *ptp, CurrentScope);
FreeIdList(EnumList);
FreeNode(EnumList);
}
;
IdentList(struct id_list **p;)
IdentList(struct node **p;)
{
register struct id_list *q = new_id_list();
register struct node *q;
} :
IDENT { q->id_ptr = dot.TOK_IDF; *p = q;}
IDENT { q = MkNode(Value, NULLNODE, NULLNODE, &dot);
*p = q;
}
[
',' IDENT { q->next = new_id_list();
q = q->next;
q->id_ptr = dot.TOK_IDF;
}
',' IDENT
{ q->next = MkNode(Value,NULLNODE,NULLNODE,&dot);
q = q->next;
}
]*
{ q->next = 0; }
{ q->next = 0; }
;
SubrangeType(struct type **ptp;)
{
struct type *tp;
struct node *nd1 = 0, *nd2 = 0;
}:
/*
This is not exactly the rule in the new report, but see
the rule for "SimpleType".
*/
'[' ConstExpression
UPTO ConstExpression
'[' ConstExpression(&nd1)
UPTO ConstExpression(&nd2)
']'
/*
Evaluate the expressions. Check that they are indeed constant.
@ -295,7 +299,7 @@ FieldListSequence(struct scope *scope;):
FieldList(struct scope *scope;)
{
struct id_list *FldList;
struct node *FldList;
struct idf *id;
struct def *df, *df1;
struct type *tp;
@ -303,7 +307,7 @@ FieldList(struct scope *scope;)
[
IdentList(&FldList) ':' type(&tp)
{ EnterIdList(FldList, D_FIELD, 0, tp, scope);
FreeIdList(FldList);
FreeNode(FldList);
}
|
CASE
@ -312,7 +316,7 @@ FieldList(struct scope *scope;)
|
{ id = gen_anon_idf(); }
] /* Changed rule in new modula-2 */
':' qualident(D_TYPE|D_HTYPE, &df, "type")
':' qualident(D_TYPE|D_HTYPE, &df, "type", (struct node **) 0)
{ df1 = define(id, scope, D_FIELD);
df1->df_type = df->df_type;
}
@ -335,8 +339,11 @@ CaseLabelList:
CaseLabels [ ',' CaseLabels ]*
;
CaseLabels:
ConstExpression [ UPTO ConstExpression ]?
CaseLabels
{
struct node *nd1, *nd2 = 0;
}:
ConstExpression(&nd1) [ UPTO ConstExpression(&nd2) ]?
;
SetType(struct type **ptp;)
@ -364,7 +371,7 @@ PointerType(struct type **ptp;)
/* Either a Module or a Type, but in both cases defined
in this scope, so this is the correct identification
*/
qualident(D_TYPE|D_HTYPE, &df, "type")
qualident(D_TYPE|D_HTYPE, &df, "type", (struct node **) 0)
{
if (!df->df_type) {
error("type \"%s\" not declared",
@ -429,7 +436,7 @@ FormalTypeList(struct paramlist **ppr; struct type **ptp;)
{ p->next = 0; }
]?
')'
[ ':' qualident(D_TYPE|D_HTYPE, &df, "type")
[ ':' qualident(D_TYPE|D_HTYPE, &df, "type", (struct node **) 0)
{ *ptp = df->df_type; }
]?
;
@ -438,24 +445,26 @@ ConstantDeclaration
{
struct def *df;
struct idf *id;
struct node *nd;
}:
IDENT { id = dot.TOK_IDF; }
'=' ConstExpression { df = define(id, CurrentScope, D_CONST);
'=' ConstExpression(&nd){ df = define(id, CurrentScope, D_CONST);
/* ???? */
}
;
VariableDeclaration
{
struct id_list *VarList;
struct node *VarList;
struct type *tp;
struct node *nd = 0;
} :
IdentList(&VarList)
[
ConstExpression
ConstExpression(&nd)
]?
':' type(&tp)
{ EnterIdList(VarList, D_VARIABLE, 0, tp, CurrentScope);
FreeIdList(VarList);
FreeNode(VarList);
}
;

View file

@ -10,9 +10,10 @@ static char *RcsId = "$Header$";
#include "def.h"
#include "type.h"
#include "idf.h"
#include "misc.h"
#include "main.h"
#include "scope.h"
#include "LLlex.h"
#include "node.h"
#include "debug.h"
struct def *h_def; /* Pointer to free list of def structures */
@ -63,7 +64,7 @@ define(id, scope, kind)
return df;
}
if (kind != D_ERROR) {
error("identifier \"%s\" already declared", id->id_text);
error("identifier \"%s\" already declared", id->id_text);
}
return df;
}
@ -115,7 +116,7 @@ lookup(id, scope)
}
Export(ids, qualified)
register struct id_list *ids;
register struct node *ids;
{
/* From the current scope, the list of identifiers "ids" is
exported. Note this fact. If the export is not qualified, make
@ -125,36 +126,38 @@ Export(ids, qualified)
register struct def *df;
while (ids) {
df = define(ids->id_ptr, CurrentScope, D_ISEXPORTED);
df = define(ids->nd_IDF, CurrentScope, D_ISEXPORTED);
if (qualified) {
df->df_flags |= D_QEXPORTED;
}
else {
df->df_flags |= D_EXPORTED;
df = define(ids->id_ptr, enclosing(CurrentScope),
df = define(ids->nd_IDF, enclosing(CurrentScope),
D_IMPORT);
}
ids = ids->next;
}
}
Import(ids, id, local)
register struct id_list *ids;
struct idf *id;
Import(ids, idn, local)
register struct node *ids;
struct node *idn;
{
/* "ids" is a list of imported identifiers.
If "id" is a null-pointer, the identifiers are imported from the
enclosing scope. Otherwise they are imported from the module
indicated by "id", which must be visible in the enclosing scope.
An exception must be made for imports of the Compilation Unit.
If "idn" is a null-pointer, the identifiers are imported from
the enclosing scope. Otherwise they are imported from the module
indicated by "idn", which must be visible in the enclosing
scope. An exception must be made for imports of the
Compilation Unit.
This case is indicated by the value 0 of the flag "local".
In this case, if "id" is a null pointer, the "ids" identifiers
In this case, if "idn" is a null pointer, the "ids" identifiers
are all module identifiers. Their Definition Modules must be
read. Otherwise "id" is a module identifier whose Definition
read. Otherwise "idn" is a module identifier whose Definition
Module must be read. "ids" then represents a list of
identifiers defined in this module.
*/
register struct def *df;
register struct idf *id = 0;
int scope;
int kind;
int imp_kind;
@ -162,6 +165,7 @@ Import(ids, id, local)
#define FROM_ENCLOSING 1
struct def *lookfor(), *GetDefinitionModule();
if (idn) id = idn->nd_IDF;
kind = D_IMPORT;
scope = enclosing(CurrentScope)->sc_scope;
if (!id) imp_kind = FROM_ENCLOSING;
@ -173,35 +177,35 @@ Import(ids, id, local)
/* enter all "ids" with type D_ERROR */
kind = D_ERROR;
if (df->df_kind != D_ERROR) {
error("identifier \"%s\" does not represent a module", id->id_text);
node_error(idn, "identifier \"%s\" does not represent a module", id->id_text);
}
}
else scope = df->mod_scope;
}
while (ids) {
if (imp_kind == FROM_MODULE) {
if (!(df = lookup(ids->id_ptr, scope))) {
error("identifier \"%s\" not declared in qualifying module",
ids->id_ptr->id_text);
if (!(df = lookup(ids->nd_IDF, scope))) {
node_error(ids, "identifier \"%s\" not declared in qualifying module",
ids->nd_IDF->id_text);
df = ill_df;
}
else
if (!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
error("identifier \"%s\" not exported from qualifying module",
ids->id_ptr->id_text);
node_error(ids,"identifier \"%s\" not exported from qualifying module",
ids->nd_IDF->id_text);
}
}
else {
if (local) {
df = lookfor(ids->id_ptr,
df = lookfor(ids->nd_IDF,
enclosing(CurrentScope), 0);
} else df = GetDefinitionModule(ids->id_ptr);
} else df = GetDefinitionModule(ids->nd_IDF);
if (df->df_kind == D_ERROR) {
error("identifier \"%s\" not visible in enclosing scope",
ids->id_ptr->id_text);
node_error(ids, "identifier \"%s\" not visible in enclosing scope",
ids->nd_IDF->id_text);
}
}
define(ids->id_ptr, CurrentScope, kind)->imp_def = df;
define(ids->nd_IDF, CurrentScope, kind)->imp_def = df;
if (df->df_kind == D_TYPE &&
df->df_type->tp_fund == ENUMERATION) {
/* Also import all enumeration literals */

View file

@ -9,7 +9,8 @@ static char *RcsId = "$Header$";
#include "def.h"
#include "type.h"
#include "scope.h"
#include "misc.h"
#include "LLlex.h"
#include "node.h"
struct def *
Enter(name, kind, type, pnam)
@ -30,7 +31,7 @@ Enter(name, kind, type, pnam)
}
EnterIdList(idlist, kind, flags, type, scope)
register struct id_list *idlist;
register struct node *idlist;
struct type *type;
struct scope *scope;
{
@ -39,7 +40,7 @@ EnterIdList(idlist, kind, flags, type, scope)
int assval = 0;
while (idlist) {
df = define(idlist->id_ptr, scope, kind);
df = define(idlist->nd_IDF, scope, kind);
df->df_type = type;
df->df_flags = flags;
if (kind == D_ENUM) {

View file

@ -13,6 +13,7 @@ static char *RcsId = "$Header$";
#include "f_info.h"
#include "LLlex.h"
#include "main.h"
#include "node.h"
#define MAXERR_LINE 5 /* Number of error messages on one line ... */
#define ERROUT STDERR
@ -28,8 +29,6 @@ static char *RcsId = "$Header$";
#define VDEBUG 7
#endif
#define NILEXPR ((struct expr *) 0)
int err_occurred;
extern char *symbol2str();
@ -37,12 +36,12 @@ extern char *symbol2str();
/* There are three general error-message functions:
lexerror() lexical and pre-processor error messages
error() syntactic and semantic error messages
expr_error() errors in expressions
node_error() errors in nodes
The difference lies in the place where the file name and line
number come from.
Lexical errors report from the global variables LineNumber and
FileName, expression errors get their information from the
expression, whereas other errors use the information in the token.
FileName, node errors get their information from the
node, whereas other errors use the information in the token.
*/
#ifdef DEBUG
@ -50,7 +49,7 @@ extern char *symbol2str();
debug(level, fmt, args)
char *fmt;
{
if (level <= options['D']) _error(VDEBUG, NILEXPR, fmt, &args);
if (level <= options['D']) _error(VDEBUG, NULLNODE, fmt, &args);
}
#endif DEBUG
@ -58,44 +57,44 @@ debug(level, fmt, args)
error(fmt, args)
char *fmt;
{
_error(ERROR, NILEXPR, fmt, &args);
_error(ERROR, NULLNODE, fmt, &args);
}
/*VARARGS2*/
expr_error(expr, fmt, args)
struct expr *expr;
node_error(node, fmt, args)
struct node *node;
char *fmt;
{
_error(ERROR, expr, fmt, &args);
_error(ERROR, node, fmt, &args);
}
/*VARARGS1*/
warning(fmt, args)
char *fmt;
{
_error(WARNING, NILEXPR, fmt, &args);
_error(WARNING, NULLNODE, fmt, &args);
}
/*VARARGS2*/
expr_warning(expr, fmt, args)
struct expr *expr;
node_warning(node, fmt, args)
struct node *node;
char *fmt;
{
_error(WARNING, expr, fmt, &args);
_error(WARNING, node, fmt, &args);
}
/*VARARGS1*/
lexerror(fmt, args)
char *fmt;
{
_error(LEXERROR, NILEXPR, fmt, &args);
_error(LEXERROR, NULLNODE, fmt, &args);
}
/*VARARGS1*/
lexwarning(fmt, args)
char *fmt;
{
_error(LEXWARNING, NILEXPR, fmt, &args);
_error(LEXWARNING, NULLNODE, fmt, &args);
}
/*VARARGS1*/
@ -104,13 +103,13 @@ fatal(fmt, args)
int args;
{
_error(FATAL, NILEXPR, fmt, &args);
_error(FATAL, NULLNODE, fmt, &args);
sys_stop(S_EXIT);
}
_error(class, expr, fmt, argv)
_error(class, node, fmt, argv)
int class;
struct expr *expr;
struct node *node;
char *fmt;
int argv[];
{
@ -118,8 +117,10 @@ _error(class, expr, fmt, argv)
for a given line to MAXERR_LINE.
*/
static unsigned int last_ln = 0;
static int e_seen = 0;
unsigned int ln = 0;
static char * last_fn = 0;
char *fn = 0;
static int e_seen = 0;
char *remark = 0;
/* Since name and number are gathered from different places
@ -158,13 +159,19 @@ _error(class, expr, fmt, argv)
case FATAL:
remark = "fatal error --";
break;
#ifdef DEBUG
case VDEBUG:
remark = "(debug)";
break;
#endif DEBUG
}
/* the place */
switch (class) {
case WARNING:
case ERROR:
ln = /* ???? expr ? expr->ex_line : */ dot.tk_lineno;
fn = node ? node->nd_filename : dot.tk_filename;
ln = node ? node->nd_lineno : dot.tk_lineno;
break;
case LEXWARNING:
case LEXERROR:
@ -174,13 +181,14 @@ _error(class, expr, fmt, argv)
case VDEBUG:
#endif DEBUG
ln = LineNumber;
fn = FileName;
break;
}
#ifdef DEBUG
if (class != VDEBUG) {
#endif
if (ln == last_ln) {
if (fn == last_fn && ln == last_ln) {
/* we've seen this place before */
e_seen++;
if (e_seen == MAXERR_LINE) fmt = "etc ...";
@ -192,13 +200,14 @@ _error(class, expr, fmt, argv)
else {
/* brand new place */
last_ln = ln;
last_fn = fn;
e_seen = 0;
}
#ifdef DEBUG
}
#endif DEBUG
if (FileName) fprint(ERROUT, "\"%s\", line %u: ", FileName, ln);
if (fn) fprint(ERROUT, "\"%s\", line %u: ", fn, ln);
if (remark) fprint(ERROUT, "%s ", remark);

View file

@ -10,15 +10,18 @@ static char *RcsId = "$Header$";
#include "idf.h"
#include "def.h"
#include "scope.h"
#include "node.h"
}
number:
number(struct node **p;):
[
INTEGER
|
REAL
] { *p = MkNode(Value, NULLNODE, NULLNODE, dot); }
;
qualident(int types; struct def **pdf; char *str;)
qualident(int types; struct def **pdf; char *str; struct node **p;)
{
int scope;
int module;
@ -30,6 +33,9 @@ qualident(int types; struct def **pdf; char *str;)
*pdf = df;
if (df->df_kind == D_ERROR) types = 0;
}
if (p) {
*p = MkNode(Value, NULLNODE, NULLNODE,&dot);
}
}
[
{ if (types &&!(scope = has_selectors(df))) {
@ -38,8 +44,13 @@ qualident(int types; struct def **pdf; char *str;)
}
}
/* selector */
'.' IDENT
{ if (types) {
'.' { if (p) *p = MkNode(Link, *p, NULLNODE, &dot); }
IDENT
{ if (p) {
p = &((*p)->nd_right);
*p = MkNode(Value, NULLNODE, NULLNODE,&dot);
}
if (types) {
module = (df->df_kind == D_MODULE);
df = lookup(dot.TOK_IDF, scope);
if (!df) {
@ -62,99 +73,179 @@ qualident(int types; struct def **pdf; char *str;)
}
;
/* Inline substituted wherever it occurred
selector:
'.' /* field */ IDENT
'.' IDENT
;
*/
ExpList(struct node **pnd;)
{
struct node **nd;
} :
expression(pnd) { nd = pnd; }
[
',' { *nd = MkNode(Link, *nd, NULLNODE, &dot);
nd = &(*nd)->nd_right;
}
expression(nd)
]*
;
ExpList:
expression [ ',' expression ]*
;
ConstExpression:
expression
ConstExpression(struct node **pnd;):
expression(pnd)
/*
* Changed rule in new Modula-2.
* Check that the expression is a constant expression and evaluate!
*/
;
expression:
SimpleExpression [ relation SimpleExpression ]?
expression(struct node **pnd;)
{
struct node *nd;
} :
SimpleExpression(&nd)
[
/* relation */
[ '=' | '#' | UNEQUAL | '<' | LESSEQUAL | '>' |
GREATEREQUAL | IN
]
{ nd = MkNode(Oper, nd, NULLNODE, &dot); }
SimpleExpression(&(nd->nd_right))
]?
{ *pnd = nd; }
;
/* Inline in expression
relation:
'=' | '#' | UNEQUAL | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN
;
*/
SimpleExpression:
[ '+' | '-' ]? term [ AddOperator term ]*
;
AddOperator:
'+' | '-' | OR
;
term:
factor [ MulOperator factor ]*
;
MulOperator:
'*' | '/' | DIV | MOD | AND | '&'
;
factor
SimpleExpression(struct node **pnd;)
{
struct def *df;
register struct node *nd;
} :
qualident(0, &df, (char *) 0)
[ '+' | '-' ]?
term(pnd) { nd = *pnd; }
[
designator_tail? ActualParameters?
|
bare_set
]
|
bare_set
| %default
number
|
STRING
|
'(' expression ')'
|
NOT factor
;
bare_set:
'{' [ element [ ',' element ]* ]? '}'
;
ActualParameters:
'(' ExpList? ')'
;
element:
expression [ UPTO expression ]?
;
designator
{
struct def *df;
} :
qualident(0, &df, (char *) 0)
designator_tail?
;
designator_tail:
visible_designator_tail
[
selector
|
visible_designator_tail
/* AddOperator */
[ '+' | '-' | OR ]
{ *pnd = nd = MkNode(Oper, nd, NULLNODE, &dot); }
term(&(nd->nd_right))
]*
;
visible_designator_tail:
'[' ExpList ']'
|
'^'
/* Inline in "SimpleExpression"
AddOperator:
'+' | '-' | OR
;
*/
term(struct node **pnd;)
{
register struct node *nd;
}:
factor(pnd) { nd = *pnd; }
[
/* MulOperator */
[ '*' | '/' | DIV | MOD | AND | '&' ]
{ *pnd = nd = MkNode(Oper, nd, NULLNODE, &dot); }
factor(&(nd->nd_right))
]*
;
/* inline in "term"
MulOperator:
'*' | '/' | DIV | MOD | AND | '&'
;
*/
factor(struct node **p;)
{
struct def *df;
} :
qualident(0, &df, (char *) 0, p)
[
designator_tail(p)?
[
{ *p = MkNode(Call, p, NULLNODE, &dot); }
ActualParameters(&((*p)->nd_right))
]?
| { *p = MkNode(Call, p, NULLNODE, &dot); }
bare_set(&((*p)->nd_right))
]
|
bare_set(p)
| %default
number(p)
|
STRING { *p = MkNode(Value, NULLNODE, NULLNODE, &dot); }
|
'(' expression(p) ')'
|
NOT { *p = MkNode(Uoper, NULLNODE, NULLNODE, &dot); }
factor(&((*p)->nd_left))
;
bare_set(struct node **pnd;)
{
struct node **nd;
} :
'{' {
dot.tk_symb = SET;
*pnd = MkNode(Link, NULLNODE, NULLNODE, &dot);
nd = &((*pnd)->nd_left);
}
[
element(nd)
[
',' { *nd = MkNode(Link, *nd, NULLNODE, &dot);
nd = &((*nd)->nd_right);
}
element(nd)
]*
]?
'}'
;
ActualParameters(struct node **pnd;):
'(' ExpList(pnd)? ')'
;
element(struct node **pnd;):
expression(pnd)
[
UPTO { *pnd = MkNode(Link, *pnd, NULLNODE, &dot);}
expression(&((*pnd)->nd_right))
]?
;
designator(struct node **pnd;)
{
struct def *df;
} :
qualident(0, &df, (char *) 0, pnd)
designator_tail(pnd)?
;
designator_tail(struct node **pnd;):
visible_designator_tail(pnd)
[
/* selector */
'.' { *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
IDENT { (*pnd)->nd_right =
MkNode(Value, NULLNODE, NULLNODE, &dot);
}
|
visible_designator_tail(pnd)
]*
;
visible_designator_tail(struct node **pnd;):
'[' { *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
ExpList(&((*pnd)->nd_right))
']'
|
'^' { *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
;

View file

@ -2,13 +2,6 @@
/* $Header$ */
/* Structure to link idf structures together
*/
struct id_list {
struct id_list *next;
struct idf *id_ptr;
};
/* ALLOCDEF "id_list" */
#define is_anon_idf(x) ((x)->id_text[0] == '#')

View file

@ -24,22 +24,6 @@ match_id(id1, id2)
}
}
struct id_list *h_id_list; /* Header of free list of id_list structures */
/* FreeIdList: take a list of id_list structures and put them
on the free list of id_list structures
*/
FreeIdList(p)
struct id_list *p;
{
register struct id_list *q;
while (q = p) {
p = p->next;
free_id_list(q);
}
}
struct idf *
gen_anon_idf()
{

31
lang/m2/comp/node.H Normal file
View file

@ -0,0 +1,31 @@
/* N O D E O F A N A B S T R A C T P A R S E T R E E */
/* $Header$ */
struct node {
struct node *next;
#define nd_left next
struct node *nd_right;
int nd_class; /* kind of node */
#define Value 1 /* idf or constant */
#define Oper 2 /* binary operator */
#define Uoper 3 /* unary operator */
#define Call 4 /* cast or procedure - or function call */
#define Link 5
struct type *nd_type; /* type of this node */
struct token nd_token;
#define nd_symb nd_token.tk_symb
#define nd_lineno nd_token.tk_lineno
#define nd_filename nd_token.tk_filename
#define nd_IDF nd_token.TOK_IDF
#define nd_STR nd_token.TOK_STR
#define nd_SLE nd_token.TOK_SLE
#define nd_INT nd_token.TOK_INT
#define nd_REL nd_token.TOK_REL
};
/* ALLOCDEF "node" */
extern struct node *MkNode();
#define NULLNODE ((struct node *) 0)

41
lang/m2/comp/node.c Normal file
View file

@ -0,0 +1,41 @@
/* N O D E O F A N A B S T R A C T P A R S E T R E E */
static char *RcsId = "$Header$";
#include <em_label.h>
#include <em_arith.h>
#include <alloc.h>
#include "def.h"
#include "type.h"
#include "LLlex.h"
#include "node.h"
struct node *h_node; /* header of free list */
struct node *
MkNode(class, left, right, token)
struct node *left, *right;
struct token *token;
{
/* Create a node and initialize it with the given parameters
*/
register struct node *nd = new_node();
nd->nd_left = left;
nd->nd_right = right;
nd->nd_token = *token;
nd->nd_class = class;
nd->nd_type = NULLTYPE;
return nd;
}
FreeNode(nd)
register struct node *nd;
{
/* Put nodes that are no longer needed back onto the free
list
*/
if (nd->nd_left) FreeNode(nd->nd_left);
if (nd->nd_right) FreeNode(nd->nd_right);
free_node(nd);
}

View file

@ -7,12 +7,12 @@ static char *RcsId = "$Header$";
#include <em_arith.h>
#include <em_label.h>
#include "idf.h"
#include "misc.h"
#include "main.h"
#include "LLlex.h"
#include "scope.h"
#include "def.h"
#include "type.h"
#include "node.h"
#include "debug.h"
static struct idf *impl_name = 0;
@ -57,13 +57,16 @@ ModuleDeclaration
}
;
priority:
'[' ConstExpression ']'
priority
{
struct node *nd;
}:
'[' ConstExpression(&nd) ']'
;
export(int def;)
{
struct id_list *ExportList;
struct node *ExportList;
int QUALflag = 0;
} :
EXPORT
@ -74,17 +77,17 @@ export(int def;)
{
if (!def) Export(ExportList, QUALflag);
else warning("export list in definition module ignored");
FreeIdList(ExportList);
FreeNode(ExportList);
}
;
import(int local;)
{
struct id_list *ImportList;
struct idf *id = 0;
struct node *ImportList;
struct node *id = 0;
} :
[ FROM
IDENT { id = dot.TOK_IDF; }
IDENT { id = MkNode(Value, NULLNODE, NULLNODE, &dot); }
]?
IMPORT IdentList(&ImportList) ';'
/*
@ -95,7 +98,8 @@ import(int local;)
*/
{
Import(ImportList, id, local);
FreeIdList(ImportList);
FreeNode(ImportList);
if (id) FreeNode(id);
}
;

View file

@ -2,20 +2,27 @@
{
static char *RcsId = "$Header$";
#include <em_arith.h>
#include "LLlex.h"
#include "node.h"
}
statement:
statement
{
struct node *nd1, *nd2;
} :
[
/*
* This part is not in the reference grammar. The reference grammar
* states : assignment | ProcedureCall | ...
* but this gives LL(1) conflicts
*/
designator
designator(&nd1)
[
ActualParameters?
ActualParameters(&nd2)?
|
BECOMES expression
BECOMES expression(&nd2)
]
/*
* end of changed part
@ -37,7 +44,10 @@ statement:
|
EXIT
|
RETURN expression?
RETURN
[
expression(&nd1)
]?
]?
;
@ -57,15 +67,21 @@ StatementSequence:
statement [ ';' statement ]*
;
IfStatement:
IF expression THEN StatementSequence
[ ELSIF expression THEN StatementSequence ]*
IfStatement
{
struct node *nd1;
} :
IF expression(&nd1) THEN StatementSequence
[ ELSIF expression(&nd1) THEN StatementSequence ]*
[ ELSE StatementSequence ]?
END
;
CaseStatement:
CASE expression OF case [ '|' case ]*
CaseStatement
{
struct node *nd;
} :
CASE expression(&nd) OF case [ '|' case ]*
[ ELSE StatementSequence ]?
END
;
@ -75,19 +91,28 @@ case:
/* This rule is changed in new modula-2 */
;
WhileStatement:
WHILE expression DO StatementSequence END
WhileStatement
{
struct node *nd;
}:
WHILE expression(&nd) DO StatementSequence END
;
RepeatStatement:
REPEAT StatementSequence UNTIL expression
RepeatStatement
{
struct node *nd;
}:
REPEAT StatementSequence UNTIL expression(&nd)
;
ForStatement:
ForStatement
{
struct node *nd1, *nd2, *nd3;
}:
FOR IDENT
BECOMES expression
TO expression
[ BY ConstExpression ]?
BECOMES expression(&nd1)
TO expression(&nd2)
[ BY ConstExpression(&nd3) ]?
DO StatementSequence END
;
@ -95,6 +120,9 @@ LoopStatement:
LOOP StatementSequence END
;
WithStatement:
WITH designator DO StatementSequence END
WithStatement
{
struct node *nd;
}:
WITH designator(&nd) DO StatementSequence END
;

View file

@ -11,7 +11,8 @@ static char *RcsId = "$Header$";
#include "def.h"
#include "type.h"
#include "idf.h"
#include "misc.h"
#include "LLlex.h"
#include "node.h"
/* To be created dynamically in main() from defaults or from command
line parameters.
@ -164,7 +165,7 @@ has_selectors(df)
*/
struct paramlist *
ParamList(ids, tp, VARp)
register struct id_list *ids;
register struct node *ids;
struct type *tp;
{
register struct paramlist *pr;