Упражнения по Компютърна лингвистика за специалност Информатика 4. курс, задочна и редовна форма на обучение.
при гл. ас. д-р инж. Георги Пашев
e-mail: georgepashev@uni-plovdiv.bg
Линк към Google Classroom на дисциплината: ( https://classroom.google.com/c/MTY4OTIzMzU0Njk0?cjc=rwht7yj )
Линк към теми за проекти от упражнения: (https://docs.google.com/document/d/1uEz3dke1fuo55sFK2Dp0hwc-MTDnt5lHjJaoo5ZdFwU/edit?usp=sharing)
Упражнения, теми:
Упражнение 1: Крайни автомати
1. Създайте парсър на удобен за вас програмен език (на упр. ще бъде показан пример с езика PHP), който да имплементира краен автомат, който се подава като параметър на парсващата функция/процедура, заедно с текст за парсване и връща информация дали текстът е парснат успешно (отговаря на крайния автомат), или не.
2. Използвайки 1, създайте краен автомат, който да парсва изречения от този тип:
ab, aabb, abbb, aaaab, .... (променлив брой a...b...)
3. Използвайки 1, създайте парсър на дата във формат "DD.MM.YYг.".
Упражнение 2: Регулярни изрази
1. Като използвате помощния файл за упражненията и др. материали онлайн, запознайте се със синтаксиса на регулярните изрази.
2. Запознайте се с PHP функции preg_match, preg_match_all, preg_replace.
3. Като използвате preg_match_all, напишете PHP скрипт, който намира в текст всички дати във формат DD.MM.YYYY, като отделя дните, месеците и годините в подходящи подмасиви и генерира изходящ текст от рода:
Намерена е дата 15.01.2018г, денят е 15 подред на месец 01 от година 2018г.
4. Като използвате някои от функциите, напишете PHP скрипт, който намира в текст всички дати във формат DD.MM.YYYY, и генерира подобен на този текст, в който датите са в американски формат MM/DD/YYYY.
Например, текста:
На 24.09.2018г. се проведе упражнение по Компютърна лингвистика
да се превежда като
На 09/24/2018г. се проведе упражнение по Компютърна лингвистика
5. Напишете PHP скрипт, който намира в текст всички URL адреси по http/https/ftp адресна схема и ги показва в списък.
Задача: крос транслиране на командни компютърни езици с регулярни изрази. Примерен крос транслатор може да свалите от тук:
https://www.dropbox.com/s/znhxozltwq30kxe/translator.php?dl=0
Упражнение 3. Контекстно независими граматики
Използва се инструмента Grammophone, линк към който може да намерите в помощния файл за упражненията по-долу.
1. Решете задачите от темата за Контекстно независими граматики в помощния файл.
2. Допълнителни задачи:
2.1. Напишете контекстно независима граматика, която да парсва успешно програмен текст на "мини програмен език" (който за целта на упражненията ще бъде наречен PeUScript), на който е написан следния пример:
def A=0 as Int
def B=12.0 as Float
def I=0 as Int
while I<100 or not A>7000 do
print "Stojnostta na I e "+I+"\n"
A=I+B
I=I+1
print "Stojnostta na B e"+B+"\n"
if B <> 12.0 then
break
endif
done
2.2. Напишете с помощта на езици PHP и Javascript (или други удобни за вас) кространслатор и среда на изпълнение на PeUScript , като първо преведете програмния текст на Javascript и стартирайте така получения JavaScript код в браузъра.
Примерен проект за Bison & Flex (инсталирани в Линукс/Убунту програмна среда): Свали от тук
Виртуална машина за VirtualBox с готови инсталирани пакети за работа свалете от тук:
https://www.dropbox.com/s/ipki0tirv9qn2z1/xubuntu.rar?dl=0
Компилацията се извършва с последователно извикване на командите:
flex -o calc.flex.cc calc.lex
bison calc.yy
cc -fpermissive calc.tab.cc calc.flex.cc -Wall -lm -o rpccalc
Еквиваленти на BISON и FLEX за други езици и програмни среди:
1. Parsimonious за Python
За употреба на пакета се изисква Python конзола. Портативен (portable) вариант за Windows на такава с предварително инсталиран пакет на Parsimonious може да изтеглите от тук:
(https://www.dropbox.com/s/v96u1wpgi8q4p3g/Portable%20Python%203.7.0%20x64.rar?dl=0)
Работещ пример на елементарна граматика за инструмента:
from parsimonious.grammar import Grammar
grammar = Grammar(
"""
bold_text = bold_open text bold_close
text = ~"[A-Z 0-9]*"i
bold_open = "(("
bold_close = "))"
""")
print(grammar.parse('((bold stuff))'))
Конзолата на Python се стартира от разархивирания архив от папката: App\Python и файла е python.exe
При нужда от инсталация на допълнителен пакет в папката App\Python се стартира Windows конзола и се изпълнява командата:
python -m pip install <package name>
Пример, парсващ елементарен израз:
from parsimonious.grammar import Grammar
grammar = Grammar(
"""
exps = exp op exp
exp = num / expparen
expparen = lparen num rparen
op = ~"[\+\-]"i
lparen = "("
rparen = ")"
num = ~"[0-9]+"i
""")
print(grammar.parse('12+23'))
2. PLY за Python (напълно функционален заместител на bison/flex)
2.1. Инсталирайте PLY в конзолата с изпълнение на командата в командната конзола:
python -m pip install ply
2.2. Създайте в директорията App\Python файл calclex.py, със следното съдържание:
# ------------------------------------------------------------
# calclex.py
#
# tokenizer for a simple expression evaluator for
# numbers and +,-,*,/
# ------------------------------------------------------------
import ply.lex as lex
# List of token names. This is always required
tokens = (
'NUMBER',
'PLUS',
'MINUS',
'TIMES',
'DIVIDE',
'LPAREN',
'RPAREN',
)
# Regular expression rules for simple tokens
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_LPAREN = r'\('
t_RPAREN = r'\)'
# A regular expression rule with some action code
def t_NUMBER(t):
r'\d+'
t.value = int(t.value)
return t
# Define a rule so we can track line numbers
def t_newline(t):
r'\n+'
t.lexer.lineno += len(t.value)
# A string containing ignored characters (spaces and tabs)
t_ignore = ' \t'
# Error handling rule
def t_error(t):
print("Illegal character '%s'" % t.value[0])
t.lexer.skip(1)
# Build the lexer
lexer = lex.lex()
2.3 Създайте в директорията App\Python файл yacc.py, със следното съдържание:
# Yacc example
import ply.yacc as yacc
# Get the token map from the lexer. This is required.
from calclex import tokens
def p_expression_plus(p):
'expression : expression PLUS term'
p[0] = p[1] + p[3]
def p_expression_minus(p):
'expression : expression MINUS term'
p[0] = p[1] - p[3]
def p_expression_term(p):
'expression : term'
p[0] = p[1]
def p_term_times(p):
'term : term TIMES factor'
p[0] = p[1] * p[3]
def p_term_div(p):
'term : term DIVIDE factor'
p[0] = p[1] / p[3]
def p_term_factor(p):
'term : factor'
p[0] = p[1]
def p_factor_num(p):
'factor : NUMBER'
p[0] = p[1]
def p_factor_expr(p):
'factor : LPAREN expression RPAREN'
p[0] = p[2]
# Error rule for syntax errors
def p_error(p):
print("Syntax error in input!")
# Build the parser
parser = yacc.yacc()
while True:
try:
s = input('calc > ')
except EOFError:
break
if not s: continue
result = parser.parse(s)
print(result)
2.4. Стартирайте парсъра с изпълнение на Windows конзолната команда:
python yacc.py
4. Търсене на отношение в текст
Да се състави алгоритъм (и да се имплементира на PHP), който автоматизирано намира отношения на пишещия към търсени термини в текста, като се създадат примерни речници:
Алгоритъмът да е достатъчно съобразителен, за да открива инвесии (напр. чрез откриване на ключова дума "не").
Примерно решение тук: [https://www.dropbox.com/s/uw5hoaxmepnoztp/analizator_otnoshenie.php?dl=0]
5. Чат ботове
Примерен чат бот, разработван по време на упражненията, който умее да прави изводи спрямо PROLOG базирана база знания:
http://gp.gpashev.com:93/CrossTranslatorWeb/indexPrologBot.php
(Изходния код се предоставя по време на упражненията).
Помощен файл за упражненията свалете от тук
fulltext