2012-06-29 14 views
5

텍스트 영역의 변경 이벤트에 응답하는 bbcode -> html 변환기가 있습니다. 현재이 작업은 일련의 정규 표현식을 사용하여 수행되며 많은 병리학 적 케이스가 있습니다. 저는 항상이 문법으로 연필을 선명하게하고 싶었지만 야크 면도를하고 싶지 않았습니다. 하지만 ... 최근에 나는 pegjs을 알게되었고, 이는 PEG 파서 생성을 꽤 완벽하게 구현 한 것 같습니다. 대부분의 문법이 지정되어 있지만, 이제는 이것이 본격적인 파서의 적절한 사용인지 궁금해졌습니다.BBCode 구문 분석을 위해 PEG 파서 사용 : pegjs 또는 ... 무엇?

내 구체적인 질문은 다음과 같습니다

  1. 내 응용 프로그램에 구문 오류 메이크업 감각에 실패 할 수 있습니다 파서를 사용하여 BBCode는 구현 않는, HTML로 내가 할 수있는 무엇을 번역하고 원시 텍스트로 나머지를 떠나에 의존으로 ? 예 : [url=/foo/bar]click me![/url]은 닫는 태그의 닫는 괄호가 입력되면 확실히 성공할 것으로 예상됩니다. 그러나 그 동안 사용자는 무엇을 보았을까요? 정규식을 사용하면 일치하지 않는 내용은 무시하고 미리보기 용으로 일반 텍스트로 처리 할 수 ​​있습니다. 공식적인 문법을 사용하면 파스 트리에서 HTML을 만드는 것에 의존하고 있기 때문에 가능한지 여부를 알 수 없습니다. 구문 분석에 실패하면 ... 무엇을 할 수 있습니까?

  2. 어디에서 변형해야하는지 명확하지 않습니다. 공식 lex/yacc 기반 구문 분석기에서 노드 유형을 나타내는 헤더 파일과 기호가 있습니다. pegjs에서는 노드 텍스트로 중첩 된 배열을 얻습니다. 번역 된 코드를 pegjs 생성 구문 분석기의 동작으로 내보낼 수 있지만 구문 분석기와 이미 터를 결합하는 코드 냄새처럼 보입니다. 내가 PEG.parse.parse() 전화를한다면, 나는 다음과 같이 다시 뭔가를 얻을 : 당신을

    document 
        = (open_tag/close_tag/new_line/text)* 
    
    open_tag 
        = ("[" tag_name "="? tag_data? tag_attributes? "]") 
    
    
    close_tag 
        = ("[/" tag_name "]") 
    
    text 
        = non_tag+ 
    
    non_tag 
        = [\n\[\]] 
    
    new_line 
        = ("\r\n"/"\n") 
    

    나는 물론, 문법을 축약하고있어,하지만 :

[ 
     [ 
      "[", 
      "img", 
      "", 
      [ 
      "/", 
      "f", 
      "o", 
      "o", 
      "/", 
      "b", 
      "a", 
      "r" 
      ], 
      "", 
      "]" 
     ], 
     [ 
      "[/", 
      "img", 
      "]" 
     ] 
    ]

같은 문법을 부여 아이디어를 얻으십시오. 따라서 알 수 있다면 배열의 배열에 문맥 정보가 없기 때문에 어떤 노드인지 알 수 있고 문자열 비교를 할 수 있습니다. 파서가 이미이 작업을 수행했다고 생각합니다. 구문 분석 중에 콜백을 정의하고 액션을 사용하여 실행하는 것이 가능할 것이라고 기대하지만 웹에서 사용 가능한 정보가 부족합니다.

내가 잘못된 나무를 짖고 있습니까? regex 스캐닝으로 돌아가서 파싱을 잊어 버려야할까요? 나는 실시간 미리보기가 어려울 것입니다 것을 tosay이 첫 번째 질문에 대해서는

감사

+0

스티브, 당신의 질문은 매우 흥미 롭습니다 (+1), 나는 확장에서 똑같은 일을하고 싶습니다 : 텍스트 영역에서 BBCode를 파싱합니다 (불행히도 이것은 포럼이 여전히 사용하고있는 형식입니다). 그리고 "라이브 "PEG.js 또는 정규 표현식을 제외한 다른 텍스트를 사용하여 입력 된 텍스트에서 미리보기. BBCode 파서의 문법을 만들었습니까? GitHub 또는 다른 어떤 방법으로 솔루션을 공유 할 수 없습니까? 그것은 나를 많이 도울 것입니다. 대단히 감사드립니다! – Sk8erPeter

+0

[patorjk의 bbcode 파서] (https://github.com/patorjk/Extendible-BBCode-Parser)를 사용했습니다. 특수 태그가 있으면 잘 작동하고 자신의 필요에 맞게 조정할 수 있습니다. –

+0

이론적으로 정규 표현식을 사용하여 BBCode를 구문 분석하는 것은 오류없이 수행 할 수 있기 때문에 피하고 싶었던 정규 표현식을 사용합니다 ([kav- nordmann.de/blog/do_NOT_parse_using_regexp.html)) 경우에 따라 그래서 서로 문법 형식을 파싱하여 구문 분석을하고 싶었습니다. 시작한 문법을 ​​향상 시키려고하지 않으셨습니까? :) 그것의 기초를 공유하지 못했습니다? :) – Sk8erPeter

답변

2

합니다. 구문 분석기가 입력 내용이 "진행중인 작업"이라는 것을 이해하지 못한다는 점에서 지적한 문제는 옳습니다. Peg.js는 오류가 어느 시점에서 발생했는지 알려주므로 정보를 가져 와서 몇 마디 뒤로 가서 다시 구문 분석하거나 끝 태그가없는 경우 끝에 추가하십시오.

질문의 두 번째 부분은 쉽지만 나중에는 문법이 너무 좋아 보이지 않습니다. 순간 예를

text 
    = text:non_tag+ { 
    // we captured the text in an array and can manipulate it now 
    return text.join(""); 
    } 

에 대한 당신의 문법에 인라인이 콜백을 작성해야하므로 기본적으로 당신이하는 일은, 모든 규칙에 넣어 콜백입니다. 지금 당장이 일을 많이하고 있어요. 그래서 그걸 고치려면 당황하지 말고. 그러나 나는 이것을 할 시간을 찾았는지 확신 할 수 없다.

1

이 대체 규칙과 같은 것을 시도해보십시오. 너는 바른 길을 가고있다. 결과를 모으라고 말하면됩니다.

텍스트 = 결과 : non_tag + {return result.join (''); }

3

첫 번째 질문 (불완전한 텍스트에 대한 문법) : 당신은open_tag

incomplete_tag = ("[" tag_name "="? tag_data? tag_attributes?) 
//       the closing bracket is omitted ---^ 

을 추가하고 마지막에 불완전한 태그를 포함 할 document을 변경할 수 있습니다

. 트릭은 파서에게 필요한 모든 제작물을 으로 항상 구문 분석기에 제공하지만 유효한 것이 먼저옵니다. 실시간 미리보기 중에 incomplete_tag을 무시할 수 있습니다.

두 번째 질문 (조치를 포함하는 방법) : 당신은 표현 후 행동을 소위 쓰기

. 액션은 중괄호로 묶인 자바 스크립트 코드이며 pegjs 표현 뒤에 허용됩니다. 이자형. 또한 생산의 중간에!

실제로는 { return result.join("") }과 같은 동작이 필요합니다. pegjs는 단일 문자로 분리되기 때문입니다. 또한 복잡한 중첩 배열을 반환 할 수 있습니다. 따라서 저는 보통 액션을 작게 유지하기 위해 문법의 머리 부분에있는 pegjs 초기화 프로그램에 도우미 함수를 작성합니다. 기능 이름을 신중하게 선택하면 작업이 자체적으로 문서화됩니다.

시험에 대해서는 PEG for Python style indentation을 참조하십시오. 면책 조항 : 이것은 내 대답입니다.