Parsobober is a static program analyzer for SIMPLE language. It is an interactive tool that automatically answers PQL queries about the programs.
curl https://raw.githubusercontent.com/BobryPb/Parsobober/main/tests/SPA-Official/cez/dropbox -o ./parsobober-code
docker run -i -v ./parsobober-code:/app/code maksimowiczm/parsobobergit clone https://github.com/BobryPb/Parsobober parsobober
cd parsobober
docker build . -t parsobober
docker run -i -v ./tests/SPA-Official/cez/dropbox:/app/code parsobobergit clone https://github.com/BobryPb/Parsobober parsobober
cd parsobober
dotnet run -c release --project src/Parsobober.Cli "./tests/SPA-Official/cez/dropbox"Parsobober.Cli- Command line interface for the programParsobober.Pkb.*- Program Knowledge BaseParsobober.Simple.*,Parsobober.DesignExtractor- SPA front-endParsobober.Pql.*- Query processor for PQL queries
Relationship Calls(p, q) holds if procedure p directly calls q.
Calls*(p,q) holds if procedure p calls directly or indirectly q, that is:
Relationship Modifies is defined as follows:
- For an assignment
a,Modifies(a, v)holds if variablevappears on the left hand side ofa. - For a container statement
s(i.e., ‘if’ or ‘while’),Modifies(s, v)holds if there is a statements1in the container such thatModifies(s1, v)holds. - For a procedure
p,Modifies(p, v)holds if there is a statementsinpor in a procedure called (directly or indirectly) frompsuch thatModifies(s, v)holds. - For a procedure call statement
s‘call p’Modifies(s, v)is defined in the same way asModifies(p, v).
Relationship Uses is defined as follows:
- For an assignment
a,Uses(a, v)holds if variablevappears on the right hand side ofa. - For a container statement
s(i.e., ‘if’ or ‘while’),Uses(s, v)holds if there is a statements1in the container such thatUses(s1, v)holds. - For a procedure
p,Uses(p, v)holds if there is a statementsinpor in a procedure called (directly or indirectly) frompsuch thatUses(s, v)holds. - For a procedure call statement
s‘call p’Uses(s, v)is defined in the same way asUses(p, v).
For any two statements s1 and s2, the relationship Parent(s1, s2) holds if s2 is directly nested in s1.
For any two statements s1 and s2, the relationship Parent*(s1, s2) holds if s2 is nested in s1 directly or
indirectly.
Parent*(s1, s2) holds if
Parent(s1, s2)orParent(s1, s)andParent*(s, s2)for some statements
For any two statements s1 and s2, the relationship Follows(s1, s2) holds if s2 appears in program text directly
after s1 at the same nesting level, and s1 and s2 belong to the same statement list.
For any two statements s1 and s2, the relationship Follows*(s1, s2) holds if s2 appears in program text after
s1 at the same nesting level, and s1 and s2 belong to the same statement list, directly or indirectly.
Follows*(s1, s2) holds if
Follows(s1, s2)orFollows(s1, s)andFollows*(s, s2)for some statements
Let n1 and n2 be program lines.
Relationship Next(n1, n2) holds if n1 and n2 are in the same procedure, and n2 can be executed immediately after
n1 in some program execution sequence.
Black magic can only be possessed by sorcerers. [ not me :( ]
- Calls
Calls(<procedure name>, <procedure name>)Calls(procedure, <procedure name>)Calls(<procedure name>, procedure)Calls(procedure, procedure)Calls(<procedure name>, _)Calls(_, <procedure name>)Calls(_, _)
- Calls transitive
Calls*(<procedure name>, <procedure name>)Calls*(procedure, <procedure name>)Calls*(<procedure name>, procedure)Calls*(procedure, procedure)Calls*(<procedure name>, _)Calls*(_, <procedure name>)Calls*(_, _)
- Modifies
Modifies(<line number>, <variable name>)Modifies(<procedure name>, <variable name>)Modifies(<line number>, _)Modifies(<procedure name>, _)Modifies(statement, _)Modifies(procedure, _)Modifies(statement, <variable name>)Modifies(<line number>, variable)Modifies(<procedure name>, variable)Modifies(procedure, <variable name>)Modifies(statement, variable)
- Uses
Uses(<line number>, <variable name>)Uses(<procedure name>, <variable name>)Uses(<line number>, _)Uses(<procedure name>, _)Uses(statement, _)Uses(procedure, _)Uses(statement, <variable name>)Uses(<line number>, variable)Uses(<procedure name>, variable)Uses(procedure, <variable name>)Uses(statement, variable)
- Parent
Parent(<line number>, <line number>)Parent(<line number>, _)Parent(_, <line number>)Parent(_, _)Parent(statement, _)Parent(_, statement)Parent(statement, <line number>)Parent(<line number>, statement)Parent(statement, statement)
- Parent transitive
Parent*(<line number>, <line number>)Parent*(<line number>, _)Parent*(_, <line number>)Parent*(_, _)Parent*(statement, _)Parent*(_, statement)Parent*(statement, <line number>)Parent*(<line number>, statement)Parent*(statement, statement)
- Follows
Follows(<line number>, <line number>)Follows(<line number>, _)Follows(_, <line number>)Follows(_, _)Follows(statement, _)Follows(_, statement)Follows(statement, <line number>)Follows(<line number>, statement)Follows(statement, statement)
- Follows transitive
Follows*(<line number>, <line number>)Follows*(<line number>, _)Follows*(_, <line number>)Follows*(_, _)Follows*(statement, _)Follows*(_, statement)Follows*(statement, <line number>)Follows*(<line number>, statement)Follows*(statement, statement)
- Next
Next(<line number>, <line number>)Next(<line number>, _)Next(_, <line number>)Next(_, _)Next(program_line, _)Next(_, program_line)Next(program_line, <line number>)Next(<line number>, program_line)
- Next transitive
Next*(<line number>, <line number>)Next*(<line number>, _)Next*(_, <line number>)Next*(_, _)Next*(program_line, _)Next*(_, program_line)Next*(program_line, <line number>)Next*(<line number>, program_line)
- With
prodecure.procName:NAMEcall.procName:NAMEvariable.varName:NAMEconstant.value:INTEGERstmt.stmt#:INTEGER
- Pattern
Example queries using example code
> if i, i1;
> Select i such that Follows*(_, i1) and Follows*(i1, i)
34,55,166,170,173,230
> stmt s;
> Select s such that Parent(6,s) with s.stmt# = 7
7
> assign a;
> Select a pattern a(_, "width + incre + left")
7