-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser_03.py
85 lines (61 loc) · 2.09 KB
/
parser_03.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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from core import State, Event, StateMachine, NetworkBus
from pyparsing import (
Word, alphas, alphanums, nums, Literal, Group,
ZeroOrMore, OneOrMore, oneOf, StringEnd,
Optional, Suppress, Keyword, Regex,
quotedString, delimitedList, Combine,
ParseException, dblSlashComment, Regex
)
class SemanticModel:
def __init__(self):
self.states = {}
self.events = {}
def add_event(self, event_name):
return self.events.setdefault(event_name, Event(event_name))
def add_state(self, state_name):
if self.states:
return self.states.setdefault(state_name, State(state_name))
else:
self.initial_state = State(state_name)
self.states[state_name] = self.initial_state
return self.initial_state
def parse_action(self, source, location, tokens):
(state_name, cmd_name) = tokens
state = self.add_state(state_name)
cmd = self.add_event(cmd_name)
state.add_action(cmd)
def parse_transition(self, source, location, tokens):
(state_from, trigger, state_to) = tokens
s_from = self.add_state(state_from)
s_to = self.add_state(state_to)
evt = self.add_event(trigger)
s_from.add_transition(evt, s_to)
return (s_from, evt, s_to)
@property
def state_machine(self):
return StateMachine(self.initial_state)
_tail = Suppress('--')
_arrow = Suppress('->')
state = Word(alphas, alphanums+'_')
code = Regex('[A-Z0-9]{4}')
transition = state + _tail + code + _arrow + state
transitions = OneOrMore(transition)
action = state + _arrow + code
actions = ZeroOrMore(action)
script = transitions + actions + StringEnd()
script.ignore(dblSlashComment)
model = SemanticModel()
transition.setParseAction(model.parse_transition)
action.setParseAction(model.parse_action)
filename = sys.argv[1]
with open(filename, 'r') as source:
items = script.parseFile(source)
sm = model.state_machine
bus = NetworkBus()
bus.subscribe(sm)
bus.send('D1CL')
bus.send('KEY1')
bus.send('KEY2')