Skip to content
Snippets Groups Projects
Unverified Commit b6bd831b authored by thorstenhater's avatar thorstenhater Committed by GitHub
Browse files

Parser improvements for modcc (#1050)

* Add ranges in STATE blocks of the form FROM ... TO ...
* Unit test for the above
* Add type check for <..., ...> ranges
* Add units in procedure argument lists
* Unit test for the above.
parent d8893d9b
No related branches found
No related tags found
No related merge requests found
......@@ -399,9 +399,16 @@ void Parser::parse_state_block() {
}
parm.token = token_;
//state_block.state_variables.push_back(token_.spelling);
get_token();
if(token_.type == tok::from) {
// silently skips from/to
from_to_description();
if (status_ == lexerStatus::error) {
return;
}
}
// get unit parameters
if (line == location_.line && token_.type == tok::lparen) {
parm.units = unit_description();
......@@ -763,6 +770,10 @@ std::pair<Token, Token> Parser::range_description() {
}
get_token();
if(token_.type != tok::integer) {
error(pprintf("range description must be <int, int>, found '%'", token_));
return {};
}
lb = token_;
get_token();
......@@ -772,6 +783,10 @@ std::pair<Token, Token> Parser::range_description() {
}
get_token();
if(token_.type != tok::integer) {
error(pprintf("range description must be <int, int>, found '%'", token_));
return {};
}
ub = token_;
get_token();
......@@ -784,6 +799,39 @@ std::pair<Token, Token> Parser::range_description() {
return {lb, ub};
}
std::pair<Token, Token> Parser::from_to_description() {
Token lb, ub;
if(token_.type != tok::from) {
error(pprintf("range description must be of form FROM <int> TO <int>, found '%'", token_));
return {};
}
get_token();
if(token_.type != tok::integer) {
error(pprintf("range description must be of form FROM <int> TO <int>, found '%'", token_));
return {};
}
lb = token_;
get_token();
if(token_.type != tok::to) {
error(pprintf("range description must be of form FROM <int> TO <int>, found '%'", token_));
return {};
}
get_token();
if(token_.type != tok::integer) {
error(pprintf("range description must be of form FROM <int> TO <int>, found '%'", token_));
return {};
}
ub = token_;
get_token();
return {lb, ub};
}
// Returns a prototype expression for a function or procedure call
// Takes an optional argument that allows the user to specify the
// name of the prototype, which is used for prototypes where the name
......@@ -804,7 +852,6 @@ expression_ptr Parser::parse_prototype(std::string name=std::string()) {
// check for an argument list enclosed in parenthesis (...)
// return a prototype with an empty argument list if not found
if( token_.type != tok::lparen ) {
//return make_expression<PrototypeExpression>(identifier.location, identifier.spelling, {});
return expression_ptr{new PrototypeExpression(identifier.location, identifier.spelling, {})};
}
......@@ -822,6 +869,14 @@ expression_ptr Parser::parse_prototype(std::string name=std::string()) {
get_token(); // consume the identifier
// args may have a unit attached
if(token_.type == tok::lparen) {
unit_description();
if(status_ == lexerStatus::error) {
return {};
}
}
// look for a comma
if(!(token_.type == tok::comma || token_.type==tok::rparen)) {
error( "expected a comma or closing parenthesis, found '"
......
......@@ -69,6 +69,7 @@ private:
std::string value_literal();
int value_signed_integer();
std::pair<Token, Token> range_description();
std::pair<Token, Token> from_to_description();
/// build the identifier list
void add_variables_to_symbols();
......
......@@ -54,6 +54,8 @@ static Keyword keywords[] = {
{"COMPARTMENT", tok::compartment},
{"METHOD", tok::method},
{"STEADYSTATE", tok::steadystate},
{"FROM", tok::from},
{"TO", tok::to},
{"if", tok::if_stmt},
{"IF", tok::if_stmt},
{"else", tok::else_stmt},
......
......@@ -64,6 +64,7 @@ enum class tok {
solve, method, steadystate,
threadsafe, global,
point_process,
from, to,
// prefix binary operators
min, max,
......
......@@ -93,7 +93,7 @@ TEST(Parser, procedure) {
" y = a + b *c + a + b\n"
"}"
,
"PROCEDURE trates(v) {\n"
"PROCEDURE trates(v (mV)) {\n"
" LOCAL qt\n"
" qt=q10^((celsius-22)/10)\n"
" minf=1-1/(1+exp((v-vhalfm)/km))\n"
......@@ -685,6 +685,10 @@ TEST(Parser, parse_state_block) {
"STATE {\n"
" h (nA)\n"
" m (nA) r (uA)\n"
"}",
"STATE {\n"
" h FROM 0 TO 1\n"
" m r (uA)\n"
"}"
};
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment