如何在 Happy 解析器中匹配正则表达式?

发布于 2025-01-04 21:04:09 字数 1160 浏览 1 评论 0原文

我正在使用 Happy 编写一个 JavaScript 解析器,我需要匹配正则表达式。我不想完全解析正则表达式,只需将其存储为字符串。

我的 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 }

I'm writing a JavaScript parser with Happy and I need to match a regular expression. I don't want to fully parse the regex, just store it as a string.

The relevant part of my AST looks like this:

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

This is the relevant Happy code:

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 }

My question is, how should I define my regex non-terminal? Is this kind of structure right?

regex :: { String }
    : '/' whatHere? '/' { $2 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

滥情稳全场 2025-01-11 21:04:09

您应该将 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 }

You should define regex as a terminal that is recognized by the lexer (i.e. 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 }
蹲在坟头点根烟 2025-01-11 21:04:09

要回答评论中的问题,需要更多空间。

类似于(间隔并评论):

/             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

浓缩:

/(\\.|[^\[/\\]|\[[^\]]*\])*/

To answer the question in the comment, need a bit more room.

Something like (spaced out and commented):

/             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

Condensed:

/(\\.|[^\[/\\]|\[[^\]]*\])*/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文