public void TestNonSLRGrammar() { // 1. S’ ::= S 4. L ::= * R // 2. S ::= L = R 5. L ::= id // 3. S ::= R 6. R ::= L var configurator = ParserFactory.Configure <int>(); var s = configurator.CreateNonTerminal(); s.DebugName = "S"; var l = configurator.CreateNonTerminal(); l.DebugName = "L"; var r = configurator.CreateNonTerminal(); r.DebugName = "R"; s.AddProduction(l, "=", r); s.AddProduction(r); l.AddProduction("*", r); l.AddProduction("id"); r.AddProduction(l); configurator.CreateParser(); }
public void TestMultipleEpsilonParametersInARow() { var configurator = ParserFactory.Configure <int>(); var a = configurator.CreateNonTerminal(); a.DebugName = "A"; var b = configurator.CreateNonTerminal(); b.DebugName = "B"; var c = configurator.CreateNonTerminal(); c.DebugName = "C"; var d = configurator.CreateNonTerminal(); d.DebugName = "D"; a.AddProduction("a", b, c, d, "a"); b.AddProduction("b"); b.AddProduction(); c.AddProduction("c"); c.AddProduction(); d.AddProduction("d"); d.AddProduction(); var parser = configurator.CreateParser(); parser.Parse("aa"); parser.Parse("aba"); parser.Parse("abca"); parser.Parse("abcda"); parser.Parse("aca"); parser.Parse("ada"); parser.Parse("abda"); }
public void TestGrammarWithEpsilonTransitions() { var configurator = ParserFactory.Configure <int>(); var func = configurator.CreateNonTerminal(); func.DebugName = "FUNC"; var paramList = configurator.CreateNonTerminal(); paramList.DebugName = "PARAMLIST"; var optionalParamList = configurator.CreateNonTerminal(); optionalParamList.DebugName = "OPTIONALPARAMLIST"; func.AddProduction("func", "(", optionalParamList, ")"); paramList.AddProduction(paramList, ",", "ident"); paramList.AddProduction("ident"); optionalParamList.AddProduction(paramList); optionalParamList.AddProduction(); var parser = configurator.CreateParser(); parser.Parse("func(ident,ident,ident,ident)"); parser.Parse("func()"); }
public void TestDeepEpsilonChain() { var configurator = ParserFactory.Configure <int>(); var a = configurator.CreateNonTerminal(); var b = configurator.CreateNonTerminal(); var c = configurator.CreateNonTerminal(); var d = configurator.CreateNonTerminal(); var e = configurator.CreateNonTerminal(); a.AddProduction("a", b); b.AddProduction(c); b.AddProduction(); c.AddProduction("d", d); d.AddProduction(e); d.AddProduction(); e.AddProduction("e"); var parser = configurator.CreateParser(); parser.Parse("ade"); parser.Parse("a"); parser.Parse("ad"); }
public void TestNonAssociativity() { try { // Configure an illegal rule var configurator = ParserFactory.Configure <int>(); var number = configurator.CreateTerminal(@"\d+", int.Parse); var equals = configurator.CreateTerminal("="); configurator.NonAssociative(equals); var exp = configurator.CreateNonTerminal(); exp.AddProduction(exp, equals, exp) .SetReduceFunction(f => f[0] - f[2]); exp.AddProduction(number).SetReduceFunction( f => f[0]); configurator.CreateParser(); Assert.Fail("You shall not parse!"); } catch (ShiftReduceConflictException <int> ) { // We cool } }
public void TestACalculator() { // This is a full on integration test that builds a parser and performs a simple calculation. var configurator = ParserFactory.Configure <int>(); ITerminal <int> number = configurator.CreateTerminal("\\d+", int.Parse); number.DebugName = "number"; INonTerminal <int> expr = configurator.CreateNonTerminal(); expr.DebugName = "expr"; INonTerminal <int> term = configurator.CreateNonTerminal(); term.DebugName = "term"; INonTerminal <int> factor = configurator.CreateNonTerminal(); factor.DebugName = "factor"; expr.AddProduction(expr, "+", term).SetReduceFunction(s => s[0] + s[2]); expr.AddProduction(expr, "-", term).SetReduceFunction(s => s[0] - s[2]); expr.AddProduction(term).SetReduceFunction(s => s[0]); term.AddProduction(term, "*", factor).SetReduceFunction(s => s[0] * s[2]); term.AddProduction(term, "/", factor).SetReduceFunction(s => s[0] / s[2]); term.AddProduction(factor).SetReduceFunction(s => s[0]); factor.AddProduction(number).SetReduceFunction(s => s[0]); factor.AddProduction("(", expr, ")").SetReduceFunction(s => s[1]); var parser = configurator.CreateParser(); int result = parser.Parse(new StringReader("2-2-5")); Assert.AreEqual(-5, result); }
public void TestShiftReduceError() { INonTerminal <string> ifStatement = null; try { // This configuration is not a valid LR1 parser. It contains shift reduce conflicts // clasical dangling else case var configurator = ParserFactory.Configure <string>(); var ident = configurator.CreateTerminal("[a-z]+"); ident.DebugName = "ident"; ifStatement = configurator.CreateNonTerminal(); ifStatement.DebugName = "ifStatement"; var statement = configurator.CreateNonTerminal(); statement.DebugName = "statement"; ifStatement.AddProduction("if", "\\(", ident, "\\)", "then", statement); ifStatement.AddProduction("if", "\\(", ident, "\\)", "then", statement, "else", statement); statement.AddProduction(ifStatement); statement.AddProduction(ident, "=", ident); configurator.LexerSettings.CreateLexer = false; configurator.CreateParser(); Assert.Fail("No exception for ambiguous grammar"); } catch (ShiftReduceConflictException <string> e) { Assert.AreEqual(ifStatement, e.ReduceSymbol); Assert.AreEqual("else", e.ShiftSymbol.DebugName); } }
public void TestParseTableToString() { // Need to get our hands on a parse table, which isn't the easiest thing for a normal user // since its encapsulated and destroyed. However, we have magic casts at our disposal. // We are simply going to test that it doesn't break, not really what it contains. var configurator = ParserFactory.Configure <int>(); var a = configurator.CreateNonTerminal(); a.DebugName = "a"; var b = configurator.CreateNonTerminal(); b.DebugName = "b"; var c = configurator.CreateNonTerminal(); c.DebugName = "c"; a.AddProduction(b); a.AddProduction(c); b.AddProduction("b"); c.AddProduction("c"); var grammar = (IGrammar <int>)configurator; var parser = configurator.CreateParser(); string debugString = parser.ParseTable.ToDebugString(grammar, 3); Assert.IsNotNull(debugString); }
public void TestSingleRuleTerminalGrammar() { var configurator = ParserFactory.Configure <int>(); var s = configurator.CreateNonTerminal(); s.DebugName = "S"; s.AddProduction("a", "b", "c", "d"); var parser = configurator.CreateParser(); parser.Parse("abcd"); }
public void TestCanMultiplyDefineTerminalStringsInConfiguration() { var configurator = ParserFactory.Configure <int>(); INonTerminal <int> nonTerminal = configurator.CreateNonTerminal(); nonTerminal.DebugName = "NonTerm"; nonTerminal.AddProduction("this", "is", "a", "string"); nonTerminal.AddProduction("this", "is", "a", "test"); var parser = configurator.CreateParser(); Assert.IsNotNull(parser); }
public void TestLeftAssociative() { var configurator = ParserFactory.Configure <int>(); var number = configurator.CreateTerminal(@"\d+", int.Parse); var plus = configurator.CreateTerminal("\\+"); var minus = configurator.CreateTerminal("-"); var mul = configurator.CreateTerminal("\\*"); var div = configurator.CreateTerminal("/"); configurator.LeftAssociative(plus, minus); configurator.LeftAssociative(mul, div); var exp = configurator.CreateNonTerminal(); exp.AddProduction(exp, plus, exp).SetReduceFunction(s => { Console.WriteLine("{0} + {1}", s[0], s[2]); return(s[0] + s[2]); }); exp.AddProduction(exp, minus, exp).SetReduceFunction(s => { Console.WriteLine("{0} - {1}", s[0], s[2]); return(s[0] - s[2]); }); exp.AddProduction(exp, mul, exp).SetReduceFunction(s => { Console.WriteLine("{0} * {1}", s[0], s[2]); return(s[0] * s[2]); }); exp.AddProduction(exp, div, exp).SetReduceFunction(s => { Console.WriteLine("{0} / {1}", s[0], s[2]); return(s[0] / s[2]); }); exp.AddProduction("(", exp, ")").SetReduceFunction(s => { Console.WriteLine("Paranthesis ({0})", s[1]); return(s[1]); }); exp.AddProduction(number).SetReduceFunction(s => s[0]); var parser = configurator.CreateParser(); Assert.AreEqual(-2, parser.Parse("1 - (1 + (1 * 2))")); Assert.AreEqual(2, parser.Parse("(((1 - 1) + 1) * 2)")); Assert.AreEqual(4 - 7 - 3, parser.Parse("4 - 7 - 3")); Assert.AreEqual(1 + 2 - 3 * 4, parser.Parse("1 + 2 - 3 * 4")); Assert.AreEqual(5 * 5 / 5, parser.Parse("5*5/5")); Assert.AreEqual(1 + 2 - 3 * 4 / 5 + 124 * 8, parser.Parse("1 + 2 - 3 * 4 / 5 + 124 * 8")); }
public void TestNonTerminalFollow() { // This grammar will require the parser factory to perform an aggregated FOLLOW // which it doesn't do if there aren't two nonteminals in a row var configurator = ParserFactory.Configure <int>(); var a = configurator.CreateNonTerminal(); var b = configurator.CreateNonTerminal(); var c = configurator.CreateNonTerminal(); var d = configurator.CreateNonTerminal(); a.AddProduction(a, b, c, d); b.AddProduction("b"); c.AddProduction(b); d.AddProduction("d"); configurator.CreateParser(); }
public void TestRetardedCyclicGrammar() { try { var configurator = ParserFactory.Configure <byte>(); var t = configurator.CreateNonTerminal(); t.AddProduction(t); configurator.CreateParser(); Assert.Fail(); } catch (ShiftReduceConflictException <byte> ) { // There is no real need to check this exception. It says something // about wanting to shift the augmented start symbol. We are cool that this // sillyness doesn't run on forever. } }
public static void RunTechnical() { var configurator = ParserFactory.Configure <bool>(); configurator.LexerSettings.Ignore = new[] { @"\s+" }; var name = configurator.CreateTerminal("[a-z]+"); var quotedString = configurator.CreateTerminal("\"[^\"]+\""); var obj = configurator.CreateNonTerminal(); var optionalObjectList = configurator.CreateNonTerminal(); var objectList = configurator.CreateNonTerminal(); var optionalAttributeList = configurator.CreateNonTerminal(); var attributeList = configurator.CreateNonTerminal(); var attribute = configurator.CreateNonTerminal(); obj.AddProduction(name, "{", optionalObjectList, optionalAttributeList, "}"); optionalObjectList.AddProduction(objectList); optionalObjectList.AddProduction(); objectList.AddProduction(objectList, obj); objectList.AddProduction(obj); optionalAttributeList.AddProduction(attributeList); optionalAttributeList.AddProduction(); attributeList.AddProduction(attributeList, attribute); attributeList.AddProduction(attribute); attribute.AddProduction("[", name, "=", quotedString, "]"); var parser = configurator.CreateParser(); parser.Parse("fruits {" + " banana {" + " [tasty=\"true\"]" + " [colour=\"yellow\"]" + " }" + "" + " orange {" + " }" + " " + " [eatable=\"if not rotten\"]" + "}"); }
public void TestConstantStringsInRulesTakesPrecedenceOverDeclaredTerminals() { var configurator = ParserFactory.Configure <int>(); var ident = configurator.CreateTerminal("[a-z]+"); var s = configurator.CreateNonTerminal(); int x = 0; s.AddProduction("abc", ident).SetReduceFunction(f => { x = 1; return(0); }); var parser = configurator.CreateParser(); parser.Parse("abc abcde"); Assert.AreEqual(1, x); }
public void TestRightAssociativity() { var configurator = ParserFactory.Configure <int>(); var number = configurator.CreateTerminal(@"\d+", int.Parse); var minus = configurator.CreateTerminal("-"); configurator.RightAssociative(minus); var exp = configurator.CreateNonTerminal(); exp.AddProduction(exp, minus, exp).SetReduceFunction(f => f[0] - f[2]); exp.AddProduction(number).SetReduceFunction(f => f[0]); var parser = configurator.CreateParser(); Assert.AreEqual(4 - (7 - 3), parser.Parse("4 - 7 - 3")); }
public void TestRecoverFromErrors() { // Valid inputs are long lists of "a" followed by a ;. // "b" however is a legal token, and the error recovery should // skip tokens until it gets another ;. // The error recovery routine should also be called with the exception that is generated at that point int caughtErrors = 0; var configurator = ParserFactory.Configure <int>(); var listOfA = configurator.CreateNonTerminal(); var a = configurator.CreateNonTerminal(); var terminatedA = configurator.CreateNonTerminal(); a.AddProduction(a, "a").SetReduceFunction(f => f[0] + 1); a.AddProduction("a").SetReduceFunction(f => 1); terminatedA.AddProduction(a, ";").SetReduceFunction(f => f[0]); terminatedA.AddProduction(configurator.ErrorToken, ";").SetErrorFunction((e, f) => { Console.WriteLine(e); ++caughtErrors; return(0); }); listOfA.AddProduction(terminatedA).SetReduceFunction(f => f[0]); listOfA.AddProduction(listOfA, terminatedA).SetReduceFunction(f => f[0] + f[1]); // Bogus terminal that isn't in any sort of use configurator.CreateTerminal("b"); var parser = configurator.CreateParser(); const string legal = "aaaaaaa;aaaaaaaaaa;aaa;aa;a;aaaaa;aaaaaaaa;"; int legalAs = parser.Parse(legal); Assert.AreEqual(legal.Aggregate(0, (i, c) => c == 'a' ? i + 1 : i), legalAs); Assert.AreEqual(0, caughtErrors); const string withErrors = "aaaaaaa;aaaaaabaaa;aaa;aa;a;aaaaa;aaaaaaaa;"; legalAs = parser.Parse(withErrors); Assert.AreEqual("aaaaaaa;THESEAREEATEN;aaa;aa;a;aaaaa;aaaaaaaa;".Aggregate(0, (i, c) => c == 'a' ? i + 1 : i), legalAs); Assert.AreEqual(1, caughtErrors); }
public void TestRedeclaredTerminalDoesNotChangePrecedence() { var configurator = ParserFactory.Configure <int>(); var name = configurator.CreateTerminal("abc"); var ident = configurator.CreateTerminal("[a-z]+"); var s = configurator.CreateNonTerminal(); int x = 0; s.AddProduction("abc", ident).SetReduceFunction(f => { x = 1; return(0); }); var parser = configurator.CreateParser(); parser.Parse("abc abcde"); Assert.AreEqual(1, x); }
public void TestUnaryMinus() { var configurator = ParserFactory.Configure <int>(); var expr = configurator.CreateNonTerminal(); var mul = configurator.CreateTerminal(@"\*"); var minus = configurator.CreateTerminal("-"); var number = configurator.CreateTerminal(@"\d+", int.Parse); configurator.LeftAssociative(minus); configurator.LeftAssociative(mul); var highPrecgroup = configurator.LeftAssociative(); expr.AddProduction(expr, minus, expr).SetReduceFunction(f => { Console.WriteLine("{0} - {1}", f[0], f[2]); return(f[0] - f[2]); }); expr.AddProduction(expr, mul, expr).SetReduceFunction(f => { Console.WriteLine("{0} * {1}", f[0], f[2]); return(f[0] * f[2]); }); var uMinusProduction = expr.AddProduction(minus, expr); uMinusProduction.SetReduceFunction(f => { Console.WriteLine("-{0}", f[1]); return(-f[1]); }); uMinusProduction.SetPrecedence(highPrecgroup); expr.AddProduction(number).SetReduceFunction(f => f[0]); var parser = configurator.CreateParser(); int result = parser.Parse("9 - -5*-4 - 2"); Assert.AreEqual(9 - -5 * -4 - 2, result); }
public void TestShiftReduceConflictWithAccept() { // For certain grammars you can produce this stuff. It is not a real world case // but the exception should still be helpful // Here's how this retarded grammar looks // a := a | b | c // b := "b" // c := "c" // try { var configurator = ParserFactory.Configure <int>(); var a = configurator.CreateNonTerminal(); a.DebugName = "a"; var b = configurator.CreateNonTerminal(); b.DebugName = "b"; var c = configurator.CreateNonTerminal(); c.DebugName = "c"; a.AddProduction(a); a.AddProduction(b); a.AddProduction(c); b.AddProduction("b"); c.AddProduction("c"); configurator.CreateParser(); Assert.Fail(); } catch (ShiftReduceConflictException <int> ) { // There is no real need to check this exception. It says something // about wanting to reduce on the $. We are cool that this // sillyness doesn't run on forever. } }
public void TestLr1Harness() { // Duplicate grammar from dragon book, for comparison // // S -> CC // C -> cC | d var configurator = ParserFactory.Configure <int>(); var s = configurator.CreateNonTerminal(); s.DebugName = "S"; var c = configurator.CreateNonTerminal(); c.DebugName = "C"; s.AddProduction(c, c); c.AddProduction("c", c); c.AddProduction("d"); var parser = configurator.CreateParser(); parser.Parse("ccccccccdd"); }
public void TestBadToken() { var c = ParserFactory.Configure <int>(); var a = c.CreateNonTerminal(); c.CreateTerminal("b"); a.AddProduction(a, "a"); a.AddProduction("a"); var parser = c.CreateParser(); try { parser.Parse("aa aaa\naa a a a\na a a b"); Assert.Fail("No error for bad token"); } catch (ParseException e) { Assert.AreEqual(3, e.LexerState.CurrentLineNumber); Assert.AreEqual("a a a b", e.LexerState.CurrentLine); } }
public void TestReduceReduceConflict() { // Represents the grammar // // x := t | y // t := "A" // y := "A" // INonTerminal <object> y = null, t = null; try { var configurator = ParserFactory.Configure <object>(); INonTerminal <object> x = configurator.CreateNonTerminal(); x.DebugName = "X"; t = configurator.CreateNonTerminal(); t.DebugName = "T"; y = configurator.CreateNonTerminal(); y.DebugName = "Y"; x.AddProduction(t); x.AddProduction(y); t.AddProduction("A"); y.AddProduction("A"); configurator.CreateParser(); Assert.Fail(); } catch (ReduceReduceConflictException <object> e) { Assert.AreEqual(y, e.NewReduceSymbol); Assert.AreEqual(t, e.PreviousReduceSymbol); } }
public static void Run() { var configurator = ParserFactory.Configure <object>(); var quotedString = configurator.CreateTerminal("\"(\\\\.|[^\"])*\"", f => f.Substring(1, f.Length - 2)); var doubleValue = configurator.CreateTerminal(@"\d+\.\d+", f => double.Parse(f)); var integerValue = configurator.CreateTerminal(@"\d+", f => int.Parse(f)); var jsonObject = configurator.CreateNonTerminal(); var optionalElementList = configurator.CreateNonTerminal(); var elementList = configurator.CreateNonTerminal(); var element = configurator.CreateNonTerminal(); var value = configurator.CreateNonTerminal(); var array = configurator.CreateNonTerminal(); var optionalValueList = configurator.CreateNonTerminal(); var valueList = configurator.CreateNonTerminal(); jsonObject.AddProduction("{", optionalElementList, "}") .SetReduceFunction(f => new JsonObject { Elements = (List <JsonElement>)f[1] }); optionalElementList.AddProduction(elementList) .SetReduceFunction(f => f[0]); optionalElementList.AddProduction() .SetReduceFunction(f => new List <JsonElement>()); elementList.AddProduction(elementList, ",", element) .SetReduceFunction(f => { var list = (List <JsonElement>)f[0]; list.Add((JsonElement)f[2]); return(list); }); elementList.AddProduction(element) .SetReduceFunction(f => new List <JsonElement> { (JsonElement)f[0] }); element.AddProduction(quotedString, ":", value) .SetReduceFunction(f => new JsonElement { Name = (string)f[0], Value = f[2] }); value.AddProduction(quotedString).SetReduceFunction(f => f[0]); value.AddProduction(integerValue).SetReduceFunction(f => f[0]); value.AddProduction(doubleValue).SetReduceFunction(f => f[0]); value.AddProduction(jsonObject).SetReduceFunction(f => f[0]); value.AddProduction(array).SetReduceFunction(f => f[0]); value.AddProduction("true").SetReduceFunction(f => true); value.AddProduction("false").SetReduceFunction(f => false); value.AddProduction("null").SetReduceFunction(f => null); array.AddProduction("[", optionalValueList, "]") .SetReduceFunction(f => ((List <object>)f[1]).ToArray()); optionalValueList.AddProduction(valueList) .SetReduceFunction(f => f[0]); optionalValueList.AddProduction() .SetReduceFunction(f => new List <object>()); valueList.AddProduction(valueList, ",", value) .SetReduceFunction(f => { var list = (List <object>)f[0]; list.Add(f[2]); return(list); }); valueList.AddProduction(value) .SetReduceFunction(f => new List <object> { f[0] }); configurator.LexerSettings.EscapeLiterals = true; configurator.LexerSettings.Ignore = new[] { @"\s+" }; var parser = configurator.CreateParser(); var jObject = (JsonObject)parser.Parse("{ \"Property1\":\"va\\\"lue\", \"IntegerProperty\" : 1234 }"); }
public void TestExpectedInput() { var configurator = ParserFactory.Configure <int>(); var word = configurator.CreateTerminal("[a-z]+"); word.DebugName = "word"; var illegalWord = configurator.CreateTerminal("[A-Z]+"); // Never legal, used to cause errors illegalWord.DebugName = "illegalWord"; var list = configurator.CreateNonTerminal(); list.DebugName = "list"; var element = configurator.CreateNonTerminal(); element.DebugName = "element"; element.AddProduction("{", list, "}"); element.AddProduction(word); list.AddProduction(list, ",", element); list.AddProduction(element); var parser = configurator.CreateParser(); // This should parse parser.Parse("a, b, {c, d, e, f, {g}, h, i}, {j, k}"); // You shall not parse try { parser.Parse("a, b, {c, d, e, F, {g}, h, i}, {j, k}"); } catch (ParseException e) { // This will fail on the F // The exception should contain that the expected input is word or { var expectedTokens = e.ExpectedTokens; Assert.AreEqual(2, expectedTokens.Length); Assert.IsTrue(expectedTokens.Contains("word")); Assert.IsTrue(expectedTokens.Contains("{")); } // You shall not parse try { parser.Parse("a, b, {c, d, e, f f, {g}, h, i}, {j, k}"); } catch (ParseException e) { // This will fail on the second f since there is no comma // The exception should contain that the expected input is , or } var expectedTokens = e.ExpectedTokens; // EOF is here, since this is a LALR1 parser, even though it not strictly ballroom to use that token here // the error actually appears after a reduce. This is OK Assert.AreEqual(3, expectedTokens.Length); Assert.IsTrue(expectedTokens.Contains(",")); Assert.IsTrue(expectedTokens.Contains("}")); } }
public SceneParser() { var configurator = ParserFactory.Configure <object>(); // Non-terminals. var sceneFile = CreateNonTerminal <SceneFile>(configurator); var directiveList = CreateNonTerminal <Directive[]>(configurator); var directive = CreateNonTerminal <Directive>(configurator); var standardDirectiveType = CreateNonTerminal <StandardDirectiveType>(configurator); var paramSet = CreateNonTerminal <Param[]>(configurator); var param = CreateNonTerminal <Param>(configurator); var paramValueList = CreateNonTerminal <object[]>(configurator); var paramValue = CreateNonTerminal <object>(configurator); var point = CreateNonTerminal <Point>(configurator); var vector = CreateNonTerminal <Vector>(configurator); var matrix = CreateNonTerminal <Matrix4x4>(configurator); var floatOrInt = CreateNonTerminal <float>(configurator); var activeTransformType = CreateNonTerminal <ActiveTransformType>(configurator); // Terminals. var floatLiteral = CreateTerminalParse(configurator, @"-?\d*\.\d+", Convert.ToSingle); var integerLiteral = CreateTerminalParse(configurator, @"-?\d+", Convert.ToInt32); var quotedString = CreateTerminalParse(configurator, "\"(\\\\.|[^\"])*\"", x => x.Substring(1, x.Length - 2)); // Productions. sceneFile.Add(directiveList).SetReduceToFirst(); directiveList.Add(directiveList, directive).SetReduce((a, b) => a.Concat(new[] { b }).ToArray()); directiveList.Add(directive).SetReduce(a => new[] { a }); directive.Add(standardDirectiveType, quotedString, paramSet).SetReduce( (a, b, c) => new StandardDirective { DirectiveType = a, ImplementationType = b, Parameters = new ParamSet(c) }); directive.Add(standardDirectiveType, quotedString).SetReduce( (a, b) => new StandardDirective { DirectiveType = a, ImplementationType = b, Parameters = new ParamSet() }); directive.Add(CreateTerminal(configurator, "Texture"), quotedString, quotedString, quotedString, paramSet).SetReduce( (_, b, c, d, e) => new TextureDirective { Name = b, TextureType = c, TextureClass = d, Parameters = new ParamSet(e) }); directive.Add(CreateTerminal(configurator, "Texture"), quotedString, quotedString, quotedString).SetReduce( (_, b, c, d) => new TextureDirective { Name = b, TextureType = c, TextureClass = d, Parameters = new ParamSet() }); directive.Add(CreateTerminal(configurator, "Identity")).SetReduce(_ => new IdentityDirective()); directive.Add(CreateTerminal(configurator, "Translate"), vector).SetReduce( (_, b) => new TranslateDirective { Translation = b }); directive.Add(CreateTerminal(configurator, "Scale"), vector).SetReduce( (_, b) => new ScaleDirective { Scale = b }); directive.Add(CreateTerminal(configurator, "Rotate"), floatOrInt, vector).SetReduce( (_, b, c) => new RotateDirective { Angle = b, Axis = c }); directive.Add(CreateTerminal(configurator, "LookAt"), point, point, vector).SetReduce( (_, b, c, d) => new LookAtDirective { Eye = b, LookAt = c, Up = d }); directive.Add(CreateTerminal(configurator, "CoordinateSystem"), quotedString).SetReduce( (_, b) => new CoordinateSystemDirective { Name = b }); directive.Add(CreateTerminal(configurator, "CoordSysTransform"), quotedString).SetReduce( (_, b) => new CoordSysTransformDirective { Name = b }); directive.Add(CreateTerminal(configurator, "Transform"), matrix).SetReduce( (_, b) => new TransformDirective { Transform = b }); directive.Add(CreateTerminal(configurator, "ConcatTransform"), matrix).SetReduce( (_, b) => new ConcatTransformDirective { Transform = b }); directive.Add(CreateTerminal(configurator, "TransformTimes"), floatOrInt, floatOrInt).SetReduce( (_, b, c) => new TransformTimesDirective { Start = b, End = c }); directive.Add(CreateTerminal(configurator, "ActiveTransform"), activeTransformType).SetReduce( (_, b) => new ActiveTransformDirective { Type = b }); directive.Add(CreateTerminal(configurator, "MakeNamedMaterial"), quotedString, quotedString, paramSet).SetReduce( (_, b, c, d) => new MakeNamedMaterialDirective { MaterialName = b, MaterialType = c, Parameters = new ParamSet(d) }); directive.Add(CreateTerminal(configurator, "NamedMaterial"), quotedString).SetReduce( (_, b) => new NamedMaterialDirective { MaterialName = b }); directive.Add(CreateTerminal(configurator, "ObjectBegin"), quotedString).SetReduce( (_, b) => new ObjectBeginDirective { Name = b }); directive.Add(CreateTerminal(configurator, "ObjectEnd")).SetReduce(_ => new ObjectEndDirective()); directive.Add(CreateTerminal(configurator, "ObjectInstance"), quotedString).SetReduce( (_, b) => new ObjectInstanceDirective { Name = b }); directive.Add(CreateTerminal(configurator, "ReverseOrientation")).SetReduce(_ => new ReverseOrientationDirective()); directive.Add(CreateTerminal(configurator, "TransformBegin")).SetReduce(_ => new TransformBeginDirective()); directive.Add(CreateTerminal(configurator, "TransformEnd")).SetReduce(_ => new TransformEndDirective()); directive.Add(CreateTerminal(configurator, "WorldBegin")).SetReduce(_ => new WorldBeginDirective()); directive.Add(CreateTerminal(configurator, "WorldEnd")).SetReduce(_ => new WorldEndDirective()); directive.Add(CreateTerminal(configurator, "AttributeBegin")).SetReduce(_ => new AttributeBeginDirective()); directive.Add(CreateTerminal(configurator, "AttributeEnd")).SetReduce(_ => new AttributeEndDirective()); standardDirectiveType.Add(CreateTerminal(configurator, "Accelerator")).SetReduce(_ => StandardDirectiveType.Accelerator); standardDirectiveType.Add(CreateTerminal(configurator, "AreaLightSource")).SetReduce(_ => StandardDirectiveType.AreaLightSource); standardDirectiveType.Add(CreateTerminal(configurator, "Camera")).SetReduce(_ => StandardDirectiveType.Camera); standardDirectiveType.Add(CreateTerminal(configurator, "Film")).SetReduce(_ => StandardDirectiveType.Film); standardDirectiveType.Add(CreateTerminal(configurator, "LightSource")).SetReduce(_ => StandardDirectiveType.LightSource); standardDirectiveType.Add(CreateTerminal(configurator, "Material")).SetReduce(_ => StandardDirectiveType.Material); standardDirectiveType.Add(CreateTerminal(configurator, "PixelFilter")).SetReduce(_ => StandardDirectiveType.PixelFilter); standardDirectiveType.Add(CreateTerminal(configurator, "Renderer")).SetReduce(_ => StandardDirectiveType.Renderer); standardDirectiveType.Add(CreateTerminal(configurator, "Sampler")).SetReduce(_ => StandardDirectiveType.Sampler); standardDirectiveType.Add(CreateTerminal(configurator, "Shape")).SetReduce(_ => StandardDirectiveType.Shape); standardDirectiveType.Add(CreateTerminal(configurator, "SurfaceIntegrator")).SetReduce(_ => StandardDirectiveType.SurfaceIntegrator); standardDirectiveType.Add(CreateTerminal(configurator, "Volume")).SetReduce(_ => StandardDirectiveType.Volume); standardDirectiveType.Add(CreateTerminal(configurator, "VolumeIntegrator")).SetReduce(_ => StandardDirectiveType.VolumeIntegrator); paramSet.Add(paramSet, param).SetReduce((a, b) => a.Concat(new[] { b }).ToArray()); paramSet.Add(param).SetReduce(a => new[] { a }); param.Add(quotedString, CreateTerminal(configurator, @"\["), paramValueList, CreateTerminal(configurator, @"\]")) .SetReduce((a, b, c, d) => GetParamList(a, c)); param.Add(quotedString, paramValue).SetReduce(GetParam); paramValueList.Add(paramValueList, paramValue).SetReduce((a, b) => a.Concat(new[] { b }).ToArray()); paramValueList.Add(paramValue).SetReduce(a => new [] { a }); paramValue.Add(floatOrInt).SetReduce(a => a); paramValue.Add(quotedString).SetReduce(a => a); point.Add(floatOrInt, floatOrInt, floatOrInt).SetReduce((a, b, c) => new Point(a, b, c)); vector.Add(floatOrInt, floatOrInt, floatOrInt).SetReduce((a, b, c) => new Vector(a, b, c)); matrix.Add(floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt, floatOrInt) .SetReduce((m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) => new Matrix4x4(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33)); floatOrInt.Add(floatLiteral).SetReduceToFirst(); floatOrInt.Add(integerLiteral).SetReduce(a => (float)a); activeTransformType.Add(CreateTerminal(configurator, "StartTime")).SetReduce(x => ActiveTransformType.Start); activeTransformType.Add(CreateTerminal(configurator, "EndTime")).SetReduce(x => ActiveTransformType.End); activeTransformType.Add(CreateTerminal(configurator, "All")).SetReduce(x => ActiveTransformType.All); // Ignore whitespace and comments configurator.LexerSettings.Ignore = new[] { @"\s+", @"#[^\n]*\n" }; _parser = configurator.CreateParser(); }