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; }; }
public static Parser Named(this Parser parser, string name) { var unary = new UnaryParser(parser); unary.Name = name ?? Guid.NewGuid().ToString(); return(unary); }
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); }
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)); }
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(); }
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(); }
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; }
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); }
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; }; }
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(); }
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(); }
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; }; }
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; }; }
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; }; }