Add new state options to parser and actually enable them

- Added new state options that DECORATE got to the lemon parser.
- Enable token generation for state options. They were previously not
  generated, so the grammar treated them as function calls instead.
This commit is contained in:
Randy Heit 2016-03-03 15:34:42 -06:00
parent 078d37e073
commit 964ff46063
8 changed files with 101 additions and 39 deletions

View file

@ -120,6 +120,7 @@ FScanner &FScanner::operator=(const FScanner &other)
CMode = other.CMode; CMode = other.CMode;
Escape = other.Escape; Escape = other.Escape;
StateMode = other.StateMode; StateMode = other.StateMode;
StateOptions = other.StateOptions;
// Copy public members // Copy public members
if (other.String == other.StringBuffer) if (other.String == other.StringBuffer)
@ -277,6 +278,7 @@ void FScanner::PrepareScript ()
CMode = false; CMode = false;
Escape = true; Escape = true;
StateMode = 0; StateMode = 0;
StateOptions = false;
StringBuffer[0] = '\0'; StringBuffer[0] = '\0';
BigStringBuffer = ""; BigStringBuffer = "";
} }
@ -409,15 +411,19 @@ void FScanner::SetEscape (bool esc)
// * ; // * ;
// * } - Automatically exits state mode after it's seen. // * } - Automatically exits state mode after it's seen.
// //
// Quoted strings are returned as TOK_NonWhitespace, minus the quotes. In // Quoted strings are returned as TOK_NonWhitespace, minus the quotes. Once
// addition, any two consecutive sequences of TOK_NonWhitespace also exit // two consecutive sequences of TOK_NonWhitespace have been encountered
// state mode. // (which would be the state's sprite and frame specifiers), nearly normal
// processing resumes, with the exception that various identifiers
// used for state options will be returned as tokens and not identifiers.
// This ends once a ';' or '{' character is encountered.
// //
//========================================================================== //==========================================================================
void FScanner::SetStateMode(bool stately) void FScanner::SetStateMode(bool stately)
{ {
StateMode = stately ? 2 : 0; StateMode = stately ? 2 : 0;
StateOptions = stately;
} }
//========================================================================== //==========================================================================

View file

@ -28,6 +28,7 @@ public:
void SetCMode(bool cmode); void SetCMode(bool cmode);
void SetEscape(bool esc); void SetEscape(bool esc);
void SetStateMode(bool stately); void SetStateMode(bool stately);
void DisableStateOptions();
const SavedPos SavePos(); const SavedPos SavePos();
void RestorePos(const SavedPos &pos); void RestorePos(const SavedPos &pos);
@ -99,6 +100,7 @@ protected:
int LastGotLine; int LastGotLine;
bool CMode; bool CMode;
BYTE StateMode; BYTE StateMode;
bool StateOptions;
bool Escape; bool Escape;
}; };

View file

@ -49,7 +49,7 @@ std2:
TOK2 = (NWS\STOP1); TOK2 = (NWS\STOP1);
TOKC2 = (NWS\STOPC); TOKC2 = (NWS\STOPC);
*/ */
#define RET(x) TokenType = x; goto normal_token; #define RET(x) TokenType = (x); goto normal_token;
if (tokens && StateMode != 0) if (tokens && StateMode != 0)
{ {
/*!re2c /*!re2c
@ -63,10 +63,10 @@ std2:
'wait' { RET(TK_Wait); } 'wait' { RET(TK_Wait); }
'fail' { RET(TK_Fail); } 'fail' { RET(TK_Fail); }
'loop' { RET(TK_Loop); } 'loop' { RET(TK_Loop); }
'goto' { StateMode = 0; RET(TK_Goto); } 'goto' { StateMode = 0; StateOptions = false; RET(TK_Goto); }
":" { RET(':'); } ":" { RET(':'); }
";" { RET(';'); } ";" { RET(';'); }
"}" { StateMode = 0; RET('}'); } "}" { StateMode = 0; StateOptions = false; RET('}'); }
WSP+ { goto std1; } WSP+ { goto std1; }
"\n" { goto newline; } "\n" { goto newline; }
@ -181,6 +181,15 @@ std2:
'action' { RET(TK_Action); } 'action' { RET(TK_Action); }
'readonly' { RET(TK_ReadOnly); } 'readonly' { RET(TK_ReadOnly); }
/* Actor state options */
'bright' { RET(StateOptions ? TK_Bright : TK_Identifier); }
'fast' { RET(StateOptions ? TK_Fast : TK_Identifier); }
'slow' { RET(StateOptions ? TK_Slow : TK_Identifier); }
'nodelay' { RET(StateOptions ? TK_NoDelay : TK_Identifier); }
'canraise' { RET(StateOptions ? TK_CanRaise : TK_Identifier); }
'offset' { RET(StateOptions ? TK_Offset : TK_Identifier); }
'light' { RET(StateOptions ? TK_Light : TK_Identifier); }
/* other DECORATE top level keywords */ /* other DECORATE top level keywords */
'#include' { RET(TK_Include); } '#include' { RET(TK_Include); }
'fixed_t' { RET(TK_Fixed_t); } 'fixed_t' { RET(TK_Fixed_t); }
@ -228,8 +237,8 @@ std2:
"<>=" { RET(TK_LtGtEq); } "<>=" { RET(TK_LtGtEq); }
"**" { RET(TK_MulMul); } "**" { RET(TK_MulMul); }
"::" { RET(TK_ColonColon); } "::" { RET(TK_ColonColon); }
";" { RET(';'); } ";" { StateOptions = false; RET(';'); }
"{" { RET('{'); } "{" { StateOptions = false; RET('{'); }
"}" { RET('}'); } "}" { RET('}'); }
"," { RET(','); } "," { RET(','); }
":" { RET(':'); } ":" { RET(':'); }

View file

@ -129,4 +129,12 @@ xx(TK_Wait, "'wait'")
xx(TK_Meta, "'meta'") xx(TK_Meta, "'meta'")
xx(TK_Deprecated, "'deprecated'") xx(TK_Deprecated, "'deprecated'")
xx(TK_ReadOnly, "'readonly'") xx(TK_ReadOnly, "'readonly'")
xx(TK_CanRaise, "'canraise'")
xx(TK_Fast, "'fast'")
xx(TK_Light, "'light'")
xx(TK_NoDelay, "'nodelay'")
xx(TK_Offset, "'offset'")
xx(TK_Slow, "'slow'")
xx(TK_Bright, "'bright'")
#undef xx #undef xx

View file

@ -377,10 +377,11 @@ static void PrintStateLine(FLispString &out, ZCC_TreeNode *node)
ZCC_StateLine *snode = (ZCC_StateLine *)node; ZCC_StateLine *snode = (ZCC_StateLine *)node;
out.Open("state-line"); out.Open("state-line");
out.Add(snode->Sprite, 4); out.Add(snode->Sprite, 4);
if (snode->bBright) if (snode->bNoDelay) out.Add("nodelay", 7);
{ if (snode->bBright) out.Add("bright", 6);
out.Add("bright", 6); if (snode->bFast) out.Add("fast", 4);
} if (snode->bSlow) out.Add("slow", 4);
if (snode->bCanRaise) out.Add("canraise", 8);
out.Add(*(snode->Frames)); out.Add(*(snode->Frames));
PrintNodes(out, snode->Offset); PrintNodes(out, snode->Offset);
PrintNodes(out, snode->Action, false); PrintNodes(out, snode->Action, false);

View file

@ -41,6 +41,19 @@ static void SetNodeLine(ZCC_TreeNode *name, int line)
struct StateOpts { struct StateOpts {
ZCC_Expression *Offset; ZCC_Expression *Offset;
bool Bright; bool Bright;
bool Fast;
bool Slow;
bool NoDelay;
bool CanRaise;
void Zero() {
Offset = NULL;
Bright = false;
Fast = false;
Slow = false;
NoDelay = false;
CanRaise = false;
}
}; };
struct VarOrFun struct VarOrFun
@ -433,15 +446,23 @@ state_line(X) ::= NWS(A) NWS(B) expr state_opts(C) state_action(D).
} }
line->Frames = stat->Strings.Alloc(FName(B.Name()).GetChars()); line->Frames = stat->Strings.Alloc(FName(B.Name()).GetChars());
line->bBright = C.Bright; line->bBright = C.Bright;
line->bFast = C.Fast;
line->bSlow = C.Slow;
line->bNoDelay = C.NoDelay;
line->bCanRaise = C.CanRaise;
line->Offset = C.Offset; line->Offset = C.Offset;
line->Action = D; line->Action = D;
X = line; X = line;
} }
state_opts(X) ::= . { StateOpts opts; opts.Offset = NULL; opts.Bright = false; X = opts; } state_opts(X) ::= . { StateOpts opts; opts.Zero(); X = opts; }
state_opts(X) ::= state_opts(A) BRIGHT. { A.Bright = true; X = A; } state_opts(X) ::= state_opts(A) BRIGHT. { A.Bright = true; X = A; }
state_opts(X) ::= state_opts(A) FAST. { A.Fast = true; X = A; }
state_opts(X) ::= state_opts(A) SLOW. { A.Slow = true; X = A; }
state_opts(X) ::= state_opts(A) NODELAY. { A.NoDelay = true; X = A; }
state_opts(X) ::= state_opts(A) CANRAISE. { A.CanRaise = true; X = A; }
state_opts(X) ::= state_opts(A) OFFSET LPAREN expr(B) COMMA expr(C) RPAREN. { A.Offset = B; B->AppendSibling(C); X = A; } state_opts(X) ::= state_opts(A) OFFSET LPAREN expr(B) COMMA expr(C) RPAREN. { A.Offset = B; B->AppendSibling(C); X = A; }
state_opts(X) ::= state_opts(A) LIGHT LPAREN light_list RPAREN. { X = A; } state_opts(X) ::= state_opts(A) LIGHT LPAREN light_list RPAREN. { X = A; } ///FIXME: GZDoom would want to know this
light_list ::= STRCONST. light_list ::= STRCONST.
light_list ::= light_list COMMA STRCONST. light_list ::= light_list COMMA STRCONST.

View file

@ -147,6 +147,14 @@ static void InitTokenMap()
TOKENDEF (TK_FloatConst, ZCC_FLOATCONST); TOKENDEF (TK_FloatConst, ZCC_FLOATCONST);
TOKENDEF (TK_NonWhitespace, ZCC_NWS); TOKENDEF (TK_NonWhitespace, ZCC_NWS);
TOKENDEF (TK_Bright, ZCC_BRIGHT);
TOKENDEF (TK_Slow, ZCC_SLOW);
TOKENDEF (TK_Fast, ZCC_FAST);
TOKENDEF (TK_NoDelay, ZCC_NODELAY);
TOKENDEF (TK_Offset, ZCC_OFFSET);
TOKENDEF (TK_CanRaise, ZCC_CANRAISE);
TOKENDEF (TK_Light, ZCC_CANRAISE);
ZCC_InitOperators(); ZCC_InitOperators();
ZCC_InitConversions(); ZCC_InitConversions();
} }
@ -194,43 +202,44 @@ static void DoParse(const char *filename)
while (sc.GetToken()) while (sc.GetToken())
{ {
value.SourceLoc = sc.GetMessageLine(); value.SourceLoc = sc.GetMessageLine();
if (sc.TokenType == TK_StringConst) switch (sc.TokenType)
{ {
case TK_StringConst:
value.String = state.Strings.Alloc(sc.String, sc.StringLen); value.String = state.Strings.Alloc(sc.String, sc.StringLen);
tokentype = ZCC_STRCONST; tokentype = ZCC_STRCONST;
} break;
else if (sc.TokenType == TK_NameConst)
{ case TK_NameConst:
value.Int = sc.Name; value.Int = sc.Name;
tokentype = ZCC_NAMECONST; tokentype = ZCC_NAMECONST;
} break;
else if (sc.TokenType == TK_IntConst)
{ case TK_IntConst:
value.Int = sc.Number; value.Int = sc.Number;
tokentype = ZCC_INTCONST; tokentype = ZCC_INTCONST;
} break;
else if (sc.TokenType == TK_UIntConst)
{ case TK_UIntConst:
value.Int = sc.Number; value.Int = sc.Number;
tokentype = ZCC_UINTCONST; tokentype = ZCC_UINTCONST;
} break;
else if (sc.TokenType == TK_FloatConst)
{ case TK_FloatConst:
value.Float = sc.Float; value.Float = sc.Float;
tokentype = ZCC_FLOATCONST; tokentype = ZCC_FLOATCONST;
} break;
else if (sc.TokenType == TK_Identifier)
{ case TK_Identifier:
value.Int = FName(sc.String); value.Int = FName(sc.String);
tokentype = ZCC_IDENTIFIER; tokentype = ZCC_IDENTIFIER;
} break;
else if (sc.TokenType == TK_NonWhitespace)
{ case TK_NonWhitespace:
value.Int = FName(sc.String); value.Int = FName(sc.String);
tokentype = ZCC_NWS; tokentype = ZCC_NWS;
} break;
else
{ default:
TokenMapEntry *zcctoken = TokenMap.CheckKey(sc.TokenType); TokenMapEntry *zcctoken = TokenMap.CheckKey(sc.TokenType);
if (zcctoken != NULL) if (zcctoken != NULL)
{ {
@ -240,16 +249,18 @@ static void DoParse(const char *filename)
else else
{ {
sc.ScriptMessage("Unexpected token %s.\n", sc.TokenName(sc.TokenType).GetChars()); sc.ScriptMessage("Unexpected token %s.\n", sc.TokenName(sc.TokenType).GetChars());
break; goto parse_end;
} }
break;
} }
ZCCParse(parser, tokentype, value, &state); ZCCParse(parser, tokentype, value, &state);
if (failed) if (failed)
{ {
sc.ScriptMessage("Parse failed\n"); sc.ScriptMessage("Parse failed\n");
break; goto parse_end;
} }
} }
parse_end:
value.Int = -1; value.Int = -1;
ZCCParse(parser, ZCC_EOF, value, &state); ZCCParse(parser, ZCC_EOF, value, &state);
ZCCParse(parser, 0, value, &state); ZCCParse(parser, 0, value, &state);

View file

@ -253,7 +253,11 @@ struct ZCC_StateGoto : ZCC_StatePart
struct ZCC_StateLine : ZCC_StatePart struct ZCC_StateLine : ZCC_StatePart
{ {
char Sprite[4]; char Sprite[4];
BITFIELD bBright:1; BITFIELD bBright : 1;
BITFIELD bFast : 1;
BITFIELD bSlow : 1;
BITFIELD bNoDelay : 1;
BITFIELD bCanRaise : 1;
FString *Frames; FString *Frames;
ZCC_Expression *Offset; ZCC_Expression *Offset;
ZCC_TreeNode *Action; ZCC_TreeNode *Action;