Что хороший путь состоит в том, чтобы связать из общего служебного окна и frontmost окна документа?

Решение:

Вы должны заменить следующее:

lexer(Tokens) -->
   white_space,
   (
      (  ":",       !, { Token = tokColon }
      ;  "(",       !, { Token = tokLParen }
      ;  ")",       !, { Token = tokRParen }
      ;  "{",       !, { Token = tokLMusta}
      ;  "}",       !, { Token = tokRMusta}
      ;  "\\",      !, { Token = tokSlash}
      ;  "->",      !, { Token = tokImpl}
      ;  "+",       !, { Token = tokPlus }
      ;  "-",       !, { Token = tokMinus }
      ;  "*",       !, { Token = tokTimes }
      ;  "=",       !, { Token = tokEqual }
      ;  "<",       !, { Token = tokLt }
      ;  ">",       !, { Token = tokGt }
      ;  "_",       !, { Token = tokUnderscore }
      ;  ".",       !, { Token = tokPeriod }
      ;  "/",       !, { Token = tokForwardSlash }
      ;  ",",       !, { Token = tokComma }
      ;  ";",       !, { Token = tokSemicolon }
      ;  digit(D),  !,
            number(D, N),
            { Token = tokNumber(N) }
      ;  letter(L), !, identifier(L, Id),
            {  member((Id, Token), [ (div, tokDiv),
                                     (mod, tokMod),
                                     (where, tokWhere)]),
               !
            ;  Token = tokVar(Id)
            }
      ;  [_],
            { Token = tokUnknown }
      ),
      !,
      { Tokens = [Token | TokList] },
      lexer(TokList)
   ;  [],
         { Tokens = [] }
   ).

на

lexer(Tokens) -->
   white_space,
   (
      (
         op_token(Token), ! % replace ;/2 long chain searched blindly with call to new predicate op_token//1 which clauses have indexed access by first arg in Prolog standard way
      ;
         digit(D),  !, number(D, N),
         { Token = tokNumber(N) }
      ;  letter(L), !, identifier(L, Id),
         {  member((Id, Token), [ (div, tokDiv),
                                 (mod, tokMod),
                                 (where, tokWhere)]),
            !
      ;  Token = tokVar(Id)
         }
      ;  [_],
         { Token = tokUnknown }
      ),
      !,
      { Tokens = [Token | TokList] },
      lexer(TokList)
   ;
      [],
      { Tokens = [] }
   ).

%%%
op_token(tokColon)      --> ";".
op_token(tokLParen)     --> "(".
op_token(tokRParen)     --> ")".
op_token(tokLMusta)     --> "{".
op_token(tokRMusta)     --> "}".
op_token(tokBackSlash)  --> "\\".
op_token(tokImpl)       --> "->".
op_token(tokPlus)       --> "+".
op_token(tokMinus)      --> "-".
op_token(tokTimes)      --> "*".
op_token(tokEqual)      --> "=".
op_token(tokLt)         --> "<".
op_token(tokGt)         --> ">".
op_token(tokUnderscore) --> "_".
op_token(tokPeriod)     --> ".".
op_token(tokSlash)      --> "/".
op_token(tokComma)      --> ",".
op_token(tokSemicolon)  --> ";".

Редактировать Guy Coder

I провел тест, используя пример данных, опубликованных в вопросе, в список, где каждый элемент в списке представлял собой строку данных, преобразованную в коды символов. Затем со временем / 1 вызывал lexer для каждого элемента в списке и повторял тест для списка 10000 раз. Причина, по которой данные были загружены в список и преобразованы в коды символов до времени / 1, заключалась в том, что эти процессы не искажали результаты. Каждый из этих прогонов повторялся 5 раз, чтобы получить согласованность данных.

В следующих запусках ниже для всех различных версий лексер был расширен, чтобы охватить все 7-битные символы ASCII, что значительно увеличило количество падежей для специальных символов.

Версия Пролога, используемая для следующего, была SWI-Пролог 8.0.

Для версии в вопросе.

Version: 1

:- set_prolog_flag(double_quotes,chars).

% 694,080,002 inferences, 151.141 CPU in 151.394 seconds (100% CPU, 4592280 Lips)
% 694,080,001 inferences, 150.813 CPU in 151.059 seconds (100% CPU, 4602271 Lips)
% 694,080,001 inferences, 152.063 CPU in 152.326 seconds (100% CPU, 4564439 Lips)
% 694,080,001 inferences, 151.141 CPU in 151.334 seconds (100% CPU, 4592280 Lips)
% 694,080,001 inferences, 151.875 CPU in 152.139 seconds (100% CPU, 4570074 Lips)

Для версии, опубликованной выше в этом ответе

Version: 2

:- set_prolog_flag(double_quotes,chars).

% 773,260,002 inferences, 77.469 CPU in 77.543 seconds (100% CPU, 9981573 Lips)
% 773,260,001 inferences, 77.344 CPU in 77.560 seconds (100% CPU, 9997705 Lips)
% 773,260,001 inferences, 77.406 CPU in 77.629 seconds (100% CPU, 9989633 Lips)
% 773,260,001 inferences, 77.891 CPU in 77.967 seconds (100% CPU, 9927511 Lips)
% 773,260,001 inferences, 78.422 CPU in 78.644 seconds (100% CPU, 9860259 Lips)

Версия 2 дает значительное улучшение за счет использования индексации из Версии 1.

При проведении дальнейших исследований кода, взглянув на op_token, который представляет собой DCG и имеет две скрытые переменные для неявного прохождения представления состояния, используя листинг / 1 показал :

op_token(tokUnderscore,['_'|A], A).

Обратите внимание, что первый параметр не является искомым символом и что в этом ответе индексный код записывается как

c_digit(0'0,0).

, где первый Параметр - это искомый символ, а второй параметр - результат.

Так что измените этот

op_token(Token), !

на этот

[S], { special_character_indexed(S,Token) }

с индексированными предложениями как

special_character_indexed( ';' ,tokSemicolon).


Версия: 3

]

:- set_prolog_flag(double_quotes,chars).

% 765,800,002 inferences, 74.125 CPU in 74.348 seconds (100% CPU, 10331197 Lips)
% 765,800,001 inferences, 74.766 CPU in 74.958 seconds (100% CPU, 10242675 Lips)
% 765,800,001 inferences, 74.734 CPU in 74.943 seconds (100% CPU, 10246958 Lips)
% 765,800,001 inferences, 74.828 CPU in 75.036 seconds (100% CPU, 10234120 Lips)
% 765,800,001 inferences, 74.547 CPU in 74.625 seconds (100% CPU, 10272731 Lips)

Версия 3 дает немного лучший, но стабильно лучший результат, чем Версия 2.

Наконец, просто изменив флаг double_quotes на atom, как отмечено в комментарии АнтонДанилова

Version: 4

:- set_prolog_flag(double_quotes,atom).

% 765,800,003 inferences, 84.234 CPU in 84.539 seconds (100% CPU, 9091300 Lips)
% 765,800,001 inferences, 74.797 CPU in 74.930 seconds (100% CPU, 10238396 Lips)
% 765,800,001 inferences, 75.125 CPU in 75.303 seconds (100% CPU, 10193677 Lips)
% 765,800,001 inferences, 75.078 CPU in 75.218 seconds (100% CPU, 10200042 Lips)
% 765,800,001 inferences, 75.031 CPU in 75.281 seconds (100% CPU, 10206414 Lips)

Версия 4 почти такая же, как и Версия 3.

Просто просматривая номера процессоров, можно быстрее использовать индексацию, например, (Версия: 1) 151.875 против (Версия: 3) 74.547

12
задан Quinn Taylor 30 June 2009 в 20:08
поделиться

4 ответа

Я всегда связывал через Общее приложение, mainWindow.document, который хорошо работает. если у Вас есть окна документы w/o, можно хотеть добавить a mainYourKindOfWindow ключ, который реализован путем наблюдения mainWindow и обновление значения на основе некоторых критериев фильтра.

4
ответ дан 2 December 2019 в 23:08
поделиться

TextEdit Leopard делает это для своего инспектора. Проверьте его в file:///Developer/Examples/AppKit/TextEdit.

3
ответ дан 2 December 2019 в 23:08
поделиться
  • поместите объектный контроллер в мое перо для общего окна. Когда окно документа изменит frontmost состояние, измените контент той привязки.

Это имеет большую часть смысла мне. Вы изменили бы содержание на экземпляр документа ([NSDocumentController currentDocument]).

Недостаток этого - то, что, если бы у меня должен был быть другой вид служебного окна, я должен был бы не забыть поднимать трубку привязку от окна документа до того служебного окна также!

Ха? Я не понимаю это.

0
ответ дан 2 December 2019 в 23:08
поделиться

Leopard's TextEdit does this for its inspector. Check it out in >file:///Developer/Examples/AppKit/TextEdit.

In TextEdit, inspector values are bound via an intermediate object controller. The controller content object is bound to the shared application mainWindow.

You may bind the content to mainWindow.firstResponder and uncheck "Raises for not applicable keys".

0
ответ дан 2 December 2019 в 23:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: