@property<EOL><INDENT>def structure(self):<DEDENT>
def _rstrip_backslash(l):<EOL><INDENT>l = l.rstrip()<EOL>if l.endswith('<STR_LIT:\\>'):<EOL><INDENT>return l[:-<NUM_LIT:1>]<EOL><DEDENT>return l<EOL><DEDENT>instructions = []<EOL>lineno = -<NUM_LIT:1><EOL>insnre = re.compile(r'<STR_LIT>')  <EOL>contre = re.compile(r'<STR_LIT>')          <EOL>commentre = re.compile(r'<STR_LIT>')           <EOL>in_continuation = False<EOL>current_instruction = None<EOL>for line in self.lines:<EOL><INDENT>lineno += <NUM_LIT:1><EOL>if commentre.match(line):<EOL><INDENT>continue<EOL><DEDENT>if not in_continuation:<EOL><INDENT>m = insnre.match(line)<EOL>if not m:<EOL><INDENT>continue<EOL><DEDENT>current_instruction = {'<STR_LIT>': m.groups()[<NUM_LIT:0>].upper(),<EOL>'<STR_LIT>': lineno,<EOL>'<STR_LIT>': lineno,<EOL>'<STR_LIT:content>': line,<EOL>'<STR_LIT:value>': _rstrip_backslash(m.groups()[<NUM_LIT:1>])}<EOL><DEDENT>else:<EOL><INDENT>current_instruction['<STR_LIT:content>'] += line<EOL>current_instruction['<STR_LIT>'] = lineno<EOL>if current_instruction['<STR_LIT:value>']:<EOL><INDENT>current_instruction['<STR_LIT:value>'] += _rstrip_backslash(line)<EOL><DEDENT>else:<EOL><INDENT>current_instruction['<STR_LIT:value>'] = _rstrip_backslash(line.lstrip())<EOL><DEDENT><DEDENT>in_continuation = contre.match(line)<EOL>if not in_continuation and current_instruction is not None:<EOL><INDENT>instructions.append(current_instruction)<EOL><DEDENT><DEDENT>return instructions<EOL>
Returns a list of dicts describing the commands:
[
    {"instruction": "FROM",       # always upper-case
     "startline": 0,              # 0-based
     "endline": 0,                # 0-based
     "content": "From fedora\n",
     "value": "fedora"},

    {"instruction": "CMD",
     "startline": 1,
     "endline": 2,
     "content": "CMD yum -y update && \\\n    yum clean all\n",
     "value": "yum -y update && yum clean all"}
]

Comments are ignored.