--- a/absyntax/absyntax.def Wed Jan 31 16:04:06 2007 +0100
+++ b/absyntax/absyntax.def Wed Jan 31 19:23:46 2007 +0100
@@ -571,7 +571,7 @@
SYM_REF2(action_qualifier_c, action_qualifier, action_time)
-SYM_REF6(transition_c, transition_name, integer, from_steps, to_steps, transition_condition, unused)
+SYM_REF6(transition_c, transition_name, integer, from_steps, to_steps, transition_condition_il, transition_condition_st)
SYM_REF2(steps_c, step_name, step_name_list)
--- a/stage1_2/iec.flex Wed Jan 31 16:04:06 2007 +0100
+++ b/stage1_2/iec.flex Wed Jan 31 19:23:46 2007 +0100
@@ -171,7 +171,7 @@
/* Function only called from within flex, but defined
* in iec.y!
- * We delcare it here...
+ * We declare it here...
*
* Search for a symbol in either of the two symbol tables
* and return the token id of the first symbol found.
@@ -183,6 +183,19 @@
%}
+/*********************************************/
+/* Change parse state to body definitions... */
+/*********************************************/
+
+%{
+static int goto_body_state__ = 0;
+
+void cmd_goto_body_state(void) {goto_body_state__ = 1;}
+int get_goto_body_state(void) {return goto_body_state__;}
+void rst_goto_body_state(void) {goto_body_state__ = 0;}
+%}
+
+
/***************************************************/
/* Forward Declaration of functions defined later. */
/***************************************************/
@@ -270,38 +283,38 @@
* to be later matched correctly by the apropriate language parser (st or il).
* The state machine has 6 possible states (INITIAL, config, decl, body, st, il)
* Possible state changes are:
- * INITIAL -> decl (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
+ * INITIAL -> decl_state (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
* and followed by a VAR declaration)
- * INITIAL -> body (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
+ * INITIAL -> il_st_state (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
* and _not_ followed by a VAR declaration)
- * INITIAL -> config (when a CONFIGURATION is found)
- * decl -> body (when the last END_VAR is found, i.e. the function body starts)
- * body -> sfc (when it figures out it is parsing sfc language)
- * body -> st (when it figures out it is parsing st language)
- * body -> il (when it figures out it is parsing il language)
- * decl -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
- * st -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
- * sfc -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
- * il -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
- * config -> INITIAL (when a END_CONFIGURATION is found)
+ * INITIAL -> config_state (when a CONFIGURATION is found)
+ * decl_state -> il_st_state (when the last END_VAR is found, i.e. the function body starts)
+ * il_st_state -> sfc_state (when it figures out it is parsing sfc language)
+ * il_st_state -> st_state (when it figures out it is parsing st language)
+ * il_st_state -> il_state (when it figures out it is parsing il language)
+ * decl_state -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
+ * st_state -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
+ * sfc_state -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
+ * il_state -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
+ * config_state -> INITIAL (when a END_CONFIGURATION is found)
*/
/* we are parsing a configuration. */
-%s config
+%s config_state
/* we are parsing a function, program or function block declaration */
-%s decl
+%s decl_state
/* we will be parsing a function body. Whether il/st is remains unknown */
-%x body
+%x il_st_state
/* we are parsing il code -> flex must return the EOL tokens! */
-%s il
+%s il_state
/* we are parsing st code -> flex must not return the EOL tokens! */
-%s st
+%s st_state
/* we are parsing sfc code -> flex must not return the EOL tokens! */
-%s sfc
+%s sfc_state
@@ -620,6 +633,11 @@
/*****************************************************/
/*****************************************************/
+ if (goto_body_state__) {
+ yy_push_state(il_st_state);
+ goto_body_state__ = 0;
+ }
+
/*********************************/
/* Handle the pragmas! */
/*********************************/
@@ -634,7 +652,7 @@
yylval.ID=strdup(yytext+1);
return pragma_token;
}
-<body>{pragma} {/* return the pragmma without the enclosing '{' and '}' */
+<il_st_state>{pragma} {/* return the pragmma without the enclosing '{' and '}' */
yytext[strlen(yytext)-2] = '\0';
yylval.ID=strdup(yytext+1);
return pragma_token;
@@ -710,9 +728,9 @@
/* Handle all the state changes! */
/*********************************/
- /* INITIAL -> decl */
+ /* INITIAL -> decl_state */
<INITIAL>{
- /* NOTE: how about functions that do not delcare variables, and go directly to the body???
+ /* NOTE: how about functions that do not declare variables, and go directly to the il_st_state???
* - According to Section 2.5.1.3 (Function Declaration), item 2 in the list, a FUNCTION
* must have at least one input argument, so a correct declaration will have at least
* one VAR_INPUT ... VAR_END construct!
@@ -724,65 +742,76 @@
* construct!
*
* All the above means that we needn't worry about PROGRAMs, FUNCTIONs or
- * FUNCTION_BLOCKs that do not have at least one VAR_END before the body.
+ * FUNCTION_BLOCKs that do not have at least one VAR_END before the il_st_state.
* If the code has an error, and no VAR_END before the body, we will simply
- * continue in the <decl> state, untill the end of the FUNCTION, FUNCTION_BLOCK
+ * continue in the <decl_state> state, untill the end of the FUNCTION, FUNCTION_BLOCK
* or PROGAM.
*/
-FUNCTION BEGIN(decl); return FUNCTION;
-FUNCTION_BLOCK BEGIN(decl); return FUNCTION_BLOCK;
-PROGRAM BEGIN(decl); return PROGRAM;
-CONFIGURATION BEGIN(config); return CONFIGURATION;
+FUNCTION BEGIN(decl_state); return FUNCTION;
+FUNCTION_BLOCK BEGIN(decl_state); return FUNCTION_BLOCK;
+PROGRAM BEGIN(decl_state); return PROGRAM;
+CONFIGURATION BEGIN(config_state); return CONFIGURATION;
}
- /* INITIAL -> body */
+ /* INITIAL -> il_st_state */
/* required if the function, program, etc.. has no VAR block! */
<INITIAL>{
-FUNCTION BEGIN(body); return FUNCTION;
-FUNCTION_BLOCK BEGIN(body); return FUNCTION_BLOCK;
-PROGRAM BEGIN(body); return PROGRAM;
+FUNCTION BEGIN(il_st_state); return FUNCTION;
+FUNCTION_BLOCK BEGIN(il_st_state); return FUNCTION_BLOCK;
+PROGRAM BEGIN(il_st_state); return PROGRAM;
}
- /* decl -> body */
-<decl>{
+ /* decl_state -> il_st_state */
+<decl_state>{
END_VAR{st_whitespace}VAR unput_text(strlen("END_VAR")); return END_VAR;
-END_VAR{st_whitespace} unput_text(strlen("END_VAR")); BEGIN(body); return END_VAR;
+END_VAR{st_whitespace} unput_text(strlen("END_VAR")); BEGIN(il_st_state); return END_VAR;
}
- /* body -> (il | st | sfc) */
-<body>INITIAL_STEP unput_text(0); BEGIN(sfc);
-
-<body>{
-{qualified_identifier}{st_whitespace}":=" unput_text(0); BEGIN(st);
-{qualified_identifier}"[" unput_text(0); BEGIN(st);
-
-RETURN unput_text(0); BEGIN(st);
-IF unput_text(0); BEGIN(st);
-CASE unput_text(0); BEGIN(st);
-FOR unput_text(0); BEGIN(st);
-WHILE unput_text(0); BEGIN(st);
-REPEAT unput_text(0); BEGIN(st);
-EXIT unput_text(0); BEGIN(st);
+ /* il_st_state -> (il_state | st_state | sfc_state) */
+<il_st_state>{
+INITIAL_STEP unput_text(0); BEGIN(sfc_state);
+{qualified_identifier}{st_whitespace}":=" unput_text(0); BEGIN(st_state);
+{qualified_identifier}"[" unput_text(0); BEGIN(st_state);
+
+RETURN unput_text(0); BEGIN(st_state);
+IF unput_text(0); BEGIN(st_state);
+CASE unput_text(0); BEGIN(st_state);
+FOR unput_text(0); BEGIN(st_state);
+WHILE unput_text(0); BEGIN(st_state);
+REPEAT unput_text(0); BEGIN(st_state);
+EXIT unput_text(0); BEGIN(st_state);
+:= unput_text(0); BEGIN(st_state); /* occurs only in transitions, and not FB bodies! */
+
{identifier} {int token = get_identifier_token(yytext);
if (token == prev_declared_fb_name_token) {
/* the code has a call to a function block */
- BEGIN(st);
+ BEGIN(st_state);
} else {
- BEGIN(il);
+ BEGIN(il_state);
}
unput_text(0);
}
-. unput_text(0); BEGIN(il);
-
-} /* end of body lexical parser */
-
- /* (decl | body | il | st | sfc) -> INITIAL */
+. unput_text(0); BEGIN(il_state);
+
+} /* end of il_st_state lexical parser */
+
+ /* (il_state | st_state) -> $previous_state (decl_state or sfc_state) */
+<il_state,st_state>{
+END_FUNCTION yy_pop_state(); unput_text(0);
+END_FUNCTION_BLOCK yy_pop_state(); unput_text(0);
+END_PROGRAM yy_pop_state(); unput_text(0);
+END_TRANSITION yy_pop_state(); unput_text(0);
+END_ACTION yy_pop_state(); unput_text(0);
+}
+
+ /* (decl_state | sfc_state) -> INITIAL */
+<decl_state,sfc_state>{
END_FUNCTION BEGIN(INITIAL); return END_FUNCTION;
END_FUNCTION_BLOCK BEGIN(INITIAL); return END_FUNCTION_BLOCK;
END_PROGRAM BEGIN(INITIAL); return END_PROGRAM;
-
+}
/* config -> INITIAL */
END_CONFIGURATION BEGIN(INITIAL); return END_CONFIGURATION;
@@ -793,8 +822,8 @@
/***************************************/
/* NOTE: pragmas are handled right at the beginning... */
-<INITIAL,config,decl,st,sfc,body>{st_whitespace_no_pragma} /* Eat any whitespace */
-<il,body>{il_whitespace_no_pragma} /* Eat any whitespace */
+<INITIAL,config_state,decl_state,st_state,sfc_state,il_st_state>{st_whitespace_no_pragma} /* Eat any whitespace */
+<il_state,il_st_state>{il_whitespace_no_pragma} /* Eat any whitespace */
/*****************************************/
@@ -1000,7 +1029,7 @@
* ignore them!
*/
-<sfc>{
+<sfc_state>{
ACTION return ACTION;
END_ACTION return END_ACTION;
@@ -1054,7 +1083,7 @@
/***********************************/
/* B 2.1 Instructions and Operands */
/***********************************/
-<il>\n return EOL;
+<il_state>\n return EOL;
/*******************/
@@ -1247,8 +1276,8 @@
/*****************************************/
/* B.1.1 Letters, digits and identifiers */
/*****************************************/
-<st>{identifier}/({st_whitespace})"=>" {yylval.ID=strdup(yytext); return sendto_identifier_token;}
-<il>{identifier}/({il_whitespace})"=>" {yylval.ID=strdup(yytext); return sendto_identifier_token;}
+<st_state>{identifier}/({st_whitespace})"=>" {yylval.ID=strdup(yytext); return sendto_identifier_token;}
+<il_state>{identifier}/({il_whitespace})"=>" {yylval.ID=strdup(yytext); return sendto_identifier_token;}
{identifier} {yylval.ID=strdup(yytext);
/*printf("returning identifier...: %s, %d\n", yytext, get_identifier_token(yytext));*/
return get_identifier_token(yytext);}
@@ -1280,9 +1309,6 @@
%%
-
-
-
/***********************************/
/* Utility function definitions... */
/***********************************/
--- a/stage1_2/iec.y Wed Jan 31 16:04:06 2007 +0100
+++ b/stage1_2/iec.y Wed Jan 31 19:23:46 2007 +0100
@@ -168,7 +168,9 @@
/************************/
/* The functions declared here are defined in iec.flex... */
void print_include_stack(void);
-
+void cmd_goto_body_state(void);
+int get_goto_body_state(void);
+void rst_goto_body_state(void);
%}
@@ -181,7 +183,13 @@
struct {
symbol_c *first;
symbol_c *second;
- } double_symbol; /* used by il_simple_operator_clash_il_operand */
+ symbol_c *third;
+ symbol_c *fourth;
+ } tmp_symbol; /* used as a temorary reference to symbols by:
+ il_simple_operator_clash_il_operand
+ transaction_tmp
+ action_tmp
+ */
}
@@ -809,7 +817,10 @@
%type <leaf> transition
%type <leaf> steps
%type <list> step_name_list
-%type <leaf> transition_condition
+%type <tmp_symbol> transition_header
+%type <leaf> transition_condition_il
+%type <leaf> transition_condition_st
+%type <tmp_symbol> action_header
%type <leaf> action
%type <leaf> transition_name
@@ -946,7 +957,7 @@
%type <leaf> label
%type <leaf> il_simple_operation
// helper symbol for il_simple_operation
-%type <double_symbol> il_simple_operator_clash_il_operand
+%type <tmp_symbol> il_simple_operator_clash_il_operand
%type <leaf> il_expression
%type <leaf> il_jump_operation
%type <leaf> il_fb_call
@@ -3629,7 +3640,7 @@
/********************************************/
/* B 1.6 Sequential Function Chart elements *
-/********************************************/////////////////////////////////////////////////////////////////////////////////////////////
+/********************************************/
/* TODO ... */
sequential_function_chart:
@@ -3728,17 +3739,6 @@
indicator_name: variable_name;
-transition:
- TRANSITION FROM steps TO steps transition_condition END_TRANSITION
- {$$ = new transition_c(NULL, NULL, $3, $5, $6, NULL);}
-| TRANSITION transition_name FROM steps TO steps transition_condition END_TRANSITION
- {$$ = new transition_c($2, NULL, $4, $6, $7, NULL);}
-| TRANSITION '(' PRIORITY ASSIGN integer ')' FROM steps TO steps transition_condition END_TRANSITION
- {$$ = new transition_c(NULL, $5, $8, $10, $11, NULL);}
-| TRANSITION transition_name '(' PRIORITY ASSIGN integer ')' FROM steps TO steps transition_condition END_TRANSITION
- {$$ = new transition_c($2, $6, $9, $11, $12, NULL);}
-;
-
transition_name: identifier;
steps:
@@ -3755,16 +3755,43 @@
{$$ = $1; $$->add_element($3);}
;
-transition_condition:
+transition_header:
+ TRANSITION FROM steps TO steps
+ {$$.first = NULL; $$.second = NULL; $$.third = $3; $$.fourth = $5; cmd_goto_body_state();}
+| TRANSITION transition_name FROM steps TO steps
+ {$$.first = $2; $$.second = NULL; $$.third = $4; $$.fourth = $6; cmd_goto_body_state();}
+| TRANSITION '(' PRIORITY ASSIGN integer ')' FROM steps TO steps
+ {$$.first = NULL; $$.second = $5; $$.third = $8; $$.fourth = $10; cmd_goto_body_state();}
+| TRANSITION transition_name '(' PRIORITY ASSIGN integer ')' FROM steps TO steps
+ {$$.first = $2; $$.second = $6; $$.third = $9; $$.fourth = $11; cmd_goto_body_state();}
+;
+
+transition_condition_il:
':' simple_instr_list
- {$$ = new transition_condition_c($2, NULL);}
-| ASSIGN expression ';'
- {$$ = new transition_condition_c(NULL, $2);}
-;
+ {$$ = new transition_condition_c($2, NULL);} ;
+
+transition_condition_st:
+ ASSIGN expression ';'
+ {$$ = new transition_condition_c(NULL, $2);};
+
+transition:
+ transition_header transition_condition_il END_TRANSITION
+ {$$ = new transition_c($1.first, $1.second, $1.third, $1.fourth, $2,
+NULL);}
+| transition_header transition_condition_st END_TRANSITION
+ {$$ = new transition_c($1.first, $1.second, $1.third, $1.fourth, NULL,
+$2);}
+;
+
+action_header:
+ ACTION action_name ':'
+ {$$.first = $2; cmd_goto_body_state();}
+;
+
action:
- ACTION action_name ':' function_block_body END_ACTION
- {$$ = new action_c($2, $4);}
+ action_header function_block_body END_ACTION
+ {$$ = new action_c($1.first, $2);}
;
--- a/stage4/generate_iec/generate_iec.cc Wed Jan 31 16:04:06 2007 +0100
+++ b/stage4/generate_iec/generate_iec.cc Wed Jan 31 19:23:46 2007 +0100
@@ -1135,7 +1135,12 @@
symbol->to_steps->accept(*this);
s4o.indent_right();
s4o.print(s4o.indent_spaces);
- symbol->transition_condition->accept(*this);
+ if (symbol->transition_condition_il != NULL) {
+ symbol->transition_condition_il->accept(*this);
+ }
+ if (symbol->transition_condition_st != NULL) {
+ symbol->transition_condition_st->accept(*this);
+ }
s4o.indent_left();
s4o.print(s4o.indent_spaces);
s4o.print("END_TRANSITION");