Форум программистов, компьютерный форум, киберфорум
Наши страницы
Haskell
Войти
Регистрация
Восстановить пароль
 
alex4212345
0 / 0 / 0
Регистрация: 11.11.2018
Сообщений: 6
1

Функция-анализатор, которая распознает регулярные выражения

23.11.2018, 13:31. Просмотров 462. Ответов 7

Помогите пожалуйста написать функцию-анализатор reg, которая распознает регулярное выражение, - значение типа RE. Например, используя функцию regExp:

Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 regExp :: String -> Maybe RE
regExp str = case (parse reg "" str) of
               Left _   -> Nothing
               Right rg -> Just rg
 
data RE = Null           | 
          Term Char  | 
          Seq RE RE | 
          Alt RE RE  | 
          Rep RE       | --  (*)
          Plus RE      | --  (+)
          Opt RE        --  (?)
       deriving (Eq, Show) 
 
reg :: Parser RE
reg = undefined
Какие ответы должны получиться при тестирование:
• regExp “(a?)a” = Just (Seq (Opt (Term ‘a’)) (Term ‘a’))
• regExp “ab(+)” = Nothing


Вот то что я написал, но почему-то показывает много ошибок, которые никак не могу понять и исправить.

Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
data RE = Null           | 
          Term Char  | 
          Seq RE RE | 
          Alt RE RE  | 
          Rep RE       | --  (*)
          Plus RE      | --  (+)
          Opt RE        --  (?)
       deriving (Eq, Show)
 
reg :: Parser RE
reg = do spaces;
         rex <- rexpr 
         eof 
         return rex  
 
lexem :: Parser a -> Parser a
lexem p = do {a <- p; spaces ; return a}
 
symbol :: Char ->  Parser ()
symbol ch = lexem (char ch >> return ())
 
rexpr,rterm,rfact :: Parser RE
rexpr = rterm `chainl1` topp
rterm = (try(seq' rfact rterm)) <|> rfact
rfact = symbol <|> parens rexpr
 
topp,bott :: Parser (RE -> RE -> RE)
topp = undefined
bott = infixOp "|" Alt
 
regExp :: String -> Maybe RE
regExp str = case (parse reg "" str) of
               Left _   -> Nothing
               Right rg -> Just rg
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.11.2018, 13:31
Ответы с готовыми решениями:

Лексический анализатор - как использовать регулярные выражения?
Вот код анализатора. Как использовать регулярные выражение? И мне нужно разделить идентификатор...

Упрощенный синтаксический анализатор(для проверки методов/функций) используя регулярные выражения
Нужно написать метод, регулярное выражение, на С#, который будет проверять правильность ввода...

ЧПУ. Замена строк, регулярные выражения. Как правильно использовать переменную в регулярные выражения ?
Здравствуйте! Решил реализовать ЧПУ на своем сайте. Первый этап это замена всех реальных ссылок на...

Регулярные выражения. не работает функция. Что не так?
function get_tracking_url(tracking_number:string):string; begin if...

Регулярные выражения. Создайте программу, которая будет проверять корректность ввода логина
Регулярные выражения. Создайте программу, которая будет проверять корректность ввода логина....

7
XRuZzz
Антикодер
1626 / 786 / 46
Регистрация: 15.09.2012
Сообщений: 2,898
23.11.2018, 21:00 2
Откуда тип Parser берётся? Из библиотеки parsec что ли?
0
alex4212345
0 / 0 / 0
Регистрация: 11.11.2018
Сообщений: 6
23.11.2018, 21:02  [ТС] 3
import Text.ParserCombinators.Parsec
да, из библиотеки.
0
XRuZzz
Антикодер
1626 / 786 / 46
Регистрация: 15.09.2012
Сообщений: 2,898
24.11.2018, 12:22 4
А у вас первая ошибка такая?

error:
• Couldn't match expected type ‘ParsecT String () Data.Functor.Identity.Identity RE’
with actual type ‘Char -> Parser ()’
• Probable cause: ‘symbol’ is applied to too few arguments
In the first argument of ‘(<|>)’, namely ‘symbol’
In the expression: symbol <|> parens rexpr
In an equation for ‘rfact’: rfact = symbol <|> parens rexpr
Цитата Сообщение от alex4212345 Посмотреть сообщение
lexem :: Parser a -> Parser a lexem p = do {a <- p; spaces ; return a}
Зачем вам лексемы разделять пробелами(spaces) в регулярке? Там же пробел на равне с обычными символами используется.

Добавлено через 1 час 53 минуты
Я только сходу не могу сообразить как распарсить последовательность в рекурсивное дерево Seq RE RE.
1
24.11.2018, 12:22
alex4212345
0 / 0 / 0
Регистрация: 11.11.2018
Сообщений: 6
24.11.2018, 15:12  [ТС] 5
да, такая же первая ошибка.
Просто без пробела тогда? не помню почему так писал, но кажется без пробела как-то не так считало.

Все что дано в лабораторной о последовательности:
• Последовательность двух рядом записанных регулярных выражений.
o Регулярное выражение ab - последовательность двух терминалов, a и b - образец, который сопоставляется только со строкой "ab".
o Круглые скобки можно использовать для группировки подвыражений регулярного выражения, a (bc), (ab) c и abc все задают одинаковый регулярное выражение (последовательность - ассоциативная).
0
XRuZzz
Антикодер
1626 / 786 / 46
Регистрация: 15.09.2012
Сообщений: 2,898
24.11.2018, 15:38 6
можно посмотреть статью:
https://www.schoolofhaskell.com/user...5-a-simple-dsl
на тему парсера.
Смотрел доку тут:
http://hackage.haskell.org/package/p...rsec-Char.html
И нашёл там alphaNum - мне кажется это то что нужно для конструктора Term.
А дальше надо сообразить как распарсить последовательность в рекурсивное дерево Seq RE RE. Вот кстати Дмитрий Маликов нечто похожее спрашивал:
https://stackoverflow.com/questions/...ta-with-parsec

Насчёт spaces в lexem - можно либо разрешить бесполезные пробелы в регулярке либо запретить, я не знаю как в стандартах регулярок, никогда не делаю бесполезные пробелы.
1
XRuZzz
Антикодер
1626 / 786 / 46
Регистрация: 15.09.2012
Сообщений: 2,898
25.11.2018, 09:17 7
У Дениса Москвина, кстати, хороший материал по работе с парсерами есть:
stepik → Функциональное программирование на языке Haskell (часть 2) → 1.3 Аппликативный парсер Parsec
1
XRuZzz
Антикодер
1626 / 786 / 46
Регистрация: 15.09.2012
Сообщений: 2,898
29.11.2018, 14:23 8
Только через список сообразил как разобрать список символов и цифр в дерево Seq. Может можно как то напрямую это сделать?
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module Main where
 
import Text.Parsec
import Text.Parsec.String (Parser)
import Text.Parsec.Language (emptyDef)
 
import qualified Text.Parsec.Expr as Ex
import qualified Text.Parsec.Token as Tok
 
...
 
rterm :: Parser RE
rterm = do
    c <- alphaNum
    return $ Term c
 
rsequence :: Parser RE
rsequence = do
        t <- many rterm
        return $ listToSeq t
 
listToSeq [] = Null
listToSeq (x:xs) = (Seq x (listToSeq xs))
 
main :: IO ()
main = do
  print $ parse rsequence "" "abcdef"
Добавлено через 52 минуты
Ну если тупо переписать по ответу на вопрос Д. Маликова, получается:
Haskell
1
rsequence = foldr Seq Null <$> many rterm
1
29.11.2018, 14:23
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.11.2018, 14:23

Регулярные выражения - вывод сообщения об ошибке при нахождении в строке выражения, начинающегося с цифры
Нужно чтобы при нахождении в строке выражения начинающегося с цифры появлялось сообщение об...

Регулярные выражения: вставка символов в середину найденного выражения
Есть строки типа этого: &quot;В году 1783 марта месяца произошло событие, которые на долго...

Нейросеть, которая распознает символ
Здравствуйте,формучане. у меня такая задача-нужно сделать нейросеть, которая распознает символ,но...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.