# Parser for word syllables. # Copyright (C) 2021 Ngô Ngọc Đức Huy # # This file is part of Hàësdáïga utils. # # Hàësdáïga utils is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Hàësdáïga utils is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Hàësdáïga utils. If not, see . use JSON::Tiny; grammar Syllable { token TOP { } token onset { * } token nucleus { ? } token coda { * } token vowel { <[aeiouy]>} token rise-vowel { <[áéíóúý]>} token fall-vowel { <[àèìòùỳ]>} token first-vowel { [ | | ] } token second-vowel { [ | '~' ] } token consonant { <[bcdfghjlmnprstvwz']> } } class Parser { method nucleus ($/) { make ($.made, $ ?? $.made !! Nil).flat } method first-vowel ($/) { make $ ?? $.made !! ( $ ?? $.made !! $.made); } method rise-vowel ($/) { given $/ { when 'á' { make ('a', 'rising')} when 'é' { make ('e', 'rising')} when 'í' { make ('i', 'rising')} when 'ó' { make ('o', 'rising')} when 'ú' { make ('u', 'rising')} when 'ý' { make ('y', 'rising')} } } method fall-vowel ($/) { given $/ { when 'à' { make ('a', 'falling')} when 'è' { make ('e', 'falling')} when 'ì' { make ('i', 'falling')} when 'ò' { make ('o', 'falling')} when 'ù' { make ('u', 'falling')} when 'ỳ' { make ('y', 'falling')} } } method vowel ($/) { make ($/.words.join, 'level') } method second-vowel ($/) { make $/.words.join } method coda ($/) {make $ ?? $.join !! Nil} } sub extras ($char) { my %parsing; %parsing{"type"} = "punctuation"; %parsing{"name"} = do given $char { when ',' { 'comma' } when ':' { 'colon' } when '!' { 'exclam' } when '(' { 'parenleft' } when ')' { 'parenright' } when '.' { 'period' } when '?' { 'question' } }; return %parsing } sub parse-one ($word) { if $word ∈ <. , ? ! ( ) :> { return extras($word); } my $C1 = Syllable.parse($word).join; my $C2 = Syllable.parse( $word, actions => Parser).made; my ($V1, $T, $V2) = Syllable.parse( $word, actions => Parser).made; if $V2 eqv '~' { $V2 = 'long' } if $C1 eqv "'" { $C1 = 'glottal'} my %parsing; %parsing{"type"} = "syllable"; %parsing{"C1"} = $C1; %parsing{"C2"} = $C2; %parsing{"V1"} = $V1; %parsing{"V2"} = $V2; %parsing{"T" } = $T ; return %parsing } sub MAIN ($phrase) { my @list; for $phrase.words -> $word { @list.push(parse-one($word)) } say to-json @list; }