-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparse.py
executable file
·159 lines (122 loc) · 4.46 KB
/
parse.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env python
'''
This module will read in the RML file and parse it using the pyparsing library.
'''
import pyparsing as pp
# Define parsers for literals
boolean_literal = pp.Keyword("True") | pp.Keyword("False")
def build_identifier_parser():
'''
Return a parser for parsing identifiers.
Identifiers ::= <alphas> <alphanum>* - <boolean-literal> - <temporal-operator>
It's recommanded that only small-case letters are used.
'''
initial_letters = "abcdefghijklmnopqrstuvwxyzABCDEHIJKLMNOPQRSTUVWYZ_" # removed X F G
body_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTVWXYZ_1234567890" # removed U
identifier_parser = ~boolean_literal + pp.Word(initial_letters, body_letters)
return identifier_parser
def build_propositional_formula_parser():
'''
Return a parser for parsing propositional_formula.
'''
identifier_set = set([])
def record_identifiers(t):
identifier_set.add(t[0])
return t
identifier = build_identifier_parser()
identifier.setParseAction(record_identifiers)
unary_op = pp.Literal('!')
binary_op = pp.oneOf("&& || ->")
lpar = pp.Literal('(').suppress()
rpar = pp.Literal(')').suppress()
expr = pp.Forward()
atom = boolean_literal \
| identifier \
| unary_op + expr \
| pp.Group(lpar + expr + rpar)
def add_identifiers_to_result(t):
t["identifiers"] = identifier_set
expr << atom + pp.ZeroOrMore(binary_op + expr)
expr.setParseAction(add_identifiers_to_result)
return expr
def build_LTL_formula_parser():
'''
Return a parser for parsing LTL formula.
'''
identifier_set = set([])
def record_identifiers(t):
identifier_set.add(t[0])
return t
identifier = build_identifier_parser()
identifier.setParseAction(record_identifiers)
unary_op = pp.oneOf("X F G !")
binary_op = pp.oneOf("U && || ->")
lpar = pp.Literal('(').suppress()
rpar = pp.Literal(')').suppress()
expr = pp.Forward()
atom = boolean_literal \
| identifier \
| unary_op + expr \
| pp.Group(lpar + expr + rpar)
def add_identifiers_to_result(t):
t["identifiers"] = identifier_set
expr << atom + pp.ZeroOrMore(binary_op + expr)
expr.setParseAction(add_identifiers_to_result)
return expr
def build_guarded_command_parser():
'''
Return a parser for parsing guarded commands.
'''
# condition
condition = build_propositional_formula_parser()
def add_condition_variables(t):
t["condition_variables"] = t["identifiers"]
return t
condition.addParseAction(add_condition_variables)
# action
assignment = build_propositional_formula_parser()
def add_assignment_variables(t):
t["assignment_variables"] = t["identifiers"]
return t
assignment.addParseAction(add_assignment_variables)
action = build_identifier_parser()("assigned_variable") + pp.Literal(":=") + assignment("assignment")
# action list
action_list = pp.delimitedList(pp.Group(action))
# assemble
guarded_command = pp.Literal("[]") \
+ condition("condition_part") \
+ pp.Literal("~>") \
+ action_list("action_part")
return guarded_command
def build_RML_parser():
'''
Return the complete parser for parsing a RML module file.
'''
module_name = build_identifier_parser()
variable = build_identifier_parser()
guarded_command = build_guarded_command_parser()
LTL_formula = build_LTL_formula_parser()
# init-part
init = pp.Keyword("init").suppress() + pp.OneOrMore(pp.Group(guarded_command))
# update-part
update = pp.Keyword("update").suppress() + pp.OneOrMore(pp.Group(guarded_command))
# goal-part
goal = pp.Keyword("goal").suppress() + LTL_formula("formula")
def add_goal_variables(t):
t["variables"] = t["identifiers"]
return t
goal.addParseAction(add_goal_variables)
# module-body
module_body = init("init") + update("update") + goal("goal")
# variable-list
variable_list = pp.delimitedList(variable)
# module
module = pp.Keyword("module").suppress() \
+ module_name("name") \
+ pp.Keyword("controls").suppress() \
+ pp.Group(variable_list)("variable_list") \
+ module_body \
+ pp.Keyword("end module").suppress()
# RML_file
RML_file = pp.OneOrMore(pp.Group(module))
return RML_file