Как мне сопоставить регулярное выражение в парсере Happy? - PullRequest
1 голос
/ 14 февраля 2012

Я пишу синтаксический анализатор 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

Это соответствующий счастливый код:

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 ]

3 голосов
/ 14 февраля 2012

Чтобы ответить на вопрос в комментарии, нужно немного больше места.

Что-то вроде (с интервалом и комментариями):

/             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

Сгущено:

/(\\.|[^\[/\\]|\[[^\]]*\])*/
3 голосов
/ 14 февраля 2012

Вы должны определить регулярное выражение как терминал, который распознается лексером (то есть 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 }
...