Wiki

Clone wiki

MindStream / Статьи на русском / Устройство скриптовой машины / Описание формата скриптов

1.Пример парсера лежит тут - mindstream\Scripting\Script.Parser.pas. Его надо брать за основу.

2.Реализованный парсер конечно же есть. И не один. Но мы будем писать НОВЫЙ.Тому есть много ВЕСКИХ причин.

3.Токен - базовый элемент грамматики языка.

4.Все "токены" разделяются пробелами или табуляциями. Или новой строкой (#13#10 или #10 или #13). Пример:

  1. A B C - три токена - A B C
  2. A B + - три токена - A B +
  3. A B+ - два токена - A B+
  4. A+ B - два токена - A+ B
  5. A+B - один токен - A+B
  6. Сначала парсер бъёт входной поток по пробелам или новым строкам, а потом только анализирует содержимое полученных токенов.

5.Токен // - определяет строковый комментарий. Парсер должен пропустить все символы от // до конца строки (#13#10 или #10 или #13).

6.Токен /* - определяет блочный комментарий. Парсер должен пропустить все символы от /* до */.

6.1.AA /* somecoment */ -> токен АА

6.2.AA /* somecoment */ BB -> 2 токена АА BB

6.3.

AA /* some
coment */ 
BB
-> токены AA BB

6.4.

AA /* some
coment
-> токен AA

6.5.

A /* // somecoment */
B 
-> токены A B

6.6.A // /* somecoment */ -> токен A

6.7.

A /* // somecoment 
*/ B 
-> токены A B

6.8.

A /* 
// somecoment  */ B 
-> токен A

6.9.

A /* // somecoment 
*/ B // C 
-> токены A B

6.10.

A // /* somecoment 
*/ B // C 
-> токены A */ B

6.11.

A /* somecoment
XXX
YYY
XXX 
*/ B // C 
-> токены A B

6.12.

A /* somecoment
XXX
YYY
*/ B /* XXX */ C 
-> токены A B C

6.13.

A /* somecoment
XXX
YYY
*/ B /* XXX 
YYY */ C
-> токены A B C

6.14.

/* somecoment */ A 
-> токен A

6.15.

/* somecoment */ A /* somecoment */ 
-> токен A

6.16.

/* somecoment */ A /* somecoment */ B 
-> токены A B

7.Токен false - представляет собой булевское значение false.

7.1. A false -> -> токены A false

7.2.

A /*
false */ B
false
-> токены A B false

8.Токен true - представляет собой булевское значение true.

9.Конструкция вида [x] далее означает повторение значения x от 0 до N. Где x - может принимать ЛЮБОЕ значение. К токенам это не относится. Это скажем так - мета-язык для описания токенов. - Также договоримся, что a - это символ, а N - цифра.

10.Токен вида '[a]' - представляет собою строку. a - может быть ЛЮБЫМ сиволом кроме ', включая #13 и #10. Пример:

  • 'abc' - строка abc.
  • 'abc d' - строка abc d.

'ab 
c'
-> строка abc#13#10c.

'ab
qwe qwe
qwe qwe
c'
-> строка ab#13#10qwe qwe#13#10qwe qwe#13#10c

11.Поддчеркну! Строки бывают МНОГОСТРОЧНЫМИ. Как в примере выше.

12.Токен вида [[#[N]]['[a]'][#[N]]] - также даёт строку. Пример:

  1. #12#13#14 - даёт строку #12#13#14.
  2. #12#13#14'a' - даёт строку #12#13#14a.
  3. #12#13#14'ab' - даёт строку #12#13#14ab.
  4. #12#13#14'ab'#15 - даёт строку #12#13#14ab#15.
  5. #12#13#14'ab'#15'cd' - даёт строку #12#13#14ab#15cd.
  6. #12#13'abc<тут разрыв>def'#14#15 - дает 2 строки #12#13abc и def#14#15
  7. #32 - дает строку
  8. #65 - дает строку a
  9. #33 - дает строку !

13.Токен вида '[''][a]['']' - даёт строку с кавычками. Примеры:

  1. '''' - даёт строку '.
  2. '''''' - даёт строку ''.
  3. '''a''' - даёт строку 'a'.
  4. 'a''' - даёт строку a'.
  5. '''a' - даёт строку 'a.

14.Договоримся, что конструкция вида (x) - далее означает повторение значения x от 1 до N.

15.Токен вида (N) - даёт НЕОТРИЦАТЕЛЬНОЕ число. Пример:

  1. 1 - число 1.
  2. 2 - число 2.
  3. 0 - число 0.
  4. 20 - число 20.
  5. 200 - число 200.

16.Токен вида -(N) - даёт НЕПОЛОЖИТЕЛЬНОЕ число. МИНУС от числа отрываться НЕ МОЖЕТ. -1 - валидное число, а - 1 - невалидное. Это ДВА токена - - и 1. Пример:

  1. -1 - число -1.
  2. -2 - число -2.
  3. -0 - число 0.
  4. -20 - число -20.
  5. -200 - число -200.
  6. - 2 - токен - и число 2.

17.Токен вида $(H) (где H шестнадцатиричная цифра от 0 до F) - даёт НЕОТРИЦАТЕЛЬНОЕ шестнадцаттричное число. Пример:

  1. $0 - число 0.
  2. $1 - число 1.
  3. $2 - число 2.
  4. $A - число 10.
  5. $F - число 15.
  6. $10 - число 16.
  7. $FF - число 255.
  8. $ A - 2 токена $ и A
  9. Отрицательных нестнадцатиричных чисел - НЕ БЫВАЕТ. -$(H) -НЕВАЛИДНЫЙ ТОКЕН.

18.Токен вида #$(H) - даёт символ в шестнадцатиричном представлении. Ну и далее по индукции со строками. Пример:

  1. #$0 - строка 0.
  2. #$A - строка #10.
  3. #$D - строка #13.
  4. #$D'a' - строка #13a.
  5. 'a'#$D - строка a#13.
  6. ''''#$D - строка '#13.
  7. #$D'''' - строка #13'.

19.Токен вида "[a]" - представляет собой ИДЕНТИФИКАТОР. Идентификатор может включать в себя пробелы и #13 и #10. Идентификаторы - РЕГИСТРОЗАВИСИМЫЕ. Кавычка " - ВКЛЮЧАЕТСЯ в имя идентификатора. Идентификатор означает САМ СЕБЯ. Пример:

  • "" - идентификатор "".
  • "a" - идентификатор "a".
  • "ab" - идентификатор "ab".
  • "a+b" - идентификатор "a+b".
  • "a+A" - идентификатор "a+A".
  • "a
  • b" - идентификатор "a#13#10b".
  • "a
  • b
  • c" - идентификатор "a#13#10b#13#10c".

20.Итак - ПОКА у нас есть строки, числа, булевские значения и идентификаторы.

21.Далее есть "специальные конструкции". Пока к делу не относящиеся.

22.Перечислим их.

23.Конструкция USES [Token] ; - означает использование словарей (от 0 до N). Token - это ЛЮБОЙ валидный токен определённый выше КРОМЕ чисел и булевских значений. Пока должна скиповаться. Примеры:

  • USES A ;.
  • USES A B ;.
  • USES A B 'C' ;.

  • USES A

  • B
  • C ;.

  • USES A

  • B
  • 'C' ;.
  • USES A
  • B
  • "C" ;.

  • USES ;.

  • USES

  • ;.

24.Конструкция INCLUDE String - означает использования словаря. Ровно ОДНОГО. Пока должна скиповаться. Примеры:

  • INCLUDE 'a'.
  • INCLUDE 'ab'.
  • INCLUDE 'a'#13#10.

  • INCLUDE 'a

  • '.

  • INCLUDE $A.

25.Конструкция CONST Identifier Value - означает определение константы. Identifier - валидный идентификатор вида [a] или "[a]". Value - значение константы. Строка, булевское true или false, число. Другая константа (определённая ранее). Примеры:

  1. CONST A 1 - константа с именем A и численным значением 1.
  2. CONST A 2 - константа с именем A и численным значением 2.
  3. CONST A 0 - константа с именем A и численным значением 0.
  4. CONST A -1 - константа с именем A и численным значением -1.
  5. CONST A $A - константа с именем A и численным значением 10.
  6. CONST A $FF - константа с именем A и численным значением 255.
  7. CONST "A" 1 - константа с именем "A" и численным значением 1.
  8. CONST "A" 2 - константа с именем "A" и численным значением 2.
  9. CONST "A" 0 - константа с именем "A" и численным значением 0.
  10. CONST "A" -1 - константа с именем "A" и численным значением -1.
  11. CONST A 'a' - константа с именем A и строковым значением a.
  12. CONST "A" 'a' - константа с именем "A" и строковым значением a.
  13. CONST A '' - константа с именем A и строковым значением (пусто).
  14. CONST "A" '' - константа с именем "A" и строковым значением (пусто).
  15. CONST A '''' - константа с именем A и строковым значением '.
  16. CONST "A" '''' - константа с именем "A" и строковым значением '.
  17. CONST A false - константа с именем A и булевым значением false.
  18. CONST "A" false - константа с именем "A" и булевым значением false.
  19. CONST A true - константа с именем A и булевым значением true.
  20. CONST "A" true - константа с именем "A" и булевым значением true.
  21. CONST A B - константа с именем A и значением ДРУГОЙ константы B.
  22. CONST "A" B - константа с именем "A" и значением ДРУГОЙ константы B.
  23. CONST A "B" - константа с именем A и значением ДРУГОЙ константы "B".
  24. CONST "A" "B" - константа с именем "A" и значением ДРУГОЙ константы "B".

26.Далее следуют определения слов. Устройство скриптовой машины. Вводная

27.Конструкция : Identifier - начинает определение слова.

28.Конструкция ; - заканчивает определение слова.

29.Конструкция ref; - заканчивает определение слова. Будем ПОКА считать, что это аналог конструкции ;. Примеры:

  1. : A ; - определяет слово A.
  2. : "A" ; - определяет слово "A".
  3. : A ref; - определяет слово A.
  4. : "A" ref; - определяет слово "A".
  5. : A : B ; ; - определяет слово A и вложенное слово B.
  6. : "A" : B ; ; - определяет слово "A" и вложенное слово B.
  7. : A : "B" ; ; - определяет слово A и вложенное слово "B".
  8. : "A" : "B" ; ; - определяет слово "A" и вложенное слово "B".
  9. : A CONST C 1 ; - определяет слово A и вложенную целочисленную константу C.
  10. : A CONST C 'a' ; - определяет слово A и вложенную строковую константу C.
  11. : A CONST C false ; - определяет слово A и вложенную булевскую константу C.

30.Конструкция FORWARD Identifier - "предварительно декларирует слово Identifier". Чтобы на него могли сослаться другие, зависимые от него слова. Примеры:

#!delphi 
    FORWARD A // - предварительно декларируем слово A
    ...
    : A
    ; // - определяем слово A
#!delphi 
    FORWARD "A" // - предварительно декларируем слово "A"
    ...
    : "A"
    ; // - определяем слово "A"
#!delphi    
    FORWARD "A B" // - предварительно декларируем слово "A B"
    ...
    : "A B"
    ; // - определяем слово "A B"
#!delphi    
    FORWARD A // - предварительно декларируем слово A
    : B
     A // - ссылаемся на слово A
    ; // - определяем слово B
    : A
    ; // - определяем слово A
31.Конструкция Seq: ( Identifier1 .. IdentifierN ) - определяет список ссылок на слова. Примеры:
#!delphi 
    : A
    ; // A
    : B
    ; // B
    : C
     Seq: ( A B ) // - список слов A и B
    ; // C
#!delphi 
    : A
     Seq: ( ) // - пустой список
    ; // A
#!delphi 
    : A
     Seq: () // - ТАКЖЕ пустой список
    ; // A
#!delphi    
    : A
    ; // A
    : B
    ; // B
    : C
     Seq: ( A 1 B ) // - список слов A, числа 1 и B
    ; // C
#!delphi    
    : A
    ; // A
    : B
    ; // B
    : C
     Seq: ( A 'a' B ) // - список слов A, строки a и B
    ; // C
#!delphi    
    : A
    ; // A
    : B
    ; // B
    : C
     Seq: ( A false B ) // - список слов A, булевского значения false и B
    ; // C
32.Конструкция WL String1 String2 - является "слабой ссылкой" на слово. Загружаемой OnDemand. String1 - имя слова. String2 - имя файла из которого надо загрузить слово. Файл String2 ищется в той же директории, что и наш исходный. Если не задан ПОЛНЫЙ путь к файлу. Если слово String1 не найдено в файле String2, то должен вернуться nil. Примеры:
#!delphi
    : A
      WL 'WordName' 'WordFile' // - ссылка на слово WordName из файла WordFile.
    ; // A
#!delphi
    : X1
    ; // X1 
    : A
      Seq: ( WL 'WordName' 'WordFile' // - ссылка на слово WordName из файла WordFile.
       X1 // - ссылка на слово X1 из НАШЕГО ЖЕ файла
      )
    ; // A
#!delphi
    : A
      WL 'WordName' 'c:\temp\WordFile' // - ссылка на слово WordName из файла c:\temp\WordFile по ПОЛНОМУ пути.
    ; // A
33.Все конструкции НЕ ОПИСАННЫЕ выше являются ОШИБОЧНЫМИ. Должны выдавать ОШИБКУ парсинга.

34.Теперь перечислим "предопределённые" вложенные слова. Это уже ближе к UML. Они определяются как вложенные слова вида:

  1. CONST XXX Value
  2. : Name Value ;
  3. : Name Seq: ( Ref1 .. RefN ) ;

35.Children - вложеные дети элемента модели.

35a.Constants - вложеные константы элемента модели.

36.Attributes - атрибуты элемента модели.

37.Operations - операции элемента модели.

38.Dependencies - исходящие связи элемента модели.

39.Injected - входящие связи элемента модели.

40.Inherits - наследуемые элементы элемента модели.

41.Implements - реализуемые элементы элемента модели.

42.Implemented - реализуемые операции элемента модели.

43.Overridden - перекрываемые операции элемента модели.

44.Target - цель (тип) элемента модели.

45.Stereotype - стереотип элемента модели.

46.Parent - родительский элемент элемента модели.

47.Возможно что-то ещё забыл. Тогда это следует дописать.

Updated