add files

main
Michael 2025-01-05 17:12:09 +01:00
parent a89fea250c
commit 4ac0ac96eb
12 changed files with 1337 additions and 0 deletions

6
SL3a.txt 100644
View File

@ -0,0 +1,6 @@
write 1 & 1;
write "Hallo Welt";
write "Hallo" & "Welt";
write 1 & "Welt";
x := 4711;
write x;

4
SL3b.txt 100644
View File

@ -0,0 +1,4 @@
write 1+"1";
write 1+true;
write 1 & "1";
write "1"&false;

7
SL3c.txt 100644
View File

@ -0,0 +1,7 @@
testlist := [1,2,"Hallo",4,5,null,false,true];
trace testlist;
trace testlist is number;
trace testlist is list;
trace testlist is not list;
trace count testlist;
trace first testlist;

9
SL3d.txt 100644
View File

@ -0,0 +1,9 @@
a := 4711;
trace time a;
b := 2020-01-01T12:00:00;
time a := b;
c := a;
time c := now;
trace time c;
trace time a;
trace time [1,2,3];

24
SL3e.txt 100644
View File

@ -0,0 +1,24 @@
testlist := [100, 200, 50, 120, 150, 90] ;
trace testlist where [true, false, false, true, true, false];
trace testlist where it is less than or equal 100;
trace testlist where it is within 80 to 120;
trace testlist where it is within 100 to [100,110,120,130,140,150];
trace testlist where 2 * it / 3 is within 80 to 120;
testlist[2] := 199;
trace testlist;
x := 100;
y := 200;
z := 300;
time of x := 2020-06-08T15:15:15;
time of y := 2020-06-09T11:11:00;
time of z := 2020-06-10T12:00:00;
xyz := [x,y,z];
trace xyz where it occurs before time of z;
trace xyz where they occurred after time of x;

16
SL3f.txt 100644
View File

@ -0,0 +1,16 @@
for x in 12 ... 18 do
bmi := x * 2.3;
if bmi is greater than or equal 40 then
trace "Adipositas III";
elseif bmi is greater than or equal 35 then
trace "Adipositas II";
elseif bmi is greater than or equal 30 then
trace "Adipositas I";
else
trace "Keine Adipositas";
endif;
enddo;
//trace bmi;

294
arden_types.py 100644
View File

@ -0,0 +1,294 @@
from abc import ABC, abstractmethod
from datetime import date
class BaseType(ABC):
@abstractmethod
def __str__(self):
pass
def __init__(self):
self.time = NullType(False)
def __repr__(self):
return str(self)
#def __eq__(self,b):
# return BoolType(str(type(self).__name__) is b)
def __and__(self,other):
if isinstance(other, StrType):
return StrType(str(self) + str(other))
return NullType()
def IS(self,b,invert=False):
if b is type(self):
return BoolType(True)
return BoolType(False)
def NOT(self,b,invert=False):
return NullType()
def ISNOT(self,b,invert=False):
return ~self.IS(b)
def LISTACCESS(self,b):
return NullType()
def TIME(self):
return self.time
class NumType(BaseType):
def __init__(self, value: (int, float)):
super().__init__()
if isinstance(value, str):
try:
value = int(value)
except ValueError:
value = float(value)
if not isinstance(value, (int, float)):
raise TypeError(f"Expected a number, got {type(value)}")
self.value = value
def __mul__(self,other):
if isinstance(other, NumType):
return NumType(self.value * other.value)
if isinstance(other, ListType):
return ListType([item * self for item in other.value])
return NullType()
def __truediv__(self,other):
if isinstance(other, NumType):
return NumType(self.value / other.value)
if isinstance(other, ListType):
return ListType([item / self for item in other.value])
return NullType()
def __add__(self,other):
if isinstance(other, NumType):
return NumType(self.value + other.value)
return NullType()
def __sub__(self,other):
if isinstance(other, NumType):
return NumType(self.value - other.value)
return NullType()
def __gt__(self, other):
if isinstance(other, NumType):
return BoolType(self.value > other.value)
return NullType
def __lt__(self, other):
if isinstance(other, NumType):
return BoolType(self.value < other.value)
return NullType
def __ge__(self, other):
if isinstance(other, NumType):
return BoolType(self.value >= other.value)
if isinstance(other, ListType):
return ListType([self >= item for item in other.value])
return NullType
def __le__(self, other):
if isinstance(other, NumType):
return BoolType(self.value <= other.value)
if isinstance(other, ListType):
return ListType([self <= item for item in other.value])
return NullType
def __pow__(self, other):
if isinstance(other, NumType):
return NumType(self.value ** other.value)
return NullType
def __neg__(self):
return NumType(-self.value)
def __str__(self):
return str(self.value)
def IS(self,b,invert=False):
if b is type(self):
return BoolType(True)
if type(b) is self:
return BoolType(self.value == b.value)
if type(b) is Condition:
return b.value(self)
return BoolType(False)
class StrType(BaseType):
def __init__(self, value: str):
super().__init__()
if not isinstance(value, str):
raise TypeError(f"Expected a string, got {type(value)}")
self.value = value
def __and__(self,other):
return StrType(str(self) + str(other))
def __str__(self):
return self.value
class BoolType(BaseType):
def __init__(self, value: bool):
super().__init__()
if not isinstance(value, bool):
raise TypeError(f"Expected a boolean, got {type(value)}")
self.value = value
def __eq__(self, other):
return self.value == other.value
def __bool__(self):
return self.value
def __invert__(self):
return BoolType(not self.value)
def __str__(self):
if self.value:
return "true"
else:
return "false"
def __and__(self,other):
if isinstance(other, BoolType):
return BoolType(self.value and other.value)
return NullType
def NOT(self):
return ~self
class ListType(BaseType):
def __init__(self, value: list):
super().__init__()
if not isinstance(value, list):
raise TypeError(f"Expected a list, got {type(value)}")
self.value = value
def __str__(self):
return f"[{', '.join(str(item) for item in self.value)}]"
def __gt__(self, other):
if isinstance(other, NumType):
return ListType([item > other for item in self.value])
return NullType
def __lt__(self, other):
if isinstance(other, NumType):
return ListType([item < other for item in self.value])
return NullType
def __ge__(self, other):
if isinstance(other, NumType):
return ListType([item >= other for item in self.value])
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item >= b_item for a_item, b_item in zip(self.value, other.value)])
return NullType
def __le__(self, other):
if isinstance(other, NumType):
return ListType([item <= other for item in self.value])
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item <= b_item for a_item, b_item in zip(self.value, other.value)])
return NullType
def __and__(self,other):
if isinstance(other, BoolType) or isinstance(other, NumType):
return ListType([item and other for item in self.value])
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item and b_item for a_item, b_item in zip(self.value, other.value)])
return NullType
def __or__(self,other):
if isinstance(other, BoolType) or isinstance(other, NumType):
return ListType([item or other for item in self.value])
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item or b_item for a_item, b_item in zip(self.value, other.value)])
return NullType
def __truediv__(self,other):
if isinstance(other, NumType):
return ListType([item / other for item in self.value])
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item / b_item for a_item, b_item in zip(self.value, other.value)])
return NullType
def WHERE(self,other):
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item for a_item, b_item in zip(self.value, other.value) if b_item])
return NullType
def IS(self,a,invert=False):
if a is NumType:
return ListType([item.IS(a) for item in self.value])
if a is type(self):
return BoolType(True^invert)
if type(a) is Condition:
return a.value(self)
else:
return BoolType(False^invert)
def OCCURS(self,a):
if type(a) is Condition:
return ListType([a.value(item.time) for item in self.value])
def NOT(self):
return ListType([~item for item in self.value])
def LISTACCESS(self,a):
if type(a) is NumType:
return self.value[a.value]
return NullType()
def LISTINDEXASSIGN(self,a,b):
if type(a) is NumType:
self.value[a.value-1] = b
#self.value.insert(a.value,b)
return NullType()
def TIME(self):
return ListType([item.time for item in self.value])
class DateType(BaseType):
def __init__(self, value: date):
super().__init__()
if not isinstance(value, date):
raise TypeError(f"Expected a date, got {type(value)}")
self.value = value
def __gt__(self, other):
if isinstance(other, DateType):
return BoolType(self.value > other.value)
return NullType
def __lt__(self, other):
if isinstance(other, DateType):
return BoolType(self.value < other.value)
return NullType
def __str__(self):
return self.value.strftime('%Y-%m-%dT%H:%M:%S')
class Condition(BaseType):
def __init__(self, condition):
self.value = condition
def __and__(self, other):
return Condition(lambda x: self.value(x) and other.value(x))
def __or__(self,other):
return Condition(lambda x: self.value(x) or other.value(x))
def __str__(self):
return str(self.value)
class NullType(BaseType):
def __init__(self, has_time=True):
if has_time:
super().__init__()
def __str__(self):
return "Null"

664
grammar.y 100644
View File

@ -0,0 +1,664 @@
%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); }

222
interpreter.py 100644
View File

@ -0,0 +1,222 @@
from datetime import datetime
from collections import deque
from arden_types import StrType, NumType, DateType, ListType, NullType, BoolType, Condition
import math
import copy
class InterpreterError(Exception):
pass
class Interpreter:
def __init__(self):
self.variables = {}
self.it_queue = deque()
def interpret(self, node):
node_type = node["type"]
args = node.get('arg', [])
if node_type == "WHERE":
self.it_queue.append(self.interpret(args[0]))
evaluated_args = [self.interpret(arg) for arg in (args if isinstance(args, list) else [args])]
return getattr(self, node_type)(node, *evaluated_args)
def STATEMENTBLOCK(self,node):
for stmt in node.get("statements"):
self.interpret(stmt)
#Statements
def WRITE(self,node,a):
print(a)
def TRACE(self,node,a):
print(f"LINE {node['line']}: {a}")
def ASSIGN(self,node,a):
#self.variables.update({node.get("varname"): (self.variables.get(node.get("varname")[0],NullType()),a)})
self.variables.update({node.get("varname"): copy.copy(a)})
def TIMEASSIGN(self,node,a):
#self.variables.update({node.get("varname"): (a,self.variables.get(node.get("varname"))[1])})
value = self.variables[node.get("varname")]
value.time = a
self.variables.update({node.get("varname"): copy.copy(value)})
def LISTINDEXASSIGN(self,node,a,b):
value = self.variables[node.get("varname")]
return value.LISTINDEXASSIGN(a,b)
def LISTINDEXTIMEASSIGN(self,node,a,b):
value = self.variables[node.get("varname")]
return value.LISTINDEXASSIGN(a,b)
def IF(self,node,a):
if a:
self.interpret(node.get("statements"))
return
for elseif in node.get("elseif"):
if self.interpret(elseif):
return
else:
if node.get("else"):
self.interpret(node.get("else"))
def ELSEIF(self,node,a):
if a:
self.interpret(node.get("statements"))
return True
return False
def ELSE(self,node):
self.interpret(node.get("statements"))
def FOR(self,node,a):
for x in a.value:
self.variables[node.get("varname")] = x
self.interpret(node.get("statements"))
del self.variables[node.get("varname")]
#Types
def NUMTOKEN(self,node):
return NumType(node.get("value"))
def STRTOKEN(self,node):
return StrType(node.get("value"))
def TIMETOKEN(self,node):
try:
return DateType(datetime.strptime(node.get("value"), "%Y-%m-%dT%H:%M:%S"))
except ValueError:
return DateType(datetime.strptime(node.get("value"), "%Y-%m-%d"))
def NULLTOKEN(self,node):
return NullType()
def NOW(self,node):
return DateType(datetime.now())
def VARIABLE(self,node):
return self.variables.get(node.get("name"))
def TIME(self,node,a):
return a.TIME()
def LIST(self,node):
return ListType([self.interpret(node) for node in node["elements"]])
def BOOL(self,node):
return BoolType(True) if node.get("value") == "1" else BoolType(False)
def NULLTYPE(self,node):
return NullType
def NUMTYPE(self,node):
return NumType
def LISTTYPE(self,node):
return ListType
def TRUE(self,node):
return True
def FALSE(self,node):
return False
def IT(self,node):
if self.it_queue:
return self.it_queue[-1]
return NullType()
def LISTACCESS(self,node,a,b):
return a.LISTACCESS(b)
#Binary Operators
def AMBERSAND(self,node,a,b):
return a & b
def PLUS(self,node,a,b):
return a + b
def MINUS(self,node,a,b):
return a - b
def TIMES(self,node,a,b):
return a * b
def DIVIDE(self,node,a,b):
return a / b
def POWER(self,node,a,b):
return a ** b
def WHERE(self,node,a,b):
res = a.WHERE(b)
self.it_queue.pop()
return res
def GT(self,node,a,b):
return a > b
def LT(self,node,a,b):
return a < b
def AND(self,node,a,b):
return a & b
def OR(self,node,a,b):
return a | b
def RANGE(self,node,a,b):
rangelist = []
x = range(a.value,b.value+1)
for i in x:
rangelist.append(NumType(i))
return ListType(rangelist)
#Unary Operators
def UMINUS(self,node,a):
return -a
def COS(self,node,a):
return NumType(math.cos(a))
def SIN(self,node,a):
return NumType(math.sin(a))
def IS(self,node,a,b):
return a.IS(b)
def ISNOT(self,node,a,b):
return a.IS(b).NOT()
def OCCURS(self,node,a,b):
return a.OCCURS(b)
def NOT(self,a):
return ~a
def FIRST(self,node,a):
return a.value[0]
def COUNT(self,node, a):
return NumType(len(a.value))
#Conditions
def LESS(self,node,a):
return Condition(lambda x: x < a)
def BEFORE(self,node,a):
return Condition(lambda x: x < a)
def GREATER(self,node,a):
return Condition(lambda x: x > a)
def AFTER(self,node,a):
return Condition(lambda x: x > a)
def LESSEQUAL(self,node,a):
return Condition(lambda x: x <= a)
def GREATEREQUAL(self,node,a):
return Condition(lambda x: x >= a)
def WITHIN(self,node,a,b):
return Condition(lambda x: (a <= x) & (x <= b))

11
parser.py 100644
View File

@ -0,0 +1,11 @@
import subprocess
import json
class ParserError(Exception):
pass
class Parser:
def parse(self,tokens):
result = subprocess.run(['./parse.exe'], input=json.dumps(tokens, indent=4).encode('utf-8'),stdout=subprocess.PIPE)
ast = json.loads(result.stdout.decode('utf-8'))
if "error" in ast:
raise ParserError(f"{ast['message']}")
return json.loads(result.stdout.decode('utf-8'))

21
run.py 100644
View File

@ -0,0 +1,21 @@
import argparse
from tokenizer import Tokenizer
from parser import Parser
from interpreter import Interpreter
import json
arg_parser = argparse.ArgumentParser(description="DSM")
arg_parser.add_argument("input_file", type=str, help="The input file to process")
args = arg_parser.parse_args()
tokenizer = Tokenizer()
parser = Parser()
interpreter = Interpreter()
#try:
tokens = tokenizer.tokenize(args.input_file)
#print(json.dumps(tokens, indent=4))
ast = parser.parse(tokens)
#print(json.dumps(ast, indent=4))
interpreter.interpret(ast)
#except Exception as e:
# print(f"{type(e).__name__}: {e}")

59
tokenizer.py 100644
View File

@ -0,0 +1,59 @@
import re
import json
class TokenizerError(Exception):
pass
class Tokenizer:
def __init__(self):
self.reserved = [
'READ', 'WRITE', 'IF', 'THEN', 'ELSEIF', 'ELSE', 'ENDIF', 'FOR',
'IN', 'DO', 'ENDDO', 'NOW', 'CURTIME', 'MINIMUM', 'MAXIMUM',
'FIRST', 'LAST', 'SUM', 'AVERAGE', 'EARLIEST', 'LATEST', 'COS', 'SIN', 'TIME', 'OF', 'TRACE', 'TRUE', 'FALSE', 'IS', 'LIST', 'NUMBER', 'NOT', 'COUNT',
'WHERE', 'IT', 'THEY', 'AND', 'OR', 'LESS', 'GREATER', 'THAN', 'TO', 'WITHIN', 'EQUAL', 'OCCURS', 'OCCURRED', 'AFTER', 'BEFORE'
]
self.regex_patterns = {
"STRTOKEN": r'(".*?")',
"TIMETOKEN": r'\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2})?',
"COMMENT": r'//.*$',
"SEMICOLON": r';',
"COMMA": r',',
"ASSIGN": r':=',
"PLUS": r'\+',
"MINUS": r'\-',
"POWER": r'\*\*',
"TIMES": r'\*',
"DIVIDE": r'\/',
"LPAR": r'\(',
"RPAR": r'\)',
"LSPAR": r'\[',
"RSPAR": r'\]',
"AMBERSAND": r'&',
"NEQ": r'<>',
"LT": r'<',
"GT": r'>',
"LTEQ": r'<=',
"GTEQ": r'>=',
"EQ": r'=',
"RANGE": r'\.\.\.'
}
self.regex_patterns |= {
"NULLTOKEN": r'\bNULL\b'
}
self.regex_patterns |= {i: rf'\b{i}\b' for i in self.reserved}
self.regex_patterns |= {
"NUMTOKEN": r'\d+(\.\d*)?',
"IDENTIFIER": r'\w+'
}
self.combined_pattern = '|'.join(f'(?P<{name}>{pattern})' for name, pattern in self.regex_patterns.items())
self.regex = re.compile(self.combined_pattern, re.IGNORECASE)
def tokenize(self, input_file):
tokens = []
with open(input_file, 'r') as file:
for i, line in enumerate(file):
for match in self.regex.finditer(line):
token_type = match.lastgroup
token_value = match.group(token_type)
if token_type == "STRTOKEN":
token_value = token_value.replace('"','')
tokens.append([str(i + 1), token_type, token_value])
return tokens