Exemple #1
0
        private void ParseNode(Scanner scanner, TablatureNode tablature)
        {
            scanner.SkipWhitespaces(false);
            if (scanner.EndOfInput)
            {
                return;
            }

            if (scanner.Peek() == '+')
            {
                CommandletParserBase commandletParser;;
                if (!CommandletParser.TryCreate(scanner, this, out commandletParser))
                {
                    return;
                }

                CommandletNode commandlet;
                if (!commandletParser.TryParse(scanner, out commandlet))
                {
                    return;
                }

                tablature.Nodes.Add(commandlet);
                return;
            }

            BarNode bar;

            if (new BarParser(false).TryParse(scanner, out bar))
            {
                tablature.Nodes.Add(bar);
            }
        }
        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);
        }
Exemple #3
0
        public override bool TryParse(Scanner scanner, out VoiceNode result)
        {
            var anchor = scanner.MakeAnchor();

            scanner.SkipWhitespaces();

            result = new VoiceNode();
            BeatNode unit;

            while (new BeatParser().TryParse(scanner, out unit))
            {
                result.Beats.Add(unit);
                scanner.SkipWhitespaces();

                if (VoiceParser.IsEndOfVoice(scanner))
                {
                    break;
                }
            }

            result.Range = anchor.Range;
            return(true);
        }
        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);
        }