#!/usr/bin/env python
"""Parser for parsing iocShell cd commands
These take these forms
1) cd ${TOP}
2) cd("${IOC_DATA}/${IOC}/autosave-req")
3) chdir("../..")
4) chdir ${TOP}
"""

import os
import sys
from plex import *
import random
import StringIO

# Here's where we define the lexicon for the parser. 
letter = Range("AZaz")
digit = Range("09")
hspace = Any(" \t")
space = Any(" \t\n")
newline = Str("\n")
spchars = Any(".-_:+/*<>")
comma = Str(",")
quote = Str('"')
macrospec1 = Str('$(') + Rep1(letter | digit | spchars) + Str(')')
macrospec2 = Str('${') + Rep1(letter | digit | spchars) + Str('}')
name = Rep1(letter | digit | spchars | macrospec1 | macrospec2)
nameinquotes = quote + name + quote
openParan = Str("(")
closeParan = Str(")")
comment = Bol + Str("#") + Rep(AnyBut("\n")) + Str("\n")

fileLexicon = Lexicon([
    (comment,  'comment'),
    (space, IGNORE),
    (Str("cd("), Begin("Folder")),
    (Str("cd "), Begin("Folder")),
    (Str("chdir("), Begin("Folder")),
    (Str("chdir "), Begin("Folder")),
    State('Folder', [
                    (nameinquotes, 'foldernameinquotes'),
                    (name, 'foldername'),
                    (newline, Begin('')),
                    (closeParan, Begin(''))
                    ]),
    (space, IGNORE)
])

def parseEpicsCDCommand(line):
    '''Parses a epics cd command and returns the folder name we are cd'ing to'''
    scanner = Scanner(fileLexicon, StringIO.StringIO(line))
    while 1:
        token = scanner.read()
        if token[0] is None:
            break
        elif token[0] == 'foldername':
            return token[1]
        elif token[0] == 'foldernameinquotes':
            return token[1].strip('"')
        else:
            sys.stderr.write("Unknown token" + token)
    return line


if __name__ == "__main__":
    print '|' + parseEpicsCDCommand('cd ${TOP}') + '|'
    print '|' + parseEpicsCDCommand('cd(${TOP})') + '|'
    print '|' + parseEpicsCDCommand('cd("${IOC_DATA}/${IOC}/autosave-req")') + '|'
    print '|' + parseEpicsCDCommand('cd(${IOC_DATA}/${IOC}/autosave-req)') + '|'
    print '|' + parseEpicsCDCommand('cd ${IOC_DATA}/${IOC}/autosave-req') + '|'
    print '|' + parseEpicsCDCommand('cd("${IOC_DATA}/${IOC}/autosave-req")  ') + '|'
    print '|' + parseEpicsCDCommand('cd $(AREA_DETECTOR)/ADApp/Db') + '|'
    print '|' + parseEpicsCDCommand('chdir("../..")') + '|'
    print '|' + parseEpicsCDCommand('chdir ${TOP}') + '|'
    
