2010-03-17 2 views
1

... 나는 벽을 치고 있는데, 왜 이것이 작동하지 않는지 이해하지 못한다. (나는 하나의 태그 버전을 해석 할 수 있어야한다.) 또는 종료 2 개 태그 버전()) :나는이 파싱이 간단하다고 생각했다.

이 경우
Rebol[] 

content: {<pre:myTag  attr1="helloworld" attr2="hello"/> 
<pre:myTag  attr1="helloworld" attr2="hello"> 
</pre:myTag> 
<pre:myTag  attr3="helloworld" attr4="hello"/> 
} 

spacer: charset reduce [#" " newline] 
letter: charset reduce ["ABCDEFGHIJKLMNOPQRSTUabcdefghijklmnopqrstuvwxyz1234567890="] 

rule: [ 

any [ 
{<pre:myTag} 
any [any letter {"} any letter {"}] mark: 
(print {clipboard... after any letter {"} any letter {"}} write clipboard:// mark input) 
any spacer mark: (print "clipboard..." write clipboard:// mark input) ["/>" | ">" 
any spacer </pre:myTag> 
] 
any spacer 
(insert mark { Visible="false"}) 
] 
to end 

] 

parse content rule 
write clipboard:// content 
print "The end" 
input 

답변

5

, 문제가 규칙 아니다 - 것을 그것의 당신의 '당신은 삽입 할 지점의 위치를 ​​변경하는 각 태그 변경 후 삽입 . 삽입은 정확하지만 삽입 후, 구문 분석 규칙이 위치 2에 여전히, 그냥 "D"가 어디에 전에, 지금은 "CD"가

>> probe parse str: "abd" ["ab" mark: (insert mark "c") "d"] probe str 
false 
"abcd" 
== "abcd" 

과 :

는 설명하기 규칙이 실패합니다. 세 가지 전략 :)

>> probe parse str: "abd" ["ab" mark: (insert mark "c") "cd"] probe str 
true 
"abcd" 
== "abcd" 

이 새 내용의 길이를 계산하고 건너 뛸 :

1) 새로운 내용을 통합

>> probe parse str: "abd" ["ab" mark: (insert mark "c") 1 skip "d"] probe str 
true 
"abcd" 
== "abcd" 

3) 조작 한 후 위치를 변경합니다

>> probe parse str: "abd" ["ab" mark: (mark: insert mark "c") :mark "d"] probe str 
true 
"abcd" 
== "abcd" 

숫자 2)는 문자열 길이가 16임을 알기 때문에 귀하의 경우 가장 빠릅니다.

rule: [ 
    any [ 
     {<pre:myTag} ; opens tag 

     any [ ; eats through all attributes 
      any letter {"} any letter {"} 
     ] 

     mark: (; mark after the last attribute, pause (input) 
      print {clipboard... after any letter {"} any letter {"}} 
      write clipboard:// mark 
      input 
     ) 

     any spacer mark: ; space, mark, print, pause 
     (print "clipboard..." write clipboard:// mark input) 

     [ ; close tag 
      "/>" 
      | 
      ">" any spacer </pre:myTag> 
     ] 

     any spacer ; redundant without /all 

     (insert mark { Visible="false"}) 
     16 skip ; adjust position based on the new content 
    ] 

    to end 
] 

참고 : 이것은 [16 스킵]이 추가 된 것과 같은 규칙입니다.

+0

대단히 감사합니다. Chris 님, 진심으로 감사합니다. 저는 이제 구문 분석을 진행하고 있습니다. :) –

+0

하지만 분명히 문자열 길이를 하드 코딩하지 마십시오! 구문 분석의 기본 동작은 단어를 평가하는 것이므로 * replacement : {Visible = "false"} * 및 * replacement-length : length? 바꿔 놓음*. 규칙에서 교체 및 교체 길이를 사용하십시오. 물론 그것은 XML/HTML을위한 비 DOM 지향 파서를 사용하는 것은 좋은 생각입니다. 나는 그것을 반복하지 않을 것입니다 ... :) – HostileFork

+0

Rebol Q & A를 수행하는 사람들의 아이디어는 +1입니다. AltME 및 R3 채팅. 지역 사회의 일부 다른 사람들이 나머지 문명에 합류 할 수 있다고 말하면, 그런 죽은 언어처럼 보이지 않을 수도 있습니다. – HostileFork