public static bool TryCreate(Scanner scanner, ILogger logger, out CommandletParserBase parser) { var anchor = scanner.MakeAnchor(); if (!scanner.Expect('+')) { logger.Report(LogLevel.Error, scanner.Pointer.AsRange(scanner.Source), Messages.Error_InstructionExpected); parser = null; return(false); } scanner.SkipWhitespaces(); var name = scanner.Read(c => char.IsLetterOrDigit(c) || c == '-'); Type parserType; if (!CommandletParsers.TryGetValue(name.ToLowerInvariant(), out parserType)) { logger.Report(LogLevel.Error, scanner.Pointer.AsRange(scanner.Source), Messages.Error_UnknownInstruction); parser = null; return(false); } var nameNode = new LiteralNode <string>($"+{name}", anchor.Range); parser = (CommandletParserBase)Activator.CreateInstance(parserType); parser.CommandletNameNode = nameNode; return(true); }
public static bool TryReadCloseBarLine(Scanner scanner, ILogger logger, out LiteralNode <CloseBarLine> barLine) { if (scanner.Expect(":||")) { barLine = new LiteralNode <CloseBarLine>(CloseBarLine.EndRepeat, scanner.LastReadRange); return(true); } if (scanner.Expect("||")) { barLine = new LiteralNode <CloseBarLine>(CloseBarLine.Double, scanner.LastReadRange); return(true); } if (scanner.Expect("|")) { barLine = new LiteralNode <CloseBarLine>(CloseBarLine.Standard, scanner.LastReadRange); return(true); } barLine = null; return(false); }
public override bool TryParse(Scanner scanner, out NoteValueNode result) { var anchor = scanner.MakeAnchor(); result = new NoteValueNode(); LiteralNode <BaseNoteValue> baseNoteValue; if (!Parser.TryReadBaseNoteValue(scanner, this, out baseNoteValue)) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_NoteValueExpected); result = null; return(false); } result.Base = baseNoteValue; if (scanner.Expect('/')) //tuplet { LiteralNode <int> tuplet; if (!Parser.TryReadInteger(scanner, out tuplet)) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_TupletValueExpected); result = null; return(false); } if (!NoteValue.IsValidTuplet(tuplet.Value)) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_InvalidTuplet); result = null; return(false); } result.Tuplet = tuplet; } LiteralNode <NoteValueAugment> augment; if (!Parser.TryReadNoteValueAugment(scanner, this, out augment)) { result = null; return(false); } result.Augment = augment; result.Range = anchor.Range; return(true); }
public static bool TryReadOpenBarLine(Scanner scanner, ILogger logger, out LiteralNode <OpenBarLine> barLine) { if (scanner.Expect("||:")) { barLine = new LiteralNode <OpenBarLine>(OpenBarLine.BeginRepeat, scanner.LastReadRange); return(true); } if (scanner.Expect("||")) { logger.Report(LogLevel.Warning, scanner.LastReadRange, Messages.Warning_DoubleBarLineCannotBeOpenLine); barLine = null; return(false); } if (scanner.Expect('|')) { barLine = new LiteralNode <OpenBarLine>(OpenBarLine.Standard, scanner.LastReadRange); return(true); } barLine = null; return(false); }
public static bool TryReadNoteValueAugment(Scanner scanner, ILogger logger, out LiteralNode <NoteValueAugment> augmentNode) { var anchor = scanner.MakeAnchor(); var dots = 0; while (!scanner.EndOfLine) { if (!scanner.Expect('.')) { break; } ++dots; } switch (dots) { case 0: augmentNode = new LiteralNode <NoteValueAugment>(NoteValueAugment.None, anchor.Range); return(true); case 1: augmentNode = new LiteralNode <NoteValueAugment>(NoteValueAugment.Dot, anchor.Range); return(true); case 2: augmentNode = new LiteralNode <NoteValueAugment>(NoteValueAugment.TwoDots, anchor.Range); return(true); case 3: augmentNode = new LiteralNode <NoteValueAugment>(NoteValueAugment.ThreeDots, anchor.Range); return(true); default: logger.Report(LogLevel.Error, anchor.Range, Messages.Error_TooManyDotsInNoteValueAugment); augmentNode = null; return(false); } }
public override bool TryParse(Scanner scanner, out ChordFingeringNode result) { result = new ChordFingeringNode(); var anchor = scanner.MakeAnchor(); var remainingLine = scanner.RemainingLine.Trim(); var containsDelimiter = remainingLine.Any(char.IsWhiteSpace); var containsFingerIndexSpecifier = remainingLine.Any(c => c == '<' || c == '>'); var isShortForm = !containsDelimiter && !containsFingerIndexSpecifier; while (!_terminatorPredicate(scanner)) { var noteAnchor = scanner.MakeAnchor(); var str = isShortForm ? scanner.ReadPattern(@"[\dxX\-]") : scanner.ReadAnyPatternOf(@"\d+", @"[xX\-]"); if (string.IsNullOrEmpty(str)) { this.Report(LogLevel.Warning, scanner.LastReadRange, Messages.Error_ChordFingeringInvalidFingering); result = null; return(false); } switch (str) { case "x": case "X": case "-": { var fret = new LiteralNode <int>(Chord.FingeringSkipString, scanner.LastReadRange); result.Fingerings.Add(new ChordFingeringNoteNode { Fret = fret, Range = scanner.LastReadRange }); break; } default: int fretNumber; if (!int.TryParse(str, out fretNumber)) // todo: prevent too large fret number { this.Report(LogLevel.Warning, scanner.LastReadRange, Messages.Error_ChordFingeringInvalidFingering); result = null; return(false); } if (fretNumber > 24) { this.Report(LogLevel.Warning, scanner.LastReadRange, Messages.Warning_ChordFingeringFretTooHigh); } var note = new ChordFingeringNoteNode { Fret = new LiteralNode <int>(fretNumber, scanner.LastReadRange), Range = scanner.LastReadRange }; if (fretNumber != 0) { scanner.SkipWhitespaces(); if (scanner.Expect('<')) { scanner.SkipWhitespaces(); var fingerIndexString = scanner.ReadPattern(@"[\dtT]"); if (string.IsNullOrEmpty(fingerIndexString)) { this.Report(LogLevel.Error, scanner.Pointer.AsRange(), Messages.Error_ChordFingerIndexExpected); return(false); } LeftHandFingerIndex fingerIndex; switch (fingerIndexString) { case "t": case "T": fingerIndex = LeftHandFingerIndex.Thumb; break; case "1": fingerIndex = LeftHandFingerIndex.Index; break; case "2": fingerIndex = LeftHandFingerIndex.Middle; break; case "3": fingerIndex = LeftHandFingerIndex.Ring; break; case "4": fingerIndex = LeftHandFingerIndex.Pinky; break; default: this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_UnrecognizableFingerIndex); return(false); } note.FingerIndex = new LiteralNode <LeftHandFingerIndex>(fingerIndex, scanner.LastReadRange); scanner.SkipWhitespaces(); ExistencyNode importancy; if (new CharExistencyParser('!').TryParse(scanner, out importancy)) { note.Importancy = importancy; scanner.SkipWhitespaces(); } if (!scanner.Expect('>')) { this.Report(LogLevel.Error, scanner.Pointer.AsRange(), Messages.Error_ChordFingerIndexNotEnclosed); return(false); } } } note.Range = noteAnchor.Range; result.Fingerings.Add(note); break; } scanner.SkipWhitespaces(); } if (result.Fingerings.Count != Defaults.Strings) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_ChordFingeringNotMatchingStringCount, Defaults.Strings); result = null; return(false); } result.Range = anchor.Range; return(true); }