context free grammars in JavaMOP CS 119 a property can be seen as - - PowerPoint PPT Presentation
context free grammars in JavaMOP CS 119 a property can be seen as - - PowerPoint PPT Presentation
context free grammars in JavaMOP CS 119 a property can be seen as a language defined by a grammar 2 http://fsl.cs.uiuc.edu/index.php/Special:CFGPlugin 3 Instances of MOP MOP JavaMOP BusMOP HardwareMOP logic plugins MOP CFG
2
3
http://fsl.cs.uiuc.edu/index.php/Special:CFGPlugin
4 ERE LTL ptLTL ptCaRet logic plugins
… …
JavaMOP BusMOP
MOP
CFG languages
Instances of MOP
MOP JavaMOP BusMOP HardwareMOP …
today
5
the 4 elements
context free languages pushdown Automata
(theoretical concept)
context free grammars parsers
6
Chomsky’s language hierarchy
http://en.wikipedia.org/wiki/Chomsky_hierarchy
7
context free languages and pushdown automata
$ l l l l
q1 q2 q3 q4
S ! ² | lSr ²
² ! push($) l ! push(l) r top()=l ! pop() ² top()=$ ! pop() r top()=l ! pop()
ln rn input: llll rrrr
example
8
CFL parsers
- top-down parser
– expands non-terminals into RH-sides
- bottom-up parser
– reduces RH-sides to non-terminals – LALR(1) ½ LR(1) ½ DCFL ½ CFL S ! Ax ! ax ax ! Ax ! S S ! Ax A ! a A ! b
example grammar: JavaMOP
Consider the term: ax
9
structure of a table-driven bottom-up parser
- an input buffer
- a stack of states visited
- an action-table giving a
grammar rule to apply given the current state and current terminal in input buffer
- a goto-table describing
which new state it should go to
10
actions
- Shift - push token onto stack
- Reduce - remove handle from stack and push
- n corresponding nonterminal
- Accept - recognize sentence when stack
contains only the distinguished symbol and input is empty
- Error - happens when none of the above is
possible; means original input was not a sentence!
11
abstract algorithm
- start with an empty stack
- a "shift" action corresponds to pushing
the current input symbol onto the stack
- a "reduce" action occurs when we have
a handle on top of the stack. To perform the reduction, we pop the handle off the stack and replace it with the terminal on the LHS of the corresponding rule.
12
the lock/release example
S ! lock S release S ! epsilon specification SHIFT lock lock lock release release release () SHIFT lock lock release release release (lock) SHIFT lock release release release (lock lock) SHIFT release release release (lock lock lock) RED(S) release release (lock lock lock release) SHIFT release release (lock lock S) RED(S) release (lock lock S release) SHIFT release (lock S) RED(S) (lock S release) ACC (S)
13
expressions example
14
recall structure of a table-driven bottom-up parser
15
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input JavaMOP
16
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input 1 JavaMOP
17
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input 1 2 JavaMOP
18
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input 1 2 2 JavaMOP
19
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input 1 2 2 5 JavaMOP
20
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input 1 2 2 5 1 2 7 JavaMOP
21
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input 1 2 7 9 JavaMOP
22
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input 1 2 7 9 1 6 JavaMOP
23
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input 1 6 8 JavaMOP
24
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input 1 6 8 3 JavaMOP
25
event lock event release productions : S -> lock S release | epsilon specification lock lock lock release release release $ input 1 6 8 3 JavaMOP
26
JavaMOP algorithm
1 6 8
27
properties of Java library APIs properties of Java library APIs
R1: There should be no two calls to next() without a call to hasNext() in between,
- n the same iterator.
28
class class Test { public public static tatic void
- id main(String[] args) {
Vector<Integer> v1 = new ew Vector(); Vector<Integer> v2 = new ew Vector(); v1.add(1); v1.add(3); v2.add(5); v2.add(7); Iterator it1 = v1.iterator(); Iterator it2 = v2.iterator(); int int sum = 0; if if(it2.hasNext()) sum += (Integer)it2.next(); if if(it1.hasNext()) sum += (Integer)it2.next(); System.out.println(”sum(v2) = " + sum); } } should have been: if if(it2 it2.hasNext())
an example an example
unguarded call: it2 it2.next()
)
29
recall the recall the regular expression specification egular expression specification
partial, matching against suffix trace /*@ partial centralized scope = global logic = ERE HasNext(Iterator i) { event hasnext<i> : end(call(* i.hasNext())); event next<i> : begin(call(* i.next())); formula : next next } validation handler{ System.err.println("*** call hasNext() before next()"); } @*/ validation (not violation)
30
CFG Property in FG Property in JavaMOP avaMOP (trying to (trying to replicate the RE solution) eplicate the RE solution)
/*@ partial centralized scope = global logic = CFG HasNext(Iterator i) { event hasnext<i> : end(call(* i.hasNext())); event next<i> : begin(call(* i.next())); productions : Pattern -> next next } validation handler{ System.err.println("*** call hasNext() before next()"); } @*/ in this case we can write the same spec more or less
31
(hasNext hasNext* next)* which was slightly too strong, but let’s try to emulate it i) total trace semantics ii)looking for violation recall recall this other regular expression his other regular expression
32
CFG Property in CFG Property in JavaMOP avaMOP
/*@ centralized scope = global logic = CFG HasNext(Iterator i){ event hasnext<i> : end(call(* i.hasNext())); event next<i> : begin(call(* i.next())); productions : Iterate -> hasnext HasnextStar next Iterate | epsilon, HasnextStar -> hasnext HasnextStar | epsilon } violation handler{ System.err.println("*** call hasNext() before next()"); } @*/ no longer partial
33
DEMO ON SLIDES
34
35
36
37
38
39
40
41
42
43
END OF DEMO ON SLIDES
44
CFG Property in CFG Property in JavaMOP avaMOP as a state machine as a state machine
/*@ centralized scope = global logic = CFG HasNext(Iterator i) { event hasnext<i> : end(call(* i.hasNext())); event next<i> : begin(call(* i.next())); productions : Iterate -> hasnext HasnextStar next Iterate | epsilon, HasnextStar -> hasnext HasnextStar | epsilon } violation handler{ System.err.println("*** call hasNext() before next()"); } @*/
State0 -> hasnext State1 , State1 -> hasnext State1 | next State0
state machine like notation
epsilon needed | epsilon
45
class class Test { public public static tatic void
- id main(String[] args) {
Vector<Integer> v1 = new ew Vector(); Vector<Integer> v2 = new ew Vector(); v1.add(1); v1.add(3); v2.add(5); v2.add(7); Iterator it1 = v1.iterator(); Iterator it2 = v2.iterator(); int int sum = 0; if if(it1.hasNext()) sum += (Integer)it2.next(); if if(it1.hasNext()) sum += (Integer)it2.next(); System.out.println(”sum(v2) = " + sum); } } change from: if if(it2 it2.hasNext()) to: if if(it1 it1.hasNext())
suppose we changed the example suppose we changed the example
program still has the same error! does our latest spec still catch the error?
46
no: CFG property no: CFG property will not catch error ill not catch error
the monitor generating event is hasnext since it occurs first (and not next!!)
Since only
- peration
- n it2 is next,
a monitor is not created.
/*@ centralized scope = global logic = CFG HasNext(Iterator i) { event hasnext<i> : end(call(* i.hasNext())); event next<i> : begin(call(* i.next())); productions : Iterate -> hasnext HasnextStar next Iterate | epsilon, HasnextStar -> hasnext HasnextStar | epsilon } violation handler{ System.err.println("*** call hasNext() before next()"); } @*/
47
CFG validation & violation
- CFG:
– makes most sense together with validation – because the monitor generating events in a CFG are the first ones appearing (in JavaMOP). – does not work well when searching for violation since one here potentially looks for event sequences that do not follow the grammar.
- ERE:
– makes sense with violation as well as validation – because all events (with maximum number of parameters) are monitor generating.
48
properties of Java library APIs properties of Java library APIs
R2: An enumeration should not be propagated after the underlying vector has been changed.
49
CFG specification CFG specification
/*@ partial centralized scope = global logic = CFG SafeEnum (Vector v, Enumeration+ e) { event create<e, v> : end(call(Enumeration v.elements())) with (e); event updatesource<v> : end(call(* v.add*(..))) \/ … \/ end(call(* v.set*(..))); event next<e> : begin(call(Object e.nextElement())); productions : S -> create NextStar updatesource UpdateStar next, NextStar -> next NextStar | epsilon, UpdateStar -> updatesource UpdateStar | epsilon } validation handler { System.out.println("the collection is changed during iteration!"); } @*/ works the same with or without the ‘partial’ keyword.
50
<v,e> v1 v2 e1 e2 e3 <v> <e> e1 e2 e3 v1 v2
create next update
events: events: create<v,e> update<v> next<e> monitor creation event One index per parameter set. Weak references.
indexing works as for regular expressions
51
- ur non-regular property
lock lock lock unlock unlock unlock
lockn unlockn
R4: locks can be taken in a nested manner, but should be released in reverse order.
52
stack of lock histories
Data = LockHist-stack LockHist = Set | Bag | Stack
public interface LockHist { public void lock(Lock l); public boolean unlock(Lock l); public boolean isEmpty(); public void clear(); }
Data = Level ! LockHist 3 4 7
L1 L2 L6 L7 L5 L3
53
an example
void start() { a(); } void a() { l1.lock(); l2.lock(); l1.unlock(); l2.unlock(); l3.lock(); }
/*@
centralized scope = global logic = CFG SafeLock(Lock l) { event lock<l> : begin(call(* l.lock())); event unlock<l> : begin(call(* l.unlock())); productions: S -> lock S unlock S | epsilon } violation handler{ System.out.println("*** Unsafe lock order!"); } @*/ does this spec catch any errors? NO!
54
another example
void start() { a(); } void a() { l1.lock(); l2.lock(); l1.unlock(); l2.unlock(); l2.unlock(); }
/*@
centralized scope = global logic = CFG SafeLock(Lock l) { event lock<l> : begin(call(* l.lock())); event unlock<l> : begin(call(* l.unlock())); productions: S -> lock S unlock S | epsilon } violation handler{ System.out.println("*** Unsafe lock order!"); } @*/ does this one? YES! l2 unlocked twice
55 void start() { a(); } void a() { l1.lock(); l1.lock(); l1.unlock(); l1.unlock(); l1.lock(); b(); } void b() { l1.unlock(); }
/*@ scope = global logic = CFG SafeLock(Lock l) { event lock<l> : begin(call(* l.lock())); event unlock<l> : begin(call(* l.unlock())); event begin : begin(call(* Test*.*(..))); event end : end(call(* Test*.*(..))); productions: S -> begin S end S | lock S unlock S | epsilon } violation handler{ System.out.println("Unsafe lock operation found!"); } @*/
Within one method invocation, locks should be acquired and released correctly (all taken locks should be released as many times as taken)
error
Error #0: javamop.MoPException: monitor should start with events that have all the parameters!
56 void start() { a(); } void a() { l1.lock(); l1.lock(); l1.unlock(); l1.unlock(); l1.lock(); b(); } void b() { l1.unlock(); }
Within one method invocation, locks should be acquired and released correctly (all taken locks should be released as many times as taken)
error
/*@ centralized scope = global logic = CFG SafeLock(Lock l) { event lock<l> : begin(call(* l.lock())); event unlock<l> : begin(call(* l.unlock())); event begin : begin(call(* Test*.*(..))); event end : end(call(* Test*.*(..))); productions: S -> epsilon | S lock M unlock A, M -> epsilon | M begin M end | M lock M unlock, A -> epsilon | A begin | A end } violation handler{ System.out.println("Unsafe lock operation found!"); } @*/
57