2017-09-25 14 views
2

나는 적절한 설정 형식을 위해 GUI 편집기를 사용하고 있습니다. 기본적으로 편집기는 구성 파일을 구문 분석하고 사용자가 GUI에서 편집 한 다음 오브젝트를 다시 파일에 쓸 수 있도록 오브젝트 특성을 표시합니다.주석을 보존하고 오류를 복구하는 파서

  • 가 구문 분석 된 데이터 구조는 개체 속성 정보를 포함있을 경우 의견과 공백 쓰기
  • 에 손실됩니다, 그래서 : - 편집 -에 대한 부분은 제외 할 쓰기

    내가 구문 분석있어 구문 오류가 발생하면 나머지 파일은 건너 뜁니다.

이 문제를 어떻게 해결하겠습니까? 이 문제에 대한 일반적인 접근 방식은 무엇입니까? 저는 파이썬과 파섹 모듈 https://pythonhosted.org/parsec/documentation.html을 사용하고 있습니다. 그러나 도움과 일반적인 방향에 감사드립니다.

나는 또한 Pylens (https://pythonhosted.org/pylens/)를 시도했는데, 이것은 필자가 구문 오류를 건너 뛸 수 없다는 점을 제외하면 필자가 필요로하는 것과 거의 비슷하다.

답변

0

결국 나는 연구 시간을 다 쓰고 오히려 수동 건너 뛰기로 해결해야합니다. 기본적으로 파서가 실패 할 때마다 우리는 커서를 한 문자 앞당기 고 반복하려고합니다. 공백/주석/구문 오류와 상관없이 프로세스가 건너 뛴 부분은 Text 구조로 덤프됩니다. 코드는 반복적 인 결과로 모든 장소에 통합해야하는 부분을 제외하고는 매우 재사용 가능하며 원래 파서는 실패 할 수 있습니다.

누구나 도움이 될 수 있도록이 코드는 다음과 같습니다. 그것은 Parsy로 작성되었습니다.

class Text(object): 
    '''Structure to contain all the parts that the parser does not understand. 
    A better name would be Whitespace 
    ''' 
    def __init__(self, text=''): 
     self.text = text 

    def __repr__(self): 
     return "Text(text='{}')".format(self.text) 

    def __eq__(self, other): 
     return self.text.strip() == getattr(other, 'text', '').strip() 


def many_skip_error(parser, skip=lambda t, i: i + 1, until=None): 
    '''Repeat the original `parser`, aggregate result into `values` 
    and error in `Text`. 
    ''' 
    @Parser 
    def _parser(stream, index): 
     values, result = [], None 

     while index < len(stream): 
      result = parser(stream, index) 
      # Original parser success 
      if result.status: 
       values.append(result.value) 
       index = result.index 
      # Check for end condition, effectively `manyTill` in Parsec 
      elif until is not None and until(stream, index).status: 
       break 
      # Aggregate skipped text into last `Text` value, or create a new one 
      else: 
       if len(values) > 0 and isinstance(values[-1], Text): 
        values[-1].text += stream[index] 
       else: 
        values.append(Text(stream[index])) 
       index = skip(stream, index) 
     return Result.success(index, values).aggregate(result) 
    return _parser 


# Example usage 
skip_error_parser = many_skip_error(original_parser) 

기타 참고로, 여기서 실제 문제는 올바른 두 단계의 구문 분석 프로세스 대신 파서 연결자 라이브러리를 사용하고 있다는 것입니다. 전통적인 구문 분석에서 tokenizer는 공백/주석/구문 오류를 유지/건너 뛰는 작업을 처리하여 모든 공백을 효율적으로 만들고 파서가 볼 수 없도록합니다.

1

이 문제에 대한 일반적인 접근 방법에 대해 질문했습니다.

sketch-n-sketch : 이미지를 묘사하는 소스 언어를 편집하거나 직접 표현하는 이미지를 편집 할 수있는 벡터 이미지의 "직접 조작"인터페이스는 다음과 같습니다. 이러한 변경 사항은 소스 코드에 반영됩니다. 비디오 프리젠 테이션을 확인하십시오.

Boomerang : 렌즈를 사용하여 구체적인 구문의 추상적 인 의미에 초점을 맞추고 그 추상 모델을 변경 한 다음 원본 소스에 반영합니다.

두 프로젝트 모두 저자가 취한 접근법을 설명하는 몇 개의 논문을 제출했습니다. 제가 말할 수있는 한 Lens 접근 방식이 인기가 있습니다. 구문 분석 및 인쇄가 일부 소스 코드를 사용하고 코드가 설명하는 추상 개념에 초점을 맞춘 Lens의 getput 함수가되는 곳입니다.