Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        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);
            }
        }
Exemplo n.º 6
0
        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);
        }