mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 07:12:02 +00:00
095b11bc36
is unable to synthesize one. - Converted xlatcc to use lemon during its build process. Now you don't need bison to rebuild everything anymore. SVN r470 (trunk)
828 lines
16 KiB
Text
828 lines
16 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;
|
|
|
|
while ((tokentype = yylex(&token)) != 0)
|
|
{
|
|
Parse (pParser, tokentype, 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 ::= 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.
|
|
|
|
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;
|
|
}
|