mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 08:31:45 +00:00
ec17f5a5b9
error handling. - Fixed: dehsupp/scanner.re defined "}" as the token RPAREN. dehsupp/parse.y also defined action_list_def as needing a RBARCE. I'm surprised it worked at all before. I guess Lemon really was too accepting. - Changed the way that xlatcc handles include statements so that I don't need to modify the logic of lempar.c. I also discovered that the grammar was improperly defined and only accepted the first statement. It worked before because Lemon used to accept multiple times before reaching the EOF token. I have also verified that it is still generating the proper lumps. - Removed some unused wadsrc files from the repository. - Fixed my re2c upgrade. - Updated lemon.c to v1.53. SVN r711 (trunk)
852 lines
17 KiB
Text
852 lines
17 KiB
Text
%include{
|
|
#include "xlat.h"
|
|
#include "xlat-parse.h"
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
|
|
int yyerror (char *s);
|
|
|
|
typedef struct _Symbol
|
|
{
|
|
struct _Symbol *Next;
|
|
int Value;
|
|
char Sym[1];
|
|
} Symbol;
|
|
|
|
static bool FindToken (char *tok, int *type);
|
|
static void AddSym (char *sym, int val);
|
|
static bool FindSym (char *sym, Symbol **val);
|
|
|
|
static int EnumVal;
|
|
|
|
struct ListFilter
|
|
{
|
|
WORD filter;
|
|
BYTE value;
|
|
};
|
|
|
|
typedef struct _morefilters
|
|
{
|
|
struct _morefilters *next;
|
|
struct ListFilter filter;
|
|
} MoreFilters;
|
|
|
|
typedef struct _morelines
|
|
{
|
|
struct _morelines *next;
|
|
BoomArg arg;
|
|
} MoreLines;
|
|
|
|
typedef struct _specialargs
|
|
{
|
|
BYTE addflags;
|
|
BYTE args[5];
|
|
} SpecialArgs;
|
|
|
|
typedef struct _boomarg
|
|
{
|
|
BYTE constant;
|
|
WORD mask;
|
|
MoreFilters *filters;
|
|
} ParseBoomArg;
|
|
|
|
typedef union YYSTYPE
|
|
{
|
|
int val;
|
|
char sym[80];
|
|
char string[80];
|
|
Symbol *symval;
|
|
} YYSTYPE;
|
|
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
|
|
int yylex (YYSTYPE *yylval)
|
|
{
|
|
char token[80];
|
|
int toksize;
|
|
int c;
|
|
|
|
loop:
|
|
while (Source == NULL)
|
|
{
|
|
if (!EndFile ())
|
|
return 0;
|
|
}
|
|
while (isspace (c = fgetc (Source)) && c != EOF)
|
|
{
|
|
if (c == '\n')
|
|
SourceLine++;
|
|
}
|
|
|
|
if (c == EOF)
|
|
{
|
|
if (EndFile ())
|
|
goto loop;
|
|
return 0;
|
|
}
|
|
if (isdigit (c))
|
|
{
|
|
int buildup = c - '0';
|
|
if (c == '0')
|
|
{
|
|
c = fgetc (Source);
|
|
if (c == 'x' || c == 'X')
|
|
{
|
|
for (;;)
|
|
{
|
|
c = fgetc (Source);
|
|
if (isdigit (c))
|
|
{
|
|
buildup = (buildup<<4) + c - '0';
|
|
}
|
|
else if (c >= 'a' && c <= 'f')
|
|
{
|
|
buildup = (buildup<<4) + c - 'a' + 10;
|
|
}
|
|
else if (c >= 'A' && c <= 'F')
|
|
{
|
|
buildup = (buildup<<4) + c - 'A' + 10;
|
|
}
|
|
else
|
|
{
|
|
ungetc (c, Source);
|
|
yylval->val = buildup;
|
|
return NUM;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ungetc (c, Source);
|
|
}
|
|
}
|
|
while (isdigit (c = fgetc (Source)))
|
|
{
|
|
buildup = buildup*10 + c - '0';
|
|
}
|
|
ungetc (c, Source);
|
|
yylval->val = buildup;
|
|
return NUM;
|
|
}
|
|
if (isalpha (c))
|
|
{
|
|
int buildup = 0;
|
|
|
|
token[0] = c;
|
|
toksize = 1;
|
|
while (toksize < 79 && (isalnum (c = fgetc (Source)) || c == '_'))
|
|
{
|
|
token[toksize++] = c;
|
|
}
|
|
token[toksize] = 0;
|
|
if (toksize == 79 && isalnum (c))
|
|
{
|
|
while (isalnum (c = fgetc (Source)))
|
|
;
|
|
}
|
|
ungetc (c, Source);
|
|
if (FindToken (token, &buildup))
|
|
{
|
|
return buildup;
|
|
}
|
|
if (FindSym (token, &yylval->symval))
|
|
{
|
|
return SYMNUM;
|
|
}
|
|
strcpy (yylval->sym, token);
|
|
return SYM;
|
|
}
|
|
if (c == '/')
|
|
{
|
|
c = fgetc (Source);
|
|
if (c == '*')
|
|
{
|
|
for (;;)
|
|
{
|
|
while ((c = fgetc (Source)) != '*' && c != EOF)
|
|
{
|
|
if (c == '\n')
|
|
SourceLine++;
|
|
}
|
|
if (c == EOF)
|
|
return 0;
|
|
if ((c = fgetc (Source)) == '/')
|
|
goto loop;
|
|
if (c == EOF)
|
|
return 0;
|
|
ungetc (c, Source);
|
|
}
|
|
}
|
|
else if (c == '/')
|
|
{
|
|
while ((c = fgetc (Source)) != '\n' && c != EOF)
|
|
;
|
|
if (c == '\n')
|
|
SourceLine++;
|
|
else if (c == EOF)
|
|
return 0;
|
|
goto loop;
|
|
}
|
|
else
|
|
{
|
|
ungetc (c, Source);
|
|
return DIVIDE;
|
|
}
|
|
}
|
|
if (c == '"')
|
|
{
|
|
int tokensize = 0;
|
|
while ((c = fgetc (Source)) != '"' && c != EOF)
|
|
{
|
|
yylval->string[tokensize++] = c;
|
|
}
|
|
yylval->string[tokensize] = 0;
|
|
return STRING;
|
|
}
|
|
if (c == '|')
|
|
{
|
|
c = fgetc (Source);
|
|
if (c == '=')
|
|
return OR_EQUAL;
|
|
ungetc (c, Source);
|
|
return OR;
|
|
}
|
|
switch (c)
|
|
{
|
|
case '^': return XOR;
|
|
case '&': return AND;
|
|
case '-': return MINUS;
|
|
case '+': return PLUS;
|
|
case '*': return MULTIPLY;
|
|
case '(': return LPAREN;
|
|
case ')': return RPAREN;
|
|
case ',': return COMMA;
|
|
case '{': return LBRACE;
|
|
case '}': return RBRACE;
|
|
case '=': return EQUALS;
|
|
case ';': return SEMICOLON;
|
|
case ':': return COLON;
|
|
case '[': return LBRACKET;
|
|
case ']': return RBRACKET;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
void *ParseAlloc(void *(*mallocProc)(size_t));
|
|
void Parse(void *yyp, int yymajor, YYSTYPE yyminor);
|
|
void ParseFree(void *p, void (*freeProc)(void*));
|
|
void ParseTrace(FILE *TraceFILE, char *zTracePrompt);
|
|
|
|
void yyparse (void)
|
|
{
|
|
void *pParser = ParseAlloc (malloc);
|
|
YYSTYPE token;
|
|
int tokentype;
|
|
int include_state = 0;
|
|
|
|
while ((tokentype = yylex(&token)) != 0)
|
|
{
|
|
/* Whenever the sequence INCLUDE STRING is encountered in the token
|
|
* stream, feed a dummy NOP token to the parser so that it will
|
|
* reduce the include_statement before grabbing any more tokens
|
|
* from the current file.
|
|
*/
|
|
if (tokentype == INCLUDE && include_state == 0)
|
|
{
|
|
include_state = 1;
|
|
}
|
|
else if (tokentype == STRING && include_state == 1)
|
|
{
|
|
include_state = 2;
|
|
}
|
|
else
|
|
{
|
|
include_state = 0;
|
|
}
|
|
Parse (pParser, tokentype, token);
|
|
if (include_state == 2)
|
|
{
|
|
include_state = 0;
|
|
Parse (pParser, NOP, token);
|
|
}
|
|
}
|
|
memset (&token, 0, sizeof(token));
|
|
Parse (pParser, 0, token);
|
|
ParseFree (pParser, free);
|
|
}
|
|
|
|
static Symbol *FirstSym;
|
|
|
|
static void AddSym (char *sym, int val)
|
|
{
|
|
Symbol *syme = malloc (strlen (sym) + sizeof(Symbol));
|
|
syme->Next = FirstSym;
|
|
syme->Value = val;
|
|
strcpy (syme->Sym, sym);
|
|
FirstSym = syme;
|
|
}
|
|
|
|
static bool FindSym (char *sym, Symbol **val)
|
|
{
|
|
Symbol *syme = FirstSym;
|
|
|
|
while (syme != NULL)
|
|
{
|
|
if (strcmp (syme->Sym, sym) == 0)
|
|
{
|
|
*val = syme;
|
|
return 1;
|
|
}
|
|
syme = syme->Next;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static bool FindToken (char *tok, int *type)
|
|
{
|
|
static const char tokens[][8] =
|
|
{
|
|
"endl", "print", "include", "special", "define", "enum",
|
|
"arg5", "arg4", "arg3", "arg2", "flags", "lineid", "tag"
|
|
|
|
};
|
|
static const short types[] =
|
|
{
|
|
ENDL, PRINT, INCLUDE, SPECIAL, DEFINE, ENUM,
|
|
ARG5, ARG4, ARG3, ARG2, FLAGS, LINEID, TAG
|
|
};
|
|
int i;
|
|
|
|
for (i = sizeof(tokens)/sizeof(tokens[0])-1; i >= 0; i--)
|
|
{
|
|
if (strcmp (tok, tokens[i]) == 0)
|
|
{
|
|
*type = types[i];
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int yyerror (char *s)
|
|
{
|
|
if (SourceName != NULL)
|
|
printf ("%s, line %d: %s\n", SourceName, SourceLine, s);
|
|
else
|
|
printf ("%s\n", s);
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
%token_type {YYSTYPE}
|
|
|
|
%syntax_error {yyerror("syntax error");}
|
|
|
|
%type exp {int}
|
|
%type special_args {SpecialArgs}
|
|
%type list_val {struct ListFilter}
|
|
%type arg_list {MoreFilters *}
|
|
%type boom_args {ParseBoomArg}
|
|
%type boom_op {int}
|
|
%type boom_selector {int}
|
|
%type boom_line {BoomArg}
|
|
%type boom_body {MoreLines *}
|
|
%type maybe_argcount {int}
|
|
|
|
%left OR.
|
|
%left XOR.
|
|
%left AND.
|
|
%left MINUS PLUS.
|
|
%left MULTIPLY DIVIDE.
|
|
%left NEG.
|
|
|
|
main ::= translation_unit.
|
|
|
|
exp(A) ::= NUM(B). { A = B.val; }
|
|
exp(A) ::= SYMNUM(B). { A = B.symval->Value; }
|
|
exp(A) ::= exp(B) PLUS exp(C). { A = B + C; }
|
|
exp(A) ::= exp(B) MINUS exp(C). { A = B - C; }
|
|
exp(A) ::= exp(B) MULTIPLY exp(C). { A = B * C; }
|
|
exp(A) ::= exp(B) DIVIDE exp(C). { A = B / C; }
|
|
exp(A) ::= exp(B) OR exp(C). { A = B | C; }
|
|
exp(A) ::= exp(B) AND exp(C). { A = B & C; }
|
|
exp(A) ::= exp(B) XOR exp(C). { A = B ^ C; }
|
|
exp(A) ::= MINUS exp(B). [NEG] { A = -B; }
|
|
exp(A) ::= LPAREN exp(B) RPAREN. { A = B; }
|
|
|
|
translation_unit ::= . /* empty */
|
|
translation_unit ::= translation_unit external_declaration.
|
|
|
|
external_declaration ::= define_statement.
|
|
external_declaration ::= include_statement.
|
|
external_declaration ::= print_statement.
|
|
external_declaration ::= enum_statement.
|
|
external_declaration ::= linetype_declaration.
|
|
external_declaration ::= boom_declaration.
|
|
external_declaration ::= special_declaration.
|
|
external_declaration ::= NOP.
|
|
|
|
print_statement ::= PRINT LPAREN print_list RPAREN.
|
|
{
|
|
printf ("\n");
|
|
}
|
|
|
|
print_list ::= . /* EMPTY */
|
|
print_list ::= print_item.
|
|
print_list ::= print_item COMMA print_list.
|
|
|
|
print_item ::= STRING(A). { printf ("%s", A.string); }
|
|
print_item ::= exp(A). { printf ("%d", A); }
|
|
print_item ::= ENDL. { printf ("\n"); }
|
|
|
|
define_statement ::= DEFINE SYM(A) LPAREN exp(B) RPAREN.
|
|
{
|
|
AddSym (A.sym, B);
|
|
}
|
|
|
|
include_statement ::= INCLUDE STRING(A).
|
|
{
|
|
IncludeFile (A.string);
|
|
}
|
|
|
|
enum_statement ::= enum_open enum_list RBRACE.
|
|
|
|
enum_open ::= ENUM LBRACE.
|
|
{
|
|
EnumVal = 0;
|
|
}
|
|
|
|
enum_list ::= . /* empty */
|
|
enum_list ::= single_enum.
|
|
enum_list ::= single_enum COMMA enum_list.
|
|
|
|
single_enum ::= SYM(A).
|
|
{
|
|
AddSym (A.sym, EnumVal++);
|
|
}
|
|
|
|
single_enum ::= SYM(A) EQUALS exp(B).
|
|
{
|
|
AddSym (A.sym, EnumVal = B);
|
|
}
|
|
|
|
/* special declarations work just like they do for ACS, so
|
|
* specials can be defined just by including zspecial.acs
|
|
*/
|
|
special_declaration ::= SPECIAL special_list SEMICOLON.
|
|
|
|
special_list ::= special_def.
|
|
special_list ::= special_list COMMA special_def.
|
|
|
|
special_def ::= exp(A) COLON SYM(B) LPAREN maybe_argcount RPAREN.
|
|
{
|
|
AddSym (B.sym, A);
|
|
}
|
|
special_def ::= exp COLON SYMNUM(B) LPAREN maybe_argcount RPAREN.
|
|
{
|
|
printf ("%s, line %d: %s is already defined\n", SourceName, SourceLine, B.symval->Sym);
|
|
}
|
|
|
|
maybe_argcount ::= . /* empty */
|
|
maybe_argcount ::= exp.
|
|
maybe_argcount ::= exp COMMA exp.
|
|
|
|
linetype_declaration ::= exp(linetype) EQUALS exp(flags) COMMA exp(special) LPAREN special_args(arg) RPAREN.
|
|
{
|
|
Simple[linetype].NewSpecial = special;
|
|
Simple[linetype].Flags = flags | arg.addflags;
|
|
Simple[linetype].Args[0] = arg.args[0];
|
|
Simple[linetype].Args[1] = arg.args[1];
|
|
Simple[linetype].Args[2] = arg.args[2];
|
|
Simple[linetype].Args[3] = arg.args[3];
|
|
Simple[linetype].Args[4] = arg.args[4];
|
|
}
|
|
linetype_declaration ::= exp EQUALS exp COMMA SYM(S) LPAREN special_args RPAREN.
|
|
{
|
|
printf ("%s, line %d: %s is undefined\n", SourceName, SourceLine, S.sym);
|
|
}
|
|
|
|
boom_declaration ::= LBRACKET exp(special) RBRACKET LPAREN exp(firsttype) COMMA exp(lasttype) RPAREN LBRACE boom_body(stores) RBRACE.
|
|
{
|
|
if (NumBoomish == MAX_BOOMISH)
|
|
{
|
|
MoreLines *probe = stores;
|
|
|
|
while (probe != NULL)
|
|
{
|
|
MoreLines *next = probe->next;
|
|
free (probe);
|
|
probe = next;
|
|
}
|
|
printf ("%s, line %d: Too many BOOM translators\n", SourceName, SourceLine);
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
MoreLines *probe;
|
|
|
|
Boomish[NumBoomish].FirstLinetype = firsttype;
|
|
Boomish[NumBoomish].LastLinetype = lasttype;
|
|
Boomish[NumBoomish].NewSpecial = special;
|
|
|
|
for (i = 0, probe = stores; probe != NULL; i++)
|
|
{
|
|
MoreLines *next = probe->next;;
|
|
if (i < MAX_BOOMISH_EXEC)
|
|
{
|
|
Boomish[NumBoomish].Args[i] = probe->arg;
|
|
}
|
|
else if (i == MAX_BOOMISH_EXEC)
|
|
{
|
|
printf ("%s, line %d: Too many commands for this BOOM translator\n", SourceName, SourceLine);
|
|
}
|
|
free (probe);
|
|
probe = next;
|
|
}
|
|
if (i < MAX_BOOMISH_EXEC)
|
|
{
|
|
Boomish[NumBoomish].Args[i].bDefined = 0;
|
|
}
|
|
NumBoomish++;
|
|
}
|
|
}
|
|
|
|
boom_body(A) ::= . /* empty */
|
|
{
|
|
A = NULL;
|
|
}
|
|
boom_body(A) ::= boom_line(B) boom_body(C).
|
|
{
|
|
A = malloc (sizeof(MoreLines));
|
|
A->next = C;
|
|
A->arg = B;
|
|
}
|
|
|
|
boom_line(A) ::= boom_selector(sel) boom_op(op) boom_args(args).
|
|
{
|
|
A.bDefined = 1;
|
|
A.bOrExisting = (op == OR_EQUAL);
|
|
A.bUseConstant = (args.filters == NULL);
|
|
A.ArgNum = sel;
|
|
A.ConstantValue = args.constant;
|
|
A.AndValue = args.mask;
|
|
|
|
if (args.filters != NULL)
|
|
{
|
|
int i;
|
|
MoreFilters *probe;
|
|
|
|
for (i = 0, probe = args.filters; probe != NULL; i++)
|
|
{
|
|
MoreFilters *next = probe->next;
|
|
if (i < 15)
|
|
{
|
|
A.ResultFilter[i] = probe->filter.filter;
|
|
A.ResultValue[i] = probe->filter.value;
|
|
}
|
|
else if (i == 15)
|
|
{
|
|
yyerror ("Lists can only have 15 elements");
|
|
}
|
|
free (probe);
|
|
probe = next;
|
|
}
|
|
A.ListSize = i > 15 ? 15 : i;
|
|
}
|
|
}
|
|
|
|
boom_selector(A) ::= FLAGS. { A = 4; }
|
|
boom_selector(A) ::= ARG2. { A = 0; }
|
|
boom_selector(A) ::= ARG3. { A = 1; }
|
|
boom_selector(A) ::= ARG4. { A = 2; }
|
|
boom_selector(A) ::= ARG5. { A = 3; }
|
|
|
|
boom_op(A) ::= EQUALS. { A = '='; }
|
|
boom_op(A) ::= OR_EQUAL. { A = OR_EQUAL; }
|
|
|
|
boom_args(A) ::= exp(B).
|
|
{
|
|
A.constant = B;
|
|
A.filters = NULL;
|
|
}
|
|
boom_args(A) ::= exp(B) LBRACKET arg_list(C) RBRACKET.
|
|
{
|
|
A.mask = B;
|
|
A.filters = C;
|
|
}
|
|
|
|
arg_list(A) ::= list_val(B).
|
|
{
|
|
A = malloc (sizeof(MoreFilters));
|
|
A->next = NULL;
|
|
A->filter = B;
|
|
}
|
|
arg_list(A) ::= list_val(B) COMMA arg_list(C).
|
|
{
|
|
A = malloc (sizeof(MoreFilters));
|
|
A->next = C;
|
|
A->filter = B;
|
|
}
|
|
|
|
list_val(A) ::= exp(B) COLON exp(C).
|
|
{
|
|
A.filter = B;
|
|
A.value = C;
|
|
}
|
|
|
|
special_args(Z) ::= . /* empty */
|
|
{
|
|
Z.addflags = 0;
|
|
memset (Z.args, 0, 5);
|
|
}
|
|
special_args(Z) ::= TAG.
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT1;
|
|
memset (Z.args, 0, 5);
|
|
}
|
|
special_args(Z) ::= TAG COMMA exp(B).
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT1;
|
|
Z.args[0] = 0;
|
|
Z.args[1] = B;
|
|
Z.args[2] = 0;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= TAG COMMA exp(B) COMMA exp(C).
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT1;
|
|
Z.args[0] = 0;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= TAG COMMA exp(B) COMMA exp(C) COMMA exp(D).
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT1;
|
|
Z.args[0] = 0;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= TAG COMMA exp(B) COMMA exp(C) COMMA exp(D) COMMA exp(E).
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT1;
|
|
Z.args[0] = 0;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = E;
|
|
}
|
|
special_args(Z) ::= TAG COMMA TAG.
|
|
{
|
|
Z.addflags = SIMPLE_HAS2TAGS;
|
|
Z.args[0] = Z.args[1] = 0;
|
|
Z.args[2] = 0;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= TAG COMMA TAG COMMA exp(C).
|
|
{
|
|
Z.addflags = SIMPLE_HAS2TAGS;
|
|
Z.args[0] = Z.args[1] = 0;
|
|
Z.args[2] = C;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= TAG COMMA TAG COMMA exp(C) COMMA exp(D).
|
|
{
|
|
Z.addflags = SIMPLE_HAS2TAGS;
|
|
Z.args[0] = Z.args[1] = 0;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= TAG COMMA TAG COMMA exp(C) COMMA exp(D) COMMA exp(E).
|
|
{
|
|
Z.addflags = SIMPLE_HAS2TAGS;
|
|
Z.args[0] = Z.args[1] = 0;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = E;
|
|
}
|
|
special_args(Z) ::= LINEID.
|
|
{
|
|
Z.addflags = SIMPLE_HASLINEID;
|
|
memset (Z.args, 0, 5);
|
|
}
|
|
special_args(Z) ::= LINEID COMMA exp(B).
|
|
{
|
|
Z.addflags = SIMPLE_HASLINEID;
|
|
Z.args[0] = 0;
|
|
Z.args[1] = B;
|
|
Z.args[2] = 0;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= LINEID COMMA exp(B) COMMA exp(C).
|
|
{
|
|
Z.addflags = SIMPLE_HASLINEID;
|
|
Z.args[0] = 0;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= LINEID COMMA exp(B) COMMA exp(C) COMMA exp(D).
|
|
{
|
|
Z.addflags = SIMPLE_HASLINEID;
|
|
Z.args[0] = 0;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= LINEID COMMA exp(B) COMMA exp(C) COMMA exp(D) COMMA exp(E).
|
|
{
|
|
Z.addflags = SIMPLE_HASLINEID;
|
|
Z.args[0] = 0;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = E;
|
|
}
|
|
special_args(Z) ::= exp(A).
|
|
{
|
|
Z.addflags = 0;
|
|
Z.args[0] = A;
|
|
Z.args[1] = 0;
|
|
Z.args[2] = 0;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA exp(B).
|
|
{
|
|
Z.addflags = 0;
|
|
Z.args[0] = A;
|
|
Z.args[1] = B;
|
|
Z.args[2] = 0;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C).
|
|
{
|
|
Z.addflags = 0;
|
|
Z.args[0] = A;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA exp(D).
|
|
{
|
|
Z.addflags = 0;
|
|
Z.args[0] = A;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA exp(D) COMMA exp(E).
|
|
{
|
|
Z.addflags = 0;
|
|
Z.args[0] = A;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = E;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA TAG.
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT2;
|
|
Z.args[0] = A;
|
|
Z.args[1] = 0;
|
|
Z.args[2] = 0;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA TAG COMMA exp(C).
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT2;
|
|
Z.args[0] = A;
|
|
Z.args[1] = 0;
|
|
Z.args[2] = C;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA TAG COMMA exp(C) COMMA exp(D).
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT2;
|
|
Z.args[0] = A;
|
|
Z.args[1] = 0;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA TAG COMMA exp(C) COMMA exp(D) COMMA exp(E).
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT2;
|
|
Z.args[0] = A;
|
|
Z.args[1] = 0;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = E;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA exp(B) COMMA TAG.
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT3;
|
|
Z.args[0] = A;
|
|
Z.args[1] = B;
|
|
Z.args[2] = 0;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA exp(B) COMMA TAG COMMA exp(D).
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT3;
|
|
Z.args[0] = A;
|
|
Z.args[1] = B;
|
|
Z.args[2] = 0;
|
|
Z.args[3] = D;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA exp(B) COMMA TAG COMMA exp(D) COMMA exp(E).
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT3;
|
|
Z.args[0] = A;
|
|
Z.args[1] = B;
|
|
Z.args[2] = 0;
|
|
Z.args[3] = D;
|
|
Z.args[4] = E;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA TAG.
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT4;
|
|
Z.args[0] = A;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = 0;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA TAG COMMA exp(E).
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT4;
|
|
Z.args[0] = A;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = 0;
|
|
Z.args[4] = E;
|
|
}
|
|
special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA exp(D) COMMA TAG.
|
|
{
|
|
Z.addflags = SIMPLE_HASTAGAT5;
|
|
Z.args[0] = A;
|
|
Z.args[1] = B;
|
|
Z.args[2] = C;
|
|
Z.args[3] = D;
|
|
Z.args[4] = 0;
|
|
}
|