Возникли некоторые простые проблемы с синтаксическими анализаторами Scala. - PullRequest
2 голосов
/ 22 мая 2011

Сначала код:

package com.digitaldoodles.markup

import scala.util.parsing.combinator.{Parsers, RegexParsers}
import com.digitaldoodles.rex._


class MarkupParser extends RegexParsers {
    val stopTokens = (Lit("{{") | "}}" | ";;" | ",,").lookahead
    val name: Parser[String] = """[@#!$]?[a-zA-Z][a-zA-Z0-9]*""".r
    val content: Parser[String] = (patterns.CharAny ** 0 & stopTokens).regex
    val function: Parser[Any] = name ~ repsep(content, "::") <~ ";;"
    val block1: Parser[Any] = "{{" ~> function
    val block2: Parser[Any] = "{{" ~> function <~ "}}"
    val lst: Parser[Any] = repsep("[a-z]", ",") 
}

object ParseExpr extends MarkupParser {
    def main(args: Array[String]) {
        println("Content regex is ", (patterns.CharAny ** 0 & stopTokens).regex)
        println(parseAll(block1, "{{@name 3:4:foo;;"))
        println(parseAll(block2, "{{@name 3:4:foo;; stuff}}"))
        println(parseAll(lst, "a,b,c")) 
    }
}

, затем результаты прогона:

[info] == run ==
[info] Running com.digitaldoodles.markup.ParseExpr 
(Content regex is ,(?:[\s\S]{0,})(?=(?:(?:\{\{|\}\})|;;)|\,\,))
[1.18] parsed: (@name~List(3:4:foo))
[1.24] failure: `;;' expected but `}' found

{{@name 3:4:foo;; stuff}}
                       ^

[1.1] failure: string matching regex `\z' expected but `a' found

a,b,c
^

Я использую пользовательскую библиотеку для сборки некоторых своих регулярных выражений, поэтому я распечаталрегулярное выражение "content";Предполагается, что в основном это будет любой текст, вплоть до определенных шаблонов токенов, но не включающий определенные положительные утверждения.

Наконец, проблемы:

1) Первый запуск на "block1" завершился успешно, но не должен, потому что разделитель в функции "repsep" - это "::", но ":" анализируются как разделители.

2) Запуск на "block2" завершается неудачей, предположительно потому, что предварительный просмотрпункт не работает - но я не могу понять, почему это должно быть.Предложение lookahead уже было выполнено в «repsep» при запуске на «block1» и, похоже, работает там, так почему оно должно завершиться неудачей на блоке 2?

3) Простое упражнение repsep на «lst» завершается неудачнопотому что внутренне механизм синтаксического анализа, кажется, ищет границу - это то, что мне нужно как-то обойти?

Спасибо, Кен

1 Ответ

2 голосов
/ 22 мая 2011

1) Нет, "::" не анализируются как разделители.Если это так, результат будет (@name~List(3, 4, foo)).

2) Это происходит потому, что «}}» также является разделителем, поэтому он принимает самое длинное совпадение, которое может - то, которое включает «* 1005».*" также.Если вы сделаете предыдущее выражение не нетерпеливым, то оно не будет выполнено в «s» на «stuff», что, как я полагаю, соответствует ожиданиям.

3) Вы передали литерал, а нерегулярное выражение.Измените "[a-z]" на "[a-z]".r, и оно будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...