Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
O
OUTDATED Verse-library
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
AutonomyCourse_ECEIllinois
OUTDATED Verse-library
Commits
0bcb8572
Commit
0bcb8572
authored
2 years ago
by
braught2
Browse files
Options
Downloads
Patches
Plain Diff
update main method to show easy usage
parent
422ebd69
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
pythonparser.py
+75
-71
75 additions, 71 deletions
pythonparser.py
with
75 additions
and
71 deletions
pythonparser.py
+
75
−
71
View file @
0bcb8572
...
...
@@ -244,16 +244,45 @@ def createTransition(path, vertices, modes):
return
edges
class
controller_ast
():
'''
Initalizing function for a controller_ast object.
Reads in the code and parses it to a python ast and statement tree.
Statement tree is a tree of nodes that contain a list in their data. The list contains a single guard or a list of resets.
Variables (inputs to the controller) are collected.
Modes are collected from all enums that have the word
"
mode
"
in them.
Vertices are generated by taking the products of mode types.
'''
def
__init__
(
self
,
code
):
self
.
code
=
code
self
.
tree
=
ast
.
parse
(
code
)
#statement tree is a tree of nodes that contain a list in their data. The list contains a single guard or a list of resets
self
.
statementtree
,
self
.
variables
,
self
.
modes
=
self
.
initalwalktree
(
code
,
tree
)
self
.
statementtree
,
self
.
variables
,
self
.
modes
=
self
.
initalwalktree
(
code
,
self
.
tree
)
self
.
vertices
=
[]
self
.
vertexStrings
=
[]
for
vertex
in
itertools
.
product
(
*
self
.
modes
.
values
()):
self
.
vertices
.
append
(
vertex
)
vertexstring
=
vertex
[
0
]
for
index
in
range
(
1
,
len
(
vertex
)):
vertexstring
+=
"
;
"
+
vertex
[
index
]
self
.
vertexStrings
.
append
(
vertexstring
)
self
.
paths
=
None
'''
Function to populate paths variable with all paths of the controller.
'''
def
getAllPaths
(
self
):
currentModes
=
[]
for
modeTypes
in
self
.
modes
.
values
():
currentModes
.
extend
(
modeTypes
)
self
.
paths
=
self
.
getNextModes
(
currentModes
)
return
self
.
paths
#assume that currentModes is a list of all node types!
#TODO: should we not force all modes be listed? Or rerun for each unknown/don't care node? Or add them all to the list
'''
getNextModes takes in a list of current modes. It should include all modes.
getNextModes returns a list of paths that can be followed when in the given mode.
A path is a list of statements, all guards and resets along the path. They are in the order they are encountered in the code.
TODO: should we not force all modes be listed? Or rerun for each unknown/don
'
t care node? Or add them all to the list
'''
def
getNextModes
(
self
,
currentModes
):
#walk the tree and capture all paths that have modes that are listed. Path is a list of statements
paths
=
[]
...
...
@@ -263,6 +292,10 @@ class controller_ast():
return
paths
'''
Helper function to walk the statement tree from parentnode and find paths that are allowed in the currentMode.
Returns a list of paths.
'''
def
walkstatements
(
self
,
parentnode
,
currentModes
):
nextsPaths
=
[]
...
...
@@ -292,7 +325,15 @@ class controller_ast():
return
nextsPaths
def
create_json
(
input_file_name
,
output_file_name
):
'''
Function to create a json of the full graph.
Requires that paths class variables has been set.
'''
def
create_json
(
self
,
input_file_name
,
output_file_name
):
if
not
self
.
paths
:
print
(
"
Cannot call create_json without calling getAllPaths
"
)
return
with
open
(
input_file_name
)
as
in_json_file
:
input_json
=
json
.
load
(
in_json_file
)
...
...
@@ -305,16 +346,16 @@ class controller_ast():
guards
=
[]
resets
=
[]
for
path
in
paths
:
transitions
=
createTransition
(
path
,
vertices
,
modes
)
for
path
in
self
.
paths
:
transitions
=
createTransition
(
path
,
self
.
vertices
,
self
.
modes
)
for
edge
in
transitions
:
edges
.
append
([
edge
.
source
,
edge
.
dest
])
guards
.
append
(
guardString
(
edge
.
guards
))
resets
.
append
(
resetString
(
edge
.
resets
))
output_dict
[
'
vertex
'
]
=
vertexStrings
output_dict
[
'
vertex
'
]
=
self
.
vertexStrings
#print(vertices)
output_dict
[
'
variables
'
]
=
variables
output_dict
[
'
variables
'
]
=
self
.
variables
# #add edge, transition(guards) and resets
output_dict
[
'
edge
'
]
=
edges
#print(len(edges))
...
...
@@ -331,6 +372,10 @@ class controller_ast():
print
(
"
wrote json to
"
+
output_file_name
)
#inital tree walk, parse into a tree of resets/modes
'''
Function called by init function. Walks python ast and parses to a statement tree.
Returns a statement tree (nodes contain a list of either a single guard or muliple resets), the variables, and a mode dictionary
'''
def
initalwalktree
(
self
,
code
,
tree
):
vars
=
[]
out
=
[]
...
...
@@ -346,17 +391,19 @@ class controller_ast():
if
isinstance
(
node
,
ast
.
FunctionDef
):
if
node
.
name
==
'
controller
'
:
#print(node.body)
out
=
self
.
parsenodelist
(
code
,
node
.
body
,
False
,
Tree
(),
None
)
statementtree
=
self
.
parsenodelist
(
code
,
node
.
body
,
False
,
Tree
(),
None
)
#print(type(node.args))
args
=
node
.
args
.
args
for
arg
in
args
:
if
"
mode
"
not
in
arg
.
arg
:
vars
.
append
(
arg
.
arg
)
#todo: what to add for return values
return
[
out
,
vars
,
mode_dict
]
return
[
statementtree
,
vars
,
mode_dict
]
'''
Helper function for initalwalktree which parses the statements in the controller function into a statement tree
'''
def
parsenodelist
(
self
,
code
,
nodes
,
addResets
,
tree
,
parent
):
childrens_guards
=
[]
childrens_resets
=
[]
...
...
@@ -407,80 +454,37 @@ if __name__ == "__main__":
input_file_name
=
'
billiard_input.json
'
#sys.argv[2]
output_file_name
=
'
out.json
'
#sys.argv[3]
with
open
(
input_file_name
)
as
in_json_file
:
input_json
=
json
.
load
(
in_json_file
)
output_dict
=
{
}
#read in the controler code
f
=
open
(
input_code_name
,
'
r
'
)
code
=
f
.
read
()
tree
=
ast
.
parse
(
code
)
#tree = ast.parse()
#paths, variables, modes = walktree(code, tree)
test
=
controller_ast
(
code
)
paths
=
test
.
getNextModes
(
"
NormalA;Normal3
"
)
variables
=
test
.
variables
modes
=
test
.
modes
#parse the controller code into our controller ast objct
controller_obj
=
controller_ast
(
code
)
#demonstrate you can check getNextModes after only initalizing
paths
=
controller_obj
.
getNextModes
(
"
NormalA;Normal3
"
)
print
(
"
Results
"
)
for
path
in
paths
:
for
item
in
path
:
print
(
item
.
code
)
print
()
print
(
"
Done
"
)
#print("Paths found:")
#for result in paths:
# for item in result:
#item.print()
#print(item.mode)
#print(item.modeType)
# print()
#print("Modes found: ")
#print(modes)
output_dict
.
update
(
input_json
)
vertices
=
[]
vertexStrings
=
[]
for
vertex
in
itertools
.
product
(
*
modes
.
values
()):
vertices
.
append
(
vertex
)
vertexstring
=
vertex
[
0
]
for
index
in
range
(
1
,
len
(
vertex
)):
vertexstring
+=
"
;
"
+
vertex
[
index
]
vertexStrings
.
append
(
vertexstring
)
edges
=
[]
guards
=
[]
resets
=
[]
#attempt to write to json, fail because we haven't populated paths yet
controller_obj
.
create_json
(
input_file_name
,
output_file_name
)
for
path
in
paths
:
transitions
=
createTransition
(
path
,
vertices
,
modes
)
for
edge
in
transitions
:
edges
.
append
([
edge
.
source
,
edge
.
dest
])
guards
.
append
(
guardString
(
edge
.
guards
))
resets
.
append
(
resetString
(
edge
.
resets
))
output_dict
[
'
vertex
'
]
=
vertexStrings
#print(vertices)
output_dict
[
'
variables
'
]
=
variables
# #add edge, transition(guards) and resets
output_dict
[
'
edge
'
]
=
edges
#print(len(edges))
output_dict
[
'
guards
'
]
=
guards
#print(len(guards))
output_dict
[
'
resets
'
]
=
resets
#print(len(resets))
output_json
=
json
.
dumps
(
output_dict
,
indent
=
4
)
outfile
=
open
(
output_file_name
,
"
w
"
)
outfile
.
write
(
output_json
)
outfile
.
close
()
print
(
"
wrote json to
"
+
output_file_name
)
controller_obj
.
getAllPaths
()
controller_obj
.
create_json
(
input_file_name
,
output_file_name
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment