Beispiel #1
0
 protected GroupParser(GroupParser other, ParserCloneArgs chain)
     : base(other, chain)
 {
     this.Line  = chain.Clone(other.Line);
     this.Start = chain.Clone(other.Start);
     this.End   = chain.Clone(other.End);
 }
		protected GroupParser(GroupParser other, ParserCloneArgs chain)
			: base(other, chain)
		{
			this.Line = chain.Clone(other.Line);
			this.Start = chain.Clone(other.Start);
			this.End = chain.Clone(other.End);
		}
		public XmlGrammar()
			: base("xml")
		{
			EnableMatchEvents = false;
			var comment = new GroupParser("<!--", "-->");
			var ws = Terminals.Repeat(Char.IsWhiteSpace, 1);
			var ows = Terminals.Repeat(Char.IsWhiteSpace, 0);
			var wsc = -(ws | comment);

			var name = Terminals.Repeat(new RepeatCharItem(Char.IsLetter, 1, 1), new RepeatCharItem(Char.IsLetterOrDigit, 0));
			var namedName = Terminals.Repeat(new RepeatCharItem(Char.IsLetter, 1, 1), new RepeatCharItem(Char.IsLetterOrDigit, 0)).WithName("name");

			var text = new UntilParser("<", 1).WithName("text");
			var attributeValue = new StringParser { QuoteCharacters = new [] { '"' }, Name = "value" };
			var attribute = (namedName & ows & "=" & ows & attributeValue);
			var attributes = (ws & (+attribute).SeparatedBy(ws).WithName("attributes")).Optional();

			var content = new RepeatParser { Separator = wsc };

			var startTag = "<" & namedName & attributes & ows;
			var endTag = "</" & name & ">";
			var obj = (startTag & ("/>" | (">" & wsc & content & wsc & endTag))).WithName("object");
			var cdata = ("<![CDATA[" & new UntilParser("]]>", 0, skip: true)).WithName("cdata");
			content.Inner = obj | text | cdata;

			var declaration = "<?" & name & attributes & ows & "?>";
			Inner = declaration & wsc & obj & wsc;
		}
Beispiel #4
0
 protected GroupParser(GroupParser other, ParserCloneArgs chain)
     : base(other, chain)
 {
     this.line  = chain.Clone(other.line);
     this.start = chain.Clone(other.start);
     this.end   = chain.Clone(other.end);
     SetLine();
     SetBlock();
     SetInner();
 }
Beispiel #5
0
 protected GroupParser(GroupParser other, ParserCloneArgs chain)
     : base(other, chain)
 {
     this.line = chain.Clone(other.line);
     this.start = chain.Clone(other.start);
     this.end = chain.Clone(other.end);
     SetLine();
     SetBlock();
     SetInner();
 }
		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();
		}
		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;
			};
		}