keytab_parse.dart 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. while (reader.peek()!.type == KeytabTokenType.modeStatus) {
  74. bool modeStatus;
  75. switch (reader.take()!.value) {
  76. case '+':
  77. modeStatus = true;
  78. break;
  79. case '-':
  80. modeStatus = false;
  81. break;
  82. default:
  83. throw ParseError();
  84. }
  85. final mode = reader.take();
  86. if (mode!.type != KeytabTokenType.mode) {
  87. throw ParseError();
  88. }
  89. switch (mode.value) {
  90. case 'Alt':
  91. alt = modeStatus;
  92. break;
  93. case 'Control':
  94. ctrl = modeStatus;
  95. break;
  96. case 'Shift':
  97. shift = modeStatus;
  98. break;
  99. case 'AnyMod':
  100. anyModifier = modeStatus;
  101. break;
  102. case 'Ansi':
  103. ansi = modeStatus;
  104. break;
  105. case 'AppScreen':
  106. appScreen = modeStatus;
  107. break;
  108. case 'KeyPad':
  109. keyPad = modeStatus;
  110. break;
  111. case 'AppCuKeys':
  112. appCursorKeys = modeStatus;
  113. break;
  114. case 'AppKeyPad':
  115. appKeyPad = modeStatus;
  116. break;
  117. case 'NewLine':
  118. newLine = modeStatus;
  119. break;
  120. default:
  121. throw ParseError();
  122. }
  123. }
  124. if (reader.take()!.type != KeytabTokenType.colon) {
  125. throw ParseError();
  126. }
  127. final actionToken = reader.take()!;
  128. KeytabAction action;
  129. if (actionToken.type == KeytabTokenType.input) {
  130. action = KeytabAction(KeytabActionType.input, actionToken.value);
  131. } else if (actionToken.type == KeytabTokenType.shortcut) {
  132. action = KeytabAction(KeytabActionType.shortcut, actionToken.value);
  133. } else {
  134. throw ParseError();
  135. }
  136. final record = KeytabRecord(
  137. qtKeyName: keyName.value,
  138. key: key,
  139. action: action,
  140. alt: alt,
  141. ctrl: ctrl,
  142. shift: shift,
  143. anyModifier: anyModifier,
  144. ansi: ansi,
  145. appScreen: appScreen,
  146. keyPad: keyPad,
  147. appCursorKeys: appCursorKeys,
  148. appKeyPad: appKeyPad,
  149. newLine: newLine,
  150. );
  151. _records.add(record);
  152. }
  153. }