-1

Input Example:

Blank  {Line0}
Loop 3 {Line1}
Blank  {Line1a}
Label2: Blank {Line2}
Blank  {Line3}
Loop 2 {Line4} 
Blank  {Line4a}      
Label1: Blank {Line5}       # I need to repeat the Jump statements as many times as mentioned in the Loop before the Label statement. Always The Loop statements precedes the immediate Jump statement. So here Line5, Lin6 and Line7 gets repeated twice. Jump to label1 so print line5, Line6 (since it has nothign going on) and Line7 is the end of Jump statement. Repeat it twice. Since Loop 2 {Line4} says do the following Jump Twice. 
Blank  {Line6}
Jump Label1 {Line7}
Blank  {Line8}
Jump Label2 {Line9} # This jumps back to Label2. Which repeats everything until this line including the expanded inner loop ... This is the nested loop.
Blank  {Line10}

Output Example:

Line0
Line1
Line1a
Line2
Line3
Line4
Line4a
Line5
Line6
Line7
Line5
Line6
Line7
Line8
Line9
Line2
Line3
Line4
Line4a
Line5
Line6
Line7
Line5
Line6
Line7
Line8
Line9
Line2
Line3
Line4
Line4a
Line5
Line6
Line7
Line5
Line6
Line7
Line8
Line9
Line10

I currently have a code that works for loops and repeated loops in a file. But breaks for the input file given above. I tried to implement @Samy Arous method from here: Using Python to Parse a File for Nested Loops but couldn't implement it. Moved this as a seperate question for clarity.

All the lines are just strings... It is a little complicated format so just gave a simple one. We can assume the Blank, JUMP, LOOP are all directing what needs to be done. Either just print it out or repeat based on the loop and Jump

My code:

import sys

inputtfile = sys.stdin
inputfileContents = open(r'path to input file')


def extract(line):
    return line[line.find('{') + 1: line.rfind('}')]

loopCount = 0
loopLines = []
inLoop = False
for line in inputfileContents:
    if line.startswith('Loop '):
        loopCount = int(line.split()[1])
        inLoop = True
    elif line.startswith('Jump '):
        loopLines.append(extract(line))
        for i in range(loopCount):
            for loopLine in loopLines:
                print loopLine

#reset state variables to track next possible loop
        loopCount = 0
        inLoop = False
        loopLines = []
    elif inLoop:
        loopLines.append(extract(line))
    else:
        print extract(line)
Community
  • 1
  • 1
Doodle
  • 45
  • 2
  • 7
  • Did this code even execute? These lines: `inLoop = True` `loopLines.append(extract(line))` They are between an `if` statement and an `elif`, that is invalid – smac89 Oct 16 '14 at 22:10
  • @smac89. I corrected it. Should be within the elif... Indentation error.. – Doodle Oct 16 '14 at 22:17
  • 1
    Welcome to stackoverflow. You will get better answers here if you ask more about your problem and less about your solution. If it is not clear to me what problem you are trying to solve, I probably will not try to answer. Some tips in order to improve your question: what is the desired output/behavior? the `{LineX}` things are really part of your input file? – Paulo Scardine Oct 16 '14 at 22:48
  • Why are you trying to create your own scripting language, and why are you using such odd and confusing syntax in the input? What's the overall purpose of this code? – Fred S Oct 17 '14 at 00:10
  • I have a file with that format and I need to flatten it and after which I am processing each line. The input file is not created by me. I need to parse this file to create the final output. – Doodle Oct 17 '14 at 00:17

1 Answers1

0

OK well if the input file is not yours, then you can't do much with the awful format. I think the easiest way to handle nesting is to use recursive functions.

Few assumptions about weird input format:

  • The "looped lines" always start on the next line after "Loop".
  • I ignore the labels. For "jump", that just means "end loop"

Anyway, the output I get seems to match your expected, but if my assumptions are incorrect, you'll need to modify this.

with open(r'path to input file') as f:
    inputfileContents = f.readlines()

def printLines(lines):
    nest_level = 0
    for i, line in enumerate(lines):
        print line.split('{')[-1].split('}')[0]
        if line.startswith('Jump '):
            nest_level -= 1
            if nest_level < 0:
                return
        elif line.startswith('Loop '):
            nest_level += 1
            loopCount = int(line.split()[1])-1
            for cnt in range(loopCount):
                printLines(lines[i+1:])

printLines(inputfileContents)

EDIT --> Here is a modified version that jumps to the label instead. Works with the current example input, but there's a lot of ways a bad input could break this.

with open(r'path to input file') as f:
    inputfileContents = f.readlines()

def printLines(lines):
    loop_cnt = []
    label_to_idx = {}
    for i, line in enumerate(lines):
        line = line.split('#')[0] #removing comments
        print line.split('{')[-1].split('}')[0]
        line_label = line.split('{')[0].strip()
        line_label = line_label.replace(':','') #I assume the colon is a typo?
        label_to_idx[line_label] = i

        if line.startswith('Jump '):
            if not loop_cnt:
                return
            jump_label = line.split()[1]
            start = label_to_idx[jump_label]
            loopCount = loop_cnt.pop()
            for cnt in range(loopCount):
                printLines(lines[start:])
        elif line.startswith('Loop '):
            loopCount = int(line.split()[1])-1
            loop_cnt.append(loopCount)

printLines(inputfileContents)
Fred S
  • 985
  • 4
  • 11
  • I agree with the input file format being dumb as rocks!! Thanks. The first condition that you have told me is not true sometimes. There are lines after the "Loop" and before the "Label" . – Doodle Oct 17 '14 at 23:02
  • @ FredS Do we need to check for the label if there is a line next to Loop not included in a Jump statement? – Doodle Oct 18 '14 at 03:28
  • @ Fred S The semicolon was not a typo. I modified in the question. Also There is a "blank" at each of the label statements after the semicolon so I need to modify that. Else it breaks at the Label statement. – Doodle Oct 20 '14 at 23:10
  • I cant vote up your answer yet since I am short of reputations. But thanks for your help! – Doodle Oct 20 '14 at 23:11
  • No problem. Can you tell I'm doing boring stuff at work these days? – Fred S Oct 21 '14 at 16:04
  • haha! Sure. That was my work crisis that you just solved.. May be time to move ;) – Doodle Oct 21 '14 at 23:11