import sys
import re
import os
import codecs
from .Phase1Result import *
from .LogicalLine import *
blank_slc_re = re.compile( r'^\s*//.*$', re.UNICODE)
tag_re = re.compile( r'^\s*//\s*@\s*(?P<tag>[A-Za-z]+)\s*(\(\s*(?P<value>.*?)\))?\s*$', re.UNICODE )
slc_re = re.compile( r'^(?P<content>.*?)//.*$', re.UNICODE )
smlc_re = re.compile( r'^(?P<content>.*?)/\*.*$', re.UNICODE )
emlc_re = re.compile( r'^.*?\*/(?P<rest>.*)$', re.UNICODE )
blank_re = re.compile( r'^\s*$', re.UNICODE)
mlc_re = re.compile( r'^(?P<content>.*)/\*.*\*/(?P<rest>.*)$', re.UNICODE)
def split_by_mlc(line):
contents = []
rest = line
while True:
matched = mlc_re.match(rest)
if not matched:
contents.append(rest)
return contents
contents.append(matched.group('content'))
rest = matched.group('rest')
if not rest:
return contents
def is_blank(line):
return line == None or blank_re.match(line)
def is_blank_slc(line):
return blank_slc_re.match(line)
class Phase1Parser:
def __init__(self, lines):
self.result = []
self.lines = lines
self.in_comment = None
self.line_number = 0
def is_tag_of(self, line):
m = tag_re.match(line)
if not m:
return None
self.result.append(Tag(self.line_number, m.group('tag'), m.group('value')))
return True
def remove_single_line_comment(self, content):
matched = slc_re.match(content)
if not matched:
return content
return matched.group("content")
def try_to_erase_comment(self, line):
content = " ".join(split_by_mlc(line))
content_without_slc = self.remove_single_line_comment(content)
matched = smlc_re.match(content_without_slc)
if matched:
self.in_comment = True
return matched.group("content")
return content_without_slc
def parse_line_in_comment(self, line):
if not self.in_comment:
return None
matched = emlc_re.match(line)
if matched:
self.in_comment = None
self.parse_line_out_of_comment(matched.group('rest'))
return True
def parse_line_out_of_comment(self, line):
if is_blank(line) or self.is_tag_of(line) or is_blank_slc(line):
return
rest = self.try_to_erase_comment(line)
if is_blank(rest):
return
self.result.append(Unknown(self.line_number, rest))
def parse_line(self, line):
self.parse_line_in_comment(line) or \
self.parse_line_out_of_comment(line)
def parse(self):
for line in self.lines:
self.line_number = line.get_line_number()
self.parse_line(line.get_content())
return self.result
def phase1(lines):
return Phase1Parser(lines).parse()