- DoParse() now writes out the parsed AST for the input file to <file>.ast.

Maybe TODO: Find a simple LISP pretty printer that isn't written in LISP so that the output
  isn't all on one big long line.
- zcc-parse.lemon now returns the complete AST through the parse state.
- Fixed crash in PrintEnumNode().

SVN r3773 (scripting)
This commit is contained in:
Randy Heit 2012-07-20 02:54:51 +00:00
parent a5c938445a
commit 2d139f3846
4 changed files with 23 additions and 11 deletions

View file

@ -141,7 +141,7 @@ static void PrintEnum(FString &out, ZCC_TreeNode *node)
static void PrintEnumNode(FString &out, ZCC_TreeNode *node)
{
ZCC_EnumNode *enode = (ZCC_EnumNode *)node;
out.AppendFormat("(enum-node '%s' ", FName(enode->ElemName));
out.AppendFormat("(enum-node '%s' ", FName(enode->ElemName).GetChars());
PrintNodes(out, enode->ElemValue, ')');
}

View file

@ -69,14 +69,16 @@
%type opt_func_body {ZCC_CompoundStmt *}
%type function_body {ZCC_CompoundStmt *}
main ::= translation_unit. { stat->sc.ScriptMessage("Parse complete\n"); }
main ::= translation_unit(A). { stat->TopNode = A; stat->sc.ScriptMessage("Parse complete\n"); }
translation_unit ::= .
translation_unit ::= translation_unit external_declaration.
translation_unit ::= translation_unit EOF.
translation_unit ::= error.
%type translation_unit {ZCC_TreeNode *}
translation_unit(X) ::= . { X = NULL; }
translation_unit(X) ::= translation_unit(A) external_declaration(B). { SAFE_APPEND(A,B); X = A; }
translation_unit(X) ::= translation_unit(A) EOF. { X = A; }
translation_unit(X) ::= error. { X = NULL; }
external_declaration ::= class_definition.
%type external_declaration {ZCC_TreeNode *}
external_declaration(X) ::= class_definition(A). { X = A; }
/* Optional bits. */
opt_semicolon ::= .
@ -317,7 +319,6 @@ state_line(X) ::= NWS(A) NWS(B) expr state_opts(C) state_action(D).
{
NEW_AST_NODE(StateLine, line);
const char *sprite = FName(A.Name()).GetChars();
memset(line, 0, sizeof(*line));
if (strlen(sprite) != 4)
{
Printf("Sprite name '%s' must be four characters", sprite);
@ -650,7 +651,7 @@ func_params(X) ::= VOID. { X = NULL; }
func_params(X) ::= func_param_list(A). { X = A; }
func_param_list(X) ::= func_param(A). { X = A; }
func_param_list(X) ::= func_param(A) COMMA func_param_list(B). { X = A; A->AppendSibling(B); }
func_param_list(X) ::= func_param_list(A) COMMA func_param(B). { X = A; A->AppendSibling(B); }
func_param(X) ::= func_param_flags(A) type(B) IDENTIFIER(C).
{
@ -1194,7 +1195,8 @@ iteration_statement(X) ::= FOR LPAREN for_init(IN) SEMICOLON opt_expr(EX) SEMICO
iter->LoopBumper = DO;
iter->CheckAt = ZCC_IterationStmt::Start;
// The initialization expression appears outside the loop
IN->AppendSibling(iter);
// for_init may be NULL if there is no initialization.
SAFE_APPEND(IN, iter);
// And the whole thing gets wrapped inside a compound statement in case the loop
// initializer defined any variables.
NEW_AST_NODE(CompoundStmt, wrap);

View file

@ -229,6 +229,15 @@ static void DoParse(const char *filename)
fclose(f);
}
#endif
FString ast = ZCC_PrintAST(state.TopNode);
FString astfile = ExtractFileBase(filename, false);
astfile << ".ast";
f = fopen(astfile, "w");
if (f != NULL)
{
fputs(ast.GetChars(), f);
fclose(f);
}
}
CCMD(parse)

View file

@ -7,6 +7,7 @@ struct ZCCParseState
FScanner &sc;
FSharedStringArena Strings;
FMemArena SyntaxArena;
struct ZCC_TreeNode *TopNode;
};
union ZCCToken
@ -206,7 +207,7 @@ struct ZCC_TreeNode
}
// The new sibling node should only be in a list with itself.
assert(sibling->SiblingNext == sibling && sibling->SiblingNext == sibling);
assert(sibling->SiblingNext == sibling && sibling->SiblingPrev == sibling);
// Check integrity of our sibling list.
assert(SiblingPrev->SiblingNext == this);