Время звукобуквенный разбор: Сколько звуков в слове время

Примечания для (Почему Siri звучит белым)

Докладчики: AmberNechole Hart

Дата/время: 5 марта 2020 г., 13:40

Ключевые выводы

Харт исследует причины, по которым Siri звучит белым, почему это проблема и как сделать цифровые голосовые технологии более инклюзивными.

Примечания

Харт сосредоточилась на трех вопросах в ходе своего выступления под названием «Почему Siri звучит белым?»

  1. Что звучит белым?
  2. Как продукты звучат белыми?
  3. Есть ли возможность изменить повествование?

Чтобы объяснить, что значит «звучать белым», Харт рассказала о своем личном опыте.

«Как чернокожий человек, и, честно говоря, это может случиться и с другими этническими меньшинствами, когда вы начинаете расти, вы обнаружите, что произношение белого цвета в основном эквивалентно освоению стандартного американского английского». — сказал Харт.

У этой реальности есть исторический контекст. Харт говорит, что в 1619 году, когда первый корабль с африканцами приземлился на территории, впоследствии ставшей Соединенными Штатами Америки, чернокожие получили задание на проектирование.

«Некоторые из требований: вы должны быть угодливы, — сказал Харт, — и вы должны использовать чужой голос для общения. Ограничение в том, что, опять же, вы не можете использовать свой собственный голос и что вы отсоединены от земли, от своей культуры и много раз от своего сообщества».

афроамериканский вариант английского языка является результатом этого технического задания.

«Мы не только создали свой собственный диалект, но и освоили стандартный американский английский», — сказал Харт, что позволяет чернокожим переключаться между кодами в зависимости от того, чего от них требует контекст. Белоснежное звучание в своей основе — это просто мастерство стандартного американского английского. Таким образом, белизна Siri увековечивает миф о том, что белые голоса умны и успешны, а черные — нет.

«Черный голос, способ его кодирования, его можно использовать в обществе, это нормально в неформальной беседе, — сказал Харт, — но он всегда находится за пределами профессионального и академического пространства».

Харт сосредоточился на голосовых помощниках, чтобы выяснить, как продукты в конечном итоге звучат белыми. Эти устройства работают, принимая звук от пользователя, пытаясь проанализировать звук на предмет смысла, а затем отвечая. Харт утверждает, что даже если у вас есть буквально черные актеры озвучивания, исполняющие роли цифровых помощников, это все равно будет звучать не совсем правильно.

«У вас есть черный голос, который является вашим голосовым помощником, но на самом деле это модели внизу, естественная обработка моделей внизу, которые действительно влияют на него», — сказал Харт. «Это не похоже на Иссу Рэй, с которой я связался на Insecure

, это не похоже на Джона Ледженда».

Проблема в том, что большинство этих моделей обучаются только стандартному американскому английскому языку. Эти модели синтаксического анализа оказываются неспособными поддерживать афроамериканский английский, а в некоторых случаях даже кодируют афроамериканский английский как токсичный. Эти модели синтаксического анализа также часто не «слышат» другие акценты и диалекты.

Харт предлагает четыре способа изменить это повествование.

  1. Интеграция исторического контекста.
  2. Разработайте алгоритмы вместе с лингвистами.
  3. Стимулировать недопредставленные голоса
  4. Спросить, чей голос мы хотим и не хотим слышать

«Если эти компании не заинтересованы во включении, в этом будет заинтересована их прибыль», — сказал Харт. «Я думаю, что именно здесь мы движемся, и нам действительно нужно начать думать об инклюзивности не как о чем-то, что нам нужно делать, потому что это правильно, а о чем-то, что поможет нам внедрять инновации и продвигать наши продукты вперед».

 

Что такое язык шаблонов, часть 2

В первой части этой серии я представил свой новейший проект: Late, механизм шаблонов, не зависящий от языка. Это мое первое серьезное знакомство с компиляторами и интерпретаторами, зачастую самыми сложными и эзотерическими аспектами компьютерных наук, и я документирую то, что изучаю по ходу дела. Сегодня мы рассмотрим три основных аспекта большинства языков: лексирование, синтаксический анализ и компиляцию/вычисление.

Когда дело доходит до создания собственного языка, можно легко запутаться в огромном количестве исследовательских работ, сообщений в блогах и инструментов, которые существуют сегодня. Следует ли вам использовать lex, flex, bison или yacc? Или как насчет таких вещей, как ANTLR? И какое место во всем этом занимает LLVM? И если вам случится столкнуться с описанием

Переписывание AST , проходы оптимизации, SSA и такие инструменты, как компиляция «точно в срок», любому может быть достаточно просто сказать «Нет! Это все у меня в голове» и двигаться дальше. Хитрость заключается в том, чтобы начать с одной части за один раз. По своей сути компиляция представляет собой конвейер, в котором каждый шаг имеет явно определенные входные и выходные данные. Чтобы понять, как устроены языки, мы делаем шаг за шагом, и в конце концов вся картина внезапно обретает смысл!

Было бы грубо с моей стороны не отдать должное там, где оно должно быть. Единственная причина, по которой я смог погрузиться в Late и весь мир подобных языков шаблонов, заключается в том, что я нашел и прочитал фантастическую книгу Торстена Болла «Написание интерпретатора в Go». В этой книге Торстен проделал большую работу по превращению магии интерпретаторов в простые, хорошо объясненные и понятные части. В итоге вы получите работающий и вполне способный интерпретируемый язык. Этих постов и самого Late, наверное, не было бы без этой книги, так что спасибо, Торстен!

Почти каждый язык разработан вокруг трех основных этапов:

  • Токенизация и лексикографический анализ (часто называемый лексированием)
  • Применение значения к результирующим токенам (анализ)
  • Компиляция и/или оценка результатов анализатора

Звучит много, но, как я уже говорил, мы будем делать это шаг за шагом. Если вы предпочитаете более практический пример, возьмите книгу Торстена!

Токенизация и Lexing

Первым идет Лексер. Хотя технически это две части (токенизация и лексикографический анализ), почти каждый язык объединяет их в один шаг. Lexer берет исходный ввод (шаблон, файл языка сценариев и т. д.) и разбивает его на токены, часто с сопутствующими метаданными, такими как номера строк и необработанный ввод. Предполагается, что эти токены в основном не зависят от контекста, но значимы для языка.

В качестве примера предположим, что у вас есть следующий исходный код

 а = б * 2
 

Лексирование предоставит список токенов, очень похожий на:

 IDENTIFIER("a")
ОПЕРАНД("=")
ИДЕНТИФИКАТОР("б")
ОПЕРАНД("*")
ЦЕЛОЕ ЧИСЛО(2)
 

В качестве более сложного примера предположим, что вы лексицировали следующий код в стиле Ruby.

 по умолчанию добавить (х, у)
  х + у
конец
 

Результат лексера будет выглядеть примерно так:

 KEYWORD("def")
ИДЕНТИФИКАТОР("добавить")
ЛПАРЕН("(")
ИДЕНТИФИКАТОР("х")
ЗАПЯТАЯ(",")
ИДЕНТИФИКАТОР("у")
СРАВН ("")")
ИДЕНТИФИКАТОР("х")
ОПЕРАНД("+")
ИДЕНТИФИКАТОР("у")
КЛЮЧЕВОЕ СЛОВО("конец")
 

Здесь важно отметить, что токены очень общие и предоставляют только самую основную информацию о каждом токене. В задачу лексера не входит определение правильности синтаксиса, и во многих случаях единственные ошибки, которые выдает лексер, — это обнаружение символа, который он не знает, как обрабатывать, или неожиданного маркера EOF при токенизации таких вещей, как струны.

В то время как лексеры для большинства языков программирования не имеют состояния, читая ввод и обрабатывая каждый символ, механизмам шаблонов, таким как Late, для правильной работы требуется немного состояния. Механизмы шаблонов ожидают, что сам код шаблона будет вторичным по отношению к основному содержанию ввода. Таким образом, лексер должен с радостью принимать что угодно до момента достижения токена «открытого кода» (в Liquid и Late это будет 9).0109 {{

или {% ). Однако нам нужно сохранить непоздний код для создания окончательного файла, поэтому весь непоздний код токенизируется в специальные токены RAW.

Вы можете увидеть, как это реализовано в пакете шаблона/лексера Late. Теперь, когда наш список токенов готов, пришло время перейти к синтаксическому анализатору и придать этим токенам значение.

Синтаксический анализ и AST

Синтаксический анализ — это то, где мы берем список токенов из лексера и создаем структуру, которая придает входным данным действенное значение. Для большинства языков, включая Late, структура, которую мы создаем, называется абстрактным синтаксическим деревом или AST. Использование древовидной структуры (в частности, двоичного дерева, в котором каждый узел имеет не более двух дочерних элементов) является эффективным, поскольку позволяет нам кодировать не только порядок выполнения операций, но и приоритет операций в одной и той же структуре (гарантируя, что

2 + 3 * 5 это 17 а не 25). Кроме того, древовидные структуры легко повторяются с использованием хорошо известных алгоритмов, что упрощает реализацию этапа оценки.

Синтаксический анализ — это обширная тема, исследование которой проводилось в течение многих десятилетий. Недавно я столкнулся с подробной историей анализа временной шкалы, которая может дать вам представление о глубине и широте этой темы. Слишком много всего, чтобы попытаться охватить в одном посте в блоге, поэтому сегодня я собираюсь рассказать, как парсер Late работает на высоком уровне. Полную информацию вы можете увидеть на parser.go. Здесь много всего, поэтому мы будем делать это шаг за шагом.

Создание синтаксического анализатора для обработки сложных языков может показаться серьезной задачей, но, как и все остальное с компиляторами, мы можем начать с самой простой точки и постепенно усложнять ее. Начнем с двух определений: Expression и Statement. Выражения приводят к значениям (например,

1 , "this" и 1 + 2 ), в то время как операторы, в случае Лейта, представляют собой то, как мы отслеживаем необработанный ввод: переменные ( {{ }} ) и теги ( {% %} ). При этом мы начинаем с разбора литеральных выражений (тех, которые оцениваются сами по себе): строк, чисел, идентификаторов и логических значений. Когда синтаксический анализатор видит эти токены от лексера, он применяет однозначное сопоставление от токена лексера к соответствующему узлу AST. См. parseIdentifier , parseNumberLiteral , parseStringLiteral и parseBooleanLiteral для получения подробной информации.

Теперь мы можем перейти к простым составным выражениям, таким как 1 + 2 . Важно рассматривать этот фрагмент кода не как «число + число», а как «выражение оператора выражения». Именно здесь в игру вступает рекурсия, и именно поэтому этот тип синтаксического анализатора называется Recursive Decent. Чтобы обработать этот код, мы проходим через токены, анализируя выражения по мере их появления и заканчивая их связыванием вместе с оператором. Благодаря этому мы получаем AST, который выглядит так:

Как только это заработает, расширение для разбора других выражений станет проще. Например, возьмем 1 + 2 + 3 + 4 . Вы можете задаться вопросом, должны ли синтаксический анализатор иметь случаи для обработки определенного количества связанных операторов. К счастью, это не требуется, так как каждое операторное выражение может быть представлено в виде дерева [левое выражение]-[оператор]-[правое выражение]. Для этого берем выражение по одному оператору: 1 + 2 , затем добавляем + 3 , а затем + 4 . При явной группировке выражение выглядит так: (((1 + 2) + 3) + 4) парсер дает нам следующий AST:

Теперь все становится немного сложнее, когда дело доходит до оператора приоритет. С чистым синтаксическим анализатором слева направо оператор 1 + 2 * 3 будет проанализирован и оценен как 9 (например, (1 + 2) * 3 ), по сравнению с применением правил математики и приоритета оператора. , в котором правильный ответ 7 (например, 1 + (2 * 3) ). Существует много доступных алгоритмов для обработки приоритета операторов, и он является источником многих исследований синтаксических анализаторов. Поздний, по рекомендации в книге Торстена, использует синтаксический анализатор Пратта, чтобы справиться с этим. Хотя этот тип синтаксического анализатора гораздо проще объяснить и реализовать, чем многие другие, его все же слишком много, чтобы охватить его здесь. Я расскажу подробнее в следующей записи блога, а пока вот ядро ​​парсера Pratt:

  • Каждому оператору дается уровень приоритета, где большее число означает больший приоритет (например, 9).0109 * > + )
  • Каждый входной токен связан с «префиксной» функцией ( -a ), «инфиксной» функцией ( 1 + 2 ) или обеими ( [ в определении [1,2,3] и доступ к массиву [1] ).
  • Синтаксический анализ начинается с заданного приоритета, обычно самого низкого из возможных, и перебирает токены, пока не найдет конец выражения или токен с более низким приоритетом, чем текущий.

Эти три правила делают синтаксический анализатор удивительно простым, но мощным. Всю логику для этого можно найти в parseExpression , и я более подробно расскажу о том, как все это работает, в следующем посте.

При наличии всего вышеперечисленного синтаксический анализ более сложных выражений, особенно сильно вложенных выражений, таких как [1, 1 + 1, "три", [1, 2, 3, "четыре"][3]] становится автоматическим . Синтаксический анализатор увидит этот ввод как не более чем [выражение, выражение, выражение, выражение] , а рекурсия позаботится обо всем остальном. Вы можете увидеть, как это происходит в parseArrayLiteral 9.0110 , где мы обрабатываем пустой случай [] , одноэлементные массивы [1] , а затем многоэлементные массивы примерно в 15 строках кода.

Синтаксический анализатор просматривает весь список токенов, создавая AST для каждой секции Late. Пришло время оценить эти деревья и вернуть результаты!

Компиляция и оценка

Третий шаг цепочки инструментов может варьироваться от почти тривиального (повторение и оценка AST) до сложного (генерация оптимизированного машинного кода для максимально быстрого выполнения), но точно так же, как и остальная часть этого статье, изучение того, как обрабатывать AST, сгенерированные синтаксическим анализатором, начинается с самых простых шагов. Работаете ли вы над оценщиком языка шаблонов, языковым интерпретатором (например, Ruby до 1.9), или полностью компилируя в машинный код, важно начать как можно проще и меньше. Сложность будет приходить сама собой, если вы сосредоточитесь на построении небольших простых шагов к своей цели. Помните, что LLVM не сразу появился таким гигантом, каким он является сегодня. LLVM разрабатывался более пятнадцати лет (первый официальный документ был опубликован в 2002 году) и уже тогда основывался на десятилетиях исследований и знаний о компиляторах, которые были до него.

С Late и большинством языков шаблонов мы не создаем полноценный язык программирования, который дает нам большую свободу действий в реализации этого последнего шага. Кроме того, поскольку шаблоны — это инструмент оценки за один проход, скорость выполнения не является супервысоким приоритетом, поэтому для начала стоит сосредоточиться на самой простой и удобочитаемой реализации. Таким образом, оценщик Late просматривает каждый AST с помощью алгоритма поиска в глубину, используя большой switch , чтобы знать, как обращаться с каждым типом узла AST. Вы можете увидеть это в функции eval на сайте evaluator.go. Глубина-сначала означает, что мы итерируем по дереву, переходя к дочерним узлам и оценивая сначала от абсолютного низа дерева. Затем эти результаты распространяются обратно вверх по дереву, и когда мы возвращаемся к корню дерева, мы знаем, что оценка для этого дерева выполнена. Вот наглядное изображение того, как это работает для 1 + 2 + 3 + 4 :

После оценки каждого дерева результаты объединяются обратно в одну строку и возвращаются в виде выходного документа. Эту логику можно найти в template.go, который связывает весь процесс воедино.

Последняя часть, необходимая для понимания оценки Late, — это то, как она обрабатывает значения и данные, которые пользователи захотят использовать и предоставлять в своих шаблонах. Late имеет простую модель данных с динамическим типом, в которой переменная может содержать данные любого типа, а массив может содержать любое сочетание переменных, например [1, "два", [3]] ).

admin

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *