From 1603cadc4b3345e01f866f6f94bf69df078b4808 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sat, 7 Jan 2012 04:28:24 +1000 Subject: Make the parser more generic with function pointers and a big arse table. --- LuaSL/src/LuaSL_LSL_tree.c | 275 ++++++++++++++++++++++++++++++--------------- LuaSL/src/LuaSL_LSL_tree.h | 136 +++++----------------- LuaSL/src/LuaSL_yaccer.y | 2 +- 3 files changed, 209 insertions(+), 204 deletions(-) diff --git a/LuaSL/src/LuaSL_LSL_tree.c b/LuaSL/src/LuaSL_LSL_tree.c index 8462112..6c91012 100644 --- a/LuaSL/src/LuaSL_LSL_tree.c +++ b/LuaSL/src/LuaSL_LSL_tree.c @@ -1,10 +1,107 @@ -#define LSL_Keywords_define -#define LSL_Tokens_define #include "LuaSL_LSL_tree.h" #include #include +static void outputExpressionToken(LSL_Leaf *content); +static LSL_Leaf *evaluateExpressionToken(LSL_Leaf *content, LSL_Type oldType, LSL_Leaf *old); +static void outputIntegerToken(LSL_Leaf *content); +static LSL_Leaf *evaluateIntegerToken(LSL_Leaf *content, LSL_Type oldType, LSL_Leaf *old); + +LSL_Token LSL_Tokens[] = +{ + // Start with expression operators. + // In order of precedence, high to low. + // Left to right, unless oterwise stated. + // According to http://wiki.secondlife.com/wiki/Category:LSL_Operators + +// {LSL_COMMA, ",", LSL_LEFT2RIGHT, NULL, NULL, NULL}, +// {LSL_INCREMENT_PRE, "++", LSL_RIGHT2LEFT | LSL_UNARY, NULL, NULL, NULL}, +// {LSL_INCREMENT_POST, "++", LSL_RIGHT2LEFT | LSL_UNARY, NULL, NULL, NULL}, +// {LSL_DECREMENT_PRE, "--", LSL_RIGHT2LEFT | LSL_UNARY, NULL, NULL, NULL}, +// {LSL_DECREMENT_POST, "--", LSL_RIGHT2LEFT | LSL_UNARY, NULL, NULL, NULL}, +// {LSL_DOT, ".", LSL_RIGHT2LEFT, NULL, NULL, NULL}, +// {LSL_ASSIGNMENT_PLAIN, "=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, NULL, NULL}, +// {LSL_ASSIGNMENT_DIVIDE, "/=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, NULL, NULL}, +// {LSL_ASSIGNMENT_MODULO, "%=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, NULL, NULL}, +// {LSL_ASSIGNMENT_MULTIPLY, "*=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, NULL, NULL}, +// {LSL_ASSIGNMENT_SUBTRACT, "-=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, NULL, NULL}, +// {LSL_ASSIGNMENT_ADD, "+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, NULL, NULL}, +// {LSL_ASSIGNMENT_CONCATENATE, "+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, NULL, NULL}, + {LSL_PARENTHESIS_OPEN, "(", LSL_INNER2OUTER, NULL, NULL, NULL}, + {LSL_PARENTHESIS_CLOSE, ")", LSL_INNER2OUTER, NULL, NULL, NULL}, +// {LSL_BRACKET_OPEN, "[", LSL_INNER2OUTER | LSL_CREATION, NULL, NULL, NULL}, +// {LSL_BRACKET_CLOSE, "]", LSL_INNER2OUTER | LSL_CREATION, NULL, NULL, NULL}, +// {LSL_ANGLE_OPEN, "<", LSL_LEFT2RIGHT | LSL_CREATION, NULL, NULL, NULL}, +// {LSL_ANGLE_CLOSE, ">", LSL_LEFT2RIGHT | LSL_CREATION, NULL, NULL, NULL}, +// {LSL_TYPECAST_OPEN, "(", LSL_RIGHT2LEFT | LSL_UNARY, NULL, NULL, NULL}, +// {LSL_TYPECAST_CLOSE, ")", LSL_RIGHT2LEFT | LSL_UNARY, NULL, NULL, NULL}, + {LSL_BIT_NOT, "~", LSL_RIGHT2LEFT | LSL_UNARY, NULL, NULL, NULL}, + {LSL_BOOL_NOT, "!", LSL_RIGHT2LEFT | LSL_UNARY, NULL, NULL, NULL}, + {LSL_NEGATION, "-", LSL_RIGHT2LEFT | LSL_UNARY, NULL, NULL, NULL}, + {LSL_DIVIDE, "/", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_MODULO, "%", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_MULTIPLY, "*", LSL_LEFT2RIGHT, NULL, NULL, NULL}, +// {LSL_DOT_PRODUCT, "*", LSL_LEFT2RIGHT, NULL, NULL, NULL}, +// {LSL_CROSS_PRODUCT, "%", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_SUBTRACT, "-", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_ADD, "+", LSL_LEFT2RIGHT, NULL, NULL, NULL}, +// {LSL_CONCATENATE, "+", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_LEFT_SHIFT, "<<", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_RIGHT_SHIFT, ">>", LSL_LEFT2RIGHT, NULL, NULL, NULL}, +// QUIRK - Conditionals are executed right to left. Or left to right, depending on who you ask. lol + {LSL_LESS_THAN, "<", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_GREATER_THAN, ">", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_LESS_EQUAL, "<=", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_GREATER_EQUAL, ">=", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_EQUAL, "==", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_NOT_EQUAL, "!=", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_BIT_AND, "&", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_BIT_XOR, "^", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_BIT_OR, "|", LSL_LEFT2RIGHT, NULL, NULL, NULL}, +// QUIRK - Seems to be some disagreement about BOOL_AND/BOOL_OR precedence. Either they are equal, or OR is higher. +// QUIRK - No boolean short circuiting. + {LSL_BOOL_OR, "||", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + {LSL_BOOL_AND, "&&", LSL_LEFT2RIGHT, NULL, NULL, NULL}, + + // Then the rest of the syntax tokens. + +// {LSL_COMMENT_LINE, "//", LSL_NONE, NULL, NULL, NULL}, +// {LSL_COMMENT, "/*", LSL_NONE, NULL, NULL, NULL}, +// {LSL_TYPE, "", LSL_NONE, NULL, NULL, NULL}, +// {LSL_NAME, "", LSL_NONE, NULL, NULL, NULL}, +// {LSL_IDENTIFIER, "", LSL_NONE, NULL, NULL, NULL}, +// {LSL_FLOAT, "float", LSL_NONE, NULL, NULL, NULL}, + {LSL_INTEGER, "integer", LSL_NONE, outputIntegerToken, NULL, evaluateIntegerToken}, +// {LSL_STRING, "string", LSL_NONE, NULL, NULL, NULL}, +// {LSL_KEY, "key", LSL_NONE, NULL, NULL, NULL}, +// {LSL_VECTOR, "vector", LSL_NONE, NULL, NULL, NULL}, +// {LSL_ROTATION, "rotation", LSL_NONE, NULL, NULL, NULL}, +// {LSL_LIST, "list", LSL_NONE, NULL, NULL, NULL}, +// {LSL_LABEL, "@", LSL_NONE, NULL, NULL, NULL}, + {LSL_EXPRESSION, "", LSL_NONE, outputExpressionToken, NULL, evaluateExpressionToken}, +// {LSL_DO, "do", LSL_NONE, NULL, NULL, NULL}, +// {LSL_FOR, "for", LSL_NONE, NULL, NULL, NULL}, +// {LSL_IF, "if", LSL_NONE, NULL, NULL, NULL}, +// {LSL_ELSE, "else", LSL_NONE, NULL, NULL, NULL}, +// {LSL_ELSE_IF, "else if", LSL_NONE, NULL, NULL, NULL}, +// {LSL_JUMP, "jump", LSL_NONE, NULL, NULL, NULL}, +// {LSL_STATE_CHANGE, "state", LSL_NONE, NULL, NULL, NULL}, +// {LSL_WHILE, "while", LSL_NONE, NULL, NULL, NULL}, +// {LSL_RETURN, "return", LSL_NONE, NULL, NULL, NULL}, +// {LSL_STATEMENT, ";", LSL_NONE, NULL, NULL, NULL}, +// {LSL_BLOCK_OPEN, "{", LSL_NONE, NULL, NULL, NULL}, +// {LSL_BLOCK_CLOSE, "}", LSL_NONE, NULL, NULL, NULL}, +// {LSL_PARAMETER, "", LSL_NONE, NULL, NULL, NULL}, +// {LSL_FUNCTION, "", LSL_NONE, NULL, NULL, NULL}, +// {LSL_STATE, "", LSL_NONE, NULL, NULL, NULL}, +// {LSL_SCRIPT, "", LSL_NONE, NULL, NULL, NULL}, + {999999, NULL, LSL_NONE, NULL, NULL, NULL} +}; + +LSL_Token **tokens = NULL; +int lowestToken = 999999; + static LSL_AST *newAST(LSL_Type type, LSL_AST *left, LSL_AST *right) { @@ -17,16 +114,21 @@ static LSL_AST *newAST(LSL_Type type, LSL_AST *left, LSL_AST *right) ast->right = right; ast->line = -1; ast->character = -1; + if (tokens) + ast->token = tokens[type - lowestToken]; + else + ast->token = NULL; return ast; } -void burnAST(LSL_AST *ast) +static void burnAST(LSL_AST *ast) { if (ast == NULL) return; burnAST(ast->left); burnAST(ast->right); + // TODO - burn the contents to. free(ast); } @@ -49,11 +151,15 @@ static LSL_Expression *newLSLExpression(LSL_Type type, LSL_Expression *left, LSL exp->type = type; exp->left = left; exp->right = right; + if (tokens) + exp->token = tokens[type - lowestToken]; + else + exp->token = NULL; return exp; } -void burnLSLExpression(LSL_Expression *exp) +static void burnLSLExpression(LSL_Expression *exp) { if (exp == NULL) return; @@ -77,21 +183,23 @@ LSL_Expression *addOperation(LSL_Operation type, LSL_Expression *left, LSL_Expre LSL_Expression *exp = newLSLExpression(LSL_EXPRESSION, left, right); if (exp) + { exp->content.operationValue = type; + if (tokens) + exp->token = tokens[type - lowestToken]; + else + exp->token = NULL; + } return exp; } -int evaluateExpression(LSL_Expression *exp, int old) +static int evaluateExpression(LSL_Expression *exp, int old) { if (NULL == exp) return old; #ifdef LUASL_DEBUG - #ifdef LUASL_USE_ENUM - printf(" %s ", LSL_Tokens[exp->content.operationValue - LSL_COMMA].token); - #else - printf(" # "); - #endif + printf(" %s ", exp->token->token); #endif if (LSL_INTEGER == exp->type) @@ -162,8 +270,30 @@ int evaluateExpression(LSL_Expression *exp, int old) return old; } -int evaluateAST(LSL_AST *ast, int old) +static LSL_Leaf *evaluateExpressionToken(LSL_Leaf *content, LSL_Type oldType, LSL_Leaf *old) +{ +// if (content) +// return evaluateExpression(content->expressionValue, old->integerValue); + return old; +} + +static LSL_Leaf *evaluateIntegerToken(LSL_Leaf *content, LSL_Type oldType, LSL_Leaf *old) +{ + if (content) + { +#ifdef LUASL_DEBUG + printf("%d", content->integerValue); +#endif + return content; + } + return old; +} + +static int evaluateAST(LSL_AST *ast, int old) { +// if ((ast) && (ast->token) && (ast->token->evaluate)) +// return ast->token->evaluate(&(ast->content), oldType, old); + if (NULL == ast) return old; switch(ast->type) @@ -214,7 +344,7 @@ int evaluateAST(LSL_AST *ast, int old) return old; } -void outputExpression(LSL_Expression *exp) +static void outputExpression(LSL_Expression *exp) { if (NULL == exp) return; @@ -226,93 +356,33 @@ void outputExpression(LSL_Expression *exp) else { outputExpression(exp->left); -#ifdef LUASL_USE_ENUM - printf(" %s ", LSL_Tokens[exp->content.operationValue - LSL_COMMA].token); -#else - printf(" # "); -#endif + printf(" %s ", exp->token->token); outputExpression(exp->right); } } -void outputAST(LSL_AST *ast) +static void outputExpressionToken(LSL_Leaf *content) { - if (NULL == ast) - return; - switch(ast->type) - { -#ifdef LUASL_USE_ENUM - case LSL_COMMENT : return; - case LSL_TYPE : return; - case LSL_NAME : return; - case LSL_IDENTIFIER : return; - case LSL_FLOAT : printf("%f", ast->content.floatValue); break; - case LSL_INTEGER : printf("%d", ast->content.integerValue); break; - case LSL_STRING : return; - case LSL_KEY : return; - case LSL_VECTOR : return; - case LSL_ROTATION : return; - case LSL_LIST : return; - case LSL_LABEL : return; -#endif - case LSL_EXPRESSION : outputExpression(ast->content.expressionValue); break; -#ifdef LUASL_USE_ENUM - case LSL_DO : return; - case LSL_FOR : return; - case LSL_IF : return; - case LSL_ELSE : return; - case LSL_ELSEIF : return; - case LSL_JUMP : return; - case LSL_STATE_CHANGE : return; - case LSL_WHILE : return; - case LSL_RETURN : return; - case LSL_STATEMENT : return; - case LSL_BLOCK : return; - case LSL_PARAMETER : return; - case LSL_FUNCTION : return; - case LSL_STATE : return; - case LSL_SCRIPT : return; -#endif - } + if (content) + outputExpression(content->expressionValue); } -void convertAST2Lua(LSL_AST *ast) +static void outputIntegerToken(LSL_Leaf *content) { -#ifdef LUASL_USE_ENUM - if (NULL == ast) - return; - switch(ast->type) - { - case LSL_COMMENT : return; - case LSL_TYPE : return; - case LSL_NAME : return; - case LSL_IDENTIFIER : return; - case LSL_FLOAT : return; - case LSL_INTEGER : return; - case LSL_STRING : return; - case LSL_KEY : return; - case LSL_VECTOR : return; - case LSL_ROTATION : return; - case LSL_LIST : return; - case LSL_LABEL : return; - case LSL_EXPRESSION : return; - case LSL_DO : return; - case LSL_FOR : return; - case LSL_IF : return; - case LSL_ELSE : return; - case LSL_ELSEIF : return; - case LSL_JUMP : return; - case LSL_STATE_CHANGE : return; - case LSL_WHILE : return; - case LSL_RETURN : return; - case LSL_STATEMENT : return; - case LSL_BLOCK : return; - case LSL_PARAMETER : return; - case LSL_FUNCTION : return; - case LSL_STATE : return; - case LSL_SCRIPT : return; - } -#endif + if (content) + printf("%d", content->integerValue); +} + +static void outputAST(LSL_AST *ast) +{ + if ((ast) && (ast->token) && (ast->token->output)) + ast->token->output(&(ast->content)); +} + +static void convertAST2Lua(LSL_AST *ast) +{ + if ((ast) && (ast->token) && (ast->token->convert)) + ast->token->convert(&(ast->content)); } int yyerror(const char *msg) @@ -321,7 +391,7 @@ int yyerror(const char *msg) return 0; } -LSL_AST *newTree(const char *expr) +static LSL_AST *newTree(const char *expr) { LuaSL_yyparseParam param; YY_BUFFER_STATE state; @@ -352,6 +422,25 @@ int main(void) { const char test[] = " 4 + 2 * 10 + 3 * ( 5 + 1 )"; LSL_AST *ast; + int i; + + // Figure out what numbers yacc gave to our tokens. + for (i = 0; LSL_Tokens[i].token != NULL; i++) + { + if (lowestToken > LSL_Tokens[i].type) + lowestToken = LSL_Tokens[i].type; + } + tokens = malloc(sizeof(LSL_Token *) * (i + 1)); + if (tokens) + { + // Sort the token table. + for (i = 0; LSL_Tokens[i].token != NULL; i++) + { + int j = LSL_Tokens[i].type - lowestToken; + + tokens[j] = &(LSL_Tokens[i]); + } + } if ((ast = newTree(test))) { @@ -363,6 +452,8 @@ int main(void) printf("Result of '%s' is %d\n", test, result); outputAST(ast); printf("\n"); + convertAST2Lua(ast); + printf("\n"); burnAST(ast); } diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h index a392474..1c6710d 100644 --- a/LuaSL/src/LuaSL_LSL_tree.h +++ b/LuaSL/src/LuaSL_LSL_tree.h @@ -9,6 +9,8 @@ #include "LuaSL_yaccer.tab.h" #endif +#include // So we can have NULL defined. + #define YYERRCODE 256 #define YYDEBUG 1 extern int yydebug; @@ -18,12 +20,13 @@ extern int yydebug; typedef enum { - LSL_LEFT2RIGHT = 0, - LSL_RIGHT2LEFT = 1, - LSL_INNER2OUTER = 2, - LSL_UNARY = 4, - LSL_ASSIGNMENT = 8, - LSL_CREATION = 16 + LSL_NONE = 0, + LSL_LEFT2RIGHT = 1, + LSL_RIGHT2LEFT = 2, + LSL_INNER2OUTER = 4, + LSL_UNARY = 8, + LSL_ASSIGNMENT = 16, + LSL_CREATION = 32 } LSL_Flags; #ifdef LUASL_USE_ENUM @@ -80,68 +83,6 @@ typedef enum // In order of precedence, high to low. typedef int LSL_Operation; #endif -typedef struct -{ -// LSL_Operation operation, - char *token; - LSL_Flags flags; -} LSL_Operator; - -// QUIRK - Seems to be some disagreement about BOOL_AND/BOOL_OR precedence. Either they are equal, or OR is higher. -// QUIRK - Conditionals are executed right to left. Or left to right, depending on who you ask. lol -// QUIRK - No boolean short circuiting. - -#ifdef LSL_Tokens_define -LSL_Operator LSL_Tokens[] = -{ - {",", LSL_LEFT2RIGHT}, - {"++", LSL_RIGHT2LEFT | LSL_UNARY}, - {"++", LSL_RIGHT2LEFT | LSL_UNARY}, - {"--", LSL_RIGHT2LEFT | LSL_UNARY}, - {"--", LSL_RIGHT2LEFT | LSL_UNARY}, - {".", LSL_RIGHT2LEFT}, - {"=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, - {"/=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, - {"%=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, - {"*=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, - {"-=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, - {"+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, - {"+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, - {"(", LSL_INNER2OUTER}, - {")", LSL_INNER2OUTER}, - {"[", LSL_INNER2OUTER | LSL_CREATION}, - {"]", LSL_INNER2OUTER | LSL_CREATION}, - {"<", LSL_LEFT2RIGHT | LSL_CREATION}, - {">", LSL_LEFT2RIGHT | LSL_CREATION}, - {"()", LSL_RIGHT2LEFT | LSL_UNARY}, - {"~", LSL_RIGHT2LEFT | LSL_UNARY}, - {"!", LSL_RIGHT2LEFT | LSL_UNARY}, - {"-", LSL_RIGHT2LEFT | LSL_UNARY}, - {"/", LSL_LEFT2RIGHT}, - {"%", LSL_LEFT2RIGHT}, - {"*", LSL_LEFT2RIGHT}, - {"*", LSL_LEFT2RIGHT}, - {"%", LSL_LEFT2RIGHT}, - {"-", LSL_LEFT2RIGHT}, - {"+", LSL_LEFT2RIGHT}, - {"+", LSL_LEFT2RIGHT}, - {"<<", LSL_LEFT2RIGHT}, - {">>", LSL_LEFT2RIGHT}, - {"<", LSL_LEFT2RIGHT}, - {">", LSL_LEFT2RIGHT}, - {"<=", LSL_LEFT2RIGHT}, - {">=", LSL_LEFT2RIGHT}, - {"==", LSL_LEFT2RIGHT}, - {"!=", LSL_LEFT2RIGHT}, - {"&", LSL_LEFT2RIGHT}, - {"^", LSL_LEFT2RIGHT}, - {"|", LSL_LEFT2RIGHT}, - {"||", LSL_LEFT2RIGHT}, - {"&&", LSL_LEFT2RIGHT} -}; -#endif - - #ifdef LUASL_USE_ENUM typedef enum { @@ -176,41 +117,6 @@ typedef enum } LSL_Type; #else typedef int LSL_Type; -#define LSL_EXPRESSION 1 -#endif - -#ifdef LSL_Keywords_define -char *LSL_Keywords[] = -{ - "//", // Also "/*", - "", - "", - "", - "float", - "integer", - "string", - "key", - "vector", - "rotation", - "list", - "@", - "", - "do", - "for", - "if", - "else", - "else if", - "jump", - "state", - "while", - "return", - ";", - "{}", - "", - "", - "", - "" -}; #endif typedef struct @@ -276,6 +182,20 @@ typedef union LSL_Leaf LSL_Script *scriptValue; } LSL_Leaf; +typedef void (*convertToken2Lua) (LSL_Leaf *content); +typedef void (*outputToken) (LSL_Leaf *content); +typedef LSL_Leaf *(*evaluateToken) (LSL_Leaf *content, LSL_Type oldType, LSL_Leaf *old); + +typedef struct +{ + LSL_Type type; + char *token; + LSL_Flags flags; + outputToken output; + convertToken2Lua convert; + evaluateToken evaluate; +} LSL_Token; + typedef struct { char *name; @@ -287,6 +207,7 @@ typedef struct LSL_Expression { struct LSL_Expression *left; struct LSL_Expression *right; + LSL_Token *token; LSL_Type type; LSL_Leaf content; } LSL_Expression; @@ -297,6 +218,7 @@ typedef struct LSL_AST struct LSL_AST *right; int line; int character; + LSL_Token *token; LSL_Type type; LSL_Leaf content; } LSL_AST; @@ -325,17 +247,9 @@ typedef struct #define YYLEX_PARAM ((LuaSL_yyparseParam*)data)->scanner -void burnLSLExpression(LSL_Expression *exp); -void burnAST(LSL_AST *ast); LSL_AST *addExpression(LSL_Expression *exp); LSL_Expression *addInteger(int value); LSL_Expression *addOperation(LSL_Operation type, LSL_Expression *left, LSL_Expression *right); -int evaluateExpression(LSL_Expression *exp, int old); -int evaluateAST(LSL_AST *ast, int old); -void outputExpression(LSL_Expression *exp); -void outputAST(LSL_AST *ast); -void convertAST2Lua(LSL_AST *ast); -LSL_AST *newTree(const char *expr); int yyerror(const char *msg); int yyparse(void *param); diff --git a/LuaSL/src/LuaSL_yaccer.y b/LuaSL/src/LuaSL_yaccer.y index e208cce..bbec1be 100644 --- a/LuaSL/src/LuaSL_yaccer.y +++ b/LuaSL/src/LuaSL_yaccer.y @@ -21,7 +21,7 @@ %left LSL_DIVIDE LSL_MODULO LSL_MULTIPLY %right LSL_BIT_NOT LSL_BOOL_NOT LSL_NEGATION -%token LSL_PARENTHESIS_OPEN LSL_PARENTHESIS_CLOSE +%token LSL_PARENTHESIS_OPEN LSL_PARENTHESIS_CLOSE LSL_EXPRESSION %type expr -- cgit v1.1