/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ interface(extern-c){ xml2 = library:: pkgconfig("libxml-2.0"). include { xml2 = {"string.h"} }. } Matcher = type variant {Sequence, ZeroOrMore, Text}. matchText = function(text::string, matcher::string, posStart::i64):: i64 { textLength = strlen(text):: i64. matcherLength = strlen(matcher):: i64. if(textLength >= posStart + matcherLength):: i64{ if(strncmp(text + posStart, matcher, matcherLength) == 0):: i64 { matcherLength } else {-1:: i64} } else {-2:: i64} } matchSequence = function(text::string, pattern::undefType; i12n(on), posStart::i64):: i64; i12n(off){ textLength = length(text):: i64. loop fold(pattern-> matcher:: undefType, posStart->pos):: i64{ recognizedSymbols = match(text, matcher, pos):: i64. if (recognizedSymbols > (0::i64)):: i64{ pos+recognizedSymbols } else { pos:: i64; final } } } matchZeroOrMore= function(text::string, matcher::undefType; i12n(on), posStart::i64):: i64; i12n(off){ textLength = length(text):: i64. loop (posStart->pos):: i64{ recognizedSymbols = match(text, matcher, pos):: i64. if (recognizedSymbols > (0::i64)):: i64{ pos+recognizedSymbols } else { pos:: i64; final } } } match = function(text::string, pattern::undefType; i12n(on), posStart::i64)::i64; i12n(off){ key= pattern[0]::Matcher. switch variant(key) :: int case (Sequence) {matchSequence(text, pattern[1], posStart)} case (ZeroOrMore) {matchZeroOrMore(text, pattern[1], posStart)} case (Text) {matchText(text, pattern[1], posStart)} } main = function:: i64; entry { patternAB = {Sequence(), {{ZeroOrMore(), {Text(), "a"}}, {Text(), "b"}}} :: undefType; i12n(on). // matchers = ["The ", "only ", "way "] :: [string]; i12n(on). match("aaab", patternAB, 0):: i64 }