summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp
blob: ba89e1415a81e067e079e203b8f34cdc25283fa4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "PromelaParser.h"
#include "parser/promela.tab.hpp"

struct yy_buffer_state; \
typedef yy_buffer_state *YY_BUFFER_STATE; \
extern YY_BUFFER_STATE promela__scan_buffer(char *, size_t, void*); \
extern int promela_lex (PROMELA_STYPE* yylval_param, void* yyscanner); \
int promela_lex_init (void**); \
int promela_lex_destroy (void*); \

void promela_error (uscxml::PromelaParser* ctx, void* yyscanner, const char* err) {
	uscxml::Event exceptionEvent;
	exceptionEvent.data.compound["exception"] = uscxml::Data(err, uscxml::Data::VERBATIM);
	exceptionEvent.name = "error.execution";
	exceptionEvent.eventType = uscxml::Event::PLATFORM;
	throw exceptionEvent;
}

namespace uscxml {

PromelaParser::PromelaParser(const std::string& expr, Type expectedType) {
	input_length = expr.length() + 5;  // plus some zero terminators
	input = (char*) calloc(1, input_length);
	memcpy(input, expr.c_str(), expr.length());

	promela_lex_init(&scanner);
	//	promela_assign_set_extra(ast, &scanner);
	promela__scan_buffer(input, input_length, scanner);
	promela_parse(this, scanner);
	
	if (type != expectedType) {
		std::stringstream ss;
		ss << "Promela syntax type mismatch: Expected " << typeToDesc(expectedType) << " but got " << typeToDesc(type);

		uscxml::Event exceptionEvent;
		exceptionEvent.data.compound["exception"] = uscxml::Data(ss.str(), uscxml::Data::VERBATIM);
		exceptionEvent.name = "error.execution";
		exceptionEvent.eventType = uscxml::Event::PLATFORM;
		throw exceptionEvent;
	}
}

PromelaParser::~PromelaParser() {
	free(input);
	promela_lex_destroy(scanner);
}

std::string PromelaParser::typeToDesc(int type) {
	switch (type) {
		case PROMELA_EXPR: return "expression";
		case PROMELA_DECL: return "declarations";
		case PROMELA_STMNT: return "statements";
		default:
			break;
	}
	return "";
}

std::string PromelaParserNode::typeToDesc(int type) {
	switch(type) {
		case PLUS: return "PLUS";
		case MINUS: return "MINUS";
		case TIMES: return "TIMES";
		case DIVIDE: return "DIVIDE";
		case MODULO: return "MODULO";
		case BITAND: return "BITAND";
		case BITXOR: return "BITXOR";
		case BITOR: return "BITOR";
		case GT: return "GT";
		case LT: return "LT";
		case GE: return "GE";
		case LE: return "LE";
		case EQ: return "EQ";
		case NE: return "NE";
		case AND: return "AND";
		case OR: return "OR";
		case LSHIFT: return "LSHIFT";
		case RSHIFT: return "RSHIFT";
		case NEG: return "NEG";
		case ASGN: return "ASGN";
		case INCR: return "INCR";
		case DECR: return "DECR";
		case VAR_ARRAY: return "VAR_ARRAY";
		case DECL: return "DECL";
		case STMNT: return "STMNT";
		case TYPE: return "TYPE";
		case NAME: return "NAME";
		case CONST: return "CONST";
		case PRINT: return "PRINT";
		case SHOW: return "SHOW";
		case EXPR: return "EXPR";
		case VARLIST: return "VARLIST";
		case DECLLIST: return "DECLLIST";
		case NAMELIST: return "NAMELIST";
			
		default:
			return std::string("UNK(") + toStr(type) + ")";
	}
}

}