Exemplo n.º 1
0
        private void AttachEvents()
        {
            Parser syntax_rule = this["syntax rule"];

            syntax_rule.Matched += m =>
            {
                string name       = m["meta identifier"].Text;
                bool   isTerminal = m["equals"].Text == ":=";
                var    parser     = m.Tag as UnaryParser;
                Parser inner      = DefinitionList(m["definition list"], isTerminal);
                if (name == startParserName)
                {
                    parser.Inner = separator & inner & separator;
                }
                else
                {
                    parser.Inner = inner;
                }
            };
            syntax_rule.PreMatch += m =>
            {
                string      name   = m["meta identifier"].Text;
                UnaryParser parser = (name == startParserName)
                                                                     ? new Grammar(name)
                                                                     : new UnaryParser(name);
                m.Tag = parserLookup[name] = parser;
            };
        }
Exemplo n.º 2
0
        public static Parser Named(this Parser parser, string name)
        {
            var unary = new UnaryParser(parser);

            unary.Name = name ?? Guid.NewGuid().ToString();
            return(unary);
        }
Exemplo n.º 3
0
 public static IParser GetParser(MemberInfo member)
 {
     // We need a global lock to detect recursion
     lock (parserStack) {
         if (!cache.TryGetValue(member, out var parser))
         {
             if (parserStack.Contains(member))
             {
                 var placeholder = new UnaryParser(DefaultConfig.Instance, ParserFlags.None);
                 cache.Add(member, placeholder);
                 return(placeholder);
             }
             else if (member is Type t && t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List <>))
             {
                 parser        = GetParserUncached(member);
                 cache[member] = parser;
             }
             else
             {
                 parserStack.Push(member);
                 parser = GetParserUncached(member);
                 parserStack.Pop();
                 if (cache.TryGetValue(member, out var tmp) && tmp is UnaryParser placeholder)
                 {
                     placeholder.Set(parser);
                 }
                 cache[member] = parser;
             }
         }
         return(parser);
     }
Exemplo n.º 4
0
        private static Grammar MakeParser()
        {
            // Literals
            var ws    = Terminals.WhiteSpace.Repeat(0);
            var comma = ws.Then(Terminals.Set(','), ws);
            var subExpressionAccess = ws.Then(Terminals.Set('.'), ws);
            var number = new NumberParser
            {
                AllowDecimal  = true,
                AllowExponent = true,
                AllowSign     = true,
                ValueType     = typeof(float)
            };

            var identifier = Terminals.Letter.Or(Terminals.Set(_identifierAllowedCharacters))
                             .Then(Terminals.LetterOrDigit.Or(Terminals.Set(_identifierAllowedCharacters)).Repeat(0));

            // Expressions
            var expression    = new UnaryParser();
            var subExpression = expression.Named(ElementAST.SubExpressionRoot)
                                .Then(subExpressionAccess, identifier.Named(ElementAST.SubExpressionName));
            var arguments = expression.Named(ElementAST.CallArgument).Repeat(0).SeparatedBy(comma);
            var call      = expression.Named(ElementAST.Callee)
                            .Then(ws, Terminals.Set('('), ws, arguments.Named(ElementAST.CallArguments), ws,
                                  Terminals.Set(')'));

            expression.Inner = new AlternativeParser(
                number.Named(ElementAST.NumberExpression),
                identifier.Named(ElementAST.VariableExpression),
                subExpression.Named(ElementAST.SubExpression),
                call.Named(ElementAST.CallExpression)
                );

            // Functions
            var portType = ws.Then(Terminals.Literal(":"), ws, identifier.Named(ElementAST.PortType)).Optional();
            var port     = identifier.Named(ElementAST.PortName).Then(portType).Named(ElementAST.Port);
            var ports    = port.Repeat(0).SeparatedBy(comma);
            var fnInputs = Terminals.Set('(')
                           .Then(ws, ports.Named(ElementAST.FunctionInputs), ws, Terminals.Set(')')).Optional();
            var fnOutputs   = Terminals.Literal("->").Then(ws, ports.Named(ElementAST.FunctionOutputs)).Or(portType);
            var fnSignature = identifier.Named(ElementAST.FunctionName).Then(ws, fnInputs, ws, fnOutputs, ws);

            // Statements
            var statement = new UnaryParser();
            var body      = Terminals.Set('{').Then(ws, statement.Then(ws).Repeat(0).Named(ElementAST.FunctionBody), ws,
                                                    Terminals.Set('}'));
            var assign = Terminals.Set('=').Then(ws, expression.Named(ElementAST.AssignmentStatement), ws,
                                                 Terminals.Set(';'));

            statement.Inner = fnSignature
                              .Then(body.Or(assign).Or(Terminals.Set(';').Named(ElementAST.TypeStatement)))
                              .Named(ElementAST.Statement);

            var start = ws.Then(statement, ws).Repeat(0);

            start.Until = Terminals.End;

            return(new Grammar(start));
        }
Exemplo n.º 5
0
        public EbnfGrammar()
            : base("ebnf")
        {
            DefineCommonNonTerminals = true;
            GenerateSpecialSequences();

            // terminals
            AlternativeParser terminal_string = ("'" & (+Terminals.AnyChar).Until("'").WithName("value") & "'")
                                                | ("\"" & (+Terminals.AnyChar).Until("\"").WithName("value") & "\"")
                                                | ("’" & (+Terminals.AnyChar).Until("’").WithName("value") & "’");

            SequenceParser special_sequence =
                ("?" & (+Terminals.AnyChar).Until("?").WithName("name") & "?").WithName("special sequence");

            SequenceParser meta_identifier_terminal = Terminals.Letter & -(Terminals.LetterOrDigit | '_');
            var            integer = new NumberParser();

            Parser old = DefaultSeparator;

            DefaultSeparator = cws;

            // nonterminals
            var definition_list   = new UnaryParser("definition list");
            var single_definition = new UnaryParser("single definition");
            var term            = new UnaryParser("term");
            var primary         = new UnaryParser("primary");
            var exception       = new UnaryParser("exception");
            var factor          = new UnaryParser("factor");
            var meta_identifier = new UnaryParser("meta identifier");
            var syntax_rule     = new UnaryParser("syntax rule");
            var rule_equals     = new UnaryParser("equals");

            SequenceParser optional_sequence = ("[" & definition_list & "]").WithName("optional sequence");
            SequenceParser repeated_sequence = ("{" & definition_list & "}").WithName("repeated sequence");
            SequenceParser grouped_sequence  = ("(" & definition_list & ")").WithName("grouped sequence");

            // rules
            meta_identifier.Inner = (+meta_identifier_terminal).SeparatedBy(ws);
            primary.Inner         = optional_sequence | repeated_sequence
                                    | special_sequence | grouped_sequence
                                    | meta_identifier | terminal_string.Named("terminal string") | null;
            factor.Inner            = ~(integer.Named("integer") & "*") & primary;
            term.Inner              = factor & ~("-" & exception);
            exception.Inner         = term;
            single_definition.Inner = term & -("," & term);
            definition_list.Inner   = single_definition & -("|" & single_definition);
            rule_equals.Inner       = (Parser)"=" | ":=";
            syntax_rule.Inner       = meta_identifier & rule_equals & definition_list & ";";

            Inner = cws & +syntax_rule & cws;

            DefaultSeparator = old;

            AttachEvents();
        }
Exemplo n.º 6
0
        public EbnfGrammar()
            : base("ebnf")
        {
            DefineCommonNonTerminals = true;
            GenerateSpecialSequences();

            // terminals
            var terminal_string = ("'" & (+Terminals.AnyChar).Until("'").WithName("value") & "'")
                | ("\"" & (+Terminals.AnyChar).Until("\"").WithName("value") & "\"")
                | ("’" & (+Terminals.AnyChar).Until("’").WithName("value") & "’");

            var special_sequence = ("?" & (+Terminals.AnyChar).Until("?").WithName("name") & "?").WithName("special sequence");

            var meta_identifier_terminal = Terminals.Letter & -(Terminals.LetterOrDigit | '_');
            var integer = new NumberParser();

            var old = Parser.DefaultSeparator;
            Parser.DefaultSeparator = cws;

            // nonterminals
            var definition_list = new UnaryParser("definition list");
            var single_definition = new UnaryParser("single definition");
            var term = new UnaryParser("term");
            var primary = new UnaryParser("primary");
            var exception = new UnaryParser("exception");
            var factor = new UnaryParser("factor");
            var meta_identifier = new UnaryParser("meta identifier");
            var syntax_rule = new UnaryParser("syntax rule");
            var rule_equals = new UnaryParser("equals");

            var optional_sequence = ("[" & definition_list & "]").WithName("optional sequence");
            var repeated_sequence = ("{" & definition_list & "}").WithName("repeated sequence");
            var grouped_sequence = ("(" & definition_list & ")").WithName("grouped sequence");

            // rules
            meta_identifier.Inner = (+meta_identifier_terminal).SeparatedBy(ws);
            primary.Inner = optional_sequence | repeated_sequence
                | special_sequence | grouped_sequence
                | meta_identifier | terminal_string.Named("terminal string") | null;
            factor.Inner = ~(integer.Named("integer") & "*") & primary;
            term.Inner = factor & ~("-" & exception);
            exception.Inner = term;
            single_definition.Inner = term & -("," & term);
            definition_list.Inner = single_definition & -("|" & single_definition);
            rule_equals.Inner = (Parser)"=" | ":=";
            syntax_rule.Inner = meta_identifier & rule_equals & definition_list & ";";

            this.Inner = cws & +syntax_rule & cws;

            Parser.DefaultSeparator = old;

            AttachEvents();
        }
Exemplo n.º 7
0
		public AddressGrammar()
			: base("postal-address")
		{
			var terminal = +Terminals.LetterOrDigit;

			var aptNum = (((Parser)"Apt" | "Suite") & "#" & +Terminals.Digit).Named("apt-num");
			var streetType = ((Parser)"Street" | "Drive" | "Ave" | "Avenue").Named("street-type");
			var street = (terminal.Named("street-name") & ~streetType).Named("street");
			var zipPart = (terminal.Named("town-name") & "," & terminal.Named("state-code") & terminal.Named("zip-code")).Named("zip");
			var streetAddress = (terminal.Named("house-num") & street & aptNum).Named("street-address");

			// name
			var suffixPart = ((Parser)"Sr." | "Jr." | +Terminals.Set("IVXLCDM")).Named("suffix");
			var personalPart = (terminal.Named("first-name") | (Terminals.Letter & ".")).Named("personal");
			var namePart = new UnaryParser("name");
			namePart.Inner = (personalPart & terminal.Named("last-name") & ~suffixPart) | (personalPart & namePart); // recursion

			this.Inner = namePart & Terminals.Eol & streetAddress & ~Terminals.Eol & zipPart;
		}
Exemplo n.º 8
0
        public AddressGrammar()
            : base("postal-address")
        {
            var terminal = +Terminals.LetterOrDigit;

            var aptNum        = (((Parser)"Apt" | "Suite") & "#" & +Terminals.Digit).Named("apt-num");
            var streetType    = ((Parser)"Street" | "Drive" | "Ave" | "Avenue").Named("street-type");
            var street        = (terminal.Named("street-name") & ~streetType).Named("street");
            var zipPart       = (terminal.Named("town-name") & "," & terminal.Named("state-code") & terminal.Named("zip-code")).Named("zip");
            var streetAddress = (terminal.Named("house-num") & street & aptNum).Named("street-address");

            // name
            var suffixPart   = ((Parser)"Sr." | "Jr." | +Terminals.Set("IVXLCDM")).Named("suffix");
            var personalPart = (terminal.Named("first-name") | (Terminals.Letter & ".")).Named("personal");
            var namePart     = new UnaryParser("name");

            namePart.Inner = (personalPart & terminal.Named("last-name") & ~suffixPart) | (personalPart & namePart);             // recursion

            this.Inner = namePart & Terminals.Eol & streetAddress & ~Terminals.Eol & zipPart;
        }
Exemplo n.º 9
0
        public bool TryParse(Expression e, out object val,
                             MemberInfo memberInfo           = null,
                             IReadOnlyList <Expression> args = null)
        {
            bool bOther = false;

            if (MethodCallParser.TryParse(e, out val, memberInfo, args))
            {
            }
            else if (MemberParser.TryParse(e, out val, memberInfo, args))
            {
            }
            else if (ConstParser.TryParse(e, out val, memberInfo, args))
            {
            }
            else if (NewArrayParser.TryParse(e, out val, memberInfo, args))
            {
                //解析出来之后,显示的数据依然是:Trim(value(System.Char[]))
                //在EF的Where中是不支持l.name.Trim('_')这样的操作的,只能支持:l.name.Trim()
                //但是还是需要进行解析,不然会交由OtherParser(DynamicParser)进行解析了
            }
            else if (UnaryParser.TryParse(e, out val, memberInfo, args))
            {
            }
            else
            {
                bOther = true;
                OtherParser.TryParse(e, out val, memberInfo, args);
            }

            //不是OtherParser解析的,而且val不为null,判断val的类型与Expression.Type的类型是否一致
            if (!bOther && val != null)
            {
                val = GetRightfulValue(e, val);
            }

            return(true);
        }
Exemplo n.º 10
0
        void AttachEvents()
        {
            ruleName.Matched += m => {
                Parser parser;
                var    name = m["name"].Text;
                if (!parserLookup.TryGetValue(name, out parser) && !baseLookup.TryGetValue(name, out parser))
                {
                    parser      = Terminals.LetterOrDigit.Repeat();
                    parser.Name = name;
                }
                m.Tag = parser;
            };

            literal.Matched      += m => m.Tag = new LiteralTerminal(m["value"].Text);
            optionalRule.Matched += m => m.Tag = new OptionalParser((Parser)m["parser"].Tag);
            repeatRule.Matched   += m => m.Tag = new RepeatParser((Parser)m["parser"].Tag, 0)
            {
                Separator = sws
            };
            list.Matched += m => {
                if (m.Matches.Count > 1)
                {
                    var parser = new SequenceParser();
                    foreach (var child in m.Matches)
                    {
                        if (child.Parser.Name == "ws")
                        {
                            parser.Items.Add(sws);
                        }
                        else if (child.Parser.Name == "term")
                        {
                            parser.Items.Add((Parser)child["parser"].Tag);
                        }
                    }
                    m.Tag = parser;
                }
                else
                {
                    m.Tag = m["term"]["parser"].Tag;
                }
            };

            listRepeat.Matched += m => {
                // collapse alternatives to one alternative parser
                var parser = (Parser)m["expression"]["parser"].Tag;
                var alt    = parser as AlternativeParser ?? new AlternativeParser(parser);
                alt.Items.Insert(0, (Parser)m["list"]["parser"].Tag);
                m.Tag = alt;
            };

            rule.Matched += m => {
                var parser = (UnaryParser)m.Tag;
                parser.Inner = (Parser)m["parser"].Tag;
                m.Tag        = parser;
            };
            rule.PreMatch += m => {
                var    name = m["ruleName"]["name"].Text;
                Parser parser;
                if (name == startParserName)
                {
                    parser = new Grammar(name);
                }
                else
                {
                    parser = new UnaryParser(name);
                }
                m.Tag = parser;
                parserLookup[parser.Name] = parser;
            };
        }
Exemplo n.º 11
0
		public EbnfGrammar(EbnfStyle style)
			: base("ebnf")
		{
			Style = style;
			DefineCommonNonTerminals = true;
			GenerateSpecialSequences();

			// terminals
			var comment = style.HasFlag(EbnfStyle.BracketComments) ? new GroupParser("(*", "*)") : new GroupParser("/*", "*/");
			var ows = -(Terminals.WhiteSpace | comment);
			var rws = +(Terminals.WhiteSpace | comment);
			var hex_character = ("#x" & +Terminals.HexDigit);
			var character = (("\\" & Terminals.AnyChar) | hex_character | Terminals.AnyChar.Except("]")).WithName("character");
			var character_range = (character & "-" & character).WithName("character range");
			var character_set = ("[" & ~(Parser)"^" & +(character_range | character) & "]").WithName("character set");
			var terminal_string = new StringParser { QuoteCharacters = new [] { '\"', '\'', '’' }, Name = "terminal string" };
			var special_sequence = ("?" & (+Terminals.AnyChar).Until("?").WithName("name") & "?").WithName("special sequence");
			var meta_identifier_terminal = Terminals.Letter & -(Terminals.LetterOrDigit | '_');
			var integer = new NumberParser().WithName("integer");

			// nonterminals
			var definition_list = new RepeatParser(0).WithName("definition list");
			var single_definition = new RepeatParser(1).WithName("single definition");
			var term = new SequenceParser().WithName("term");
			var primary = new AlternativeParser().WithName("primary");
			var exception = new UnaryParser("exception");
			var factor = new SequenceParser().WithName("factor");
			var meta_identifier = new RepeatParser(1).WithName("meta identifier");
			var syntax_rule = new SequenceParser().WithName("syntax rule");
			var rule_equals = new AlternativeParser().WithName("equals");
			Parser meta_reference = meta_identifier;

			Parser grouped_sequence = ("(" & ows & definition_list & ows & ")").WithName("grouped sequence");

			if (style.HasFlag(EbnfStyle.SquareBracketAsOptional))
			{
				primary.Add(("[" & ows & definition_list & ows & "]").WithName("optional sequence"));
			}

			if (!style.HasFlag(EbnfStyle.CardinalityFlags))
			{
				var repeated_sequence = ("{" & ows & definition_list & ows & "}").WithName("repeated sequence");
				primary.Add(repeated_sequence);
			}

			// rules
			meta_identifier.Inner = meta_identifier_terminal;
			meta_identifier.Separator = +(Terminals.SingleLineWhiteSpace);
			if (!style.HasFlag(EbnfStyle.CommaSeparator))
			{
				// w3c identifiers must be a single word
				meta_identifier.Maximum = 1;
				meta_reference = meta_reference.NotFollowedBy(ows & rule_equals);
			}
			primary.Add(grouped_sequence, meta_reference, terminal_string, special_sequence);
			if (style.HasFlag(EbnfStyle.CharacterSets) && !style.HasFlag(EbnfStyle.SquareBracketAsOptional))
			{
				// w3c supports character sets
				primary.Add(hex_character.Named("hex character"));
				primary.Add(character_set);
			}
			if (style.HasFlag(EbnfStyle.NumericCardinality))
				factor.Add(~(integer & ows & "*" & ows));
			factor.Add(primary);
			if (style.HasFlag(EbnfStyle.CardinalityFlags))
			{
				// w3c defines cardinality at the end of a factor
				var flags = style.HasFlag(EbnfStyle.SquareBracketAsOptional) ? "*+" : "?*+";
				factor.Add(~(ows & Terminals.Set(flags).WithName("cardinality"))); 
			}
			term.Add(factor, ~(ows & "-" & ows & exception));
			exception.Inner = term;
			single_definition.Inner = term;
			single_definition.Separator = style.HasFlag(EbnfStyle.CommaSeparator) ? (Parser)(ows & "," & ows) : ows;
			definition_list.Inner = single_definition;
			definition_list.Separator = ows & "|" & ows;
			rule_equals.Add(style.HasFlag(EbnfStyle.DoubleColonEquals) ? "::=" : "=", ":=");
			syntax_rule.Add(meta_identifier, ows, rule_equals, ows, definition_list);
			if (style.HasFlag(EbnfStyle.SemicolonTerminator))
				syntax_rule.Add(ows, ";"); // iso rules are terminated by a semicolon

			var syntax_rules = +syntax_rule;
			syntax_rules.Separator = style.HasFlag(EbnfStyle.SemicolonTerminator) ? ows : rws;

			Inner = ows & syntax_rules & ows;

			AttachEvents();
		}
Exemplo n.º 12
0
        public EbnfGrammar(EbnfStyle style)
            : base("ebnf")
        {
            Style = style;
            DefineCommonNonTerminals = true;
            GenerateSpecialSequences();

            // terminals
            var comment         = style.HasFlag(EbnfStyle.BracketComments) ? new GroupParser("(*", "*)") : new GroupParser("/*", "*/");
            var ows             = -(Terminals.WhiteSpace | comment);
            var rws             = +(Terminals.WhiteSpace | comment);
            var hex_character   = ("#x" & +Terminals.HexDigit);
            var character       = (("\\" & Terminals.AnyChar) | hex_character | Terminals.AnyChar.Except("]")).WithName("character");
            var character_range = (character & "-" & character).WithName("character range");
            var character_set   = ("[" & ~(Parser)"^" & +(character_range | character) & "]").WithName("character set");
            var terminal_string = new StringParser {
                QuoteCharacters = new [] { '\"', '\'', '’' }, Name = "terminal string"
            };
            var special_sequence         = ("?" & (+Terminals.AnyChar).Until("?").WithName("name") & "?").WithName("special sequence");
            var meta_identifier_terminal = Terminals.Letter & -(Terminals.LetterOrDigit | '_');
            var integer = new NumberParser().WithName("integer");

            // nonterminals
            var    definition_list   = new RepeatParser(0).WithName("definition list");
            var    single_definition = new RepeatParser(1).WithName("single definition");
            var    term            = new SequenceParser().WithName("term");
            var    primary         = new AlternativeParser().WithName("primary");
            var    exception       = new UnaryParser("exception");
            var    factor          = new SequenceParser().WithName("factor");
            var    meta_identifier = new RepeatParser(1).WithName("meta identifier");
            var    syntax_rule     = new SequenceParser().WithName("syntax rule");
            var    rule_equals     = new AlternativeParser().WithName("equals");
            Parser meta_reference  = meta_identifier;

            Parser grouped_sequence = ("(" & ows & definition_list & ows & ")").WithName("grouped sequence");

            if (style.HasFlag(EbnfStyle.SquareBracketAsOptional))
            {
                primary.Add(("[" & ows & definition_list & ows & "]").WithName("optional sequence"));
            }

            if (!style.HasFlag(EbnfStyle.CardinalityFlags))
            {
                var repeated_sequence = ("{" & ows & definition_list & ows & "}").WithName("repeated sequence");
                primary.Add(repeated_sequence);
            }

            // rules
            meta_identifier.Inner     = meta_identifier_terminal;
            meta_identifier.Separator = +(Terminals.SingleLineWhiteSpace);
            if (!style.HasFlag(EbnfStyle.CommaSeparator))
            {
                // w3c identifiers must be a single word
                meta_identifier.Maximum = 1;
                meta_reference          = meta_reference.NotFollowedBy(ows & rule_equals);
            }
            primary.Add(grouped_sequence, meta_reference, terminal_string, special_sequence);
            if (style.HasFlag(EbnfStyle.CharacterSets) && !style.HasFlag(EbnfStyle.SquareBracketAsOptional))
            {
                // w3c supports character sets
                primary.Add(hex_character.Named("hex character"));
                primary.Add(character_set);
            }
            if (style.HasFlag(EbnfStyle.NumericCardinality))
            {
                factor.Add(~(integer & ows & "*" & ows));
            }
            factor.Add(primary);
            if (style.HasFlag(EbnfStyle.CardinalityFlags))
            {
                // w3c defines cardinality at the end of a factor
                var flags = style.HasFlag(EbnfStyle.SquareBracketAsOptional) ? "*+" : "?*+";
                factor.Add(~(ows & Terminals.Set(flags).WithName("cardinality")));
            }
            term.Add(factor, ~(ows & "-" & ows & exception));
            exception.Inner             = term;
            single_definition.Inner     = term;
            single_definition.Separator = style.HasFlag(EbnfStyle.CommaSeparator) ? (Parser)(ows & "," & ows) : ows;
            definition_list.Inner       = single_definition;
            definition_list.Separator   = ows & "|" & ows;
            rule_equals.Add(style.HasFlag(EbnfStyle.DoubleColonEquals) ? "::=" : "=", ":=");
            syntax_rule.Add(meta_identifier, ows, rule_equals, ows, definition_list);
            if (style.HasFlag(EbnfStyle.SemicolonTerminator))
            {
                syntax_rule.Add(ows, ";");                 // iso rules are terminated by a semicolon
            }
            var syntax_rules = +syntax_rule;

            syntax_rules.Separator = style.HasFlag(EbnfStyle.SemicolonTerminator) ? ows : rws;

            Inner = ows & syntax_rules & ows;

            AttachEvents();
        }
Exemplo n.º 13
0
		void AttachEvents()
		{
			ruleName.Matched += m => {
				Parser parser;
				var name = m["name"].Text;
				if (!parserLookup.TryGetValue(name, out parser) && !baseLookup.TryGetValue(name, out parser))
				{
					parser = Terminals.LetterOrDigit.Repeat();
					parser.Name = name;
				}
				m.Tag = parser;
			};

			literal.Matched += m => m.Tag = new LiteralTerminal(m["value"].Text);
			optionalRule.Matched += m => m.Tag = new OptionalParser((Parser)m["parser"].Tag);
			repeatRule.Matched += m => m.Tag = new RepeatParser((Parser)m["parser"].Tag, 0) { Separator = sws };
			list.Matched += m => {
				if (m.Matches.Count > 1)
				{
					var parser = new SequenceParser();
					foreach (var child in m.Matches)
					{
						if (child.Parser.Name == "ws")
							parser.Items.Add(sws);
						else if (child.Parser.Name == "term")
							parser.Items.Add((Parser)child["parser"].Tag);
					}
					m.Tag = parser;
				}
				else
				{
					m.Tag = m["term"]["parser"].Tag;
				}
			};

			listRepeat.Matched += m => {
				// collapse alternatives to one alternative parser
				var parser = (Parser)m["expression"]["parser"].Tag;
				var alt = parser as AlternativeParser ?? new AlternativeParser(parser);
				alt.Items.Insert(0, (Parser)m["list"]["parser"].Tag);
				m.Tag = alt;
			};

			rule.Matched += m => {
				var parser = (UnaryParser)m.Tag;
				parser.Inner = (Parser)m["parser"].Tag;
				m.Tag = parser;
			};
			rule.PreMatch += m => {
				var name = m["ruleName"]["name"].Text;
				Parser parser;
				if (name == startParserName)
					parser = new Grammar(name);
				else
					parser = new UnaryParser(name);
				m.Tag = parser;
				parserLookup[parser.Name] = parser;
			};
		}
Exemplo n.º 14
0
        private void AttachEvents()
        {
            // attach logic to parsers
            parameter.PreMatch += m =>
            {
                string name  = m["name"]["value"].Text;
                string value = m["body"].Text;
                definition.Properties[name] = value;
                bool val;
                if (
                    string.Equals("Auto Whitespace", name, StringComparison.OrdinalIgnoreCase) &&
                    bool.TryParse(value, out val) && !val)
                {
                    definition.Whitespace = null;
                }
            };

            ruleDecl.Matched += m =>
            {
                string name          = m["name"]["value"].Text;
                bool   addWhitespace = name == definition.GrammarName;
                Parser parser        = Alternative(m, "handle",
                                                   r => Sequence(r, "symbol", Symbol, addWhitespace));
                definition.Rules[name].Inner = parser;
            };
            ruleDecl.PreMatch += m =>
            {
                string      name = m["name"]["value"].Text;
                UnaryParser parser;
                if (name == definition.GrammarName)
                {
                    parser = new Grammar(name);
                }
                else
                {
                    parser = new UnaryParser(name);
                }
                definition.Rules.Add(parser.Name, parser);
            };

            terminalDecl.Matched += m =>
            {
                Parser inner  = Sequence(m, "regExp", RegExp);
                var    parser = m.Tag as UnaryParser;
                if (parser != null)
                {
                    parser.Inner = inner;
                }
                var    groupParser = m.Tag as GroupParser;
                string name        = m["name"].Text;
                if (groupParser != null)
                {
                    if (name.EndsWith(" Start", StringComparison.Ordinal))
                    {
                        groupParser.Start = inner;
                    }
                    else if (name.EndsWith(" End", StringComparison.Ordinal))
                    {
                        groupParser.End = inner;
                    }
                    else if (name.EndsWith(" Line", StringComparison.Ordinal))
                    {
                        groupParser.Line = inner;
                    }
                    int count = name.EndsWith(" Start", StringComparison.Ordinal)
                                                                ? 6
                                                                : name.EndsWith(" Line", StringComparison.Ordinal)
                                                                      ? 5
                                                                      : name.EndsWith(" End", StringComparison.Ordinal)
                                                                            ? 4
                                                                            : 0;
                    name = name.Substring(0, name.Length - count);
                }

                if (name.Equals("Comment", StringComparison.OrdinalIgnoreCase) ||
                    name.Equals("Whitespace", StringComparison.OrdinalIgnoreCase)
                    )
                {
                    definition.ClearSeparator();
                }
            };

            terminalDecl.PreMatch += m =>
            {
                string name = m["name"].Text;
                if (name.EndsWith(" Start", StringComparison.Ordinal) ||
                    name.EndsWith(" End", StringComparison.Ordinal) ||
                    name.EndsWith(" Line", StringComparison.Ordinal))
                {
                    Parser parser;
                    int    count = name.EndsWith(" Start", StringComparison.Ordinal)
                                                                 ? 6
                                                                 : name.EndsWith(" Line", StringComparison.Ordinal)
                                                                       ? 5
                                                                       : name.EndsWith(" End", StringComparison.Ordinal)
                                                                             ? 4
                                                                             : 0;
                    name = name.Substring(0, name.Length - count);
                    if (definition.Terminals.TryGetValue(name, out parser))
                    {
                        parser = parser as GroupParser ?? new GroupParser();
                    }
                    else
                    {
                        parser = new GroupParser();
                    }
                    m.Tag = definition.Terminals[name] = parser;
                }
                else
                {
                    m.Tag = definition.Terminals[name] = new UnaryParser(name);
                }
            };

            setDecl.PreMatch += m =>
            {
                Parser parser = SetMatch(m["setExp"]);
                definition.Sets[m["setName"]["value"].Text] = parser;
                m.Tag = parser;
            };
        }
Exemplo n.º 15
0
		void AttachEvents()
		{
			// attach logic to parsers
			parameter.PreMatch += m => {
				var name = m["name"]["value"].Text;
				var value = m["body"].Text;
				definition.Properties[name] = value;
				bool val;
				if (string.Equals("Auto Whitespace", name, StringComparison.OrdinalIgnoreCase) && bool.TryParse(value, out val) && !val)
					definition.Whitespace = null;
			};

			ruleDecl.Matched += m => {
				var name = m["name"]["value"].Text;
				bool addWhitespace = name == definition.GrammarName;
				var parser = Alternative(m, "handle", r => Sequence(r, "symbol", Symbol, addWhitespace));
				definition.Rules[name].Inner = parser;
			};
			ruleDecl.PreMatch += m => {
				var name = m["name"]["value"].Text;
				UnaryParser parser;
				if (name == definition.GrammarName)
					parser = new Grammar(name);
				else
					parser = new UnaryParser(name);
				definition.Rules.Add(parser.Name, parser);
			};

			terminalDecl.Matched += m => {
				var inner = Sequence(m, "regExp", RegExp);
				var parser = m.Tag as UnaryParser;
				if (parser != null)
					parser.Inner = inner;
				var groupParser = m.Tag as GroupParser;
				var name = m["name"].Text;
				if (groupParser != null)
				{
					if (name.EndsWith(" Start", StringComparison.Ordinal))
						groupParser.Start = inner;
					else if (name.EndsWith(" End", StringComparison.Ordinal))
						groupParser.End = inner;
					else if (name.EndsWith(" Line", StringComparison.Ordinal))
						groupParser.Line = inner;
					var count = name.EndsWith(" Start", StringComparison.Ordinal) ? 6 : name.EndsWith(" Line", StringComparison.Ordinal) ? 5 : name.EndsWith(" End", StringComparison.Ordinal) ? 4 : 0;
					name = name.Substring(0, name.Length - count);
				}

				if (name.Equals("Comment", StringComparison.OrdinalIgnoreCase)
				    || name.Equals("Whitespace", StringComparison.OrdinalIgnoreCase)
				    )
				{
					definition.ClearSeparator();
				}
			};

			terminalDecl.PreMatch += m => {
				var name = m["name"].Text;
				if (name.EndsWith(" Start", StringComparison.Ordinal) || name.EndsWith(" End", StringComparison.Ordinal) || name.EndsWith(" Line", StringComparison.Ordinal))
				{
					Parser parser;
					var count = name.EndsWith(" Start", StringComparison.Ordinal) ? 6 : name.EndsWith(" Line", StringComparison.Ordinal) ? 5 : name.EndsWith(" End", StringComparison.Ordinal) ? 4 : 0;
					name = name.Substring(0, name.Length - count);
					if (definition.Terminals.TryGetValue(name, out parser))
					{
						parser = parser as GroupParser ?? new GroupParser();
					}
					else
						parser = new GroupParser();
					m.Tag = definition.Terminals[name] = parser;
				}
				else
					m.Tag = definition.Terminals[name] = new UnaryParser(name);
			};

			setDecl.PreMatch += m => {
				var parser = SetMatch(m["setExp"]);
				definition.Sets[m["setName"]["value"].Text] = parser;
				m.Tag = parser;
			};
		}