diff options
Diffstat (limited to 'lib/lex.py')
-rw-r--r-- | lib/lex.py | 156 |
1 files changed, 147 insertions, 9 deletions
@@ -13,6 +13,28 @@ class TimedWordLexer(Lexer): FUNCTIONSEP = r';' +class TimedSequenceLexer(Lexer): + tokens = {LPAREN, RPAREN, LBRACE, RBRACE, CYCLE, IDENTIFIER, NUMBER, ARGSEP, FUNCTIONSEP} + ignore = ' \t' + + LPAREN = r'\(' + RPAREN = r'\)' + LBRACE = r'\{' + RBRACE = r'\}' + CYCLE = r'cycle' + IDENTIFIER = r'[a-zA-Z_][a-zA-Z0-9_]*' + NUMBER = r'[0-9e.]+' + ARGSEP = r',' + FUNCTIONSEP = r';' + + def error(self, t): + print("Illegal character '%s'" % t.value[0]) + if t.value[0] == '{' and t.value.find('}'): + self.index += 1 + t.value.find('}') + else: + self.index += 1 + + class TimedWordParser(Parser): tokens = TimedWordLexer.tokens @@ -46,17 +68,133 @@ class TimedWordParser(Parser): @_('NUMBER') def arg(self, p): - return [float(p.NUMBER)] + return float(p.NUMBER) @_('IDENTIFIER') def arg(self, p): - return [p.IDENTIFIER] + return p.IDENTIFIER + + +class TimedSequenceParser(Parser): + tokens = TimedSequenceLexer.tokens + + @_('timedSequenceL', 'timedSequenceW') + def timedSequence(self, p): + return p[0] + + @_('loop') + def timedSequenceL(self, p): + return [p.loop] + + @_('loop timedSequenceW') + def timedSequenceL(self, p): + ret = [p.loop] + ret.extend(p.timedSequenceW) + return ret + + @_('timedWord') + def timedSequenceW(self, p): + return [p.timedWord] + + @_('timedWord timedSequenceL') + def timedSequenceW(self, p): + ret = [p.timedWord] + ret.extend(p.timedSequenceL) + return ret + + @_('timedSymbol FUNCTIONSEP timedWord') + def timedWord(self, p): + p.timedWord.word.insert(0, p.timedSymbol) + return p.timedWord + + @_('timedSymbol FUNCTIONSEP') + def timedWord(self, p): + return TimedWord(word=[p.timedSymbol]) + + @_('CYCLE LPAREN IDENTIFIER RPAREN LBRACE timedWord RBRACE') + def loop(self, p): + return Workload(p.IDENTIFIER, p.timedWord) + + @_('IDENTIFIER', 'IDENTIFIER LPAREN RPAREN') + def timedSymbol(self, p): + return (p.IDENTIFIER,) + + @_('IDENTIFIER LPAREN args RPAREN') + def timedSymbol(self, p): + return (p.IDENTIFIER, *p.args) + + @_('arg ARGSEP args') + def args(self, p): + ret = [p.arg] + ret.extend(p.args) + return ret + + @_('arg') + def args(self, p): + return [p.arg] + + @_('NUMBER') + def arg(self, p): + return float(p.NUMBER) + + @_('IDENTIFIER') + def arg(self, p): + return p.IDENTIFIER + + def error(self, p): + if p: + print("Syntax error at token", p.type) + # Just discard the token and tell the parser it's okay. + self.errok() + else: + print("Syntax error at EOF") + + +class TimedWord: + def __init__(self, word_string=None, word=list()): + if word_string is not None: + lexer = TimedWordLexer() + parser = TimedWordParser() + self.word = parser.parse(lexer.tokenize(word_string)) + else: + self.word = word + + def __getitem__(self, item): + return self.word[item] + + def __repr__(self): + ret = list() + for symbol in self.word: + ret.append('{}({})'.format(symbol[0], ', '.join(map(str, symbol[1:])))) + return 'TimedWord<"{}">'.format('; '.join(ret)) + + +class Workload: + def __init__(self, name, word): + self.name = name + self.word = word + + def __getitem__(self, item): + return self.word[item] + + def __repr__(self): + return 'Workload("{}", {})'.format(self.name, self.word) + + +class TimedSequence: + def __init__(self, seq_string=None, seq=list()): + if seq_string is not None: + lexer = TimedSequenceLexer() + parser = TimedSequenceParser() + self.seq = parser.parse(lexer.tokenize(seq_string)) + else: + self.seq = seq + def __getitem__(self, item): + return self.seq[item] -if __name__ == '__main__': - data = 'init(); sleep(12345); foo(_, 7);' - lexer = TimedWordLexer() - parser = TimedWordParser() - for tok in lexer.tokenize(data): - print('type={}, value={}'.format(tok.type, tok.value)) - print(parser.parse(lexer.tokenize(data))) + def __repr__(self): + ret = list() + for symbol in self.seq: + ret.append('{}'.format(symbol)) + return 'TimedSequence(seq=[{}])'.format(', '.join(ret)) |