Promela: how to use a for loop for an array of type typedef - spin

I would like to be able use a for loop to loop through an array of typedef values as demonstrated below:
typedef chanArray {
chan ch[5] = [1] of {bit};
}
chanArray comms[5];
active proctype Reliable() {
chanArray channel;
for ( channel in comms ) {
channel.ch[0] ! 0;
}
}
Spin gives the following error:
spin: test2.pml:8, Error: for ( channel in .channel_name ) { ... }
Is it possible to use a for loop in this form to loop through the array instead of having to use a for loop with an index pointer?

Try:
active proctype Reliable () {
byte index;
index = 0;
do
:: index < 5 -> channel.ch[index] ! 0; index++
:: else -> break
od
}
this is the only way. So the answer to your 'is it possible ...' question is 'no, it is not possible ...'

I'm new to Promela, but it seems that you are using
for '(' varref in channel ')' '{' sequence '}'
instead of
for '(' varref ':' expr '..' expr ')' '{' sequence '}'
Try with something like
int i;
for (i : 0..4 ) {...}

Related

ANTLR4 generating code for the last expression entered in curly braces

I'm building a language primarily used for calculation purposes. It is a small language with C like syntax but extremely limited functionality. For the past few days, I've been trying to generate code that is encapsulated in curly braces however whenever I enter expressions in curly braces, the code generated is always for the last expression entered. It is supposed to work on a while loop.
For example:
while( true )
{
// some expressions (not using any variables for simplicity)
5 + 9;
8 - 10;
4 * 6;
}
However the code generated only takes into account the last expression (4 * 6) in this case.
The link to the code:
https://codeshare.io/GL0xRk
And also, the code snippet for handling curly braces and some other relative code:
calcul returns [String code]
#init
{
$code = new String();
}
#after
{
System.out.print($code);
for( int i = 0; i < getvarg_count(); ++i )
{
System.out.println("POP");
}
System.out.println("HALT");
}
: (decl
{
// declaration
$code += $decl.code;
})*
NEWLINE*
{
$code += "";
}
(instruction
{
// instruction, eg. x = 5; 7 * 4;
$code += $instruction.code;
System.err.println("instruction found");
})*
;
whileStat returns [String code]
: WHILE '(' condition ')' NEWLINE* block
{
int cur_label = nextLabel();
$code = "LABEL " + cur_label + "\n";
$code += $condition.code;
$code += "JUMPF " + (cur_label + 1) + "\n";
$code += $block.code;
$code += "JUMP " + cur_label + "\n";
$code += "LABEL " + (cur_label + 1) + "\n";
}
;
block returns [String code]
#init
{
$code = new String();
}
: '{' instruction* '}' NEWLINE*
{
System.err.println("block found");
$code += $instruction.code;
System.err.println("curly braces for while found");
}
;
And the compiler code generated:
while(true)
{
5+9;
8-10;
4*6;
}
block found
curly braces for while found
instruction found
LABEL 0
PUSHI 1
JUMPF 1
PUSHI 4
PUSHI 6
MUL
POP
JUMP 0
LABEL 1
HALT
I have a feeling that the $code is always reinitialized. Or maybe it's because I have instruction* in two different rules. I'm not sure how else to handle this problem. All help is much appreciated.
Thank you
Anyway, it looks like your problem is that $instruction in block's action only refers to the last instruction because the block is outside of the *, so the action only gets run once.
You can either move the action inside the * like you did in the calcul rule or you can put all the instructions in a list with instructions+=instruction* and then use $instructions in the action (or better: a listener or visitor).
PS: I strongly recommend to use a listener or visitor instead of having actions all over your grammar. They make the grammar very hard to read.

Parse FOR loop using ANTLR based PLSQL parser

I have modified the PLSQL parser given by [Porcelli] (https://github.com/porcelli/plsql-parser ). I am using this parser to parse PlSql files. I am facing issue with parsing FOR loop statements, e.g.
for i in 1..l_line_tbl.count
LOOP
l_line_tbl(i).schedule_ship_date := l_max_ship_date;
l_line_tbl(i).ship_set_id := x_ship_set_id;
END LOOP;
Above statement is not parsing and its throwing EarlyExitException.
Now, if I modify this statement and put a space between 1 and double dot (..) , it will parse the statement. I am not sure how to handle first case.
for i in 1 ..l_line_tbl.count
LOOP
l_line_tbl(i).schedule_ship_date := l_max_ship_date;
l_line_tbl(i).ship_set_id := x_ship_set_id;
END LOOP;
Parser Grammar:
loop_statement
#init { int mode = 0; }
: label_name?
(while_key condition {mode = 1;} | for_key cursor_loop_param {mode = 2;})?
loop_key
seq_of_statements
end_key loop_key label_name?
-> {mode == 1}? ^(WHILE_LOOP[$while_key.start] label_name*
^(LOGIC_EXPR condition) seq_of_statements)
-> {mode == 2}? ^(FOR_LOOP[$for_key.start] label_name* cursor_loop_param seq_of_statements)
-> ^(loop_key label_name* seq_of_statements)
;
// $<Loop - Specific Clause
cursor_loop_param
#init { int mode = 0; }
: (index_name in_key reverse_key? lower_bound DOUBLE_PERIOD)=>
index_name in_key reverse_key? lower_bound DOUBLE_PERIOD upper_bound
-> ^(INDEXED_FOR index_name reverse_key? ^(SIMPLE_BOUND lower_bound upper_bound))
| record_name in_key ( cursor_name expression_list? {mode = 1;} | LEFT_PAREN
select_statement RIGHT_PAREN)
->{mode == 1}? ^(CURSOR_BASED_FOR record_name cursor_name expression_list?)
-> ^(SELECT_BASED_FOR record_name select_statement)
;
// $>
Lexer Grammar:
FOR_NOTATION
: UNSIGNED_INTEGER
{state.type = UNSIGNED_INTEGER; emit(); advanceInput();}
'..'
{state.type = DOUBLE_PERIOD; emit(); advanceInput();}
UNSIGNED_INTEGER
{state.type = UNSIGNED_INTEGER; emit(); advanceInput(); $channel=HIDDEN;}
;
fragment
UNSIGNED_INTEGER
: ('0'..'9')+
;

PEGJS predicate grammar

I need to create a grammar with the help of predicate. The below grammar fails for the given case.
startRule = a:namespace DOT b:id OPEN_BRACE CLOSE_BRACE {return {"namespace": a, "name": b}}
namespace = id (DOT id)*
DOT = '.';
OPEN_BRACE = '(';
CLOSE_BRACE = ')';
id = [a-zA-Z]+;
It fails for the given input as
com.mytest.create();
which should have given "create" as value of "name" key in the result part.
Any help would be great.
There are several things here.
The most important, is that you must be aware that PEG is greedy. That means that your (DOT id)* rule matches ALL the DOT id sequences, including the one that you have in startRule as DOT b:id.
That can be solved using lookahead.
The other thing is that you must remember to use join, since by default it will return each character as the member of an array.
I also added a rule for semicolons.
Try this:
start =
namespace:namespace DOT name:string OPEN_BRACE CLOSE_BRACE SM nl?
{
return { namespace : namespace, name : name };
}
/* Here I'm using the lookahead: (member !OPEN_BRACE)* */
namespace =
first:string rest:(member !OPEN_BRACE)*
{
rest = rest.map(function (x) { return x[0]; });
rest.unshift(first);
return rest;
}
member =
DOT str:string
{ return str; }
DOT =
'.'
OPEN_BRACE =
'('
CLOSE_BRACE =
')'
SM =
';'
nl =
"\n"
string =
str:[a-zA-Z]+
{ return str.join(''); }
And as far I can tell, I'm parsing that line correctly.

Is there way to detect if an optional (? operator) tree grammar rule executed in an action?

path[Scope sc] returns [Path p]
#init{
List<String> parts = new ArrayList<String>();
}
: ^(PATH (id=IDENT{parts.add($id.text);})+ pathIndex? )
{// ACTION CODE
// need to check if pathIndex has executed before running this code.
if ($pathIndex.index >=0 ){
p = new Path($sc, parts, $pathIndex.index);
}else if($pathIndex.pathKey != ""){
p = new Path($sc, parts, $pathIndex.pathKey);
}
;
Is there a way to detect if pathIndex was executed? In my action code, I tried testing $pathIndex == null, but ANTLR doesn't let you do that. ANTLRWorks gives a syntax error which saying "Missing attribute access on rule scope: pathIndex."
The reason why I need to do this is because in my action code I do:
$pathIndex.index
which returns 0 if the variable $pathIndex is translated to is null. When you are accessing an attribute, ANTLR generates pathIndex7!=null?pathIndex7.index:0 This causes a problem with an object because it changes a value I have preset to -1 as an error flag to 0.
There are a couple of options:
1
Put your code inside the optional pathIndex:
rule
: ^(PATH (id=IDENT{parts.add($id.text);})+ (pathIndex {/*pathIndex cannot be null here!*/} )? )
;
2
Use a boolean flag to denote the presence (or absence) of pathIndex:
rule
#init{boolean flag = false;}
: ^(PATH (id=IDENT{parts.add($id.text);})+ (pathIndex {flag = true;} )? )
{
if(flag) {
// ...
}
}
;
EDIT
You could also make pathIndex match nothing so that you don't need to make it optional inside path:
path[Scope sc] returns [Path p]
: ^(PATH (id=IDENT{parts.add($id.text);})+ pathIndex)
{
// code
}
;
pathIndex returns [int index, String pathKey]
#init {
$index = -1;
$pathKey = "";
}
: ( /* some rules here */ )?
;
PS. Realize that the expression $pathIndex.pathKey != "" will most likely evaluate to false. To compare the contents of strings in Java, use their equals(...) method instead:
!$pathIndex.pathKey.equals("")
or if $pathIndex.pathKey can be null, you can circumvent a NPE by doing:
!"".equals($pathIndex.pathKey)
More information would have been helpful. However, if I understand correctly, when a value for the index is not present in the input you want to test for $pathIndex.index == null. This code does that using the pathIndex rule to return the Integer $index to the path rule:
path
: ^(PATH IDENT+ pathIndex?)
{ if ($pathIndex.index == null)
System.out.println("path index is null");
else
System.out.println("path index = " + $pathIndex.index); }
;
pathIndex returns [Integer index]
: DIGIT
{ $index = Integer.parseInt($DIGIT.getText()); }
;
For testing, I created these simple parser and lexer rules:
path : 'path' IDENT+ pathIndex? -> ^(PATH IDENT+ pathIndex?)
;
pathIndex : DIGIT
;
/** lexer rules **/
DIGIT : '0'..'9' ;
IDENT : LETTER+ ;
fragment LETTER : ('a'..'z' | 'A'..'Z') ;
When the index is present in the input, as in path a b c 5, the output is:
Tree = (PATH a b c 5)
path index = 5
When the index is not present in the input, as in path a b c, the output is:
Tree = (PATH a b c)
path index is null

ANTLR Variable Troubles

In short: how do I implement dynamic variables in ANTLR?
I come to you again with a basic ANTLR question.
I have this grammar:
grammar Amethyst;
options {
language = Java;
}
#header {
package org.omer.amethyst.generated;
import java.util.HashMap;
}
#lexer::header {
package org.omer.amethyst.generated;
}
#members {
HashMap memory = new HashMap();
}
begin: expr;
expr: (defun | println)*
;
println:
'println' atom {System.out.println($atom.value);}
;
defun:
'defun' VAR INT {memory.put($VAR.text, Integer.parseInt($INT.text));}
| 'defun' VAR STRING_LITERAL {memory.put($VAR.text, $STRING_LITERAL.text);}
;
atom returns [Object value]:
INT {$value = Integer.parseInt($INT.text);}
| ID
{
Object v = memory.get($ID.text);
if (v != null) $value = v;
else System.err.println("undefined variable " + $ID.text);
}
| STRING_LITERAL
{
String v = (String) memory.get($STRING_LITERAL.text);
if (v != null) $value = String.valueOf(v);
else System.err.println("undefined variable " + $STRING_LITERAL.text);
}
;
INT: '0'..'9'+ ;
STRING_LITERAL: '"' .* '"';
VAR: ('a'..'z'|'A'..'Z')('a'..'z'|'A'..'Z'|'0'..'9')* ;
ID: ('a'..'z'|'A'..'Z'|'0'..'9')+ ;
LETTER: ('a..z'|'A'..'Z')+ ;
WS: (' '|'\t'|'\n'|'\r')+ {skip();} ;
What it does (or should do), so far, is have a built-in "println" function to do exactly what you think it does, and a "defun" rule to define variables.
When "defun" is called on either a string or integer, the value is put into the "memory" HashMap with the first parameter being the variable's name and the second being its value.
When println is called on an atom, it should display the atom's value. The atom can be either a string or integer. It gets its value from memory and returns it. So for example:
defun greeting "Hello world!"
println greeting
But when I run this code, I get this error:
line 3:8 no viable alternative at input 'greeting'
null
NOTE: This output comes when I do:
println "greeting"
Output:
undefined variable "greeting"null
Does anyone know why this is so? Sorry if I'm not being clear, I don't understand most of this.
defun greeting "Hello world!"
println greeting
But when I run this code, I get this error:
line 3:8 no viable alternative at input 'greeting'
Because the input "greeting" is being tokenized as a VAR and a VAR is no atom. So the input defun greeting "Hello world!" is properly matched by the 2nd alternative of the defun rule:
defun
: 'defun' VAR INT // 1st alternative
| 'defun' VAR STRING_LITERAL // 2nd alternative
;
but the input println "greeting" cannot be matched by the println rule:
println
: 'println' atom
;
You must realize that the lexer does not produce tokens based on what the parser tries to match at a particular time. The input "greeting" will always be tokenized as a VAR, never as an ID rule.
What you need to do is remove the ID rule from the lexer, and replace ID with VAR inside your parser rules.