From ff5b1c802a26789ff769521262db79854b24939b Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Tue, 10 Jan 2012 01:43:10 +1000 Subject: Almost got white space and comments working. Still a bug left somewhere, I think it's in operations ordering. --- LuaSL/src/LuaSL_LSL_tree.c | 132 +++++++++++++++++++--------------- LuaSL/src/LuaSL_LSL_tree.h | 88 ++++++++++++----------- LuaSL/src/LuaSL_lexer.l | 172 +++++++++++++++++++++++++-------------------- LuaSL/src/LuaSL_yaccer.y | 65 ++++++++--------- LuaSL/test.lsl | 3 +- 5 files changed, 249 insertions(+), 211 deletions(-) (limited to 'LuaSL') diff --git a/LuaSL/src/LuaSL_LSL_tree.c b/LuaSL/src/LuaSL_LSL_tree.c index 76dd433..ff7da8b 100644 --- a/LuaSL/src/LuaSL_LSL_tree.c +++ b/LuaSL/src/LuaSL_LSL_tree.c @@ -149,20 +149,42 @@ static void burnAST(LSL_AST *ast) burnAST(ast->left); burnAST(ast->right); + free(ast->content.ignorableText); free(ast); } -LSL_AST *addInteger(int value) +static LSL_AST *checkAndAddIgnorable(LSL_AST *root) +{ + if (root) + { + if (root->content.ignorableText) + { + LSL_AST *ast = newAST(LSL_SPACE, NULL, root); + + if (ast) + { + ast->content.value.spaceValue = root->content.ignorableText; + return ast; + } + } + } + return root; +} + +LSL_AST *addInteger(LSL_Leaf *lval, int value) { LSL_AST *ast = newAST(LSL_INTEGER, NULL, NULL); if (ast) - ast->content.integerValue = value; + { + ast->content.value.integerValue = value; + ast->content.ignorableText = lval->ignorableText; + } - return ast; + return checkAndAddIgnorable(ast); } -LSL_AST *addOperation(LSL_Type type, LSL_AST *left, LSL_AST *right) +LSL_AST *addOperation(LSL_Leaf *lval, LSL_Type type, LSL_AST *left, LSL_AST *right) { LSL_AST *ast = newAST(type, left, right); @@ -170,24 +192,30 @@ LSL_AST *addOperation(LSL_Type type, LSL_AST *left, LSL_AST *right) { if (LSL_EXPRESSION == type) { - ast->content.expressionValue = right; + ast->content.value.expressionValue = right; ast->left = NULL; } else - ast->content.operationValue = type; + { + ast->content.value.operationValue = type; + ast->content.ignorableText = lval->ignorableText; + } } - return ast; + return checkAndAddIgnorable(ast); } -LSL_AST *addParenthesis(LSL_AST *expr) +LSL_AST *addParenthesis(LSL_Leaf *lval, LSL_AST *expr) { LSL_AST *ast = newAST(LSL_PARENTHESIS_OPEN, NULL, expr); if (ast) + { ast = newAST(LSL_PARENTHESIS_CLOSE, ast, NULL); + ast->content.ignorableText = lval->ignorableText; + } - return ast; + return checkAndAddIgnorable(ast); } LSL_Statement *createStatement(LSL_Type type, LSL_AST *expr) @@ -202,24 +230,14 @@ LSL_Statement *createStatement(LSL_Type type, LSL_AST *expr) return stat; } -LSL_AST *addSpace(char *text, LSL_AST *root) -{ - LSL_AST *ast = newAST(LSL_SPACE, root, NULL); - - if (ast) - ast->content.spaceValue = text; - - return ast; -} - LSL_AST *addStatement(LSL_Statement *statement, LSL_AST *root) { LSL_AST *ast = newAST(LSL_STATEMENT, root, NULL); if (ast) - ast->content.statementValue = statement; + ast->content.value.statementValue = statement; - return ast; + return checkAndAddIgnorable(ast); } static void evaluateAST(LSL_AST *ast, LSL_Value *left, LSL_Value *right) @@ -259,7 +277,7 @@ static void evaluateAST(LSL_AST *ast, LSL_Value *left, LSL_Value *right) else { #ifdef LUASL_DEBUG - printf(" eval <%s %d %d %d %d> ", ast->token->token, left->content.integerValue, right->content.integerValue, lresult.content.integerValue, rresult.content.integerValue); + printf(" eval <%s %d %d %d %d> ", ast->token->token, left->content.value.integerValue, right->content.value.integerValue, lresult.content.value.integerValue, rresult.content.value.integerValue); #endif memcpy(left, &rresult, sizeof(LSL_Value)); } @@ -271,9 +289,9 @@ static void evaluateIntegerToken(LSL_Leaf *content, LSL_Value *left, LSL_Value * if (content) { #ifdef LUASL_DEBUG - printf(" <%d> ", content->integerValue); + printf(" <%d> ", content->value.integerValue); #endif - left->content.integerValue = content->integerValue; + left->content.value.integerValue = content->value.integerValue; left->type = LSL_INTEGER; } } @@ -284,13 +302,13 @@ static void evaluateNoToken(LSL_Leaf *content, LSL_Value *left, LSL_Value *right static void evaluateOperationToken(LSL_Leaf *content, LSL_Value *left, LSL_Value *right) { - if ((content) && (content->operationValue)) + if ((content) && (content->value.operationValue)) { #ifdef LUASL_DEBUG - printf(" [%s] ", tokens[content->operationValue - lowestToken]->token); + printf(" [%s] ", tokens[content->value.operationValue - lowestToken]->token); #endif - switch (content->operationValue) + switch (content->value.operationValue) { case LSL_COMMA : case LSL_INCREMENT_PRE : @@ -314,33 +332,33 @@ static void evaluateOperationToken(LSL_Leaf *content, LSL_Value *left, LSL_Value // case LSL_TYPECAST_OPEN : // case LSL_TYPECAST_CLOSE : break; - case LSL_BIT_NOT : left->content.integerValue = ~ right->content.integerValue; break; - case LSL_BOOL_NOT : left->content.integerValue = ! right->content.integerValue; break; - case LSL_NEGATION : left->content.integerValue = 0 - right->content.integerValue; break; - case LSL_DIVIDE : left->content.integerValue = left->content.integerValue / right->content.integerValue; break; - case LSL_MODULO : left->content.integerValue = left->content.integerValue % right->content.integerValue; break; - case LSL_MULTIPLY : left->content.integerValue = left->content.integerValue * right->content.integerValue; break; + case LSL_BIT_NOT : left->content.value.integerValue = ~ right->content.value.integerValue; break; + case LSL_BOOL_NOT : left->content.value.integerValue = ! right->content.value.integerValue; break; + case LSL_NEGATION : left->content.value.integerValue = 0 - right->content.value.integerValue; break; + case LSL_DIVIDE : left->content.value.integerValue = left->content.value.integerValue / right->content.value.integerValue; break; + case LSL_MODULO : left->content.value.integerValue = left->content.value.integerValue % right->content.value.integerValue; break; + case LSL_MULTIPLY : left->content.value.integerValue = left->content.value.integerValue * right->content.value.integerValue; break; // case LSL_DOT_PRODUCT : break; // case LSL_CROSS_PRODUCT : break; - case LSL_SUBTRACT : left->content.integerValue = left->content.integerValue - right->content.integerValue; break; - case LSL_ADD : left->content.integerValue = left->content.integerValue + right->content.integerValue; break; + case LSL_SUBTRACT : left->content.value.integerValue = left->content.value.integerValue - right->content.value.integerValue; break; + case LSL_ADD : left->content.value.integerValue = left->content.value.integerValue + right->content.value.integerValue; break; // case LSL_CONCATENATE : break; - case LSL_LEFT_SHIFT : left->content.integerValue = left->content.integerValue << right->content.integerValue; break; - case LSL_RIGHT_SHIFT : left->content.integerValue = left->content.integerValue >> right->content.integerValue; break; - case LSL_LESS_THAN : left->content.integerValue = left->content.integerValue < right->content.integerValue; break; - case LSL_GREATER_THAN : left->content.integerValue = left->content.integerValue > right->content.integerValue; break; - case LSL_LESS_EQUAL : left->content.integerValue = left->content.integerValue <= right->content.integerValue; break; - case LSL_GREATER_EQUAL : left->content.integerValue = left->content.integerValue >= right->content.integerValue; break; - case LSL_EQUAL : left->content.integerValue = left->content.integerValue == right->content.integerValue; break; - case LSL_NOT_EQUAL : left->content.integerValue = left->content.integerValue != right->content.integerValue; break; - case LSL_BIT_AND : left->content.integerValue = left->content.integerValue & right->content.integerValue; break; - case LSL_BIT_XOR : left->content.integerValue = left->content.integerValue ^ right->content.integerValue; break; - case LSL_BIT_OR : left->content.integerValue = left->content.integerValue | right->content.integerValue; break; - case LSL_BOOL_OR : left->content.integerValue = left->content.integerValue || right->content.integerValue; break; - case LSL_BOOL_AND : left->content.integerValue = left->content.integerValue && right->content.integerValue; break; + case LSL_LEFT_SHIFT : left->content.value.integerValue = left->content.value.integerValue << right->content.value.integerValue; break; + case LSL_RIGHT_SHIFT : left->content.value.integerValue = left->content.value.integerValue >> right->content.value.integerValue; break; + case LSL_LESS_THAN : left->content.value.integerValue = left->content.value.integerValue < right->content.value.integerValue; break; + case LSL_GREATER_THAN : left->content.value.integerValue = left->content.value.integerValue > right->content.value.integerValue; break; + case LSL_LESS_EQUAL : left->content.value.integerValue = left->content.value.integerValue <= right->content.value.integerValue; break; + case LSL_GREATER_EQUAL : left->content.value.integerValue = left->content.value.integerValue >= right->content.value.integerValue; break; + case LSL_EQUAL : left->content.value.integerValue = left->content.value.integerValue == right->content.value.integerValue; break; + case LSL_NOT_EQUAL : left->content.value.integerValue = left->content.value.integerValue != right->content.value.integerValue; break; + case LSL_BIT_AND : left->content.value.integerValue = left->content.value.integerValue & right->content.value.integerValue; break; + case LSL_BIT_XOR : left->content.value.integerValue = left->content.value.integerValue ^ right->content.value.integerValue; break; + case LSL_BIT_OR : left->content.value.integerValue = left->content.value.integerValue | right->content.value.integerValue; break; + case LSL_BOOL_OR : left->content.value.integerValue = left->content.value.integerValue || right->content.value.integerValue; break; + case LSL_BOOL_AND : left->content.value.integerValue = left->content.value.integerValue && right->content.value.integerValue; break; } #ifdef LUASL_DEBUG - printf(" (=%d) ", left->content.integerValue); + printf(" (=%d) ", left->content.value.integerValue); #endif } } @@ -348,7 +366,7 @@ static void evaluateOperationToken(LSL_Leaf *content, LSL_Value *left, LSL_Value static void evaluateStatementToken(LSL_Leaf *content, LSL_Value *left, LSL_Value *right) { if (content) - evaluateAST(content->statementValue->expression, left, right); + evaluateAST(content->value.statementValue->expression, left, right); } static void outputAST(LSL_AST *ast) @@ -367,26 +385,26 @@ static void outputAST(LSL_AST *ast) static void outputIntegerToken(LSL_Leaf *content) { if (content) - printf("%d", content->integerValue); + printf("%d", content->value.integerValue); } static void outputOperationToken(LSL_Leaf *content) { if (content) - printf("%s", tokens[content->operationValue - lowestToken]->token); + printf("%s", tokens[content->value.operationValue - lowestToken]->token); } static void outputStatementToken(LSL_Leaf *content) { if (content) - outputAST(content->statementValue->expression); + outputAST(content->value.statementValue->expression); printf(";"); } static void outputSpaceToken(LSL_Leaf *content) { if (content) - printf("%s", content->spaceValue); + printf("%s", content->value.spaceValue); } static void convertAST2Lua(LSL_AST *ast) @@ -523,9 +541,9 @@ int main(int argc, char **argv) { LSL_Value left, right; - left.content.integerValue = 0; + left.content.value.integerValue = 0; left.type = LSL_INTEGER; - right.content.integerValue = 0; + right.content.value.integerValue = 0; right.type = LSL_INTEGER; evaluateAST(ast, &left, &right); @@ -535,7 +553,7 @@ int main(int argc, char **argv) printf("Result of -\n"); outputAST(ast); printf("\n"); - printf("is %d %d. And converted to Lua it is -\n", left.content.integerValue, right.content.integerValue); + printf("is %d %d. And converted to Lua it is -\n", left.content.value.integerValue, right.content.value.integerValue); convertAST2Lua(ast); printf("\n"); burnAST(ast); diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h index adefa07..fe56c29 100644 --- a/LuaSL/src/LuaSL_LSL_tree.h +++ b/LuaSL/src/LuaSL_LSL_tree.h @@ -20,7 +20,7 @@ extern int yydebug; // http://w-hat.com/stackdepth is a useful discussion about some aspects of the LL parser. -typedef union _LSL_Leaf LSL_Leaf; +typedef struct _LSL_Leaf LSL_Leaf; typedef struct _LSL_Value LSL_Value; typedef struct _LSL_Identifier LSL_Identifier; typedef struct _LSL_Statement LSL_Statement; @@ -65,43 +65,48 @@ typedef struct evaluateToken evaluate; } LSL_Token; -union _LSL_Leaf +struct _LSL_Leaf { - char *commentValue; - char *spaceValue; - - LSL_Type operationValue; - LSL_AST *expressionValue; - - float floatValue; - int integerValue; - char *keyValue; - LSL_Leaf *listValue; - char *stringValue; - float vectorValue[3]; - float rotationValue[4]; - - LSL_Identifier *variableValue; - - char *labelValue; - LSL_Statement *doValue; - LSL_Statement *forValue; - LSL_Statement *elseIfValue; - LSL_Statement *elseValue; - LSL_Statement *ifValue; - char *jumpValue; - LSL_Statement *returnValue; - char *stateChangeValue; - LSL_Statement *whileValue; - LSL_Statement *statementValue; - - LSL_Block *blockValue; - LSL_Identifier *parameterValue; - LSL_Function *functionValue; - LSL_State *stateValue; - LSL_Script *scriptValue; - - char *unknownValue; + union + { + char *commentValue; + char *spaceValue; + + LSL_Type operationValue; + LSL_AST *expressionValue; + + float floatValue; + int integerValue; + char *keyValue; + LSL_Leaf *listValue; + char *stringValue; + float vectorValue[3]; + float rotationValue[4]; + + LSL_Identifier *variableValue; + + char *labelValue; + LSL_Statement *doValue; + LSL_Statement *forValue; + LSL_Statement *elseIfValue; + LSL_Statement *elseValue; + LSL_Statement *ifValue; + char *jumpValue; + LSL_Statement *returnValue; + char *stateChangeValue; + LSL_Statement *whileValue; + LSL_Statement *statementValue; + + LSL_Block *blockValue; + LSL_Identifier *parameterValue; + LSL_Function *functionValue; + LSL_State *stateValue; + LSL_Script *scriptValue; + + char *unknownValue; + } value; + char *ignorableText; + int line, column; }; struct _LSL_Value @@ -176,7 +181,7 @@ typedef struct } LuaSL_yyparseParam; // the parameter name (of the reentrant 'yyparse' function) -// data is a pointer to a 'SParserParam' structure +// data is a pointer to a 'yyparseParam' structure #define YYPARSE_PARAM data // the argument for the 'yylex' function @@ -184,12 +189,11 @@ typedef struct LSL_AST *addExpression(LSL_AST *exp); -LSL_AST *addInteger(int value); -LSL_AST *addOperation(LSL_Type type, LSL_AST *left, LSL_AST *right); -LSL_AST *addParenthesis(LSL_AST *expr); +LSL_AST *addInteger(LSL_Leaf *lval, int value); +LSL_AST *addOperation(LSL_Leaf *lval, LSL_Type type, LSL_AST *left, LSL_AST *right); +LSL_AST *addParenthesis(LSL_Leaf *lval, LSL_AST *expr); LSL_Statement *createStatement(LSL_Type type, LSL_AST *root); LSL_AST *addStatement(LSL_Statement *statement, LSL_AST *root); -LSL_AST *addSpace(char *text, LSL_AST *root); int yyerror(const char *msg); int yyparse(void *param); diff --git a/LuaSL/src/LuaSL_lexer.l b/LuaSL/src/LuaSL_lexer.l index 3728ab9..08a68ef 100644 --- a/LuaSL/src/LuaSL_lexer.l +++ b/LuaSL/src/LuaSL_lexer.l @@ -5,15 +5,8 @@ #include void comment(yyscan_t yyscanner); -void count(char *text); - -#ifdef LUASL_DEBUG - #undef ECHO - #define ECHO count(yytext); printf ("[%s]\n", yytext) -#else - #undef ECHO - #define ECHO count(yytext) -#endif +void common(YYSTYPE *lval, char *text, boolean checkIgnorable); +void ignorable(char *text); %} @@ -35,85 +28,84 @@ NAME [[:alpha:]](_|[[:alpha:]]|[[:digit:]])* /* The order here is important, in mysterious ways. The more specific the lower in case of ambiguities like "floats contain integers". I think, not tested that well yet. */ - /* White space. */ -[[:space:]]+ %{ ECHO; /* yylval->spaceValue = strdup(yytext); return LSL_SPACE; */ %} -"/*" %{ ECHO; comment(yyscanner); %} -"//"[^\n]* %{ ECHO; /* consume //-comment */ %} + /* Ignorables. */ +[[:space:]]+ %{ common(yylval, yytext, FALSE); ignorable(yytext); %} + /* Yes I know this will have problems with huge comments, just being simple to get it to work for now. */ +"/*"([^"*/"]*)"*/" %{ common(yylval, yytext, FALSE); ignorable(yytext); %} +"//"[^\n]* %{ common(yylval, yytext, FALSE); ignorable(yytext); %} /* Operations. */ -"&&" { ECHO; return LSL_BOOL_AND; } -"||" { ECHO; return LSL_BOOL_OR; } -"|" { ECHO; return LSL_BIT_OR; } -"^" { ECHO; return LSL_BIT_XOR; } -"&" { ECHO; return LSL_BIT_AND; } -"!=" { ECHO; return LSL_NOT_EQUAL; } -"==" { ECHO; return LSL_EQUAL; } -">=" { ECHO; return LSL_GREATER_EQUAL; } -"<=" { ECHO; return LSL_LESS_EQUAL; } -">" { ECHO; return LSL_GREATER_THAN; } -"<" { ECHO; return LSL_LESS_THAN; } -">>" { ECHO; return LSL_RIGHT_SHIFT; } -"<<" { ECHO; return LSL_LEFT_SHIFT; } -"+" { ECHO; return LSL_ADD; } -"-" { ECHO; return LSL_SUBTRACT; } -"*" { ECHO; return LSL_MULTIPLY; } -"%" { ECHO; return LSL_MODULO; } -"/" { ECHO; return LSL_DIVIDE; } -"!" { ECHO; return LSL_BOOL_NOT; } -"~" { ECHO; return LSL_BIT_NOT; } - /* "<" { ECHO; return LSL_ANGLE_OPEN; } */ - /* ">" { ECHO; return LSL_ANGLE_CLOSE; } */ -"[" { ECHO; return LSL_BRACKET_OPEN; } -"]" { ECHO; return LSL_BRACKET_CLOSE; } -"(" { ECHO; return LSL_PARENTHESIS_OPEN; } -")" { ECHO; return LSL_PARENTHESIS_CLOSE; } -"+=" { ECHO; return LSL_ASSIGNMENT_ADD; } -"-=" { ECHO; return LSL_ASSIGNMENT_SUBTRACT; } -"*=" { ECHO; return LSL_ASSIGNMENT_MULTIPLY; } -"%=" { ECHO; return LSL_ASSIGNMENT_MODULO; } -"/=" { ECHO; return LSL_ASSIGNMENT_DIVIDE; } -"=" { ECHO; return LSL_ASSIGNMENT_PLAIN; } -"." { ECHO; return LSL_DOT; } -"--" { ECHO; return LSL_DECREMENT_PRE; } -"++" { ECHO; return LSL_INCREMENT_PRE; } -"," { ECHO; return LSL_COMMA; } +"&&" { common(yylval, yytext, TRUE); return LSL_BOOL_AND; } +"||" { common(yylval, yytext, TRUE); return LSL_BOOL_OR; } +"|" { common(yylval, yytext, TRUE); return LSL_BIT_OR; } +"^" { common(yylval, yytext, TRUE); return LSL_BIT_XOR; } +"&" { common(yylval, yytext, TRUE); return LSL_BIT_AND; } +"!=" { common(yylval, yytext, TRUE); return LSL_NOT_EQUAL; } +"==" { common(yylval, yytext, TRUE); return LSL_EQUAL; } +">=" { common(yylval, yytext, TRUE); return LSL_GREATER_EQUAL; } +"<=" { common(yylval, yytext, TRUE); return LSL_LESS_EQUAL; } +">" { common(yylval, yytext, TRUE); return LSL_GREATER_THAN; } +"<" { common(yylval, yytext, TRUE); return LSL_LESS_THAN; } +">>" { common(yylval, yytext, TRUE); return LSL_RIGHT_SHIFT; } +"<<" { common(yylval, yytext, TRUE); return LSL_LEFT_SHIFT; } +"+" { common(yylval, yytext, TRUE); return LSL_ADD; } +"-" { common(yylval, yytext, TRUE); return LSL_SUBTRACT; } +"*" { common(yylval, yytext, TRUE); return LSL_MULTIPLY; } +"%" { common(yylval, yytext, TRUE); return LSL_MODULO; } +"/" { common(yylval, yytext, TRUE); return LSL_DIVIDE; } +"!" { common(yylval, yytext, TRUE); return LSL_BOOL_NOT; } +"~" { common(yylval, yytext, TRUE); return LSL_BIT_NOT; } +"[" { common(yylval, yytext, TRUE); return LSL_BRACKET_OPEN; } +"]" { common(yylval, yytext, TRUE); return LSL_BRACKET_CLOSE; } +"(" { common(yylval, yytext, TRUE); return LSL_PARENTHESIS_OPEN; } +")" { common(yylval, yytext, TRUE); return LSL_PARENTHESIS_CLOSE; } +"+=" { common(yylval, yytext, TRUE); return LSL_ASSIGNMENT_ADD; } +"-=" { common(yylval, yytext, TRUE); return LSL_ASSIGNMENT_SUBTRACT; } +"*=" { common(yylval, yytext, TRUE); return LSL_ASSIGNMENT_MULTIPLY; } +"%=" { common(yylval, yytext, TRUE); return LSL_ASSIGNMENT_MODULO; } +"/=" { common(yylval, yytext, TRUE); return LSL_ASSIGNMENT_DIVIDE; } +"=" { common(yylval, yytext, TRUE); return LSL_ASSIGNMENT_PLAIN; } +"." { common(yylval, yytext, TRUE); return LSL_DOT; } +"--" { common(yylval, yytext, TRUE); return LSL_DECREMENT_PRE; } +"++" { common(yylval, yytext, TRUE); return LSL_INCREMENT_PRE; } +"," { common(yylval, yytext, TRUE); return LSL_COMMA; } /* Types. */ -{INTEGER} %{ ECHO; yylval->integerValue = atoi(yytext); return LSL_INTEGER; %} -{FLOAT} %{ ECHO; yylval->floatValue = atof(yytext); return LSL_FLOAT; %} +{INTEGER} %{ common(yylval, yytext, TRUE); yylval->value.integerValue = atoi(yytext); return LSL_INTEGER; %} +{FLOAT} %{ common(yylval, yytext, TRUE); yylval->value.floatValue = atof(yytext); return LSL_FLOAT; %} /* Type keywords. */ -"float" %{ ECHO; return LSL_TYPE_FLOAT; %} -"integer" %{ ECHO; return LSL_TYPE_INTEGER; %} -"key" %{ ECHO; return LSL_TYPE_KEY; %} -"list" %{ ECHO; return LSL_TYPE_LIST; %} -"quaternion" %{ ECHO; return LSL_TYPE_ROTATION; %} -"rotation" %{ ECHO; return LSL_TYPE_ROTATION; %} -"string" %{ ECHO; return LSL_TYPE_STRING; %} -"vector" %{ ECHO; return LSL_TYPE_VECTOR; %} +"float" %{ common(yylval, yytext, TRUE); return LSL_TYPE_FLOAT; %} +"integer" %{ common(yylval, yytext, TRUE); return LSL_TYPE_INTEGER; %} +"key" %{ common(yylval, yytext, TRUE); return LSL_TYPE_KEY; %} +"list" %{ common(yylval, yytext, TRUE); return LSL_TYPE_LIST; %} +"quaternion" %{ common(yylval, yytext, TRUE); return LSL_TYPE_ROTATION; %} +"rotation" %{ common(yylval, yytext, TRUE); return LSL_TYPE_ROTATION; %} +"string" %{ common(yylval, yytext, TRUE); return LSL_TYPE_STRING; %} +"vector" %{ common(yylval, yytext, TRUE); return LSL_TYPE_VECTOR; %} /* Statement keywords. */ -"do" %{ ECHO; return LSL_DO; %} -"for" %{ ECHO; return LSL_FOR; %} -"else" %{ ECHO; return LSL_ELSE; %} -"if" %{ ECHO; return LSL_IF; %} -"jump" %{ ECHO; return LSL_JUMP; %} -"return" %{ ECHO; return LSL_RETURN; %} -"state" %{ ECHO; return LSL_STATE_CHANGE; %} -"while" %{ ECHO; return LSL_WHILE; %} +"do" %{ common(yylval, yytext, TRUE); return LSL_DO; %} +"for" %{ common(yylval, yytext, TRUE); return LSL_FOR; %} +"else" %{ common(yylval, yytext, TRUE); return LSL_ELSE; %} +"if" %{ common(yylval, yytext, TRUE); return LSL_IF; %} +"jump" %{ common(yylval, yytext, TRUE); return LSL_JUMP; %} +"return" %{ common(yylval, yytext, TRUE); return LSL_RETURN; %} +"state" %{ common(yylval, yytext, TRUE); return LSL_STATE_CHANGE; %} +"while" %{ common(yylval, yytext, TRUE); return LSL_WHILE; %} -{NAME} %{ ECHO; /* yylval->nameValue = strdup(yytext); return LSL_NAME; */ %} +{NAME} %{ common(yylval, yytext, TRUE); /* yylval->value.nameValue = strdup(yytext); return LSL_NAME; */ %} /* Other symbols. */ -"@" %{ ECHO; return LSL_LABEL; %} -"{" %{ ECHO; return LSL_BLOCK_OPEN; %} -"}" %{ ECHO; return LSL_BLOCK_CLOSE; %} -";" { ECHO; return LSL_STATEMENT; } +"@" %{ common(yylval, yytext, TRUE); return LSL_LABEL; %} +"{" %{ common(yylval, yytext, TRUE); return LSL_BLOCK_OPEN; %} +"}" %{ common(yylval, yytext, TRUE); return LSL_BLOCK_CLOSE; %} +";" %{ common(yylval, yytext, TRUE); return LSL_STATEMENT; %} <> { yyterminate(); } /* Everything else */ -. %{ ECHO; printf(" unexpected character.\n"); %} +. %{ common(yylval, yytext, TRUE); printf(" unexpected character.\n"); %} %% @@ -130,10 +122,11 @@ void comment(yyscan_t yyscanner) yyerror("unterminated comment"); } -int column = 0; -int line = 0; +static char *ignorableText = NULL; +static int column = 0; +static int line = 0; -void count(char *text) +void common(YYSTYPE *lval, char *text, boolean checkIgnorable) { int i; @@ -147,6 +140,33 @@ void count(char *text) column += 8 - (column % 8); else column++; + + lval->line = line; + lval->column = column; + + if (checkIgnorable) + { + lval->ignorableText = ignorableText; + ignorableText = NULL; + } + +#ifdef LUASL_DEBUG + printf ("%04d, %04d [%s]\n", line, column, text); +#endif +} + +void ignorable(char *text) +{ + if (ignorableText) + { + int lenI = strlen(ignorableText); + int lenT = strlen(text); + + ignorableText = realloc(ignorableText, lenI + lenT + 1); + sprintf(&ignorableText[lenI], "%s", text); + } + else + ignorableText = strdup(text); } int yyerror(const char *msg) diff --git a/LuaSL/src/LuaSL_yaccer.y b/LuaSL/src/LuaSL_yaccer.y index 4b456b1..ed69dd3 100644 --- a/LuaSL/src/LuaSL_yaccer.y +++ b/LuaSL/src/LuaSL_yaccer.y @@ -10,10 +10,9 @@ %define api.pure -%type ignorable -%token LSL_SPACE +%token LSL_SPACE /* Never actually emitted, but we need it in the token table. */ -%type expr +%type expr %left LSL_BOOL_AND %left LSL_BOOL_OR %left LSL_BIT_AND LSL_BIT_XOR LSL_BIT_OR @@ -31,8 +30,8 @@ %right LSL_DECREMENT_PRE LSL_INCREMENT_PRE %token LSL_COMMA -%token LSL_FLOAT -%token LSL_INTEGER +%token LSL_FLOAT +%token LSL_INTEGER %nonassoc LSL_TYPE_FLOAT LSL_TYPE_INTEGER LSL_TYPE_KEY LSL_TYPE_LIST LSL_TYPE_ROTATION LSL_TYPE_STRING LSL_TYPE_VECTOR @@ -42,47 +41,43 @@ %nonassoc LSL_BLOCK_OPEN LSL_BLOCK_CLOSE -%type statement +%type statement %nonassoc LSL_STATEMENT -%type script +%type script %% input : - ignorable - | expr { ((LuaSL_yyparseParam*)data)->ast = addOperation(LSL_EXPRESSION, $1, $1); } + expr { ((LuaSL_yyparseParam*)data)->ast = addOperation(&yylval, LSL_EXPRESSION, $1, $1); } | statement { ((LuaSL_yyparseParam*)data)->ast = addStatement($1, ((LuaSL_yyparseParam*)data)->ast); } | script ; -ignorable : LSL_SPACE { ((LuaSL_yyparseParam*)data)->ast = addSpace($1, ((LuaSL_yyparseParam*)data)->ast); } -; - expr : - expr LSL_BOOL_AND expr { $$ = addOperation( LSL_BOOL_AND, $1, $3 ); } - | expr LSL_BOOL_OR expr { $$ = addOperation( LSL_BOOL_OR, $1, $3 ); } - | expr LSL_BIT_OR expr { $$ = addOperation( LSL_BIT_OR, $1, $3 ); } - | expr LSL_BIT_XOR expr { $$ = addOperation( LSL_BIT_XOR, $1, $3 ); } - | expr LSL_BIT_AND expr { $$ = addOperation( LSL_BIT_AND, $1, $3 ); } - | expr LSL_NOT_EQUAL expr { $$ = addOperation( LSL_NOT_EQUAL, $1, $3 ); } - | expr LSL_EQUAL expr { $$ = addOperation( LSL_EQUAL, $1, $3 ); } - | expr LSL_GREATER_EQUAL expr { $$ = addOperation( LSL_GREATER_EQUAL, $1, $3 ); } - | expr LSL_LESS_EQUAL expr { $$ = addOperation( LSL_LESS_EQUAL, $1, $3 ); } - | expr LSL_GREATER_THAN expr { $$ = addOperation( LSL_GREATER_THAN, $1, $3 ); } - | expr LSL_LESS_THAN expr { $$ = addOperation( LSL_LESS_THAN, $1, $3 ); } - | expr LSL_RIGHT_SHIFT expr { $$ = addOperation( LSL_RIGHT_SHIFT, $1, $3 ); } - | expr LSL_LEFT_SHIFT expr { $$ = addOperation( LSL_LEFT_SHIFT, $1, $3 ); } - | expr LSL_ADD expr { $$ = addOperation( LSL_ADD, $1, $3 ); } - | expr LSL_SUBTRACT expr { $$ = addOperation( LSL_SUBTRACT, $1, $3 ); } - | expr LSL_MULTIPLY expr { $$ = addOperation( LSL_MULTIPLY, $1, $3 ); } - | expr LSL_MODULO expr { $$ = addOperation( LSL_MODULO, $1, $3 ); } - | expr LSL_DIVIDE expr { $$ = addOperation( LSL_DIVIDE, $1, $3 ); } - | LSL_BIT_NOT expr { $$ = addOperation( LSL_BIT_NOT, NULL, $2 ); } - | LSL_BOOL_NOT expr { $$ = addOperation( LSL_BOOL_NOT, NULL, $2 ); } - | LSL_SUBTRACT expr { $$ = addOperation( LSL_NEGATION, NULL, $2 ); } %prec LSL_NEGATION - | LSL_PARENTHESIS_OPEN expr LSL_PARENTHESIS_CLOSE { $$ = addParenthesis($2); } - | LSL_INTEGER { $$ = addInteger($1); } + expr LSL_BOOL_AND expr { $$ = addOperation(&yylval, LSL_BOOL_AND, $1, $3); } + | expr LSL_BOOL_OR expr { $$ = addOperation(&yylval, LSL_BOOL_OR, $1, $3); } + | expr LSL_BIT_OR expr { $$ = addOperation(&yylval, LSL_BIT_OR, $1, $3); } + | expr LSL_BIT_XOR expr { $$ = addOperation(&yylval, LSL_BIT_XOR, $1, $3); } + | expr LSL_BIT_AND expr { $$ = addOperation(&yylval, LSL_BIT_AND, $1, $3); } + | expr LSL_NOT_EQUAL expr { $$ = addOperation(&yylval, LSL_NOT_EQUAL, $1, $3); } + | expr LSL_EQUAL expr { $$ = addOperation(&yylval, LSL_EQUAL, $1, $3); } + | expr LSL_GREATER_EQUAL expr { $$ = addOperation(&yylval, LSL_GREATER_EQUAL, $1, $3); } + | expr LSL_LESS_EQUAL expr { $$ = addOperation(&yylval, LSL_LESS_EQUAL, $1, $3); } + | expr LSL_GREATER_THAN expr { $$ = addOperation(&yylval, LSL_GREATER_THAN, $1, $3); } + | expr LSL_LESS_THAN expr { $$ = addOperation(&yylval, LSL_LESS_THAN, $1, $3); } + | expr LSL_RIGHT_SHIFT expr { $$ = addOperation(&yylval, LSL_RIGHT_SHIFT, $1, $3); } + | expr LSL_LEFT_SHIFT expr { $$ = addOperation(&yylval, LSL_LEFT_SHIFT, $1, $3); } + | expr LSL_ADD expr { $$ = addOperation(&yylval, LSL_ADD, $1, $3); } + | expr LSL_SUBTRACT expr { $$ = addOperation(&yylval, LSL_SUBTRACT, $1, $3); } + | expr LSL_MULTIPLY expr { $$ = addOperation(&yylval, LSL_MULTIPLY, $1, $3); } + | expr LSL_MODULO expr { $$ = addOperation(&yylval, LSL_MODULO, $1, $3); } + | expr LSL_DIVIDE expr { $$ = addOperation(&yylval, LSL_DIVIDE, $1, $3); } + | LSL_BIT_NOT expr { $$ = addOperation(&yylval, LSL_BIT_NOT, NULL, $2); } + | LSL_BOOL_NOT expr { $$ = addOperation(&yylval, LSL_BOOL_NOT, NULL, $2); } + | LSL_SUBTRACT expr { $$ = addOperation(&yylval, LSL_NEGATION, NULL, $2); } %prec LSL_NEGATION + | LSL_PARENTHESIS_OPEN expr LSL_PARENTHESIS_CLOSE { $$ = addParenthesis(&yylval, $2); } + | LSL_INTEGER { $$ = addInteger(&yylval, $1); } ; statement : expr LSL_STATEMENT { $$ = createStatement(LSL_EXPRESSION, $1); YYVALID; } diff --git a/LuaSL/test.lsl b/LuaSL/test.lsl index ddfa533..40d98b3 100644 --- a/LuaSL/test.lsl +++ b/LuaSL/test.lsl @@ -1,2 +1,3 @@ -4 + 2 * 10 + 3 * (5 + 1); +4 + /* c0 */ 2 /* c1 */ * /* c2 */ 10 /* c3 */ + /* c4 */ + 3 /* c5 */ * /* c6 */ (5 /* c7 */ + /* c8 */ 1); -- cgit v1.1