%include { #include "grammar.h" #include #include #include #include #include #include "cJSON.h" using namespace std; int get_token_id (char*); const char *getValue (cJSON *token); const char *getLine (cJSON *token); cJSON *unary (char *fname, cJSON *a); cJSON *binary (char *fname, cJSON *a, cJSON *b); cJSON *ternary (char *fname, cJSON *a, cJSON *b, cJSON *c); char *linenumber; char *curtoken; char *curtype; } %code { using namespace std; typedef struct {char *value; int line;} token; token* create_token (char *value, int line) { token *t = (token*) malloc (sizeof (token)); t->value = strdup (value); t->line = line; return t; } const char * getValue (cJSON* token) { return cJSON_GetObjectItem (token, "value")->valuestring; } const char * getLine (cJSON* token) { return cJSON_GetObjectItem (token, "line")->valuestring; } int main(int argc, char* argv[]) { char *result; std::string line; std::string input = ""; while (std::getline(std::cin, line)) { input += line + "\n"; } if (input == "") { cout << "Empty input"; exit(0); } cJSON *root = cJSON_Parse(input.c_str()); if (!root) { cout << "JSON invalid\n"; exit(0); } void* pParser = ParseAlloc (malloc); int num = cJSON_GetArraySize (root); for (int i = 0; i < num; i++ ) { // Knoten im Token-Stream auslesen cJSON *node = cJSON_GetArrayItem(root,i); char *line = cJSON_GetArrayItem(node,0)->valuestring; char *type = cJSON_GetArrayItem(node,1)->valuestring; char *value = cJSON_GetArrayItem(node,2)->valuestring; cJSON *tok = cJSON_CreateObject(); cJSON_AddStringToObject(tok, "value", value); cJSON_AddStringToObject(tok, "line", line); linenumber = line; curtoken = value; curtype = type; // THE und Kommentare werden ueberlesen if (strcmp(type, "THE") == 0) continue; if (strcmp(type, "COMMENT") == 0) continue; if (strcmp(type, "MCOMMENT") == 0) continue; int tokenid = get_token_id (type); Parse (pParser, tokenid, tok); } Parse (pParser, 0, 0); ParseFree(pParser, free ); } /////////////////////// /////////////////////// // TOKENS /////////////////////// /////////////////////// int get_token_id (char *token) { if (strcmp(token, "AMBERSAND") == 0) return AMBERSAND; if (strcmp(token, "ASSIGN") == 0) return ASSIGN; if (strcmp(token, "AND") == 0) return AND; if (strcmp(token, "AFTER") == 0) return AFTER; if (strcmp(token, "BEFORE") == 0) return BEFORE; if (strcmp(token, "BETWEEN") == 0) return BETWEEN; if (strcmp(token, "COS") == 0) return COS; if (strcmp(token, "COMMA") == 0) return COMMA; if (strcmp(token, "COUNT") == 0) return COUNT; if (strcmp(token, "DIVIDE") == 0) return DIVIDE; if (strcmp(token, "DO") == 0) return DO; if (strcmp(token, "EQUAL") == 0) return EQUAL; if (strcmp(token, "ENDDO") == 0) return ENDDO; if (strcmp(token, "ENDIF") == 0) return ENDIF; if (strcmp(token, "ELSE") == 0) return ELSE; if (strcmp(token, "ELSEIF") == 0) return ELSEIF; if (strcmp(token, "FIRST") == 0) return FIRST; if (strcmp(token, "FOR") == 0) return FOR; if (strcmp(token, "GT") == 0) return GT; if (strcmp(token, "GREATER") == 0) return GREATER; if (strcmp(token, "IDENTIFIER") == 0) return IDENTIFIER; if (strcmp(token, "IS") == 0) return IS; if (strcmp(token, "ISNOT") == 0) return ISNOT; if (strcmp(token, "IF") == 0) return IF; if (strcmp(token, "IT") == 0) return IT; if (strcmp(token, "THEY") == 0) return IT; if (strcmp(token, "IN") == 0) return IN; if (strcmp(token, "LIST") == 0) return LIST; if (strcmp(token, "LPAR") == 0) return LPAR; if (strcmp(token, "RPAR") == 0) return RPAR; if (strcmp(token, "LSPAR") == 0) return LSPAR; if (strcmp(token, "RSPAR") == 0) return RSPAR; if (strcmp(token, "LT") == 0) return LT; if (strcmp(token, "LESS") == 0) return LESS; if (strcmp(token, "MINUS") == 0) return MINUS; if (strcmp(token, "NUMBER") == 0) return NUMBER; if (strcmp(token, "NUMTOKEN") == 0) return NUMTOKEN; if (strcmp(token, "NULLTOKEN") == 0) return NULLTOKEN; if (strcmp(token, "OR") == 0) return OR; if (strcmp(token, "OF") == 0) return OF; if (strcmp(token, "OCCURS") == 0) return OCCURS; if (strcmp(token, "OCCURRED") == 0) return OCCURS; if (strcmp(token, "PLUS") == 0) return PLUS; if (strcmp(token, "POWER") == 0) return POWER; if (strcmp(token, "SEMICOLON") == 0) return SEMICOLON; if (strcmp(token, "SIN") == 0) return SIN; if (strcmp(token, "STRTOKEN") == 0) return STRTOKEN; if (strcmp(token, "TIMETOKEN") == 0) return TIMETOKEN; if (strcmp(token, "TIMES") == 0) return TIMES; if (strcmp(token, "TIME") == 0) return TIME; if (strcmp(token, "TRACE") == 0) return TRACE; if (strcmp(token, "THAN") == 0) return THAN; if (strcmp(token, "THEN") == 0) return THEN; if (strcmp(token, "TO") == 0) return TO; if (strcmp(token, "RANGE") == 0) return RANGE; if (strcmp(token, "WRITE") == 0) return WRITE; if (strcmp(token, "WHERE") == 0) return WHERE; if (strcmp(token, "NOW") == 0) return NOW; if (strcmp(token, "NOT") == 0) return NOT; if (strcmp(token, "TRUE") == 0) return TRUE; if (strcmp(token, "FALSE") == 0) return FALSE; if (strcmp(token, "WITHIN") == 0) return WITHIN; printf ("{\"error\" : true, \"message\": \"UNKNOWN TOKEN TYPE %s\"}\n", token); exit(0); } cJSON* unary (char* fname, cJSON* a) { cJSON *res = cJSON_CreateObject(); cJSON *arg = cJSON_CreateArray(); cJSON_AddItemToArray(arg, a); cJSON_AddStringToObject(res, "type", fname); cJSON_AddItemToObject(res, "arg", arg); return res; } cJSON* binary (char *fname, cJSON *a, cJSON *b) { cJSON *res = cJSON_CreateObject(); cJSON *arg = cJSON_CreateArray(); cJSON_AddItemToArray(arg, a); cJSON_AddItemToArray(arg, b); cJSON_AddStringToObject(res, "type", fname); cJSON_AddItemToObject(res, "arg", arg); return res; } cJSON* ternary (char *fname, cJSON *a, cJSON *b, cJSON *c) { cJSON *res = cJSON_CreateObject(); cJSON *arg = cJSON_CreateArray(); cJSON_AddItemToArray(arg, a); cJSON_AddItemToArray(arg, b); cJSON_AddItemToArray(arg, c); cJSON_AddStringToObject(res, "type", fname); cJSON_AddItemToObject(res, "arg", arg); return res; } } %syntax_error { printf ("{\"error\" : true, \"message\": \"Syntax Error: Compiler reports unexpected token \\\"%s\\\" of type \\\"%s\\\" in line %s\"}\n", curtoken, curtype, linenumber); exit(0); } %token_type {cJSON *} %default_type {cJSON *} /////////////////////// /////////////////////// // PRECEDENCE /////////////////////// /////////////////////// %left WHERE . %left OR . %left AND . %left AMBERSAND . %right NOT . %left IS ISNOT GT LT LESS GREATER LESSEQUAL GREATEREQUAL WITHIN OCCURS AFTER BEFORE BETWEEN RANGE . %left PLUS MINUS . %left TIMES DIVIDE . %right POWER . %right SIN COS . %right UMINUS . %right TIME FIRST LAST COUNT LISTACCESS LSPAR . /////////////////////// // CODE /////////////////////// code ::= statementblock(sb) . { printf (cJSON_Print(sb)); } /////////////////////// // STATEMENTBLOCK /////////////////////// statementblock(sb) ::= . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "STATEMENTBLOCK"); cJSON *arg = cJSON_CreateArray(); cJSON_AddItemToObject(res, "statements", arg); sb = res; } statementblock(sb) ::= statementblock(a) statement(b) . { cJSON_AddItemToArray(cJSON_GetObjectItem ( a, "statements"), b); sb = a; } /////////////////////////// // WRITE /////////////////////////// statement(r) ::= WRITE ex(e) SEMICOLON . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "WRITE"); cJSON_AddItemToObject(res, "arg", e); r = res; } /////////////////////////// // Trace /////////////////////////// statement(r) ::= TRACE(a) ex(e) SEMICOLON . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "TRACE"); cJSON_AddItemToObject(res, "arg", e); cJSON_AddStringToObject(res, "line", getLine(a)); r = res; } /////////////////////////// // ASSIGN /////////////////////////// statement(r) ::= IDENTIFIER(a) ASSIGN ex(e) SEMICOLON . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "ASSIGN"); cJSON_AddStringToObject(res, "varname", getValue(a)); cJSON_AddItemToObject(res, "arg", e); r = res; } /////////////////////////// // ASSIGN TIME OF /////////////////////////// statement(r) ::= TIME of IDENTIFIER(a) ASSIGN ex(e) SEMICOLON . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "TIMEASSIGN"); cJSON_AddStringToObject(res, "varname", getValue(a)); cJSON_AddItemToObject(res, "arg", e); r = res; } statement(r) ::= IDENTIFIER(a) LSPAR ex(b) RSPAR ASSIGN ex(e) SEMICOLON . { cJSON *res = cJSON_CreateObject(); cJSON *arg = cJSON_CreateArray(); cJSON_AddStringToObject(res, "type", "LISTINDEXASSIGN"); cJSON_AddStringToObject(res, "varname", getValue(a)); cJSON_AddItemToArray(arg, b); cJSON_AddItemToArray(arg, e); cJSON_AddItemToObject(res, "arg", arg); r = res; } statement(r) ::= TIME of IDENTIFIER(a) LSPAR ex(b) RSPAR ASSIGN ex(e) SEMICOLON . { cJSON *res = cJSON_CreateObject(); cJSON *arg = cJSON_CreateArray(); cJSON_AddStringToObject(res, "type", "LISTINDEXTIMEASSIGN"); cJSON_AddStringToObject(res, "varname", getValue(a)); cJSON_AddItemToArray(arg, b); cJSON_AddItemToArray(arg, e); cJSON_AddItemToObject(res, "arg", arg); r = res; } /////////////////////////// // IF /////////////////////////// ifconditionstatement ::= ifstartstatement . ifconditionstatement ::= elseifstatement . ifstatement ::= ifstartstatement . ifstatement ::= elseifstatement . ifstatement ::= elsestatement . statement ::= ifstatement ENDIF SEMICOLON . ifstartstatement(r) ::= IF ex(c) THEN statementblock(s) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "IF"); cJSON_AddItemToObject(res, "arg", c); cJSON_AddItemToObject(res, "statements", s); cJSON *elseifs = cJSON_CreateArray(); cJSON_AddItemToObject(res, "elseif", elseifs); r = res; } elseifstatement(r) ::= ifconditionstatement(i) ELSEIF ex(c) THEN statementblock(s) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "ELSEIF"); cJSON_AddItemToObject(res, "arg", c); cJSON_AddItemToObject(res, "statements", s); cJSON *elseifArray = cJSON_GetObjectItem(i, "elseif"); cJSON_AddItemToArray(elseifArray, res); r = i; } elsestatement(r) ::= ifconditionstatement(i) ELSE statementblock(s) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "ELSE"); cJSON_AddItemToObject(res, "statements", s); cJSON_AddItemToObject(i, "else", res); r = i; } /////////////////////////// // FOR /////////////////////////// statement(r) ::= FOR IDENTIFIER(a) IN ex(e) DO statementblock(s) ENDDO SEMICOLON . { cJSON *res = cJSON_CreateObject(); cJSON *arg = cJSON_CreateArray(); cJSON_AddStringToObject(res, "type", "FOR"); cJSON_AddStringToObject(res, "varname", getValue(a)); cJSON_AddItemToObject(res, "arg", e); cJSON_AddItemToObject(res, "statements", s); r = res; } ex(r) ::= LPAR ex(a) RPAR . { r = a; } ex(r) ::= LSPAR RSPAR . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "EMPTYLIST"); r = res; } ex(r) ::= LSPAR exlist(a) RSPAR . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "LIST"); cJSON_AddItemToObject(res, "elements", a); r = res; } exlist(r) ::= ex(a) . { cJSON *elem = cJSON_CreateArray(); cJSON_AddItemToArray(elem, a); r = elem; } exlist(r) ::= exlist(a) COMMA ex(b) . { cJSON_AddItemToArray(a,b); r = a; } ex(r) ::= NUMTOKEN (a). { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "NUMTOKEN"); cJSON_AddStringToObject(res, "value", getValue(a)); cJSON_AddStringToObject(res, "line", getLine(a)); r = res; } ex(r) ::= STRTOKEN (a). { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "STRTOKEN"); cJSON_AddStringToObject(res, "value", getValue(a)); cJSON_AddStringToObject(res, "line", getLine(a)); r = res; } ex(r) ::= IDENTIFIER(a) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "VARIABLE"); cJSON_AddStringToObject(res, "name", getValue(a)); cJSON_AddStringToObject(res, "line", getLine(a)); r = res; } ex(r) ::= TIMETOKEN(a) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "TIMETOKEN"); cJSON_AddStringToObject(res, "value", getValue(a)); cJSON_AddStringToObject(res, "line", getLine(a)); r = res; } ex(r) ::= NULLTOKEN(a) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "NULLTOKEN"); r = res; } ex(r) ::= LIST(a) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "LISTTYPE"); cJSON_AddStringToObject(res, "value", getValue(a)); cJSON_AddStringToObject(res, "line", getLine(a)); r = res; } ex(r) ::= NUMBER(a) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "NUMTYPE"); cJSON_AddStringToObject(res, "name", getValue(a)); cJSON_AddStringToObject(res, "line", getLine(a)); r = res; } ex(r) ::= NOW(a) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "NOW"); r = res; } ex(r) ::= IT(a) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "IT"); r = res; } ex(r) ::= TRUE(a) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "BOOL"); cJSON_AddStringToObject(res, "value", "1"); r = res; } ex(r) ::= FALSE(a) . { cJSON *res = cJSON_CreateObject(); cJSON_AddStringToObject(res, "type", "BOOL"); cJSON_AddStringToObject(res, "value", "0"); r = res; } of ::= . of ::= OF . is ::= . is ::= IS . ex(r) ::= COS ex(a) . {r = unary ("COS", a); } ex(r) ::= FIRST ex(a) . {r = unary ("FIRST", a); } ex(r) ::= COUNT ex(a) . {r = unary ("COUNT", a); } ex(r) ::= TIME of ex(a) . {r = unary ("TIME", a); } ex(r) ::= NOT ex(a) . {r = unary ("NOT", a); } ex(r) ::= SIN ex(a) . {r = unary ("SIN", a); } ex(r) ::= LESS THAN ex(a) . {r = unary ("LESS", a); } ex(r) ::= BEFORE ex(a) . {r = unary ("BEFORE", a); } ex(r) ::= GREATER THAN ex(a) . {r = unary ("GREATER", a); } ex(r) ::= AFTER ex(a) . {r = unary ("AFTER", a); } ex(r) ::= LESS THAN OR EQUAL ex(a) . {r = unary ("LESSEQUAL", a); } ex(r) ::= GREATER THAN OR EQUAL ex(a) . {r = unary ("GREATEREQUAL", a); } ex(r) ::= WITHIN ex(a) TO ex(b). {r = binary ("WITHIN", a, b); } ex(r) ::= BETWEEN ex(a) AND ex(b). {r = binary ("BETWEEN", a, b); } ex(r) ::= ex(a) AMBERSAND ex(b) . {r = binary ("AMBERSAND", a, b); } ex(r) ::= ex(a) AND ex(b) . {r = binary ("AND", a, b); } ex(r) ::= ex(a) OR ex(b) . {r = binary ("OR", a, b); } ex(r) ::= ex(a) WHERE ex(b) . {r = binary ("WHERE", a, b); } ex(r) ::= ex(a) OCCURS ex(b) . {r = binary ("OCCURS", a, b); } ex(r) ::= ex(a) IS ex(b) . {r = binary ("IS", a, b); } ex(r) ::= ex(a) IS NOT ex(b) . {r = binary ("ISNOT", a, b); } ex(r) ::= ex(a) PLUS ex(b) . {r = binary ("PLUS", a, b); } ex(r) ::= ex(a) MINUS ex(b) . {r = binary ("MINUS", a, b); } ex(r) ::= MINUS ex(a) . [UMINUS] {r = unary ("UMINUS", a); } ex(r) ::= ex(a) TIMES ex(b) . {r = binary ("TIMES", a, b); } ex(r) ::= ex(a) DIVIDE ex(b) . {r = binary ("DIVIDE", a, b); } ex(r) ::= ex(a) POWER ex(b) . {r = binary ("POWER", a, b); } ex(r) ::= ex(a) GT ex(b) . {r = binary ("GT", a, b); } ex(r) ::= ex(a) LT ex(b) . {r = binary ("LT", a, b); } ex(r) ::= ex(a) LSPAR ex(b) RSPAR . {r = binary ("LISTACCESS", a, b); } ex(r) ::= ex(a) RANGE ex(b) . {r = binary ("RANGE", a, b); }