keytab_parse.dart 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import 'package:xterm/input/keytab/keytab.dart';
  2. import 'package:xterm/input/keytab/keytab_record.dart';
  3. import 'package:xterm/input/keytab/keytab_token.dart';
  4. import 'package:xterm/input/keytab/qt_keyname.dart';
  5. class ParseError {}
  6. class TokensReader {
  7. TokensReader(this.tokens);
  8. final List<KeytabToken> tokens;
  9. var _pos = 0;
  10. bool get done => _pos > tokens.length - 1;
  11. KeytabToken? take() {
  12. final result = peek();
  13. _pos += 1;
  14. return result;
  15. }
  16. KeytabToken? peek() {
  17. if (done) return null;
  18. return tokens[_pos];
  19. }
  20. }
  21. class KeytabParser {
  22. String? _name;
  23. final _records = <KeytabRecord>[];
  24. void addTokens(List<KeytabToken> tokens) {
  25. final reader = TokensReader(tokens);
  26. while (!reader.done) {
  27. if (reader.peek()!.type == KeytabTokenType.keyboard) {
  28. _parseName(reader);
  29. continue;
  30. }
  31. if (reader.peek()!.type == KeytabTokenType.keyDefine) {
  32. _parseKeyDefine(reader);
  33. continue;
  34. }
  35. throw ParseError();
  36. }
  37. }
  38. Keytab get result {
  39. return Keytab(name: _name, records: _records);
  40. }
  41. void _parseName(TokensReader reader) {
  42. if (reader.take()!.type != KeytabTokenType.keyboard) {
  43. throw ParseError();
  44. }
  45. final name = reader.take()!;
  46. if (name.type != KeytabTokenType.input) {
  47. throw ParseError();
  48. }
  49. _name = name.value;
  50. }
  51. void _parseKeyDefine(TokensReader reader) {
  52. if (reader.take()!.type != KeytabTokenType.keyDefine) {
  53. throw ParseError();
  54. }
  55. final keyName = reader.take()!;
  56. if (keyName.type != KeytabTokenType.keyName) {
  57. throw ParseError();
  58. }
  59. final key = qtKeynameMap[keyName.value];
  60. if (key == null) {
  61. throw ParseError();
  62. }
  63. bool? alt;
  64. bool? ctrl;
  65. bool? shift;
  66. bool? anyModifier;
  67. bool? ansi;
  68. bool? appScreen;
  69. bool? keyPad;
  70. bool? appCursorKeys;
  71. bool? appKeyPad;
  72. bool? newLine;
  73. bool? mac;
  74. while (reader.peek()!.type == KeytabTokenType.modeStatus) {
  75. bool modeStatus;
  76. switch (reader.take()!.value) {
  77. case '+':
  78. modeStatus = true;
  79. break;
  80. case '-':
  81. modeStatus = false;
  82. break;
  83. default:
  84. throw ParseError();
  85. }
  86. final mode = reader.take();
  87. if (mode!.type != KeytabTokenType.mode) {
  88. throw ParseError();
  89. }
  90. switch (mode.value) {
  91. case 'Alt':
  92. alt = modeStatus;
  93. break;
  94. case 'Control':
  95. ctrl = modeStatus;
  96. break;
  97. case 'Shift':
  98. shift = modeStatus;
  99. break;
  100. case 'AnyMod':
  101. anyModifier = modeStatus;
  102. break;
  103. case 'Ansi':
  104. ansi = modeStatus;
  105. break;
  106. case 'AppScreen':
  107. appScreen = modeStatus;
  108. break;
  109. case 'KeyPad':
  110. keyPad = modeStatus;
  111. break;
  112. case 'AppCuKeys':
  113. appCursorKeys = modeStatus;
  114. break;
  115. case 'AppKeyPad':
  116. appKeyPad = modeStatus;
  117. break;
  118. case 'NewLine':
  119. newLine = modeStatus;
  120. break;
  121. case 'Mac':
  122. mac = modeStatus;
  123. break;
  124. default:
  125. throw ParseError();
  126. }
  127. }
  128. if (reader.take()!.type != KeytabTokenType.colon) {
  129. throw ParseError();
  130. }
  131. final actionToken = reader.take()!;
  132. KeytabAction action;
  133. if (actionToken.type == KeytabTokenType.input) {
  134. action = KeytabAction(KeytabActionType.input, actionToken.value);
  135. } else if (actionToken.type == KeytabTokenType.shortcut) {
  136. action = KeytabAction(KeytabActionType.shortcut, actionToken.value);
  137. } else {
  138. throw ParseError();
  139. }
  140. final record = KeytabRecord(
  141. qtKeyName: keyName.value,
  142. key: key,
  143. action: action,
  144. alt: alt,
  145. ctrl: ctrl,
  146. shift: shift,
  147. anyModifier: anyModifier,
  148. ansi: ansi,
  149. appScreen: appScreen,
  150. keyPad: keyPad,
  151. appCursorKeys: appCursorKeys,
  152. appKeyPad: appKeyPad,
  153. newLine: newLine,
  154. mac: mac,
  155. );
  156. _records.add(record);
  157. }
  158. }