Разбор и кодировка: почему мой скрипт не работает - PullRequest
0 голосов
/ 13 марта 2010

Я хочу извлечь только значения attribute1 и attribute3. Я не понимаю, почему в моем случае кодировка не работает, чтобы "пропустить" любые другие атрибуты (attribute3 не извлекается, как я хотел):

content: {<tag attribute1="valueattribute1" attribute2="valueattribute2" attribute3="valueattribute3">
</tag>
<tag attribute2="valueattribute21" attribute1="valueattribute11" >
</tag>
}


attribute1: [{attribute1="} copy valueattribute1 to {"} thru {"}]
attribute3: [{attribute3="} copy valueattribute3 to {"} thru {"}]

spacer: charset reduce [tab newline #" "]
letter: complement spacer 
to-space: [some letter | end]

attributes-rule: [(valueattribute1: none valueattribute3: none) [attribute1 | none] any letter [attribute3 | none] (print valueattribute1 print valueattribute3)
| [attribute3 | none] any letter [attribute1 | none] (print valueattribute3 print valueattribute1
valueattribute1: none valueattribute3: none
)
| none
]

rule: [any [to {<tag } thru {<tag } attributes-rule {>} to {</tag>} thru {</tag>}] to end]

parse content rule

вывод

>> parse content rule
valueattribute1
none
== true
>>

Ответы [ 3 ]

1 голос
/ 13 марта 2010

Во-первых, вы не используете parse/all. В Rebol 2 это означает, что пробелы были эффективно удалены перед выполнением разбора. Это не так в Rebol 3: если ваши правила синтаксического анализа представлены в блочном формате (как вы делаете здесь), то подразумевается /all.

(Примечание. Казалось, что существует консенсус в отношении того, что Rebol 3 исключит неблокированную форму правил разбора в пользу функции split для этих "минимальных" сценариев разбора Это полностью избавило бы от /all. К сожалению, до сих пор не предпринято никаких действий.)

Во-вторых, в вашем коде есть ошибки, которые я не собираюсь тратить на разборку. (Это в основном потому, что я думаю, что использование разбора Rebol для обработки XML / HTML - довольно глупая идея: P)

Но не забывайте, что у вас есть важный инструмент. Если вы используете set-word в правиле синтаксического анализа, то это захватит позицию синтаксического анализа в переменную. Затем вы можете распечатать его и посмотреть, где вы находитесь. Измените часть attribute-rule, где вы сначала говорите any letter на pos: (print pos) any letter, и вы увидите это:

>> parse/all content rule
 attribute2="valueattribute2" attribute3="valueattribute3">
</tag>
<tag attribute2="valueattribute21" attribute1="valueattribute11" >
</tag>

valueattribute1
none
== true

Видите лидирующие места? Ваши правила прямо перед тем, как any letter поставили вас в пробел ... и поскольку вы сказали, что любое письмо было в порядке, ни одно письмо не подходит, и все отбрасывается.

(Примечание: в Rebol 3 есть еще лучший инструмент отладки ... слово ??. Когда вы помещаете его в блок разбора, он сообщает вам, какой токен / правило вы обрабатываете в настоящее время, а также состояние ввода. С помощью этого инструмента вы можете легко узнать, что происходит:

>> parse "hello world" ["hello" ?? space ?? "world"]
space: " world"
"world": "world"
== true

... хотя сейчас на r3 mac intel действительно глючит.)

Кроме того, если вы не используете copy, тогда ваш шаблон to X thru X не нужен, вы можете достичь этого только с thru X. Если вы хотите сделать копию, вы также можете сделать это с помощью краткого copy Y to X X или, если это всего лишь один символ, вы можете написать более ясное copy Y to X skip

В тех местах, где вы видите себя пишущим повторяющийся код, помните, что Rebol может пойти на шаг выше, используя compose и т. Д .:

>> temp: [thru (rejoin [{attribute} num {=}]) 
          copy (to-word rejoin [{valueattribute} num]) to {"} thru {"}]

>> num: 1
>> attribute1: compose temp
== [thru "attribute1=" copy valueattribute1 to {"} thru {"}]

>> num: 2
>> attribute2: compose temp
== [thru "attribute2=" copy valueattribute2 to {"} thru {"}]
1 голос
/ 13 марта 2010

Короткий ответ, [любая буква] съедает ваш attribute3 = "...", так как символ # "^" "по вашему определению является буквой '. Кроме того, у вас могут возникнуть проблемы, когда нет атрибута2, тогда ваш общий Второе правило атрибута будет съедать attribute3, и ваше правило attribute3 не будет иметь ничего для соответствия - лучше либо явно указать, что существует необязательный атрибут2, либо необязательный атрибут what-but-attribute3

attribute1="foo"       attribute2="bar" attribute3="foobar" 
<- attribute1="..." -> <-     any letter                 -> <- attibute3="..." ->

Кроме того, 'parse без уточнения / all игнорирует пробелы (или, по крайней мере, очень громоздкий, когда речь идет о пробелах) - / все настоятельно рекомендуется для этого типа синтаксического анализа.

0 голосов
/ 13 марта 2010

При добавлении parse / all, похоже, ничего не изменилось. Наконец-то это работает (использование set-word действительно очень помогло для отладки !!!), как вы думаете?

content: {<tag attribute1="valueattribute1" attribute2="valueattribute2" attribute3="valueattribute3">
</tag>
<tag attribute2="valueattribute21" attribute1="valueattribute11" >
</tag>
}


attribute1: [to {attribute1="} thru {attribute1="} copy valueattribute1 to {"} thru {"}]
attribute3: [to {attribute3="} thru {attribute3="} copy valueattribute3 to {"} thru {"}]

letter: charset reduce ["ABCDEFGHIJKLMNOPQRSTUabcdefghijklmnopqrstuvwxyz1234567890="]

attributes-rule: [(valueattribute1: none valueattribute3: none) 
[attribute1 | none] any letter pos: 
[attribute3 | none] (print valueattribute1 print valueattribute3)
| [attribute3 | none] any letter [attribute1 | none] (print valueattribute3 print valueattribute1
valueattribute1: none valueattribute3: none
)
| none
]

rule: [any [to {<tag } thru {<tag } attributes-rule {>} to {</tag>} thru {</tag>}] to end]

parse content rule

который выводит:

>> parse/all content rule
valueattribute1
valueattribute3
valueattribute11
none
== true
>>
...