DSM/grammar.y

664 lines
16 KiB
Plaintext

%include {
#include "grammar.h"
#include <string.h>
#include <stdlib.h>
#include <string>
#include <cassert>
#include <iostream>
#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); }