From 89921f7ea6dd2f6cd077a8e408cb31e4b5c07551 Mon Sep 17 00:00:00 2001 From: Jonathan Worthington Date: Tue, 7 Jul 2020 16:09:41 +0200 Subject: [PATCH] RakuAST for regex anchors --- src/Raku/Actions.nqp | 30 ++++++++++++++++++++++++++++ src/Raku/ast/regex.rakumod | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/src/Raku/Actions.nqp b/src/Raku/Actions.nqp index 7088980f220..5df78410ac1 100644 --- a/src/Raku/Actions.nqp +++ b/src/Raku/Actions.nqp @@ -779,6 +779,12 @@ class Raku::RegexActions is HLL::Actions { $res := nqp::atkey($res.WHO, $t2) unless nqp::isnull($res); nqp::ifnull($res, nqp::die("No such node RakuAST::{$t1}::{$t2}")) } + multi method r($t1, $t2, $t3) { + my $res := nqp::atkey($ast_root, $t1); + $res := nqp::atkey($res.WHO, $t2) unless nqp::isnull($res); + $res := nqp::atkey($res.WHO, $t3) unless nqp::isnull($res); + nqp::ifnull($res, nqp::die("No such node RakuAST::{$t1}::{$t2}::{$t3}")) + } method nibbler($/) { make $.ast; @@ -866,4 +872,28 @@ class Raku::RegexActions is HLL::Actions { make self.r('Regex', 'Literal').new(~$/); } } + + method metachar:sym<^>($/) { + make self.r('Regex', 'Anchor', 'BeginningOfString').new; + } + + method metachar:sym<^^>($/) { + make self.r('Regex', 'Anchor', 'BeginningOfLine').new; + } + + method metachar:sym<$>($/) { + make self.r('Regex', 'Anchor', 'EndOfString').new; + } + + method metachar:sym<$$>($/) { + make self.r('Regex', 'Anchor', 'EndOfLine').new; + } + + method metachar:sym($/) { + make self.r('Regex', 'Anchor', 'LeftWordBoundary').new; + } + + method metachar:sym($/) { + make self.r('Regex', 'Anchor', 'RightWordBoundary').new; + } } diff --git a/src/Raku/ast/regex.rakumod b/src/Raku/ast/regex.rakumod index c3a152532cc..2bf67847473 100644 --- a/src/Raku/ast/regex.rakumod +++ b/src/Raku/ast/regex.rakumod @@ -121,3 +121,44 @@ class RakuAST::Regex::Literal is RakuAST::Regex::Atom { QAST::Regex.new( :rxtype, $!text ) } } + +#| The base for all kinds of anchor. +class RakuAST::Regex::Anchor is RakuAST::Regex::Atom { + method new() { + nqp::create(self) + } + + method IMPL-REGEX-QAST(RakuAST::IMPL::QASTContext $context, %mods) { + QAST::Regex.new( :rxtype, :subtype(self.IMPL-QAST-SUBTYPE) ) + } +} + +#| The beginning of string (^) anchor. +class RakuAST::Regex::Anchor::BeginningOfString is RakuAST::Regex::Anchor { + method IMPL-QAST-SUBTYPE() { 'bos' } +} + +#| The beginning of line (^^) anchor. +class RakuAST::Regex::Anchor::BeginningOfLine is RakuAST::Regex::Anchor { + method IMPL-QAST-SUBTYPE() { 'bol' } +} + +#| The end of string ($) anchor. +class RakuAST::Regex::Anchor::EndOfString is RakuAST::Regex::Anchor { + method IMPL-QAST-SUBTYPE() { 'eos' } +} + +#| The end of line (^^) anchor. +class RakuAST::Regex::Anchor::EndOfLine is RakuAST::Regex::Anchor { + method IMPL-QAST-SUBTYPE() { 'eol' } +} + +#| The left word boundary (<<) anchor. +class RakuAST::Regex::Anchor::LeftWordBoundary is RakuAST::Regex::Anchor { + method IMPL-QAST-SUBTYPE() { 'lwb' } +} + +#| The right word boundary (>>) anchor. +class RakuAST::Regex::Anchor::RightWordBoundary is RakuAST::Regex::Anchor { + method IMPL-QAST-SUBTYPE() { 'rwb' } +}