Index: pkg/fletchc/lib/src/hub/sentence_parser.dart |
diff --git a/pkg/fletchc/lib/src/hub/sentence_parser.dart b/pkg/fletchc/lib/src/hub/sentence_parser.dart |
deleted file mode 100644 |
index 9f4d2f28885d67a61ea3878efc41b28ff3a3a424..0000000000000000000000000000000000000000 |
--- a/pkg/fletchc/lib/src/hub/sentence_parser.dart |
+++ /dev/null |
@@ -1,465 +0,0 @@ |
-// Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE.md file. |
- |
-library fletchc.hub.sentence_parser; |
- |
-import 'dart:convert' show |
- JSON; |
- |
-import '../verbs/actions.dart' show |
- Action, |
- commonActions, |
- uncommonActions; |
- |
-import '../verbs/infrastructure.dart' show |
- AnalyzedSentence, |
- DiagnosticKind, |
- throwFatalError; |
- |
-Sentence parseSentence( |
- Iterable<String> arguments, |
- {bool includesProgramName}) { |
- SentenceParser parser = |
- new SentenceParser(arguments, includesProgramName == true); |
- return parser.parseSentence(); |
-} |
- |
-class SentenceParser { |
- final String version; |
- final String programName; |
- final String shortProgramName; |
- final String currentDirectory; |
- Words tokens; |
- |
- SentenceParser(Iterable<String> tokens, bool includesProgramName) |
- : version = includesProgramName ? tokens.first : null, |
- currentDirectory = includesProgramName ? tokens.skip(1).first : null, |
- programName = includesProgramName ? tokens.skip(2).first : null, |
- shortProgramName = includesProgramName ? tokens.skip(3).first : null, |
- tokens = new Words(tokens.skip(includesProgramName ? 4 : 0)); |
- |
- Sentence parseSentence() { |
- Verb verb; |
- if (!tokens.isAtEof) { |
- verb = parseVerb(); |
- } else { |
- verb = new Verb("help", commonActions["help"]); |
- } |
- List<Preposition> prepositions = <Preposition>[]; |
- List<Target> targets = <Target>[]; |
- while (!tokens.isAtEof) { |
- Preposition preposition = parsePrepositionOpt(); |
- if (preposition != null) { |
- prepositions.add(preposition); |
- continue; |
- } |
- Target target = parseTargetOpt(); |
- if (target != null) { |
- targets.add(target); |
- continue; |
- } |
- break; |
- } |
- List<String> trailing = <String>[]; |
- while (!tokens.isAtEof) { |
- trailing.add(tokens.current); |
- tokens.consume(); |
- } |
- if (trailing.isEmpty) { |
- trailing = null; |
- } |
- return new Sentence( |
- verb, prepositions, targets, trailing, |
- version, currentDirectory, programName, |
- // TODO(ahe): Get rid of the following argument: |
- tokens.originalInput.skip(2).toList()); |
- } |
- |
- Verb parseVerb() { |
- String name = tokens.current; |
- Action action = commonActions[name]; |
- if (action != null) { |
- tokens.consume(); |
- return new Verb(name, action); |
- } |
- action = uncommonActions[name]; |
- if (action != null) { |
- tokens.consume(); |
- return new Verb(name, action); |
- } |
- return new ErrorVerb(name); |
- } |
- |
- Preposition parsePrepositionOpt() { |
- // TODO(ahe): toLowerCase()? |
- String word = tokens.current; |
- Preposition makePreposition(PrepositionKind kind) { |
- tokens.consume(); |
- Target target = tokens.isAtEof ? null : parseTarget(); |
- return new Preposition(kind, target); |
- } |
- switch (word) { |
- case "with": |
- return makePreposition(PrepositionKind.WITH); |
- |
- case "in": |
- return makePreposition(PrepositionKind.IN); |
- |
- case "to": |
- return makePreposition(PrepositionKind.TO); |
- |
- |
- default: |
- return null; |
- } |
- } |
- |
- // @private_to.instance |
- Target internalParseTarget() { |
- // TODO(ahe): toLowerCase()? |
- String word = tokens.current; |
- |
- NamedTarget makeNamedTarget(TargetKind kind) { |
- tokens.consume(); |
- return new NamedTarget(kind, parseName()); |
- } |
- |
- Target makeTarget(TargetKind kind) { |
- tokens.consume(); |
- return new Target(kind); |
- } |
- |
- if (looksLikeAUri(word)) { |
- return new NamedTarget(TargetKind.FILE, parseName()); |
- } |
- |
- switch (word) { |
- case "session": |
- return makeNamedTarget(TargetKind.SESSION); |
- |
- case "class": |
- return makeNamedTarget(TargetKind.CLASS); |
- |
- case "method": |
- return makeNamedTarget(TargetKind.METHOD); |
- |
- case "file": |
- return makeNamedTarget(TargetKind.FILE); |
- |
- case "agent": |
- return makeTarget(TargetKind.AGENT); |
- |
- case "settings": |
- return makeTarget(TargetKind.SETTINGS); |
- |
- case "tcp_socket": |
- return makeNamedTarget(TargetKind.TCP_SOCKET); |
- |
- case "sessions": |
- return makeTarget(TargetKind.SESSIONS); |
- |
- case "classes": |
- return makeTarget(TargetKind.CLASSES); |
- |
- case "methods": |
- return makeTarget(TargetKind.METHODS); |
- |
- case "files": |
- return makeTarget(TargetKind.FILES); |
- |
- case "all": |
- return makeTarget(TargetKind.ALL); |
- |
- case "run-to-main": |
- return makeTarget(TargetKind.RUN_TO_MAIN); |
- |
- case "backtrace": |
- return makeTarget(TargetKind.BACKTRACE); |
- |
- case "continue": |
- return makeTarget(TargetKind.CONTINUE); |
- |
- case "break": |
- return makeNamedTarget(TargetKind.BREAK); |
- |
- case "list": |
- return makeTarget(TargetKind.LIST); |
- |
- case "disasm": |
- return makeTarget(TargetKind.DISASM); |
- |
- case "frame": |
- return makeNamedTarget(TargetKind.FRAME); |
- |
- case "delete-breakpoint": |
- return makeNamedTarget(TargetKind.DELETE_BREAKPOINT); |
- |
- case "list-breakpoints": |
- return makeTarget(TargetKind.LIST_BREAKPOINTS); |
- |
- case "step": |
- return makeTarget(TargetKind.STEP); |
- |
- case "step-over": |
- return makeTarget(TargetKind.STEP_OVER); |
- |
- case "fibers": |
- return makeTarget(TargetKind.FIBERS); |
- |
- case "finish": |
- return makeTarget(TargetKind.FINISH); |
- |
- case "restart": |
- return makeTarget(TargetKind.RESTART); |
- |
- case "step-bytecode": |
- return makeTarget(TargetKind.STEP_BYTECODE); |
- |
- case "step-over-bytecode": |
- return makeTarget(TargetKind.STEP_OVER_BYTECODE); |
- |
- case "print": |
- return makeNamedTarget(TargetKind.PRINT); |
- |
- case "print-all": |
- return makeTarget(TargetKind.PRINT_ALL); |
- |
- case "toggle": |
- return makeNamedTarget(TargetKind.TOGGLE); |
- |
- case "help": |
- return makeTarget(TargetKind.HELP); |
- |
- case "log": |
- return makeTarget(TargetKind.LOG); |
- |
- case "devices": |
- return makeTarget(TargetKind.DEVICES); |
- |
- case "apply": |
- return makeTarget(TargetKind.APPLY); |
- |
- default: |
- return new ErrorTarget(DiagnosticKind.expectedTargetButGot, word); |
- } |
- } |
- |
- Target parseTargetOpt() { |
- Target target = internalParseTarget(); |
- return target is ErrorTarget ? null : target; |
- } |
- |
- Target parseTarget() { |
- Target target = internalParseTarget(); |
- if (target is ErrorTarget) { |
- tokens.consume(); |
- } |
- return target; |
- } |
- |
- String parseName() { |
- // TODO(ahe): Rename this method? It doesn't necessarily parse a name, just |
- // whatever is the next word. |
- String name = tokens.current; |
- tokens.consume(); |
- return name; |
- } |
- |
- /// Returns true if [word] looks like it is a (relative) URI. |
- bool looksLikeAUri(String word) { |
- return |
- word != null && |
- !word.startsWith("-") && |
- word.contains("."); |
- } |
-} |
- |
-String quoteString(String string) => JSON.encode(string); |
- |
-class Words { |
- final Iterable<String> originalInput; |
- |
- final Iterator<String> iterator; |
- |
- // @private_to.instance |
- bool internalIsAtEof; |
- |
- // @private_to.instance |
- int internalPosition = 0; |
- |
- Words(Iterable<String> input) |
- : this.internal(input, input.iterator); |
- |
- Words.internal(this.originalInput, Iterator<String> iterator) |
- : iterator = iterator, |
- internalIsAtEof = !iterator.moveNext(); |
- |
- bool get isAtEof => internalIsAtEof; |
- |
- int get position => internalPosition; |
- |
- String get current => iterator.current; |
- |
- void consume() { |
- internalIsAtEof = !iterator.moveNext(); |
- if (!isAtEof) { |
- internalPosition++; |
- } |
- } |
-} |
- |
-class Verb { |
- final String name; |
- final Action action; |
- |
- const Verb(this.name, this.action); |
- |
- bool get isErroneous => false; |
- |
- String toString() => "Verb(${quoteString(name)})"; |
-} |
- |
-class ErrorVerb implements Verb { |
- final String name; |
- |
- const ErrorVerb(this.name); |
- |
- bool get isErroneous => true; |
- |
- Action get action { |
- throwFatalError(DiagnosticKind.unknownAction, userInput: name); |
- } |
-} |
- |
-class Preposition { |
- final PrepositionKind kind; |
- final Target target; |
- |
- const Preposition(this.kind, this.target); |
- |
- String toString() => "Preposition($kind, $target)"; |
-} |
- |
-enum PrepositionKind { |
- WITH, |
- IN, |
- TO, |
-} |
- |
-class Target { |
- final TargetKind kind; |
- |
- const Target(this.kind); |
- |
- bool get isErroneous => false; |
- |
- String toString() => "Target($kind)"; |
-} |
- |
-enum TargetKind { |
- AGENT, |
- ALL, |
- APPLY, |
- BACKTRACE, |
- BREAK, |
- CLASS, |
- CLASSES, |
- CONTINUE, |
- DELETE_BREAKPOINT, |
- DEVICES, |
- DISASM, |
- FIBERS, |
- FILE, |
- FILES, |
- FINISH, |
- FRAME, |
- HELP, |
- LIST, |
- LIST_BREAKPOINTS, |
- LOG, |
- METHOD, |
- METHODS, |
- PRINT, |
- PRINT_ALL, |
- RESTART, |
- RUN_TO_MAIN, |
- SESSION, |
- SESSIONS, |
- SETTINGS, |
- STEP, |
- STEP_BYTECODE, |
- STEP_OVER, |
- STEP_OVER_BYTECODE, |
- TCP_SOCKET, |
- TOGGLE, |
-} |
- |
-class NamedTarget extends Target { |
- final String name; |
- |
- const NamedTarget(TargetKind kind, this.name) |
- : super(kind); |
- |
- String toString() { |
- return "NamedTarget($kind, ${quoteString(name)})"; |
- } |
-} |
- |
-class ErrorTarget extends Target { |
- final DiagnosticKind errorKind; |
- final String userInput; |
- |
- const ErrorTarget(this.errorKind, this.userInput) |
- : super(null); |
- |
- bool get isErroneous => true; |
- |
- String toString() => "ErrorTarget($errorKind, ${quoteString(userInput)})"; |
-} |
- |
-/// A sentence is a written command to fletch. Normally, this command is |
-/// written on the command-line and should be easy to write without having |
-/// getting into conflict with Unix shell command line parsing. |
-/// |
-/// An example sentence is: |
-/// `create class MyClass in session MySession` |
-/// |
-/// In this example, `create` is a [Verb], `class MyClass` is a [Target], and |
-/// `in session MySession` is a [Preposition]. |
-class Sentence { |
- /// For example, `create`. |
- final Verb verb; |
- |
- /// For example, `in session MySession` |
- final List<Preposition> prepositions; |
- |
- /// For example, `class MyClass` |
- final List<Target> targets; |
- |
- /// Any tokens found after this sentence. |
- final List<String> trailing; |
- |
- /// The current directory of the C++ client. |
- final String currentDirectory; |
- |
- // TODO(ahe): Get rid of this. |
- final String programName; |
- |
- final String version; |
- |
- // TODO(ahe): Get rid of this. |
- final List<String> arguments; |
- |
- const Sentence( |
- this.verb, |
- this.prepositions, |
- this.targets, |
- this.trailing, |
- this.version, |
- this.currentDirectory, |
- this.programName, |
- this.arguments); |
- |
- String toString() => "Sentence($verb, $prepositions, $targets)"; |
-} |