void CreateSeparator()
		{
			var alt = new AlternativeParser();
			var p = Comment;
			if (p != null)
				alt.Items.Add(p);
			p = Whitespace;
			if (p != null)
				alt.Items.Add(p);
			if (alt.Items.Count == 0)
				separator = null;
			else
				separator = -alt;
		}
示例#2
0
        public BnfGrammar(bool enhanced = true)
            : base("bnf")
        {
            if (enhanced)
            {
                foreach (var property in typeof(Terminals).GetProperties())
                {
                    if (typeof(Parser).IsAssignableFrom(property.PropertyType))
                    {
                        var parser = property.GetValue(null, null) as Parser;
                        baseLookup[property.Name] = parser.Named(property.Name);
                    }
                }
            }

            var lineEnd = sws & +(sws & Terminals.Eol);

            literal = (
                (sq & (+!sq).Named("value").Optional() & sq)
                | (dq & (+!dq).Named("value").Optional() & dq)
            ).Named("parser");

            RuleNameParser = "<" & Terminals.Set('>').Inverse().Repeat().Named("name") & ">";

            RuleParser = new AlternativeParser(); // defined later

            TermParser = literal | (ruleName = RuleNameParser.Named("parser"));
            if (enhanced)
            {
                TermParser.Items.Add('(' & sws & RuleParser & sws & ')');
                TermParser.Items.Add(repeatRule = ('{' & sws & RuleParser & sws & '}').Named("parser"));
                TermParser.Items.Add(optionalRule = ('[' & sws & RuleParser & sws & ']').Named("parser"));
            }

            list = (TermParser.Named("term") & -(~((+Terminals.SingleLineWhiteSpace).Named("ws")) & TermParser.Named("term"))).Named("parser");

            listRepeat = (list.Named("list") & ws & '|' & sws & ~(RuleParser.Named("expression"))).Named("parser");
            RuleParser.Items.Add(listRepeat);
            RuleParser.Items.Add(list);

            rule = (~lineEnd & sws & RuleNameParser.Named("ruleName") & ws & ruleSeparator & sws & RuleParser & lineEnd).Named("parser");
            Expresssions = new AlternativeParser();
            Expresssions.Items.Add(rule);

            this.Inner = ws & +Expresssions & ws;

            AttachEvents();
        }
示例#3
0
		Parser CharacterSet(Match match)
		{
			var alt = new AlternativeParser();
			var inverse = match.Text.StartsWith("[^", StringComparison.Ordinal);
			var characters = new List<char>();
			foreach (var child in match.Matches.Where(r => r.Name != null))
			{
				switch (child.Name)
				{
					case "character range":
						var first = Character(child.Matches.First(r => r.Name == "character"));
						var last = Character(child.Matches.Last(r => r.Name == "character"));
						if (first != null && last != null)
							alt.Add(new CharRangeTerminal(first.Value, last.Value) { Inverse = inverse });
						break;
					case "character":
						var character = Character(child);
						if (character != null)
							characters.Add(character.Value);
						break;
					default:
						throw new FormatException(string.Format("Invalid character set child for text '{0}'", child.Text));
				}
			}
			if (characters.Count > 0)
			{
				alt.Add(new CharSetTerminal(characters.ToArray()) { Inverse = inverse });
			}
			if (alt.Items.Count > 1)
				return alt;
			if (alt.Items.Count > 0)
				return alt.Items[0];
			return new UnaryParser();
			//throw new FormatException(string.Format("Character set has no characters '{0}'", match.Text));
		}
示例#4
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();
		}
示例#5
0
 protected AlternativeParser(AlternativeParser other, ParserCloneArgs chain)
     : base(other, chain)
 {
 }
示例#6
0
 protected AlternativeParser(AlternativeParser other, ParserCloneArgs chain)
     : base(other, chain)
 {
 }
示例#7
0
		public GoldGrammar()
			: base("gold")
		{
			var oldSeparator = Parser.DefaultSeparator;
			// Special Terminals

			var parameterCh = Terminals.Printable - Terminals.Set("\"'");
			var nonterminalCh = Terminals.LetterOrDigit | Terminals.Set("_-. ");
			var terminalCh = Terminals.LetterOrDigit | Terminals.Set("_-.");
			var literalCh = Terminals.Printable - Terminals.Set('\'');
			var setLiteralCh = Terminals.Printable - Terminals.Set("[]'");
			var setNameCh = Terminals.Printable - Terminals.Set("{}");

			var parameterName = ('"' & (+parameterCh).WithName("value") & '"').Separate();
			var nonterminal = ('<' & (+nonterminalCh).WithName("value") & '>').Separate();
			var terminal = ((+terminalCh).WithName("terminal") | ('\'' & (-literalCh).WithName("literal") & '\'')).Separate();
			var setLiteral = ('[' & +(setLiteralCh.WithName("ch") | '\'' & (-literalCh).WithName("ch") & '\'') & ']').WithName("setLiteral");
			var setName = ('{' & (+setNameCh).WithName("value") & '}').WithName("setName");

			// Line-Based Grammar Declarations

			var comments = new GroupParser("!*", "*!", "!");
			var newline = Terminals.Eol;
			whitespace = -(Terminals.SingleLineWhiteSpace | comments);
			Parser.DefaultSeparator = whitespace;
			var nlOpt = -newline;
			var nl = +newline | Terminals.End;

			// Parameter Definition

			var parameterItem = parameterName | terminal | setLiteral | setName | nonterminal;

			var parameterItems = +parameterItem;

			var parameterBody = parameterItems & -(nlOpt & '|' & parameterItems);

			parameter = (parameterName.Named("name") & nlOpt & '=' & parameterBody.WithName("body") & nl).WithName("parameter");

			// Set Definition

			var setItem = setLiteral | setName;

			var setExp = new AlternativeParser { Name = "setExp" };
			setExp.Add((setExp & nlOpt & '+' & setItem).WithName("add"),
				(setExp & nlOpt & '-' & setItem).WithName("sub"), 
				setItem);


			setDecl = (setName & nlOpt & '=' & setExp & nl).WithName("setDecl");

			//  Terminal Definition

			var regExp2 = new SequenceParser();

			var kleeneOpt = (~((Parser)'+' | '?' | '*')).WithName("kleene");

			regExpItem = ((setLiteral & kleeneOpt)
				| (setName & kleeneOpt)
				| (terminal.Named("terminal") & kleeneOpt)
				| ('(' & regExp2.Named("regExp2") & ')' & kleeneOpt)).WithName("regExpItem");

			var regExpSeq = (+regExpItem).WithName("regExpSeq");

			regExp2.Items.Add(regExpSeq);
			regExp2.Items.Add(-('|' & regExpSeq));

			regExp = (regExpSeq & -(nlOpt & '|' & regExpSeq)).WithName("regExp");

			var terminalName = +terminal;

			terminalDecl = (terminalName.Named("name") & nlOpt & '=' & regExp & nl).WithName("terminalDecl");

			// Rule Definition
			symbol = (terminal.Named("terminal") | nonterminal.Named("nonterminal")).WithName("symbol");

			handle = (-symbol).WithName("handle");
			var handles = handle & -(nlOpt & '|' & handle);
			ruleDecl = (nonterminal.Named("name") & nlOpt & "::=" & handles & nl).WithName("ruleDecl");

			// Rules

			var definitionDecl = parameter | setDecl | terminalDecl | ruleDecl;

			var content = -definitionDecl;

			this.Inner = nlOpt & content & nlOpt;

			Parser.DefaultSeparator = oldSeparator;
			AttachEvents();
		}
示例#8
0
		public BnfGrammar(bool enhanced = true)
			: base("bnf")
		{
			if (enhanced)
			{
				foreach (var terminal in Terminals.GetTerminals())
				{
					baseLookup[terminal.Item1] = terminal.Item2.Named(terminal.Item1);
				}
			}

			literal = (
				(sq & (+!sq).WithName("value").Optional() & sq)
				| (dq & (+!dq).WithName("value").Optional() & dq)
				| ((+(Terminals.WhiteSpace.Inverse().Except(Terminals.Set("<[{(|)}]>"))))).WithName("value")
			).WithName("parser");


			RuleNameParser = "<" & Terminals.Set("<>").Inverse().Repeat().WithName("name") & ">";

			RuleParser = new AlternativeParser(); // defined later 

			TermParser = ((ruleName = RuleNameParser.Named("parser")).NotFollowedBy(ows & ruleSeparator)) | literal;
			TermParser.Name = "term";
			if (enhanced)
			{
				TermParser.Items.Add('(' & ows & RuleParser & ows & ')');
				TermParser.Items.Add(repeatRule = ('{' & ows & RuleParser & ows & '}').WithName("parser"));
				TermParser.Items.Add(optionalRule = ('[' & ows & RuleParser & ows & ']').WithName("parser"));
			}
			TermParser.Items.Add((ows & RuleNameParser & ows & ruleSeparator).Not() & Terminals.Set("<[{(}]>").WithName("value").Named("parser"));

			list = (TermParser & -(~(rws.Named("ws")) & TermParser)).WithName("parser");

			listRepeat = (list.Named("list") & ows & '|' & ~(ows & RuleParser.Named("expression"))).WithName("parser");
			RuleParser.Items.Add(listRepeat);
			RuleParser.Items.Add(list);

			rule = (RuleNameParser.Named("ruleName") & ows & ruleSeparator & ows & RuleParser).WithName("parser");
			Expresssions = new AlternativeParser();
			Expresssions.Items.Add(rule);

			this.Inner = ows & (+Expresssions).SeparatedBy(rws) & ows;

			AttachEvents();
		}