Как мне сопоставить регулярное выражение в парсере Happy?
Я пишу синтаксический анализатор JavaScript с Happy, и мне нужно соответствовать регулярному выражению. Я не хочу полностью анализировать регулярное выражение, просто сохранить его как строку.
Соответствующая часть моего AST выглядит так:
data PrimaryExpr
-- | Literal integer
= ExpLitInt Integer
-- | Literal strings
| ExpLitStr String
-- | Identifier
| ExpId String
-- | Bracketed expression
| ExpBrackExp Expression
-- | This (current object)
| ExpThis
-- | Regular Expression
| ExpRegex String
-- | Arrays
| ExpArray ArrayLit
-- | Objects
| ExpObject [(PropName, Assignment)]
deriving Show
Это соответствующий код Happy:
primaryExpr :: { PrimaryExpr }
: LITINT { ExpLitInt $1 }
| LITSTR { ExpLitStr $1 }
| ID { ExpId $1 }
| THIS { ExpThis }
| regex { ExpRegex $1 }
| arrayLit { ExpArray $1 }
| objectLit { ExpObject $1 }
| '(' expression ')' { ExpBrackExp $2 }
У меня вопрос, как мне определить мой regex
нетерминальный? Правильна ли такая структура?
regex :: { String }
: '/' whatHere? '/' { $2 }
2 ответа
Решение
Вы должны определить regex как терминал, который распознается лексером (т.е. LITREGEX).
primaryExpr :: { PrimaryExpr }
: LITINT { ExpLitInt $1 }
| LITSTR { ExpLitStr $1 }
| LITREGEX { ExpRegex $1 }
| ID { ExpId $1 }
| THIS { ExpThis }
| arrayLit { ExpArray $1 }
| objectLit { ExpObject $1 }
| '(' expression ')' { ExpBrackExp $2 }
Чтобы ответить на вопрос в комментарии, нужно немного больше места.
Что-то вроде (размечено и прокомментировано):
/ forward slash
( \\. either: an escaped character
| [^\[/\\] anything which isn't / or [ or \
| \[ a character class containing:
[^\]]* anything which isn't ] any number of times
\]
)* any number of times
/ forward slash
Сгущенное:
/(\\.|[^\[/\\]|\[[^\]]*\])*/