A1 = Split(InputFile, vbCrLf) 'Если для разделения строк используем новую строку. Или:
A1 = Split(InputFile, ";") ' Для паскалеподобного синтаксиса.
Поприветствовать_мир
Записать_в_реестр HKCU Software\MySoft\Main LastUser Вася
Сумма 2 + 3
Показать_итог
Вывести_сообщение Заголовок vbOKOnly "Не знаю как, но парсер должен уметь обрабатывать строки, содержащие пробелы"
Запустить Calc.exe
'Для второй строки скрипта в массиве A2 например, будет лежать:
' 0 1 2 3 4
'"Записать_в_реестр", "HKCU", "Software\MySoft\Main", "LastUser", "Вася"
Select Case A2(0)
Case "Записать_в_реестр": Call Reeesr.Add(A2(1), A2(2), A2(3), A2(4)) 'делаем так
Case "Поприветствовать_мир": MsgBox("Hello world!")
Case "Вывести_сообщение": MsgBox A2(1), A2(2), A2(3)
Case "Сумма": Ret = A2(1) + A2(3)
case "Показать_итог": MsgBox Ret
Case "Запустить": Shell A2(1), vbNormalFocus
end Select
hclubmk писал(а):А чем не устраивают существующие скриптовые интерпретаторы (VBScript, AutoIt и т.п.)?
HAI
GIV MI PWEASE Y SISTEM DIR
IMMA IN Y SISTEM DELETIN Y FILES
BYE
Хакер писал(а):а «пример того, как никогда не стоит писать парсер».
Денис писал(а):hclubmk писал(а):А чем не устраивают существующие скриптовые интерпретаторы (VBScript, AutoIt и т.п.)?
Может с него требуют именно свой?
Хакер писал(а):Никто не разбирает текст, код с помощью сплитов и лефт-стрингов. Это сродни пайки тонкой электронике раскалённым в костре гвоздём.
Или ещё одна шиза: использование регулярных выражений для этой цели.
Хакер писал(а):Никто не разбирает текст, код с помощью сплитов и лефт-стрингов. Это сродни пайки тонкой электронике раскалённым в костре гвоздём.
Или ещё одна шиза: использование регулярных выражений для этой цели.
Хакер писал(а):Денис, за свой троллизм ты, наверное, будешь скоро наказан.
Кстати, давно мучает любопытство: как стоит писать интерпретатор? А именно — как оптимизировать блоки ветвления, многократно выполняемые в циклах? Например, такие:Хакер писал(а):Пример того, как не стоит писать парсер.
Насколько я понимаю, сии штуки организуются с помощью таблицы переходов, и что некоторые компиляторы — например, C# — создают подобные конструкции автоматически, но в VB.Net и тем более в старых версиях VB этого не предусмотрено. Можно ли провернуть такой фокус вручную?Денис писал(а):
- Код: Выделить всё
Do While тра-та-та
Select Case A2(0)
Case "Записать_в_реестр": Call Reeesr.Add(A2(1), A2(2), A2(3), A2(4)) 'делаем так
Case "Поприветствовать_мир": MsgBox("Hello world!")
Case "Вывести_сообщение": MsgBox A2(1), A2(2), A2(3)
Case "Сумма": Ret = A2(1) + A2(3)
Case "Показать_итог": MsgBox Ret
Case "Запустить": Shell A2(1), vbNormalFocus
End Select
Loop
Samsonov писал(а):Но возникает проблема, как обеспечить этим функциям доступ к внутренним данным текущей функции — ведь в каждом случае требуются разные переменные и разное их количество.
Вот что меня взбесило в ответах Хакера, так это то, что Автор топика попросил простой интерпретатор нескольких команд установки, копирования, распаковки. Линейный. Одноклеточный. Я ему дал такой алгоритм. Простой одноразовый проход по телу скрипта, со строго регламентированным синтаксисом (ключевое_слово параметр1 .. параметрN)
// И выходим из функции FIRST, возвращая 0 } function SECOND() { while(bTruncated) { AsrLockThisItem()
alibek писал(а):Про оптимизацию можно думать потом, когда будут написаны конечные автоматы.Samsonov писал(а):Как оптимизировать блоки ветвления, многократно выполняемые в циклах?
Мой вопрос касался конкретно того, про что я писал, — как оптимизировать блок Select Case, если все условия имеют форму сравнения с константой. Ни про что другое я не спрашивал.Денис писал(а):«Разные переменные и разное их количество» не соответствуют принципу конечного автомата.Samsonov писал(а):Но возникает проблема, как обеспечить этим функциям доступ к внутренним данным текущей функции — ведь в каждом случае требуются разные переменные и разное их количество.
Select Case strCmd
Case "Записать_в_реестр": WriteReg
Case "Поприветствовать_мир": MsgBox "Hello world!"
Case "Вывести_сообщение": MsgBox A2(1), A2(2), A2(3)
Case "Сумма": Ret = A2(1) + A2(3)
Case "Показать_итог": MsgBox Ret
Case "Запустить": Shell A2(1), vbNormalFocus
Case Else: MsgBox "Неизвестная команда"
End Select
If strCmd = "Записать_в_реестр" Then
WriteReg
ElseIf strCmd = "Поприветствовать_мир" Then
MsgBox "Hello world!"
ElseIf strCmd = "Вывести_сообщение" Then
MsgBox A2(1), A2(2), A2(3)
ElseIf strCmd = "Сумма" Then
Ret = A2(1) + A2(3)
ElseIf strCmd = "Показать_итог" Then
MsgBox Ret
ElseIf strCmd = "Запустить" Then
Shell A2(1), vbNormalFocus
Else
MsgBox "Неизвестная команда"
End If
Dim dicJumpTable As New Dictionary(Of String, Integer)
dicJumpTable.Add("Записать_в_реестр", 10)
dicJumpTable.Add("Поприветствовать_мир", 20)
dicJumpTable.Add("Вывести_сообщение", 30)
dicJumpTable.Add("Сумма", 40)
dicJumpTable.Add("Показать_итог", 50)
dicJumpTable.Add("Запустить", 60)
Do While тра-та-та
If dicJumpTable.ContainsKey(strCmd) Then
GoSub dicJumpTable.Item(strCmd)
Else
MsgBox "Неизвестная команда"
End If
Loop
Exit Sub
10: WriteReg: Return
20: MsgBox "Hello world!": Return
30: MsgBox A2(1), A2(2), A2(3): Return
40: Ret = A2(1) + A2(3): Return
50: MsgBox Ret: Return
60: Shell A2(1), vbNormalFocus: Return
Хакер писал(а):Вот для такого случая и был мой ответ. В этом случае использовать сплит и Left$ — идиотизм.
Samsonov писал(а):компилируется в нечто вроде такого:
Debugger писал(а):А как сделать правильно?
SLIM писал(а):Samsonov писал(а):компилируется в нечто вроде такого:
Ты думаешь это реально так?
Хакер писал(а):Debugger писал(а):Хакер писал(а):Вот для такого случая и был мой ответ. В этом случае использовать сплит и Left$ — идиотизм
А как сделать правильно?
«Преобразователь» на вход получает одну последовательность, на выход вываливает вторую. Второй (если нужен) «преобразователь» получает на вход первую, на выходе выдаёт третью. И так, пока не получится «удобоваримая» последовательность.
Хакер писал(а): Я уже давно сделал для себя технологию, в соответствии с которой динамически строится граф из кусочков кода
Сейчас этот форум просматривают: AhrefsBot, Yandex-бот и гости: 4