Conversation
ArtyomLobanov
left a comment
There was a problem hiding this comment.
- Добавьте интеграцию с Travis
- Обрабатывайте ошибки аккуратнее.
cat fghjftgh | wc
выводит информацию о количестве строк/слов/байт в сообщении об ошибке, а пользователь так и не узнает, что опечатался в имени файла. Не стесняйтесь кидать исключения. Их не просто так придумали. - На одинокий пайп в конце команды интерпретатор не ругается.
cat f.txt |
| } | ||
|
|
||
| dependencies { | ||
| compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8" |
| repositories { | ||
| mavenCentral() | ||
| } | ||
|
|
There was a problem hiding this comment.
Собирающийся jar файл нельзя запустить т.к. не указана точка входа в программу
|
|
||
| private var state = Identifier | ||
| private var sb = StringBuilder() | ||
| private var vsb = StringBuilder() |
There was a problem hiding this comment.
Не очень говорящие названия. Называть переменные лучше по их смыслу, а не типу.
There was a problem hiding this comment.
У них смысл строки собирать, что поделать, чисто утилитарные штуки. Названия лучше я не придумал, но расписал подробнее хоть
|
|
||
| fun isIdentifier(c: Char): Char = if (c in 'a'..'z' || c in 'z'..'Z' || c == '_' || c == '-') c else '_' | ||
|
|
||
| fun isDigit(c: Char): Char = if (c in '0'..'9') c else '0' |
There was a problem hiding this comment.
А почему метод, начинающийся на is, возвращает не boolean?
There was a problem hiding this comment.
Для матча, переименовал is в match
| } catch (e: Exception) { | ||
| output.write("cat: ${e.message}") | ||
| } | ||
| output.write("\n") |
| private fun startProcess(process: Process, output: PipedWriter) { | ||
| val streamGobbler = StreamGobbler(process.inputStream) { s -> output.write("$s\n") } | ||
| val errorGobbler = StreamGobbler(process.errorStream) { s -> output.write("$s\n") } | ||
| val executor = Executors.newSingleThreadExecutor() |
There was a problem hiding this comment.
Что-то как-то вы тут всё усложнили. Это было необходимо? В любом случае, Executor надо завершать
There was a problem hiding this comment.
Я, естественно, не знал от рождения, как на джаве запускать команды кроссплатформенно, поэтому такое решение нагуглил
| val result = WCResult() | ||
| input.forEachLine { | ||
| result.lines++ | ||
| result.words += it.split(' ').size |
There was a problem hiding this comment.
Плохой разделитель. Подумайте, когда это приводит к ошибкам.
| input.forEachLine { | ||
| result.lines++ | ||
| result.words += it.split(' ').size | ||
| result.bytes += it.toByteArray().size |
bash/README.md
Outdated
|
|
||
| Сначала строка из stdin попадает в парсер, где разбивается на токены | ||
|
|
||
| Оттуда токены передаются в лексер вместе с окружением, где по пайпам токены делятся на команды: первый токен - имя, остальные - аргументы |
There was a problem hiding this comment.
Как-то у вас всё с ног на голову перевернулось. Обычно лексер разбивает текст на маркированные токены, а парсер строит AST. Я бы у вас названия местами поменял.
There was a problem hiding this comment.
Мой мир перевернулся, почему-то у меня до этого успело сложиться впечатление, что я всё называю своими именами, а тут вот как. Хотя по факту можно и то и другое парсером назвать, но всё же лексер более подходит
| } | ||
| } | ||
|
|
||
| private fun makeFlow(commands: ArrayList<Command>) = |
There was a problem hiding this comment.
Мы же хотим расширяемую и поддерживаемую архитектуру? Давайте создадим отдельный класс Интерпретатор, который будет содержать всю эту логику, а на вход принимать лексер, парсер и, например, входной и выходной потоки. Это позволит в будущем легко подменять налету отдельные части интерпретатора, создавать подпроцессы и т.д.
| throw Exception("wc: ${e.message}" + System.lineSeparator()) | ||
| } | ||
| } | ||
| output.write("${result.lines} ${result.words} ${result.bytes} total" + System.lineSeparator()) |
There was a problem hiding this comment.
Всегда выводит 0 0 0 т.к. переменная result нигде не модифицируется
| val result = WCResult() | ||
| input.forEachLine { | ||
| result.lines++ | ||
| result.words += it.split(Regex("\\s+")).size |
There was a problem hiding this comment.
Теперь другая проблема: " some text ".split("\\s+") вернёт ["", "some", "text"]
| input.forEachLine { | ||
| result.lines++ | ||
| result.words += it.split(Regex("\\s+")).size | ||
| result.bytes += (it + System.lineSeparator()).toByteArray().size |
There was a problem hiding this comment.
У последней строки может и не быть перевода строки. Для определения размера файла есть стандартные методы. Например, File.length Не надо изобретать велосипед.
| private fun calcInput(input: Reader): WCResult { | ||
| val result = WCResult() | ||
| val text = input.readText() | ||
| result.lines = text.split("\r\n|\r|\n").size |
There was a problem hiding this comment.
| val executor = Executors.newSingleThreadExecutor() | ||
| executor.submit(streamGobbler) | ||
| executor.submit(errorGobbler) | ||
| executor.shutdown() |
There was a problem hiding this comment.
Теперь внешние команды вообще не запускаются. Вы хоть тестируйте, прежде чем пушить в репозиторий.
Я предлагал просто использовать waitFor без аргументов
There was a problem hiding this comment.
Ссори, постараюсь ответственнее относиться к этому
|
@ArtyomLobanov починил |
|
Ок. @yurii-litvinov |
| import java.io.PipedWriter | ||
|
|
||
|
|
||
| class Controller(val exceptionHandler: (Exception) -> Unit) { |
There was a problem hiding this comment.
Вообще, каждому классу нужны комментарии
Парсер и команды в чём-то имеют несколько другую семантику, но, судя по заданию, это не страшно