/// <summary> /// Prevents a default instance of the <see cref="ShaderParser"/> class from being created. /// </summary> /// <param name="languageData">The language data.</param> /// <param name="root">The root of the language.</param> private ShaderParser(ShaderLanguageData languageData, NonTerminal root) { LanguageData = languageData; Grammar = (ShaderGrammar)languageData.Grammar; Tokenizer = new Tokenizer(languageData); Parser = new Irony.Parsing.Parser(languageData, null, root); }
public XamlMarkupExtensionGrammar() { // Non Terminals var markupExtension = new NonTerminal(MarkupExtensionTerm); var arguments = new NonTerminal("Arguments"); var namedArgs = new NonTerminal("NamedArgs"); var namedArg = new NonTerminal(NamedArgumentTerm); var positionalArgs = new NonTerminal("PositionalArgs"); var argument = new NonTerminal("Argument"); // Terminals var typeName = new TypeNameTerminal(TypeNameTerm); var memberName = new MemberNameTerminal(MemberNameTerm); var @string = new StringTerminal(StringTerm); var startExtension = this.ToTransientTerm("{"); var endExtension = this.ToTransientTerm("}"); var namedArgumentSeparator = this.ToTransientTerm("="); var argumentSeparator = this.ToTransientTerm(","); // Setup rules markupExtension.Rule = (startExtension + typeName + endExtension) | (startExtension + typeName + arguments + endExtension); arguments.Rule = namedArgs | positionalArgs | (positionalArgs + argumentSeparator + namedArgs); namedArgs.Rule = namedArg | (namedArg + argumentSeparator + namedArgs); namedArg.Rule = (memberName + namedArgumentSeparator + argument); positionalArgs.Rule = namedArgs | argument | (argument + argumentSeparator + positionalArgs); argument.Rule = markupExtension | @string; this.Root = markupExtension; this.MarkTransient(arguments, argument); }
private NonTerminal CreateAugmentedRoot(NonTerminal root) { var result = new NonTerminal(root.Name + "'", root + _grammar.Eof); result.SetFlag(TermFlags.NoAstNode); //mark that we don't need AST node here return(result); }
public void TestTrueGenericsAmbiguity() { var name = new NonTerminal("Name"); var argList = new NonTerminal("List<Exp>"); var genericParameters = new NonTerminal("Gen"); var optionalGenericParameters = new NonTerminal("Opt<Gen>"); var cmp = new NonTerminal("Cmp"); var rules = new[] { new Rule(Start, Exp), new Rule(Exp, ID), new Rule(Exp, OPEN_PAREN, Exp, CLOSE_PAREN), new Rule(Exp, ID, cmp, Exp), new Rule(Exp, name, OPEN_PAREN, argList, CLOSE_PAREN), new Rule(cmp, LT), new Rule(cmp, GT), new Rule(argList, Exp), new Rule(argList, Exp, COMMA, argList), new Rule(name, ID, optionalGenericParameters), new Rule(optionalGenericParameters), new Rule(optionalGenericParameters, genericParameters), new Rule(genericParameters, LT, ID, GT) }; // currently this fails due to duplicate prefixes var ex = Assert.Throws <NotSupportedException>(() => ParserBuilder.CreateParser(rules)); this.output.WriteLine(ex.Message); var nodes = ParserBuilder.CreateParser( rules, new Dictionary <IReadOnlyList <Symbol>, Rule> { { // id<id>(id could be call(id<id>, id) or compare(id, compare(id, id)) new[] { ID, LT, ID, GT, OPEN_PAREN, ID }, rules.Single(r => r.Symbols.SequenceEqual(new Symbol[] { name, OPEN_PAREN, argList, CLOSE_PAREN })) }, { // id<id>(( could be call(id<id>, (...)) or compare(id, compare(id, (...))) new[] { ID, LT, ID, GT, OPEN_PAREN, OPEN_PAREN }, rules.Single(r => r.Symbols.SequenceEqual(new Symbol[] { name, OPEN_PAREN, argList, CLOSE_PAREN })) }, } ); var parser = new ParserNodeParser(nodes, Start, this.output.WriteLine); var listener = new TreeListener(); // compares: id < id > (id) vs. call: id<id>(id) => our resolution says call parser.Parse(new[] { ID, LT, ID, GT, OPEN_PAREN, ID, CLOSE_PAREN }, listener); this.output.WriteLine(listener.Root.Flatten().ToString()); listener.Root.Flatten().ToString().ShouldEqual("Start(Exp(Name(ID, Opt<Gen>(Gen(<, ID, >))), (, List<Exp>(Exp(ID)), )))"); }
public override void ForCircleDefinition(NonTerminal circleDef, NonTerminal coordSet) { AstBuilder(circleDef, (context, node) => { throw new InvalidOperationException("SqlGeometryParser cannot handle circle-like structures if the output style is set to GeometryCollection"); }); }
public Calculadora() : base(caseSensitive: true) { var mas = ToTerm("+"); var menos = ToTerm("-"); var por = ToTerm("*"); var division = ToTerm("/"); var potencia = ToTerm("^"); /*---no terminal----*/ var INICIO = new NonTerminal("INICIO"); var EXPRE = new NonTerminal("EXPRE"); /*------------numero----*/ NumberLiteral numero = TerminalFactory.CreateCSharpNumber("numero"); this.Root = INICIO; INICIO.Rule = EXPRE; EXPRE.Rule = EXPRE + mas + EXPRE | EXPRE + menos + EXPRE | EXPRE + por + EXPRE | EXPRE + division + EXPRE | EXPRE + potencia + EXPRE | numero; this.RegisterOperators(1, Associativity.Left, mas, menos); this.RegisterOperators(2, Associativity.Left, por, division); this.RegisterOperators(2, Associativity.Left, potencia); }
TerminalSet _skipTokensInPreview = new TerminalSet(); //used in token preview for conflict resolution public AsmGrammar2() { NumberLiteral number = new NumberLiteral("NUMBER", NumberOptions.Default); KeyTerm PLUS = this.ToTerm("+", "PLUS"); KeyTerm TIMES = this.ToTerm("*", "TIMES"); var mem_op = new NonTerminal("MemOp"); var scaleIdx = new NonTerminal("ScaleIdx"); var scaleIdxBr = new NonTerminal("ScaleIdxBrac64"); var baseReg = new NonTerminal("Base"); var scale = new NonTerminal("Scale"); var idxReg = new NonTerminal("Idx"); var disp = new NonTerminal("Disp"); this.Root = mem_op; mem_op.Rule = "[" + baseReg + PLUS + scaleIdxBr + disp + "]"; mem_op.Rule |= "[" + baseReg + disp + PLUS + scaleIdxBr + "]"; scaleIdxBr.Rule = "(" + scaleIdx + ")"; scaleIdxBr.Rule |= scaleIdx; scaleIdx.Rule = scale + TIMES + idxReg; scaleIdx.Rule |= idxReg + TIMES + scale; scaleIdx.Rule |= idxReg; baseReg.Rule = this.ToTerm("rax"); scale.Rule = this.ToTerm("0") | "1" | "2" | "4" | "8"; idxReg.Rule = this.ToTerm("rbx"); disp.Rule = PLUS + this.CustomActionHere(this.findTimesChar) + number; }
private void FixInternalReduction(Production prod) { // This production has an action or precedence. // Before more symbols can be added to the rhs // the existing action must be turned into an // internal reduction, and the action (and // precedence, if any) moved to the new reduction. // if (prod.semanticAction != null) { string anonName = "Anon@" + (++grammar.NumActions).ToString(CultureInfo.InvariantCulture); NonTerminal anonNonT = grammar.LookupNonTerminal(anonName); Production EmptyProd = new Production(anonNonT); EmptyProd.semanticAction = prod.semanticAction; EmptyProd.prec = prod.prec; grammar.AddProduction(EmptyProd); prod.rhs.Add(anonNonT); } if (prod.precSpan != null) { handler.ListError(prod.precSpan, 102); } prod.semanticAction = null; prod.precSpan = null; prod.prec = null; }
private static bool ComputeNullability(NonTerminal nonTerminal) { foreach (Production prod in nonTerminal.Productions) { if (prod.RValues.Count == 0) { nonTerminal.SetFlag(TermFlags.IsNullable); return(true); //decided, Nullable }//if //If production has terminals, it is not nullable and cannot contribute to nullability if (prod.IsSet(ProductionFlags.HasTerminals)) { continue; } //Go thru all elements of production and check nullability bool allNullable = true; foreach (BnfTerm child in prod.RValues) { allNullable &= child.FlagIsSet(TermFlags.IsNullable); }//foreach child if (allNullable) { nonTerminal.SetFlag(TermFlags.IsNullable); return(true); } }//foreach prod return(false); //cannot decide }
private bool CalculateNullability(NonTerminal nonTerminal, NonTerminalList undecided) { NtData nonTerminalInfo = (NtData)nonTerminal.ParserData; foreach (Production prod in nonTerminalInfo.Productions) { //If production has terminals, it is not nullable and cannot contribute to nullability if (prod.IsSet(ProductionFlags.HasTerminals)) { continue; } if (prod.IsSet(ProductionFlags.IsEmpty)) { nonTerminalInfo.Nullable = true; return(true); //Nullable }//if //Go thru all elements of production and check nullability bool allNullable = true; foreach (BnfTerm term in prod.RValues) { NtData ntd = term.ParserData as NtData; if (ntd != null) { allNullable &= ntd.Nullable; } }//foreach nt if (allNullable) { nonTerminalInfo.Nullable = true; return(true); } }//foreach prod return(false); //cannot decide }
/// <summary> /// Constructs the function term rule from the specified parameters. /// </summary> /// <param name="p">Parent master grammar.</param> /// <param name="bForm">Block form.</param> /// <param name="identifierType">Identifier type.</param> /// <returns>Function term grammar rule.</returns> public static NonTerminal ConstructFunctionTermRule(MasterGrammar p, BForm bForm, IdentifierType identifierType) { // NON-TERMINAL AND TERMINAL SYMBOLS var functionTerm = new NonTerminal("Functional term", typeof(TransientAstNode)); var functionTermBase = new NonTerminal("Functional term base", typeof(FunctionTermAstNode)); var functionArguments = new NonTerminal("Functional term arguments", typeof(TransientAstNode)); var argTerm = new NonTerminal("Term", typeof(TransientAstNode)); var argTermIdentifier = new NonTerminal("Identifier term", typeof(IdentifierTermAstNode)); var functionIdentifier = new IdentifierTerminal("Function identifier", IdentifierType.CONSTANT); var varOrConstIdentifier = new IdentifierTerminal("Variable or constant identifier", identifierType); // RULES functionTerm.Rule = p.ToTerm("(") + functionTermBase + ")"; functionTermBase.Rule = functionIdentifier + functionArguments; functionArguments.Rule = p.MakeStarRule(functionArguments, argTerm); argTerm.Rule = argTermIdentifier | functionTerm; argTermIdentifier.Rule = varOrConstIdentifier; p.MarkTransient(functionTerm, argTerm); return((bForm == BForm.BASE) ? functionTermBase : functionTerm); }
/// <summary> /// Constructor of the grammar node. /// </summary> /// <param name="p">Parent master grammar.</param> /// <param name="bForm">Block form.</param> public DerivedPred(MasterGrammar p, BForm bForm) : base(p, bForm) { // NON-TERMINAL AND TERMINAL SYMBOLS var derivedDef = new NonTerminal("Derived predicate definition", typeof(TransientAstNode)); var derivedDefBase = new NonTerminal("Derived predicate definition", typeof(DomainDerivedPredAstNode)); var predicateSkeleton = new NonTerminal("Derived predicate skeleton", typeof(TransientAstNode)); var predicateSkeletonBase = new NonTerminal("Derived predicate skeleton", typeof(PredicateSkeletonAstNode)); var predicateIdentifier = new IdentifierTerminal("Predicate identifier", IdentifierType.CONSTANT); // USED SUB-TREES var gd = new Gd(p); var typedList = new TypedList(p); // RULES derivedDef.Rule = p.ToTerm("(") + derivedDefBase + ")"; derivedDefBase.Rule = p.ToTerm(":derived") + predicateSkeleton + gd; predicateSkeleton.Rule = p.ToTerm("(") + predicateSkeletonBase + ")"; predicateSkeletonBase.Rule = predicateIdentifier + typedList; p.MarkTransient(derivedDef, predicateSkeleton); Rule = (bForm == BForm.BASE) ? derivedDefBase : derivedDef; }
private void ConstructStatements() { Statement = Transient <IAstStatement>("Statement"); StatementListPlus = NonTerminal("StatementListPlus", node => node.ChildAsts <IAstStatement>()); OptionalBodyOfStatements = NonTerminal("OptionalBodyOfStatements", node => (IEnumerable <IAstStatement>)node.ChildAst(0) ?? Enumerable.Empty <IAstStatement>()); ForStatement = NonTerminal("For", node => new ForStatement( // for <1> in <3> do <5> end node.Child(1).Token.Text, (IAstElement)node.ChildAst(3), node.ChildAst(OptionalBodyOfStatements) )); ContinueStatement = NonTerminal("Continue", _ => new ContinueStatement()); IfOrUnlessStatement = NonTerminal("If", node => new IfOrUnlessStatement( // (if|unless) <1> \r\n <2> (IfOrUnlessKind)Enum.Parse(typeof(IfOrUnlessKind), node.Child(0).Child(0).Token.Text, true), (IAstElement)node.ChildAst(1), new[] { (IAstElement)node.ChildAst(2) } )); VariableDefinition = NonTerminal("VariableDefinition", node => new AstVariableDefinition( node.Child(1).Token.Text, AstImplicitType.Instance, node.ChildAst(OptionalAssignedValue) )); OptionalAssignedValue = NonTerminal("OptionalAssignedValue", node => (IAstExpression)node.ChildAst(0)); Assignment = NonTerminal("Assignment", node => new AssignmentStatement((IAstAssignable)node.ChildAst(0), (IAstExpression)node.ChildAst(1))); AssignmentLeftHandSide = Transient <IAstElement>("AssignmentLeftHandSide"); ReturnStatement = NonTerminal("Return", node => new AstReturnStatement((IAstExpression)node.ChildAst(1))); }
private void ConstructDefinitions() { Definition = Transient <IAstDefinition>("Definition"); Import = NonTerminal("Import", node => new ImportDefinition((CompositeName)node.ChildAst(1))); TypeDefinition = NonTerminal("TypeDefinition", node => new AstTypeDefinition( node.ChildBefore(Name).FindTokenAndGetText(), node.Child(Name).Token.Text, node.ChildAst(OptionalTypeContent).Cast <IAstMemberDefinition>() )); TypeMember = Transient <IAstDefinition>("TypeMember"); TypeMemberList = NonTerminal("TypeMemberList", node => node.ChildAsts <IAstDefinition>()); OptionalTypeContent = NonTerminal("OptionalTypeContent", node => node.ChildAst(TypeMemberList) ?? Enumerable.Empty <IAstDefinition>()); Property = NonTerminal("Property", node => new AstPropertyDefinition( node.Child(2).Token.Text, node.ChildAst(TypeReference), node.ChildAst(OptionalAssignedValue) )); Constructor = NonTerminal("Constructor", node => new AstConstructorDefinition(node.ChildAst(ParameterList), node.ChildAst(OptionalBodyOfStatements))); Function = NonTerminal( "Function", node => new AstFunctionDefinition( node.Child(Name).Token.Text, node.ChildAst(ParameterList), node.ChildAst(OptionalBodyOfStatements), AstImplicitType.Instance ) ); OptionalAccessLevel = new NonTerminal("OptionalAccessLevel"); ParameterList = NonTerminalThatIsNotAstElement("ParameterList", node => node.ChildAsts <AstParameterDefinition>()); Parameter = Transient <AstParameterDefinition>("Parameter"); TypedParameter = NonTerminalWithSpecificType("TypedParameter", node => new AstParameterDefinition(node.Child(1).Token.Text, node.ChildAst(TypeReference))); UntypedParameter = NonTerminalWithSpecificType("UntypedParameter", node => new AstParameterDefinition(node.FindTokenAndGetText(), AstImplicitType.Instance)); }
private NonTerminal ___(string s) { if (!CheckIf___CanBeUsed(s)) { throw new ArgumentException($"Cannot use ___ method with string \"{s}\"."); } var splittedToken = Regex.Split(s, @"(\.)").Where(st => !string.IsNullOrEmpty(st)).ToList(); if (s.All(c => !char.IsLetterOrDigit(c))) { splittedToken = s.Select(c => c.ToString()).ToList(); } var result = new NonTerminal(s); result.Rule = ToTerm(splittedToken[0]); foreach (var tokenPart in splittedToken.Skip(1)) { result.Rule += ToTerm(tokenPart); } result.SetFlag(TermFlags.NoAstNode); return(result); }
public BinaryTreeGrammar() : base(false) { var number = new NumberLiteral("Number"); var comma = ToTerm(","); var open_par = ToTerm("("); var closed_par = ToTerm(")"); var start = new NonTerminal("Start"); var children = new NonTerminal("Children"); var value = new NonTerminal("Value"); start.Rule = number + children; children.Rule = open_par + value + comma + value + closed_par | open_par + value + closed_par; value.Rule = number | number + children; RegisterBracePair("(", ")"); MarkPunctuation(",", "(", ")"); this.Root = start; }
private void CreateAcceptAction(ParserState initialState, NonTerminal augmentedRoot) { var root = augmentedRoot.Productions[0].RValues[0]; var shiftAction = initialState.Actions[root] as ShiftParserAction; var shiftOverRootState = shiftAction.NewState; shiftOverRootState.Actions[_grammar.Eof] = new AcceptParserAction(); }
/// <summary> /// Initializes a new instance of the <see cref="ExpressionGrammar"/> class. /// </summary> public ExpressionGrammar() : base(false) { var number = new NumberLiteral("Number"); number.DefaultIntTypes = new TypeCode[] { TypeCode.Int16, TypeCode.Int32, TypeCode.Int64 }; number.DefaultFloatType = TypeCode.Single; var identifier = new IdentifierTerminal("Identifier"); var comma = ToTerm(","); var BinOp = new NonTerminal("BinaryOperator", "operator"); var ParExpr = new NonTerminal("ParenthesisExpression"); var BinExpr = new NonTerminal("BinaryExpression", typeof(BinaryOperationNode)); var Expr = new NonTerminal("Expression"); var Term = new NonTerminal("Term"); var Program = new NonTerminal("Program", typeof(StatementListNode)); Expr.Rule = Term | ParExpr | BinExpr; Term.Rule = number | identifier; ParExpr.Rule = "(" + Expr + ")"; BinExpr.Rule = Expr + BinOp + Expr; BinOp.Rule = ToTerm("+") | "-" | "*" | "/"; RegisterOperators(10, "+", "-"); RegisterOperators(20, "*", "/"); MarkPunctuation("(", ")"); RegisterBracePair("(", ")"); MarkTransient(Expr, Term, BinOp, ParExpr); this.Root = Expr; }
FilterStringGrammar() { var propertyName = new IdentifierTerminal("propertyName"); var compareOp = new NonTerminal("compareOp"); compareOp.Rule = ToTerm(QueryComparisons.Equal) | ToTerm(QueryComparisons.NotEqual) | ToTerm(QueryComparisons.LessThan) | ToTerm(QueryComparisons.LessThanOrEqual) | ToTerm(QueryComparisons.GreaterThan) | ToTerm(QueryComparisons.GreaterThanOrEqual); var stringLiteral = new StringLiteral("stringLiteral", "'", StringOptions.AllowsDoubledQuote); var booleanLiteral = new ConstantTerminal("booleanLiteral"); booleanLiteral.Add("true", true); booleanLiteral.Add("false", false); var literal = new NonTerminal("literal"); literal.Rule = stringLiteral | booleanLiteral; comparison = new NonTerminal("comparison"); comparison.Rule = propertyName + compareOp + literal; var booleanOp = new NonTerminal("booleanOp"); booleanOp.Rule = ToTerm(TableOperators.And) | ToTerm(TableOperators.Or); var booleanExpr = new NonTerminal("booleanExpr"); booleanOpExpr = new NonTerminal("booleanOpExpr"); booleanOpExpr.Rule = "(" + booleanExpr + ")" + booleanOp + "(" + booleanExpr + ")"; booleanExpr.Rule = comparison | booleanOpExpr; Root = booleanExpr; }
public InternalTreeNodeImpl(int origin, int location, NonTerminal symbol) : base(location) { Origin = origin; Symbol = symbol; ReadWriteChildren = new List <ITreeNode>(); }
public void TestNonLalr1() { //S->aEa | bEb | aFb | bFa //E->e //F->e var s = new NonTerminal("S"); var e = new NonTerminal("E"); var f = new NonTerminal("F"); var a = new Token("a"); var b = new Token("b"); var eToken = new Token("e"); var rules = new[] { new Rule(Start, s), new Rule(s, a, e, a), new Rule(s, b, e, b), new Rule(s, a, f, b), new Rule(s, b, f, a), new Rule(e, eToken), new Rule(f, eToken), }; var nodes = ParserBuilder.CreateParser(rules); var parser = new ParserNodeParser(nodes, Start, this.output.WriteLine); var listener = new TreeListener(); parser.Parse(new[] { a, eToken, a }, listener); this.output.WriteLine(listener.Root.Flatten().ToString()); listener.Root.Flatten().ToString() .ShouldEqual("Start(S(a, E(e), a))"); }
public GramaticaCadena() : base(caseSensitive: false) { RegexBasedTerminal numero = new RegexBasedTerminal("numero", "-?[0-9]+(\\?[0-9])?"); RegexBasedTerminal numerodecimal = new RegexBasedTerminal("decimanl", "[0-9]+[.][0-9]+"); CommentTerminal cadena = new CommentTerminal("string", "\"", ".", "\""); // es una cadena String CommentTerminal r_char = new CommentTerminal("caracteres", "'", ".", "'"); // es un caracter char #region No Terminales var mas = ToTerm("+"); NonTerminal S = new NonTerminal("S"), SUMACADENA = new NonTerminal("SUMACADENA"); #endregion #region Gramatica //Gramatica ambigua: S.Rule = SUMACADENA; SUMACADENA.Rule = cadena; /* cadena + mas + cadena | cadena + mas + numero | numero + mas + cadena | cadena + mas + numerodecimal | numerodecimal + mas + cadena | cadena + mas + r_char | r_char + mas + cadena;*/ #endregion #region Preferencias this.Root = S; #endregion }
static BnfGrammar() { /* * <grammar> ::= <rule> | <rule> <grammar> * <rule> ::= "<" <rule-name> ">" "::=" <expression> * <expression> ::= <list> | <list> "|" <expression> * <line-end> ::= <EOL> | <line-end> <line-end> * <list> ::= <term> | <term> <list> * <term> ::= <literal> | "<" <rule-name> ">" * <literal> ::= '"' <text> '"' | "'" <text> "'" */ var whitespace = CreateWhitespaceLexerRule(); var ruleName = CreateRuleNameLexerRule(); var implements = CreateImplementsLexerRule(); var eol = CreateEndOfLineLexerRule(); var notDoubleQuote = CreateNotDoubleQuoteLexerRule(); var notSingleQuuote = CreateNotSingleQuoteLexerRule(); var grammar = new NonTerminal("grammar"); var rule = new NonTerminal("rule"); var identifier = new NonTerminal("identifier"); var expression = new NonTerminal("expression"); var lineEnd = new NonTerminal("line-end"); var list = new NonTerminal("list"); var term = new NonTerminal("term"); var literal = new NonTerminal("literal"); var doubleQuoteText = new NonTerminal("doubleQuoteText"); var singleQuoteText = new NonTerminal("singleQuoteText"); var lessThan = new TerminalLexerRule('<'); var greaterThan = new TerminalLexerRule('>'); var doubleQuote = new TerminalLexerRule('"'); var slash = new TerminalLexerRule('\''); var pipe = new TerminalLexerRule('|'); var productions = new[] { new Production(grammar, rule), new Production(grammar, rule, grammar), new Production(rule, identifier, implements, expression), new Production(expression, list), new Production(expression, list, pipe, expression), new Production(lineEnd, eol), new Production(lineEnd, lineEnd, lineEnd), new Production(list, term), new Production(list, term, list), new Production(term, literal), new Production(term, identifier), new Production(identifier, lessThan, ruleName, greaterThan), new Production(literal, doubleQuote, notDoubleQuote, doubleQuote), new Production(literal, slash, notSingleQuuote, slash) }; var ignore = new[] { whitespace }; _bnfGrammar = new Grammar(grammar, productions, ignore); }
public ExceptionRules(PieGrammar grammar) { this.grammar = grammar; ExceptionHandlingBlock = new NonTerminal("exception_handling_block"); ThrowStatement = new NonTerminal("throw_statement"); }
public ActionRecord(ParserActionType actionType, ParserState newState, NonTerminal nonTerminal, int popCount) { ActionType = actionType; NewState = newState; NonTerminal = nonTerminal; PopCount = popCount; }
private NonTerminal <TAstNode> Transient <TAstNode>(string name) { var nonTerminal = new NonTerminal <TAstNode>(name); MarkTransient(nonTerminal); return(nonTerminal); }
public JsonGrammar() { //Terminals var jstring = new StringLiteral("string", "\""); var jnumber = new NumberLiteral("number"); var comma = Symbol(","); //Nonterminals var jobject = new NonTerminal("Object"); var jarray = new NonTerminal("Array"); var jvalue = new NonTerminal("Value"); var jprop = new NonTerminal("Property"); var jproplist = new NonTerminal("PropertyList"); var jlist = new NonTerminal("List"); //Rules jvalue.Rule = jstring | jnumber | jobject | jarray | "true" | "false" | "null"; jobject.Rule = "{" + jproplist + "}"; jproplist.Rule = MakeStarRule(jproplist, comma, jprop); jprop.Rule = jstring + ":" + jvalue; jarray.Rule = "[" + jlist + "]"; jlist.Rule = MakeStarRule(jlist, comma, jvalue); //Set grammar root this.Root = jvalue; RegisterPunctuation("{", "}", "[", "]", ":", ","); this.MarkTransient(jvalue, jlist, jproplist); this.LanguageFlags = LanguageFlags.None; //.BubbleNodes; }
protected virtual void ConstructNameAndTypeRules() { Name = new IdentifierTerminal("Name"); Name.StartCharCategories.AddRange(new[] { UnicodeCategory.UppercaseLetter, UnicodeCategory.LowercaseLetter, UnicodeCategory.TitlecaseLetter, UnicodeCategory.ModifierLetter, UnicodeCategory.OtherLetter, UnicodeCategory.LetterNumber }); Name.CharCategories.AddRange(Name.StartCharCategories); Name.CharCategories.AddRange(new[] { UnicodeCategory.DecimalDigitNumber, UnicodeCategory.ConnectorPunctuation, UnicodeCategory.SpacingCombiningMark, UnicodeCategory.NonSpacingMark, UnicodeCategory.Format }); DotSeparatedName = NonTerminalThatIsNotAstElement("DotSeparatedName", n => new CompositeName(n.ChildNodes.Select(c => c.Token.Text).ToArray())); TypeReference = NonTerminalWithSpecificType("TypeReference", n => (IAstTypeReference) new AstUnknownType(n.Child(Name).Token.Text)); // WIP TypeReferenceListPlus = new NonTerminal("TypeReferenceListPlus"); }
public void parsesIdentifiersAndLiteral() { Parser p = new Parser(); Token a = new Keyword("="); Token b = new Keyword(";"); Token s = new NonTerminal("S"); List <Token> production = new List <Token>(); production.Add(new Identifier("")); production.Add(a); production.Add(new IntLiteral("0")); production.Add(b); p.addProduction(s, production); p.setStartSymbol(s); p.prepareForParsing(); List <Token> parseThese = new List <Token>(); parseThese.Add(new Identifier("abc")); parseThese.Add(a); parseThese.Add(new IntLiteral("15")); parseThese.Add(b); SyntaxTree parsed = p.parse(parseThese); Assert.AreEqual(new Identifier("abc"), parsed.root.children[0].token); Assert.AreNotEqual(new Identifier(""), parsed.root.children[0].token); Assert.AreEqual(a, parsed.root.children[1].token); Assert.AreEqual(new IntLiteral("15"), parsed.root.children[2].token); Assert.AreNotEqual(new IntLiteral("0"), parsed.root.children[2].token); Assert.AreEqual(b, parsed.root.children[3].token); }
public IronyJsonGrammar() { //Terminals var jstring = new StringLiteral("string", "\""); var jnumber = new NumberLiteral("number", NumberOptions.AllowSign); var comma = ToTerm(","); //Nonterminals var jobject = new NonTerminal("Object"); var jobjectBr = new NonTerminal("ObjectBr"); var jarray = new NonTerminal("Array"); var jarrayBr = new NonTerminal("ArrayBr"); var jvalue = new NonTerminal("Value"); var jprop = new NonTerminal("Property"); //Rules jvalue.Rule = jstring | jnumber | jobjectBr | jarrayBr | "true" | "false" | "null"; jobjectBr.Rule = "{" + jobject + "}"; jobject.Rule = MakeStarRule(jobject, comma, jprop); jprop.Rule = jstring + ":" + jvalue; jarrayBr.Rule = "[" + jarray + "]"; jarray.Rule = MakeStarRule(jarray, comma, jvalue); //Set grammar root this.Root = jvalue; MarkPunctuation("{", "}", "[", "]", ":", ","); this.MarkTransient(jvalue, jarrayBr, jobjectBr); } //constructor
public void parsesLiterals() { Parser p = new Parser(); Token a = new IntLiteral("0"); Token b = new StringLiteral(""); Token c = new BoolLiteral(""); Token s = new NonTerminal("s"); List <Token> production = new List <Token>(); production.Add(a); production.Add(b); production.Add(c); p.addProduction(s, production); p.setStartSymbol(s); p.prepareForParsing(); List <Token> parseThese = new List <Token>(); parseThese.Add(new IntLiteral("-50")); parseThese.Add(new StringLiteral("abc")); parseThese.Add(new BoolLiteral("true")); SyntaxTree parsed = p.parse(parseThese); Assert.AreEqual(new IntLiteral("-50"), parsed.root.children[0].token); Assert.AreNotEqual(new IntLiteral("50"), parsed.root.children[0].token); Assert.AreEqual(new StringLiteral("abc"), parsed.root.children[1].token); Assert.AreNotEqual(new StringLiteral("def"), parsed.root.children[1].token); Assert.AreEqual(new BoolLiteral("true"), parsed.root.children[2].token); Assert.AreNotEqual(new BoolLiteral("false"), parsed.root.children[2].token); }
public ExpressionEvaluatorGrammar() { // 1. Terminals var identifier = new RegexBasedTerminal("identifier", "[a-z\\d_^~]+"); // 2. Non-terminals var root = new NonTerminal("root"); var block = new NonTerminal("block"); var expression = new NonTerminal("expression"); var expressions = new NonTerminal("expressions"); var prop = new NonTerminal("prop"); var op = new NonTerminal("op"); // 3. BNF rules op.Rule = ToTerm("OR") | "AND"; prop.Rule = identifier + "=" ; expression.Rule = "{" + (prop | block) + "}" + "|" ; expressions.Rule = MakeStarRule(expressions, expression); block.Rule = expressions + op; root.Rule = "{" + block +"}"; Root = root; //automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source this.LanguageFlags = LanguageFlags.NewLineBeforeEOF; }
public ListDerivation ExpandStep() { //Идем вправо по списку, если: // SymbolDerivation, раскрываем и заменяем если результат ListDerivation, // возвращаем его иначе себя // ListDerivation - возврящаем его // дошли до конца списка - возвращаем верхний список (ParentDerivation) while (mCurrentItemIndex < mList.Count) { ListDerivation lAsListDer = CurrentItem as ListDerivation; if (null != lAsListDer) { mCurrentItemIndex++; return(lAsListDer); } SymbolDerivation lAsSymDer = CurrentItem as SymbolDerivation; if (null != lAsSymDer) { ExpandingSymbol = lAsSymDer.Symbol; //раскрываем и заменяем IDerivation lSymbolResult = Generator.ExpandNonTerminal(lAsSymDer.Symbol); CurrentItem = lSymbolResult; ListDerivation lSymbolResultAsList = lSymbolResult as ListDerivation; //если результат ListDerivation, возвращаем его иначе себя (старый верхний список) return(lSymbolResultAsList ?? this); } mCurrentItemIndex++; } //дошли до конца списка return(ParentDerivation as ListDerivation); //??? }
public GrammarExL514() { NonTerminal A = new NonTerminal("A"); Terminal a = new Terminal("a"); A.Expression = "(" + A + ")" | a; this.Root = A; }
private ParserState CreateInitialState(NonTerminal augmentedRoot) { //for an augmented root there is an initial production "Root' -> .Root"; so we need the LR0 item at 0 index var iniItemSet = new LR0ItemSet(); iniItemSet.Add(augmentedRoot.Productions[0].LR0Items[0]); var initialState = FindOrCreateState(iniItemSet); var rootNt = augmentedRoot.Productions[0].RValues[0] as NonTerminal; Data.InitialStates[rootNt] = initialState; return initialState; }
public DBCLI_OM() { // Command name and description InitCommand("OM", "Loads and stores an ontology", "Loads and stores an ontology"); #region Symbol declaration SymbolTerminal OM_CommandString = Symbol("OM"); SymbolTerminal OM_ProtonString = Symbol("proton"); #endregion #region Non-terminal declaration NonTerminal OM = new NonTerminal("OM"); NonTerminal OM_Action = new NonTerminal("OM_Action"); NonTerminal OM_Load_options = new NonTerminal("OM_Load_options"); NonTerminal OM_Store_options = new NonTerminal("OM_Store_options"); #endregion // BNF rule CreateBNFRule(CLICommandSymbolTerminal + OM_Action); #region BNF rules OM.GraphOptions.Add(GraphOption.IsCommandRoot); OM_Action.Rule = StoreSymbol + OM_Store_options | LoadSymbol + OM_Load_options; OM_Action.GraphOptions.Add(GraphOption.IsOption); OM_Load_options.Rule = OM_ProtonString | stringLiteralExternalEntry; OM_Load_options.GraphOptions.Add(GraphOption.IsOption); OM_Store_options.Rule = stringLiteralExternalEntry; OM_Store_options.GraphOptions.Add(GraphOption.IsOption); #endregion #region Non-terminal integration _CommandNonTerminals.Add(OM_Action); _CommandNonTerminals.Add(OM_Load_options); _CommandNonTerminals.Add(OM_Store_options); #endregion #region Symbol integration _CommandSymbolTerminal.Add(OM_ProtonString); #endregion }
public SearchGrammar() { // Terminals var Term = new IdentifierTerminal("Term", "!@#$%^*_'.?", "!@#$%^*_'.?0123456789"); // The following is not very imporant, but makes scanner recognize "or" and "and" as operators, not Terms // The "or" and "and" operator symbols found in grammar get higher priority in scanning and are checked // first, before the Term terminal, so Scanner produces operator token, not Term. For our purposes it does // not matter, we get around without it. Term.Priority = Terminal.LowestPriority; var Phrase = new StringLiteral("Phrase"); // NonTerminals var OrExpression = new NonTerminal("OrExpression"); var OrOperator = new NonTerminal("OrOperator"); var AndExpression = new NonTerminal("AndExpression"); var AndOperator = new NonTerminal("AndOperator"); var ExcludeOperator = new NonTerminal("ExcludeOperator"); var PrimaryExpression = new NonTerminal("PrimaryExpression"); var ThesaurusExpression = new NonTerminal("ThesaurusExpression"); var ThesaurusOperator = new NonTerminal("ThesaurusOperator"); var ExactOperator = new NonTerminal("ExactOperator"); var ExactExpression = new NonTerminal("ExactExpression"); var ParenthesizedExpression = new NonTerminal("ParenthesizedExpression"); var ProximityExpression = new NonTerminal("ProximityExpression"); var ProximityList = new NonTerminal("ProximityList"); this.Root = OrExpression; OrExpression.Rule = AndExpression | OrExpression + OrOperator + AndExpression; OrOperator.Rule = Symbol("or") | "|"; AndExpression.Rule = PrimaryExpression | AndExpression + AndOperator + PrimaryExpression; AndOperator.Rule = Empty | "and" | "&" | ExcludeOperator; ExcludeOperator.Rule = Symbol("-"); PrimaryExpression.Rule = Term | ThesaurusExpression | ExactExpression | ParenthesizedExpression | Phrase | ProximityExpression; ThesaurusExpression.Rule = ThesaurusOperator + Term; ThesaurusOperator.Rule = Symbol("~"); ExactExpression.Rule = ExactOperator + Term | ExactOperator + Phrase; ExactOperator.Rule = Symbol("+"); ParenthesizedExpression.Rule = "(" + OrExpression + ")"; ProximityExpression.Rule = "<" + ProximityList + ">"; MakePlusRule(ProximityList, Term); RegisterPunctuation("<", ">", "(", ")"); }
public GrammarEx434() { NonTerminal E = new NonTerminal("E"); NonTerminal T = new NonTerminal("T"); NonTerminal F = new NonTerminal("F"); Terminal id = new Terminal("id"); E.Expression = E + "+" + T | T; T.Expression = T + "*" + F | F; F.Expression = "(" + E + ")" | id; this.Root = E; }
public GrammarEx446() { // A' is augmented root NonTerminal S = new NonTerminal("S"); NonTerminal L = new NonTerminal("L"); NonTerminal R = new NonTerminal("R"); Terminal id = new Terminal("id"); S.Expression = L + "=" + R | R; L.Expression = "*" + R | id; R.Expression = L; this.Root = S; }
private static void TestGLR() { Log(LogLevel.Info, "Starting TestLALR()"); var S = new NonTerminal("S"); var E = new NonTerminal("E"); S.RHS = E; E.RHS = "i".T(); E.RHS = E < "*".T() < E; E.RHS = E < "+".T() < E; Parser parser = new Parser(E, Log, LogLevel.Trace); var ok = parser.Parse("i+i*i"); Debug.Assert(ok); Log(LogLevel.Info, "End TestLALR()"); }
public ExpressionEvaluatorGrammar() { // 1. Terminals var number = new NumberLiteral("number"); var identifier = new IdentifierTerminal("identifier"); var comment = new CommentTerminal("comment", "#", "\n", "\r"); base.NonGrammarTerminals.Add(comment); // 2. Non-terminals var Variable = new NonTerminal("Variable", typeof(VarRefNode)); var Expr = new NonTerminal("Expr"); var Term = new NonTerminal("Term"); var BinExpr = new NonTerminal("BinExpr", typeof(BinExprNode)); var ParExpr = new NonTerminal("ParExpr"); var UnExpr = new NonTerminal("UnExpr", typeof(UnExprNode)); var UnOp = new NonTerminal("UnOp"); var BinOp = new NonTerminal("BinOp"); var AssignmentStmt = new NonTerminal("AssignmentStmt", typeof(AssigmentNode)); var Statement = new NonTerminal("Statement"); var ProgramLine = new NonTerminal("ProgramLine"); var Program = new NonTerminal("Program", typeof(StatementListNode)); // 3. BNF rules Variable.Rule = identifier; Expr.Rule = Term | UnExpr | BinExpr; Term.Rule = number | ParExpr | Variable; ParExpr.Rule = "(" + Expr + ")"; UnExpr.Rule = UnOp + Term; UnOp.Rule = Symbol("+") | "-"; BinExpr.Rule = Expr + BinOp + Expr; BinOp.Rule = Symbol("+") | "-" | "*" | "/" | "**"; AssignmentStmt.Rule = Variable + "=" + Expr; Statement.Rule = AssignmentStmt | Expr | Empty; ProgramLine.Rule = Statement + NewLine; Program.Rule = MakeStarRule(Program, ProgramLine); this.Root = Program; // Set grammar root // 4. Operators precedence RegisterOperators(1, "+", "-"); RegisterOperators(2, "*", "/"); RegisterOperators(3, Associativity.Right, "**"); RegisterPunctuation( "(", ")"); MarkTransient(Term, Expr, Statement); //automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source this.LanguageFlags |= LanguageFlags.NewLineBeforeEOF | LanguageFlags.SupportsInterpreter; }
private static void TestStringGrammar() { Log(LogLevel.Info, "Starting TestStringGrammar()"); var a = Terminal.T("a"); NonTerminal A = new NonTerminal("A"); A.RHS = a; A.RHS = A < A; Debug.Assert(a.ToString() == "'a'"); Debug.Assert(A.ToString() == "A"); var text = A.RHS.ToString(); Parser parser = new Parser( A, Log, LogLevel.Trace ); Log(LogLevel.Info, "End TestStringGrammar()"); var ok = parser.Parse(new Source( "a", 0)); Debug.Assert(ok); }
public DBCLI_GraphDB() { // Command name and description InitCommand("GraphDB", "Starts and quits a given GraphDB", "Starts and quits a given GraphDB"); NonTerminal GraphDB_Action = new NonTerminal("GraphDB_Action"); // BNF rule CreateBNFRule(CLICommandSymbolTerminal + GraphDB_Action); GraphDB_Action.Rule = StartSymbol + stringLiteralPVFS | StopSymbol; //GraphDB_Action.GraphOptions.Add(GraphOption.IsOption); _CommandNonTerminals.Add(GraphDB_Action); }
public DBCLI_UPDATE() { // Command name and description InitCommand("UPDATE", "Updates myAttributes of certain objects", "Updates myAttributes of certain objects"); #region Symbol declaration SymbolTerminal ADDREFSymbol = Symbol("ADDREF"); SymbolTerminal REMREFSymbol = Symbol("REMREF"); #endregion #region Non-terminal declaration NonTerminal AttrUpdateList = new NonTerminal("AttrUpdateList"); NonTerminal AttrUpdate = new NonTerminal("AttrUpdate"); NonTerminal WhereOrValuesAction = new NonTerminal("WhereOrValuesAction"); #endregion // BNF rule CreateBNFRule(CLICommandSymbolTerminal + TYPESymbol + AType + WhereOrValuesAction); WhereOrValuesAction.Rule = WhereClauseNT + ValuesSymbol + BracketRoundOpenSymbol + AttrUpdateList | ValuesSymbol + BracketRoundOpenSymbol + AttrUpdateList; AttrUpdateList.Rule = AttrUpdate + CommaSymbol + AttrUpdateList | AttrUpdate + BracketRoundCloseSymbol; AttrUpdate.Rule = AttrAssignNT | IdNT + ADDREFSymbol + GraphTypeNT + UUIDSymbol + Eq_Equals + stringLiteral | IdNT + REMREFSymbol + GraphTypeNT + UUIDSymbol + Eq_Equals + stringLiteral; #region Non-terminal integration _CommandNonTerminals.Add(AttrUpdateList); _CommandNonTerminals.Add(AttrUpdate); _CommandNonTerminals.Add(WhereOrValuesAction); #endregion }
private static void CheckWrapTailHints(GrammarData data, NonTerminal nonTerminal, BnfTermList operands) { //WrapTail hint doesn't make sense in last position, so we start with Count-2 for (int i = operands.Count - 2; i >= 0; i--) { var hint = operands[i] as GrammarHint; if (hint == null || hint.HintType != HintType.WrapTail) continue; //we have WrapTail hint; wrap all operands after this into new non-terminal var wrapNt = new NonTerminal(nonTerminal.Name + "_tail" + nonTerminal._tailCount++); wrapNt.SetOption(TermOptions.IsTransient); wrapNt.Rule = new BnfExpression(); for (int j = i + 1; j < operands.Count; j++) { wrapNt.Rule.Data[0].Add(operands[j]); } operands.RemoveRange(i, operands.Count - i); operands.Add(wrapNt); data.AllTerms.Add(wrapNt); data.NonTerminals.Add(wrapNt); }//for i }
#pragma warning disable 1718 private static void TestLALR2() { Log(LogLevel.Info, "Starting TestLALR2()"); var G = new NonTerminal("G"); var S = new NonTerminal("S"); var E = new NonTerminal("E"); var N = new NonTerminal("N"); var V = new NonTerminal("V"); S.RHS = N; N.RHS = V < "=".T() < E; N.RHS = E; E.RHS = V; V.RHS = "x".T(); V.RHS = "*".T() < E; Log(LogLevel.Info, "End TestLALR2()"); Parser parser = new Parser(S, Log, LogLevel.Trace); var ok = parser.Parse("x=*x"); Debug.Assert(ok); }
public CLI_USEHISTORY() { // Command name and description InitCommand("USEHISTORY", "Saves the actual history to a specified file", "Saves the actual history to a specified file"); NonTerminal USEHISTORY_Options = new NonTerminal("USEHISTORY_Options"); SymbolTerminal USEHISTORY_Default_Option = Symbol("default"); USEHISTORY_Options.Rule = stringLiteralExternalEntry | USEHISTORY_Default_Option; USEHISTORY_Options.GraphOptions.Add(GraphOption.IsOption); _CommandNonTerminals.Add(USEHISTORY_Options); _CommandSymbolTerminal.Add(USEHISTORY_Default_Option); // BNF rule CreateBNFRule(CLICommandSymbolTerminal + USEHISTORY_Options); }
private static bool ComputeNullability(NonTerminal nonTerminal) { foreach (Production prod in nonTerminal.Productions) { if (prod.RValues.Count == 0) { nonTerminal.SetFlag(TermFlags.IsNullable); return true; //decided, Nullable }//if //If production has terminals, it is not nullable and cannot contribute to nullability if (prod.IsSet(ProductionFlags.HasTerminals)) continue; //Go thru all elements of production and check nullability bool allNullable = true; foreach (BnfTerm child in prod.RValues) { allNullable &= child.Flags.IsSet(TermFlags.IsNullable); }//foreach child if (allNullable) { nonTerminal.SetFlag(TermFlags.IsNullable); return true; } }//foreach prod return false; //cannot decide }
public DBCLI_INSERT() { // Command name and description InitCommand("INSERT", "Inserts new Objects into an instance of the GraphDB", "Inserts new Objects into an instance of the GraphDB"); #region BNF rule var INTO = Symbol("INTO"); var VALUES = Symbol("VALUES"); var AttrAssignList = new NonTerminal("AttrAssignList"); var AttrAssign = new NonTerminal("AttrAssign"); var StringOrNumber = new NonTerminal("StringOrNumber"); var comma = Symbol(","); var gleich = Symbol("="); var LISTOF = Symbol("LISTOF"); var SETOF = Symbol("SETOF"); var SETREF = Symbol("SETREF"); CreateBNFRule(CLICommandSymbolTerminal + INTO + stringLiteral + VALUES + "(" + AttrAssignList + ")"); AttrAssignList.Rule = AttrAssign + comma + AttrAssignList | AttrAssign; AttrAssignList.GraphOptions.Add(GraphOption.IsStructuralObject); StringOrNumber.Rule = stringLiteral | numberLiteral; AttrAssign.Rule = stringLiteral + gleich + StringOrNumber | stringLiteral + gleich + LISTOF + stringLiteral | stringLiteral + gleich + SETOF + stringLiteral | stringLiteral + gleich + SETREF + stringLiteral; AttrAssignList.GraphOptions.Add(GraphOption.IsOption); #endregion }
private void CollectTermsRecursive(BnfTerm term) { // Do not add pseudo terminals defined as static singletons in Grammar class (Empty, Eof, etc) // We will never see these terminals in the input stream. // Filter them by type - their type is exactly "Terminal", not derived class. if (term.GetType() == typeof(Terminal)) return; if (_grammarData.AllTerms.Contains(term)) return; _grammarData.AllTerms.Add(term); NonTerminal nt = term as NonTerminal; if (nt == null) return; if (nt.Name == null) { if (nt.Rule != null && !string.IsNullOrEmpty(nt.Rule.Name)) nt.Name = nt.Rule.Name; else nt.Name = "NT" + (_unnamedCount++); } if (nt.Rule == null) { _language.Errors.Add("Non-terminal " + nt.Name + " has uninitialized Rule property."); return; } //check all child elements foreach (BnfTermList elemList in nt.Rule.Data) for (int i = 0; i < elemList.Count; i++) { BnfTerm child = elemList[i]; if (child == null) { _language.Errors.Add("Rule for NonTerminal " + nt.Name + " contains null as an operand in position " + i.ToString() + " in one of productions."); continue; //for i loop } //Check for nested expression - convert to non-terminal BnfExpression expr = child as BnfExpression; if (expr != null) { child = new NonTerminal(null, expr); elemList[i] = child; } CollectTermsRecursive(child); }//for i }//method
public ReportingLanguage():base(false) { // 1. Terminals var numberLiteral = TerminalFactory.CreateCSharpNumber("Number"); var boolean = new ConstantTerminal("Boolean"); boolean.Add("true", true); boolean.Add("false", false); boolean.Priority = 10; var nil = new ConstantTerminal("Null"); nil.Add("null", null); nil.Add("nothing", null); nil.Priority = 10; var identifier = new IdentifierTerminal("Identifier"); var stringLiteral = new StringLiteral("String","'",StringFlags.AllowsDoubledQuote); stringLiteral.AddStartEnd("\"",StringFlags.AllowsAllEscapes); Terminal dot = Symbol(".", "dot"); Terminal less = Symbol("<"); Terminal greater = Symbol(">"); Terminal LCb = Symbol("("); Terminal RCb = Symbol(")"); Terminal RFb = Symbol("}"); Terminal LFb = Symbol("{"); Terminal comma = Symbol(","); // Terminal LSb = Symbol("["); // Terminal RSb = Symbol("]"); var exclamationMark = Symbol("!"); Terminal and = Symbol("and"); and.Priority = 10; Terminal or = Symbol("or"); or.Priority = 10; var UserSection = Symbol("User"); var GlobalSection = Symbol("Globals"); var ParameterSection = Symbol("Parameters"); var FieldsSection = Symbol("Fields"); // 2. Non-terminals var FieldRef = new NonTerminal("FieldRef"); var userSectionStmt = new NonTerminal("UserSectionStmt"); var globalSectionStmt = new NonTerminal("GlobalSectionStmt"); var parameterSectionStmt = new NonTerminal("ParameterSectionStmt"); var fieldsSectionStmt = new NonTerminal("FieldsSectionStmt"); var QualifiedName = new NonTerminal("QualifiedName"); var FunctionExpression = new NonTerminal("FunctionExpression"); var Condition = new NonTerminal("Condition"); var Conditional = new NonTerminal("IfThen"); var Expr = new NonTerminal("Expr"); var BinOp = new NonTerminal("BinOp"); var LUnOp = new NonTerminal("LUnOp"); var ExprList = new NonTerminal("ExprList"); var BinExpr = new NonTerminal("BinExpr", typeof(BinExprNode)); var ProgramLine = new NonTerminal("ProgramLine"); var Program = new NonTerminal("Program", typeof(StatementListNode)); // 3. BNF rules #region Reporting userSectionStmt.Rule = UserSection + exclamationMark + Symbol("UserId") |UserSection + exclamationMark + Symbol("Language"); globalSectionStmt.Rule = GlobalSection + exclamationMark + Symbol("PageNumber") | GlobalSection + exclamationMark + Symbol("TotalPages") | GlobalSection + exclamationMark + Symbol("ExecutionTime") | GlobalSection + exclamationMark + Symbol("ReportFolder") | GlobalSection + exclamationMark + Symbol("ReportName"); parameterSectionStmt.Rule = ParameterSection + exclamationMark + identifier; fieldsSectionStmt.Rule = FieldsSection + exclamationMark + identifier; #endregion Expr.Rule = Symbol("null") | boolean | nil | stringLiteral | numberLiteral | QualifiedName | FunctionExpression | LCb + Expr + RCb | LFb + QualifiedName + RFb | Conditional | BinExpr //| Expr + BinOp + Expr //| LUnOp + Expr | parameterSectionStmt | globalSectionStmt | userSectionStmt | fieldsSectionStmt; ExprList.Rule = MakePlusRule(ExprList, comma, Expr); BinOp.Rule = Symbol("+") | "-" | "*" | "%" | "^" | "&" | "|" | "/" | "&&" | "||" | "==" | "!=" | greater | less | ">=" | "<=" | "is" | "<>" | "=" //| "+=" | "-=" | "." | and | or; LUnOp.Rule = Symbol("-") | "!"; FunctionExpression.Rule = QualifiedName + LCb + ExprList.Q() + RCb | QualifiedName + LCb + BinExpr + RCb; QualifiedName.Rule = identifier | QualifiedName + dot + identifier | parameterSectionStmt + "!" + identifier | "#" + identifier ; Condition.Rule = LCb + Expr + RCb; Conditional.Rule = "if" + Condition + "then" + Expr | "if" + Condition + "then" + Expr + "else" + Expr | "if" + Condition + "then" + Expr + "otherwise" + Expr; BinExpr.Rule = Expr + BinOp + Expr | LUnOp + Expr; ProgramLine.Rule = Expr + NewLine; Program.Rule = MakeStarRule(Program, ProgramLine); this.Root = Program; // Set grammar root #region 5. Operators precedence RegisterOperators(1, "is", "=", "==", "!=", "<>", ">", "<", ">=", "<="); RegisterOperators(2, "+", "-"); RegisterOperators(3, "*", "/", "%"); RegisterOperators(4, Associativity.Right, "^"); RegisterOperators(5, "|", "||", "or"); RegisterOperators(6, "&", "&&", "and"); RegisterOperators(7, "!"); #endregion RegisterPunctuation("(", ")", "[", "]", "{", "}", ",", ";"); MarkTransient( Expr, BinOp); //automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source this.SetLanguageFlags(LanguageFlags.NewLineBeforeEOF | LanguageFlags.SupportsInterpreter | LanguageFlags.AutoDetectTransient |LanguageFlags.CreateAst); }
private NonTerminal CreateAugmentedRoot(NonTerminal root) { var result = new NonTerminal(root.Name + "'", root + _grammar.Eof); result.SetFlag(TermFlags.NoAstNode); //mark that we don't need AST node here return result; }
private void CollectTermsRecursive(BnfTerm term) { if (_grammarData.AllTerms.Contains(term)) return; _grammarData.AllTerms.Add(term); NonTerminal nt = term as NonTerminal; if (nt == null) return; if (string.IsNullOrEmpty(nt.Name)) { if (nt.Rule != null && !string.IsNullOrEmpty(nt.Rule.Name)) nt.Name = nt.Rule.Name; else nt.Name = "Unnamed" + (_unnamedCount++); } if (nt.Rule == null) _language.Errors.AddAndThrow(GrammarErrorLevel.Error, null, Resources.ErrNtRuleIsNull, nt.Name); //check all child elements foreach (BnfTermList elemList in nt.Rule.Data) for (int i = 0; i < elemList.Count; i++) { BnfTerm child = elemList[i]; if (child == null) { _language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrRuleContainsNull, nt.Name, i); continue; //for i loop } //Check for nested expression - convert to non-terminal BnfExpression expr = child as BnfExpression; if (expr != null) { child = new NonTerminal(null, expr); elemList[i] = child; } CollectTermsRecursive(child); }//for i }
public BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember) { listNonTerminal.SetOption(TermOptions.IsList); if (delimiter == null) listNonTerminal.Rule = listMember | listNonTerminal + listMember; else listNonTerminal.Rule = listMember | listNonTerminal + delimiter + listMember; return listNonTerminal.Rule; }
private Production CreateProduction(NonTerminal lvalue, BnfTermList operands) { Production prod = new Production(lvalue); GrammarHintList hints = null; //create RValues list skipping Empty terminal and collecting grammar hints foreach (BnfTerm operand in operands) { if (operand == _grammar.Empty) continue; //Collect hints as we go - they will be added to the next non-hint element GrammarHint hint = operand as GrammarHint; if (hint != null) { if (hints == null) hints = new GrammarHintList(); hints.Add(hint); continue; } //Add the operand and create LR0 Item prod.RValues.Add(operand); prod.LR0Items.Add(new LR0Item(_lastItemId++, prod, prod.RValues.Count - 1, hints)); hints = null; }//foreach operand //set the flags if (prod.RValues.Count == 0) prod.Flags |= ProductionFlags.IsEmpty; //Add final LRItem ComputeProductionFlags(prod); prod.LR0Items.Add(new LR0Item(_lastItemId++, prod, prod.RValues.Count, hints)); return prod; }
public GWBasicGrammar() { #region Initialisation // BASIC is not case sensitive... this.CaseSensitive = false; // Define the Terminals var lineNumber = new NumberLiteral("NUMBER", NumberFlags.IntOnly); var fileNumber = new NumberLiteral("NUMBER", NumberFlags.IntOnly); var number = new NumberLiteral("NUMBER", NumberFlags.AllowStartEndDot); var variable = new IdentifierTerminal("Identifier", "$%!", string.Empty); var stringLiteral = new StringLiteral("STRING", "\"", StringFlags.None); //Important: do not add comment term to base.NonGrammarTerminals list - we do use this terminal in grammar rules var userFunctionName = variable; var comment = new CommentTerminal("Comment", "REM", "\n"); var short_comment = new CommentTerminal("ShortComment", "'", "\n"); var comma = Symbol(",", "comma"); var colon = Symbol(":", "colon"); var comma_opt = new NonTerminal("comma_opt"); comma_opt.Rule = Empty | ","; var semi_opt = new NonTerminal("semi_opt"); semi_opt.Rule = Empty | ";"; var pound_opt = new NonTerminal("pound_opt"); pound_opt.Rule = Empty | "#"; // Define the non-terminals var PROGRAM = new NonTerminal("PROGRAM"); var LINE = new NonTerminal("LINE"); var LINE_CONTENT = new NonTerminal("LINE_CONTENT"); var SHORT_COMMENT_OPT = new NonTerminal("SHORT_COMMENT_OPT"); var STATEMENT_LIST = new NonTerminal("STATEMENT_LIST"); var STATEMENT = new NonTerminal("STATEMENT"); var PRINT_STMT = new NonTerminal("PRINT_STMT"); var PRINT_LIST = new NonTerminal("PRINT_LIST"); var PRINT_ARG = new NonTerminal("PRINT_ARG"); var OPEN_STMT = new NonTerminal("OPEN_STMT"); var OPEN_STMT_MODE = new NonTerminal("OPEN_STMT_MODE"); var OPEN_STMT_ACCESS = new NonTerminal("OPEN_STMT_ACCESS"); var CLOSE_STMT = new NonTerminal("CLOSE_STMT"); var INPUT_STMT = new NonTerminal("INPUT_STMT"); var VARIABLES = new NonTerminal("VARIABLES"); var IF_STMT = new NonTerminal("IF_STMT"); var THEN_CLAUSE = new NonTerminal("THEN_CLAUSE"); var ELSE_CLAUSE_OPT = new NonTerminal("ELSE_CLAUSE_OPT"); //, typeof(AstNode)); var EXPR = new NonTerminal("EXPRESSION"); var EXPR_LIST = new NonTerminal("EXPRESSION_LIST"); var BINARY_OP = new NonTerminal("BINARY_OP"); var BINARY_EXPR = new NonTerminal("BINARY_EXPR"); var UNARY_EXPR = new NonTerminal("UNARY_EXPR"); var SIGN = new NonTerminal("SIGN"); var ASSIGN_STMT = new NonTerminal("ASSIGN_STMT"); var FOR_STMT = new NonTerminal("FOR_STMT"); var STEP_OPT = new NonTerminal("STEP_OPT"); var NEXT_STMT = new NonTerminal("NEXT_STMT"); var LOCATE_STMT = new NonTerminal("LOCATE_STMT"); var WHILE_STMT = new NonTerminal("WHILE_STMT"); var WEND_STMT = new NonTerminal("WEND_STMT"); var SWAP_STMT = new NonTerminal("SWAP_STMT"); var FUN_CALL = new NonTerminal("FUN_CALL"); var VARIABLE_OR_FUNCTION_EXPR = new NonTerminal("VARIABLE_OR_FUNCTION_EXPR"); var ARG_LIST = new NonTerminal("ARG_LIST"); var COMMENT_STMT = new NonTerminal("COMMENT_STMT"); var LINE_INPUT_STMT = new NonTerminal("LINE_INPUT_STMT"); var LINE_INPUT_POUND_STMT = new NonTerminal("LINE_INPUT_POUND_STMT"); var END_STMT = new NonTerminal("END_STMT"); var CLS_STMT = new NonTerminal("CLS_STMT", typeof(AstNode)); var CLEAR_STMT = new NonTerminal("CLEAR_STMT"); var DIM_STMT = new NonTerminal("DIM_STMT"); var DEF_FN_STMT = new NonTerminal("DEF_FN_STMT"); var GOTO_STMT = new NonTerminal("GOTO_STMT"); var GOSUB_STMT = new NonTerminal("GOSUB_STMT"); var RETURN_STMT = new NonTerminal("RETURN_STMT"); var ON_STMT = new NonTerminal("ON_STMT"); var LINE_NUMBERS = new NonTerminal("LINE_NUMBERS"); var RANDOMIZE_STMT = new NonTerminal("RANDOMIZE_STMT"); // set the PROGRAM to be the root node of BASIC programs. this.Root = PROGRAM; #endregion #region Grammar declaration // A program is a bunch of lines PROGRAM.Rule = MakePlusRule(PROGRAM, LINE); // A line can be an empty line, or it's a number followed by a statement list ended by a new-line. LINE.Rule = NewLine | lineNumber + LINE_CONTENT + SHORT_COMMENT_OPT + NewLine; // A statement list is 1 or more statements separated by the ':' character LINE_CONTENT.Rule = IF_STMT | COMMENT_STMT | STATEMENT_LIST; STATEMENT_LIST.Rule = MakePlusRule(STATEMENT_LIST, colon, STATEMENT); SHORT_COMMENT_OPT.Rule = short_comment | Empty; // A statement can be one of a number of types STATEMENT.Rule = ASSIGN_STMT | PRINT_STMT | INPUT_STMT | OPEN_STMT | CLOSE_STMT | LINE_INPUT_POUND_STMT | LINE_INPUT_STMT | LOCATE_STMT | CLS_STMT | END_STMT | CLEAR_STMT | DIM_STMT | DEF_FN_STMT | SWAP_STMT | RANDOMIZE_STMT | GOSUB_STMT | RETURN_STMT | GOTO_STMT | ON_STMT | FOR_STMT | NEXT_STMT | WHILE_STMT | WEND_STMT; // The different statements are defined here PRINT_STMT.Rule = "print" + PRINT_LIST; PRINT_LIST.Rule = MakeStarRule(PRINT_LIST, null, PRINT_ARG); PRINT_ARG.Rule = EXPR + semi_opt; INPUT_STMT.Rule = "input" + semi_opt + stringLiteral + ";" + VARIABLES; OPEN_STMT.Rule = "open" + EXPR + (Empty | "for" + OPEN_STMT_MODE) + (Empty | "access" + OPEN_STMT_ACCESS) + "as" + pound_opt + fileNumber; OPEN_STMT_ACCESS.Rule = "read" + (Empty | "write") | "write"; OPEN_STMT_MODE.Rule = Symbol("o") | "i" | "a" | "output" | "input" | "append"; CLOSE_STMT.Rule = "close" + pound_opt + number; LINE_INPUT_STMT.Rule = Symbol("line") + "input" + semi_opt + stringLiteral + ";" + VARIABLE_OR_FUNCTION_EXPR; LINE_INPUT_POUND_STMT.Rule = Symbol("line") + "input" + Symbol("#") + fileNumber + comma + VARIABLE_OR_FUNCTION_EXPR; DIM_STMT.Rule = "dim" + VARIABLES; DEF_FN_STMT.Rule = "def" + userFunctionName + (Empty | "(" + ARG_LIST + ")") + "=" + EXPR; VARIABLES.Rule = VARIABLE_OR_FUNCTION_EXPR | VARIABLE_OR_FUNCTION_EXPR + "," + VARIABLES; IF_STMT.Rule = "if" + EXPR + THEN_CLAUSE + ELSE_CLAUSE_OPT; THEN_CLAUSE.Rule = "then" + STATEMENT_LIST | "goto" + lineNumber; //Inject PreferShift hint here to explicitly set shift as preferred action. Suppresses warning message about conflict. ELSE_CLAUSE_OPT.Rule = Empty | PreferShiftHere() + "else" + STATEMENT_LIST; GOTO_STMT.Rule = "goto" + lineNumber; GOSUB_STMT.Rule = "gosub" + lineNumber; RETURN_STMT.Rule = "return"; ON_STMT.Rule = "on" + EXPR + (Symbol("goto") | "gosub") + LINE_NUMBERS; LINE_NUMBERS.Rule = lineNumber + (Empty | "," + LINE_NUMBERS); ASSIGN_STMT.Rule = VARIABLE_OR_FUNCTION_EXPR + "=" + EXPR; LOCATE_STMT.Rule = "locate" + EXPR + comma + EXPR; SWAP_STMT.Rule = "swap" + EXPR + comma + EXPR; END_STMT.Rule = "end"; CLS_STMT.Rule = "cls"; CLEAR_STMT.Rule = Symbol("clear") + comma + (Empty | number) + (Empty | comma + number) | "clear" + number | "clear"; COMMENT_STMT.Rule = comment | short_comment; RANDOMIZE_STMT.Rule = "randomize" + EXPR; // An expression is a number, or a variable, a string, or the result of a binary comparison. EXPR.Rule = number | variable | FUN_CALL | stringLiteral | BINARY_EXPR | "(" + EXPR + ")" | UNARY_EXPR; BINARY_EXPR.Rule = EXPR + BINARY_OP + EXPR; UNARY_EXPR.Rule = SIGN + EXPR; SIGN.Rule = Symbol("-") | "+"; //Inject PreferShift hint here to explicitly set shift as preferred action. Suppresses warning message about conflict. FUN_CALL.Rule = variable + PreferShiftHere() + "(" + ARG_LIST + ")"; VARIABLE_OR_FUNCTION_EXPR.Rule = variable | FUN_CALL; BINARY_OP.Rule = Symbol("+") | "^" | "-" | "*" | "/" | "=" | "<=" | ">=" | "<" | ">" | "<>" | "and" | "or"; //let's do operator precedence right here RegisterOperators(60, "^"); RegisterOperators(50, "*", "/"); RegisterOperators(40, "+", "-"); RegisterOperators(30, "=", "<=", ">=", "<", ">", "<>"); RegisterOperators(20, "and", "or"); EXPR_LIST.Rule = MakeStarRule(EXPR_LIST, null, EXPR); FOR_STMT.Rule = "for" + ASSIGN_STMT + "to" + EXPR + STEP_OPT; STEP_OPT.Rule = Empty | "step" + EXPR; NEXT_STMT.Rule = "next" + VARIABLES | "next"; WHILE_STMT.Rule = "while" + EXPR; WEND_STMT.Rule = "wend"; //TODO: check number of arguments for particular function in node constructor ARG_LIST.Rule = MakePlusRule(ARG_LIST, comma, EXPR); #endregion #region Punctuation RegisterPunctuation("(", ")", ",", ";"); #endregion }
public RubyGrammar() { #region Terminals //String Literals with single and double-quote start/end symbols StringLiteral STRING = new StringLiteral("STRING", TermOptions.SpecialIgnoreCase); STRING.AddStartEnd("\"", ScanFlags.None); STRING.AddStartEnd("'", ScanFlags.None); Terminal HereDoc = new Terminal("HereDoc"); //-- implement me! Terminal RegExLiteral = new Terminal("RegExLiteral"); //-- implement me! IdentifierTerminal IDENTIFIER = new IdentifierTerminal("identifier", "_!?", "_$@"); // name extraChars extraFirstChars IDENTIFIER.DisplayName = "variable"; //we need to isolate reserved words to avoid ambiguities in grammar IDENTIFIER.AddKeywords("do", "end", "def", "class", "if", "case", "return", "yield", "while", "until"); //and some others... Terminal Number = new NumberLiteral("Number"); Terminal Comment = new CommentTerminal("Comment", "#", "\n"); NonGrammarTerminals.Add(Comment); //add comment explicitly to this list as it is not reachable from Root //some conveniency variables Terminal Pipe = Symbol("|"); Terminal dot = Symbol("."); Terminal comma = Symbol(","); #endregion #region NonTerminals //NT variables names match element names in original grammar NonTerminal PROGRAM = new NonTerminal("PROGRAM"); NonTerminal COMPSTMT = new NonTerminal("COMPSTMT"); NonTerminal STMT = new NonTerminal("STMT"); NonTerminal BLOCK = new NonTerminal("BLOCK"); NonTerminal EXPR = new NonTerminal("EXPR"); //NonTerminal CALL = new NonTerminal("CALL"); NonTerminal COMMAND = new NonTerminal("COMMAND"); NonTerminal FUNCTION = new NonTerminal("FUNCTION"); NonTerminal ARG = EXPR;// new NonTerminal("ARG"); NonTerminal PRIMARY = new NonTerminal("PRIMARY", "operand"); NonTerminal WHEN_ARGS = new NonTerminal("WHEN_ARGS"); NonTerminal THEN = new NonTerminal("THEN"); NonTerminal BLOCK_BEGIN = new NonTerminal("BLOCK_BEGIN"); NonTerminal BLOCK_END = new NonTerminal("BLOCK_END"); NonTerminal BLOCK_VAR = new NonTerminal("BLOCK_VAR"); // NonTerminal MLHS_ITEM = new NonTerminal("MLHS_ITEM"); NonTerminal LHS = new NonTerminal("LHS"); NonTerminal MRHS = new NonTerminal("MRHS"); // NonTerminal MLHS = MRHS; // new NonTerminal("MLHS"); NonTerminal CALL_ARGS = new NonTerminal("CALL_ARGS"); NonTerminal CALL_ARGS_P = new NonTerminal("CALL_ARGS_P"); NonTerminal AMP_ARG = new NonTerminal("AMP_ARG"); NonTerminal STAR_ARG = new NonTerminal("STAR_ARG"); NonTerminal ARGS = new NonTerminal("ARGS"); NonTerminal ARGDECL = new NonTerminal("ARGDECL"); NonTerminal ARGLIST = new NonTerminal("ARGLIST"); // NonTerminal SINGLETON = new NonTerminal("SINGLETON"); NonTerminal ASSOCS = new NonTerminal("ASSOCS"); NonTerminal ASSOC = new NonTerminal("ASSOC"); // NonTerminal VARIABLE = new NonTerminal("VARIABLE"); --merged into IDENTIFIER NonTerminal LITERAL = new NonTerminal("LITERAL", "value"); NonTerminal TERM = new NonTerminal("TERM"); NonTerminal DO = new NonTerminal("DO"); // NonTerminal VARNAME = new NonTerminal("VARNAME"); // note 1 NonTerminal GLOBAL = new NonTerminal("GLOBAL"); NonTerminal RETURN_STMT = new NonTerminal("RETURN_STMT"); NonTerminal YIELD_STMT = new NonTerminal("YIELD_STMT"); NonTerminal DEFINEDQ_STMT = new NonTerminal("DEFINEDQ_STMT"); NonTerminal FUNCTION_STMT = new NonTerminal("FUNCTION_STMT"); NonTerminal IF_STMT = new NonTerminal("IF_STMT"); NonTerminal UNLESS_STMT = new NonTerminal("UNLESS_STMT"); NonTerminal WHILE_STMT = new NonTerminal("WHILE_STMT"); NonTerminal UNTIL_STMT = new NonTerminal("UNTIL_STMT"); NonTerminal CASE_STMT = new NonTerminal("CASE_STMT"); NonTerminal FOR_STMT = new NonTerminal("FOR_STMT"); NonTerminal BLOCK_STMT = new NonTerminal("BLOCK_STMT"); NonTerminal CLASS_DEF = new NonTerminal("CLASS_DEF"); NonTerminal BASE_REF = new NonTerminal("BASE_REF"); NonTerminal MODULE = new NonTerminal("MODULE_STMT"); NonTerminal DEFFUNC_STMT = new NonTerminal("DEFFUNC_STMT"); NonTerminal DEFSING_STMT = new NonTerminal("DEFSING_STMT"); NonTerminal SINGLETON = new NonTerminal("SINGLETON"); NonTerminal END = new NonTerminal("end"); NonTerminal SYMBOL = new NonTerminal("SYMBOL"); //Not in original grammar NonTerminal FNAME = new NonTerminal("FNAME"); BLOCK_BEGIN.Rule = Symbol("do") | "{"; BLOCK_END.Rule = Symbol("end") | "}"; NonTerminal OPERATION = new NonTerminal("OPERATION"); // Terminal VARNAME = IDENTIFIER; NonTerminal AUG_ASGN = new NonTerminal("AUG_ASGN"); NonTerminal BINOP = new NonTerminal("BINOP", "operator"); NonTerminal UNOP = new NonTerminal("UNOP"); NonTerminal DELIM = new NonTerminal("DELIM"); #endregion #region Rules //Set grammar root this.Root = PROGRAM; //PROGRAM : COMPSTMT PROGRAM.Rule = COMPSTMT; // +Grammar.Eof; //COMPSTMT : STMT (TERM EXPR)* [TERM] COMPSTMT.Rule = NewLine.Q() + STMT.Plus(TERM) + TERM.Q(); /* STMT : CALL do [`|' [BLOCK_VAR] `|'] COMPSTMT end | undef FNAME | alias FNAME FNAME | STMT if EXPR | STMT while EXPR | STMT unless EXPR | STMT until EXPR | `BEGIN' `{' COMPSTMT `}' | `"end"' `{' COMPSTMT `}' | LHS `=' COMMAND [do [`|' [BLOCK_VAR] `|'] COMPSTMT end] | EXPR */ STMT.Rule = FUNCTION | COMMAND + BLOCK.Q() | "undef" + FNAME | "alias" + FNAME + FNAME | STMT + (Symbol("if")|"while"|"unless"|"until") + EXPR | Symbol("BEGIN") + "{" + COMPSTMT + "}" // | Symbol("end") + BLOCK_BEGIN + COMPSTMT + BLOCK_END // don't quite get it // | LHS + "=" + COMMAND + BLOCK.Q() | LHS + "=" + EXPR //changed this | LHS + AUG_ASGN + EXPR | EXPR; BLOCK.Rule = "do" + WithQ(Pipe + BLOCK_VAR.Q() + Pipe) + COMPSTMT + "end"; /* EXPR : MLHS `=' MRHS | return CALL_ARGS | yield CALL_ARGS | EXPR and EXPR | EXPR or EXPR | not EXPR | COMMAND | `!' COMMAND | ARG */ //this one is completely changed, for better or worse... EXPR.Rule = // MRHS + "=" + EXPR | //changed to EXPR // LHS + "=" + EXPR //changed this // | LHS + AUG_ASGN + EXPR EXPR + BINOP + EXPR | UNOP + EXPR //| "(" + EXPR + ")" | EXPR + "?" + EXPR + ":" + EXPR //added this to cover "?" operator | "defined?" + ARG | PRIMARY ; ARG = EXPR; // CALL : FUNCTION | COMMAND // CALL.Expression = FUNCTION | COMMAND; //expression embedded directly into STMT /* COMMAND : OPERATION CALL_ARGS | PRIMARY `.' OPERATION CALL_ARGS | PRIMARY `::' OPERATION CALL_ARGS | super CALL_ARGS */ COMMAND.Rule = OPERATION + CALL_ARGS | PRIMARY + DELIM + OPERATION + CALL_ARGS | "super" + CALL_ARGS; OPERATION.Rule = IDENTIFIER; DELIM.Rule = dot | "::"; /* FUNCTION : OPERATION [`(' [CALL_ARGS] `)'] | PRIMARY `.' OPERATION `(' [CALL_ARGS] `)' | PRIMARY `::' OPERATION `(' [CALL_ARGS] `)' | PRIMARY `.' OPERATION | PRIMARY `::' OPERATION | super `(' [CALL_ARGS] `)' | super */ FUNCTION.Rule = OPERATION + CALL_ARGS_P | PRIMARY + DELIM + OPERATION + CALL_ARGS_P.Q() | "super" + CALL_ARGS_P; CALL_ARGS_P.Rule = "(" + CALL_ARGS.Q() + ")"; /* ARG : LHS `=' ARG | LHS OP_ASGN ARG | ARG `..' ARG | ARG `...' ARG | ARG `+' ARG | ARG `-' ARG | ARG `*' ARG | ARG `/' ARG | ARG `%' ARG | ARG `**' ARG | `+' ARG | `-' ARG | ARG `|' ARG | ARG `^' ARG | ARG `&' ARG | ARG `<=>' ARG | ARG `>' ARG | ARG `>=' ARG | ARG `<' ARG | ARG `<=' ARG | ARG `==' ARG | ARG `===' ARG | ARG `!=' ARG | ARG `=~' ARG | ARG `!~' ARG | `!' ARG | `~' ARG | ARG `<<' ARG | ARG `>>' ARG | ARG `&&' ARG | ARG `||' ARG | defined? ARG | PRIMARY */ /* ARG.Expression = LHS + "=" + EXPR //changed this | LHS + AUG_ASGN + EXPR | ARG + BINOP + ARG //moved to EXPR | UNOP + ARG | "defined?" + ARG | PRIMARY ; */ AUG_ASGN.Rule = Symbol("+=") | "-=" | "*=" | "/=" | "%=" | "**=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "&&=" | "||="; BINOP.Rule = Symbol("..") | "..." | "+" | "-" | "*" | "/" | "%" | "**" | "|" | "^" | "&" | "<=>" | ">" | ">=" | "<" | "<=" | "==" | "===" | "!=" | "=~" | "!~" | "<<" | ">>" | "&&" | "||" | "and" | "or"; //added these two here UNOP.Rule = Symbol("+") | "-" | "!" | "~"; /*PRIMARY: */ /* `(' COMPSTMT `)' | LITERAL | VARIABLE | PRIMARY `::' IDENTIFIER | `::' IDENTIFIER | PRIMARY `[' [ARGS] `]' | `[' [ARGS [`,']] `]' | `{' [(ARGS|ASSOCS) [`,']] `}' | return [`(' [CALL_ARGS] `)'] | yield [`(' [CALL_ARGS] `)'] | defined? `(' ARG `)' | FUNCTION | FUNCTION `{' [`|' [BLOCK_VAR] `|'] COMPSTMT `}' | if EXPR THEN COMPSTMT (elsif EXPR THEN COMPSTMT)* [else COMPSTMT] end | unless EXPR THEN COMPSTMT [else COMPSTMT] end | while EXPR DO COMPSTMT end | until EXPR DO COMPSTMT end | case COMPSTMT (when WHEN_ARGS THEN COMPSTMT)+ [else COMPSTMT] end | for BLOCK_VAR in EXPR DO COMPSTMT end | begin COMPSTMT [rescue [ARGS] DO COMPSTMT]+ [else COMPSTMT] [ensure COMPSTMT] end | class IDENTIFIER [`<' IDENTIFIER] COMPSTMT end"= | module IDENTIFIER COMPSTMT end | def FNAME ARGDECL COMPSTMT end | def SINGLETON (`.'|`::') FNAME ARGDECL COMPSTMT end */ PRIMARY.Rule = // "(" + COMPSTMT + ")" | //-- removed this to fix ambiguity LITERAL | LHS //note 1. | "[" + WithQ(ARGS + comma.Q()) + "]" | "{" + WithQ( (ARGS|ASSOC) + comma.Q() ) + "}" | RETURN_STMT | YIELD_STMT | DEFINEDQ_STMT | FUNCTION_STMT | IF_STMT | UNLESS_STMT | WHILE_STMT | UNTIL_STMT | CASE_STMT | FOR_STMT | BLOCK_STMT | CLASS_DEF | MODULE | DEFFUNC_STMT | DEFSING_STMT; // LHS.Expression = VARIABLE | PRIMARY + "[" + ARGS.Q() + "]" | PRIMARY + "." + IDENTIFIER; RETURN_STMT.Rule = "return" + EXPR;// CALL_ARGS_P.Q(); //changed this YIELD_STMT.Rule = "yield" + CALL_ARGS_P.Q(); DEFINEDQ_STMT.Rule = Symbol("defined?") + "(" + ARG + ")"; FUNCTION_STMT.Rule = FUNCTION + WithQ("{" + WithQ("|" + BLOCK_VAR.Q() + "|") + COMPSTMT + "}"); IF_STMT.Rule = "if" + EXPR + THEN + COMPSTMT + WithStar("elsif" + EXPR + THEN + COMPSTMT) + WithQ("else" + COMPSTMT) + END; UNLESS_STMT.Rule = "unless" + EXPR + THEN + COMPSTMT + "else" + COMPSTMT + END; WHILE_STMT.Rule = "while" + EXPR + DO + COMPSTMT + END; UNTIL_STMT.Rule = "until" + EXPR + DO + COMPSTMT + END; CASE_STMT.Rule = "case" + COMPSTMT + WithPlus("when" + WHEN_ARGS + THEN + COMPSTMT) + WithQ("else" + COMPSTMT) + END; FOR_STMT.Rule = "for" + BLOCK_VAR + "in" + EXPR + DO + COMPSTMT + END; BLOCK_STMT.Rule = "begin" + COMPSTMT + WithPlus("rescue" + ARGS.Q() + DO + COMPSTMT) + WithQ("else" + COMPSTMT) + WithQ("ensure" + COMPSTMT) + END; CLASS_DEF.Rule = "class" + IDENTIFIER + BASE_REF.Q() + COMPSTMT + END; BASE_REF.Rule = "<" + IDENTIFIER; MODULE.Rule = "module" + IDENTIFIER + COMPSTMT + END; DEFFUNC_STMT.Rule = "def" + FNAME + ARGDECL.Q() + COMPSTMT + END; DEFSING_STMT.Rule = "def" + SINGLETON + (dot|"::") + FNAME + ARGDECL.Q() + COMPSTMT + END; END.Rule = "end"; // TERM.Q() + "end"; // SINGLETON : VARIABLE | `(' EXPR `)' SINGLETON.Rule = IDENTIFIER | "(" + EXPR + ")"; // WHEN_ARGS : ARGS [`,' `*' ARG] | `*' ARG WHEN_ARGS.Rule = ARGS + WithQ(comma + "*" + ARG) | "*" + ARG; // THEN : TERM | then | TERM then THEN.Rule = TERM | "then" | TERM + "then"; // DO : TERM | do | TERM do DO.Rule = TERM | "do" | TERM + "do"; // BLOCK_VAR : LHS | MLHS // BLOCK_VAR.Expression = LHS | MLHS; // -- ambiguous, changing to the following: BLOCK_VAR.Rule = IDENTIFIER | "(" + IDENTIFIER.Plus(comma) + ")"; // MLHS : MLHS_ITEM `,' [MLHS_ITEM (`,' MLHS_ITEM)*] [`*' [LHS]] | `*' LHS // MLHS.Expression = MLHS_ITEM.Plus(",") + WithQ("*" + LHS.Q()) | "*" + LHS; --ambiguous //MLHS.Expression = PRIMARY.Plus(",") + WithQ("*" + LHS.Q()) | "*" + LHS; // MLHS_ITEM : LHS | '(' MLHS ')' //MLHS_ITEM.Expression = LHS | "(" + MLHS + ")"; //--ambiguous!!! using PRIMARY //MLHS_ITEM = PRIMARY; /* LHS : VARIABLE | PRIMARY `[' [ARGS] `]' | PRIMARY `.' IDENTIFIER */ // LHS.Expression = IDENTIFIER | PRIMARY + "[" + ARGS.Q() + "]" | PRIMARY + dot + IDENTIFIER; LHS.Rule = OPERATION | PRIMARY + "[" + ARGS.Q() + "]" | "(" + EXPR + ")"; // MRHS : ARGS [`,' `*' ARG] | `*' ARG MRHS.Rule = ARGS + WithQ(comma + "*" + ARG) | "*" + ARG; /* CALL_ARGS : ARGS | ARGS [`,' ASSOCS] [`,' `*' ARG] [`,' `&' ARG] | ASSOCS [`,' `*' ARG] [`,' `&' ARG] | `*' ARG [`,' `&' ARG] | `&' ARG | COMMAND */ CALL_ARGS.Rule = // ARGS | //removed this - it is covered by next expression ARGS + WithQ(comma + ASSOCS) + STAR_ARG.Q() + AMP_ARG.Q() | ASSOCS + STAR_ARG.Q() + AMP_ARG.Q() | "*" + ARG + AMP_ARG.Q() | "&" + ARG | COMMAND; AMP_ARG.Rule = comma + "&" + ARG; STAR_ARG.Rule = comma + "*" + ARG; // ARGS : ARG (`,' ARG)* ARGS.Rule = ARG.Plus(comma); // ARGDECL : `(' ARGLIST `)' | ARGLIST TERM ARGDECL.Rule = "(" + ARGLIST + ")" | ARGLIST + TERM; /* ARGLIST : IDENTIFIER(`,'IDENTIFIER)*[`,'`*'[IDENTIFIER]][`,'`&'IDENTIFIER] | `*'IDENTIFIER[`,'`&'IDENTIFIER] | [`&'IDENTIFIER] */ ARGLIST.Rule = IDENTIFIER.Plus(comma) + WithQ(comma + "*" + IDENTIFIER.Q()) + WithQ(comma + "&" + IDENTIFIER) | "*" + IDENTIFIER + WithQ(comma + "&" + IDENTIFIER) | "&" + IDENTIFIER; // ASSOCS : ASSOC (`,' ASSOC)* ASSOCS.Rule = ASSOC.Plus(comma); //ASSOC : ARG `=>' ARG ASSOC.Rule = ARG + "=>" + ARG; // VARIABLE : VARNAME | nil | self -- variable is merged into IDENTIFIER //VARIABLE.Expression = IDENTIFIER | "nil" | "self"; // LITERAL : numeric | SYMBOL | STRING | STRING2 | HERE_DOC | REGEXP LITERAL.Rule = Number | SYMBOL | STRING | HereDoc | RegExLiteral; SYMBOL.Rule = Symbol(":") + IDENTIFIER; // (FNAME | VARNAME); //note 1. /* FNAME : IDENTIFIER | `..' | `|' | `^' | `&' | `<=>' | `==' | `===' | `=~' | `>' | `>=' | `<' | `<=' | `+' | `-' | `*' | `/' | `%' | `**' | `<<' | `>>' | `~' | `+@' | `-@' | `[]' | `[]=' */ FNAME.Rule = IDENTIFIER | ".." | "|" | "^" | "&" | "<=>" | "==" | "===" | "=~" | ">" | ">=" | "<" | "<=" | "+" | "-" | "*" | "/" | "%" | "**" | "<<" | ">>" | "~" | "+@" | "-@" | "[]" | "[]="; // TERM : `;' | `\n' TERM.Rule = NewLine | ";"; //NewLine is produced by token filter #endregion //error handling EXPR.ErrorRule = SyntaxError; DEFFUNC_STMT.ErrorRule = "def" + SyntaxError + COMPSTMT + END; #region misc: Operators, TokenFilters, etc //Register operators - not sure if precedence is assigned correctly RegisterOperators(100, Associativity.Right, "**"); RegisterOperators( 90, "<<", ">>"); RegisterOperators( 80, "*", "/", "%"); RegisterOperators( 70, "+", "-"); RegisterOperators( 60, "&", "&&", "and"); RegisterOperators( 50, "|", "||", "or", "^"); RegisterOperators( 40, ">", ">=", "<", "<=", "?"); RegisterOperators( 30, "<=>" , "==" , "===" , "!=" , "=~" , "!~"); RegisterOperators( 20, "..", "..."); RegisterPunctuation("(", ")", "," ); CodeOutlineFilter filter = new CodeOutlineFilter(false); TokenFilters.Add(filter); #endregion }
public BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember) { if (delimiter == null) { //it is much simpler case listNonTerminal.SetOption(TermOptions.IsList); listNonTerminal.Rule = Empty | listNonTerminal + listMember; return listNonTerminal.Rule; } NonTerminal tmp = new NonTerminal(listMember.Name + "+"); MakePlusRule(tmp, delimiter, listMember); listNonTerminal.Rule = Empty | tmp; listNonTerminal.SetOption(TermOptions.IsStarList); return listNonTerminal.Rule; }
private void CreateAcceptAction(ParserState initialState, NonTerminal augmentedRoot) { var root = augmentedRoot.Productions[0].RValues[0]; var shiftOverRootState = initialState.Actions[root].NewState; shiftOverRootState.Actions[_grammar.Eof] = new ParserAction(ParserActionType.Accept, null, null); }
public ScriptdotnetGrammar(bool expressionGrammar) { #region 1. Terminals NumberLiteral n = TerminalFactory.CreateCSharpNumber("number"); IdentifierTerminal v = CreateScriptNetIdentifier("Identifier"); Terminal s = CreateScriptNetString("string"); Terminal @is = Symbol("is"); Terminal dot = Symbol(".", "dot"); Terminal less = Symbol("<"); Terminal greater = Symbol(">"); Terminal arrow = Symbol("->"); Terminal LSb = Symbol("["); Terminal RSb = Symbol("]"); Terminal LCb = Symbol("("); Terminal RCb = Symbol(")"); Terminal RFb = Symbol("}"); Terminal LFb = Symbol("{"); Terminal LMb = Symbol("<!"); Terminal RMb = Symbol("!>"); Terminal LGb = Symbol("<|"); Terminal RGb = Symbol("|>"); Terminal comma = Symbol(","); Terminal semicolon = Symbol(";"); Terminal colon = Symbol(":"); #endregion #region 2. Non-terminals #region 2.1 Expressions NonTerminal Expr = new NonTerminal("Expr", typeof(ScriptExpr)); NonTerminal ConstExpr = new NonTerminal("ConstExpr", typeof(ScriptConstExpr)); NonTerminal BinExpr = new NonTerminal("BinExpr", typeof(ScriptBinExpr)); NonTerminal UnaryExpr = new NonTerminal("UnaryExpr", typeof(ScriptUnaryExpr)); NonTerminal AssignExpr = new NonTerminal("AssignExpr", typeof(ScriptAssignExpr)); NonTerminal TypeConvertExpr = new NonTerminal("TypeConvertExpr", typeof(ScriptTypeConvertExpr)); NonTerminal IsExpr = new NonTerminal("IsExpr", typeof(ScriptIsExpr)); NonTerminal MetaExpr = new NonTerminal("MetaExpr", typeof(ScriptMetaExpr)); NonTerminal FuncDefExpr = new NonTerminal("FuncDefExpr", typeof(ScriptFunctionDefinition)); //typeof(ScriptFunctionDefExpression)); NonTerminal TypeExpr = new NonTerminal("TypeExpr", typeof(ScriptTypeExpr)); NonTerminal TypeConstructor = new NonTerminal("TypeConstructor", typeof(ScriptTypeConstructor)); NonTerminal FunctionCall = new NonTerminal("FunctionCall", typeof(ScriptFunctionCall)); NonTerminal ArrayResolution = new NonTerminal("ArrayResolution", typeof(ScriptArrayResolution)); NonTerminal BinOp = new NonTerminal("BinOp"); NonTerminal LUnOp = new NonTerminal("LUnOp"); NonTerminal RUnOp = new NonTerminal("RUnOp"); NonTerminal ArrayConstructor = new NonTerminal("ArrayConstructor", typeof(ScriptArrayConstructor)); NonTerminal MObjectConstructor = new NonTerminal("MObjectConstructor", typeof(ScriptMObject)); NonTerminal MObjectPart = new NonTerminal("MObjectPart", typeof(ScriptMObjectPart)); NonTerminal MObjectParts = new NonTerminal("MObjectPart", typeof(ScriptAst)); NonTerminal TypeList = new NonTerminal("TypeList", typeof(ScriptTypeExprList)); #endregion #region 2.2 QualifiedName //Expression List: expr1, expr2, expr3, .. NonTerminal ExprList = new NonTerminal("ExprList", typeof(ScriptExprList)); //A name in form: a.b.c().d[1,2].e .... NonTerminal NewStmt = new NonTerminal("NewStmt", typeof(ScriptNewStmt)); NonTerminal NewArrStmt = new NonTerminal("NewArrStmt", typeof(ScriptNewArrStmt)); NonTerminal QualifiedName = new NonTerminal("QualifiedName", typeof(ScriptQualifiedName)); NonTerminal GenericsPostfix = new NonTerminal("GenericsPostfix", typeof(ScriptGenericsPostfix)); NonTerminal GlobalList = new NonTerminal("GlobalList", typeof(ScriptGlobalList)); #endregion #region 2.3 Statement NonTerminal Condition = new NonTerminal("Condition", typeof(ScriptCondition)); NonTerminal Statement = new NonTerminal("Statement", typeof(ScriptStatement)); NonTerminal IfStatement = new NonTerminal("IfStatement", typeof(ScriptIfStatement)); NonTerminal WhileStatement = new NonTerminal("WhileStatement", typeof(ScriptWhileStatement)); NonTerminal ForStatement = new NonTerminal("ForStatement", typeof(ScriptForStatement)); NonTerminal ForEachStatement = new NonTerminal("ForEachStatement", typeof(ScriptForEachStatement)); NonTerminal OptionalExpression = new NonTerminal("OptionalExpression", typeof(ScriptExpr)); NonTerminal SwitchStatement = new NonTerminal("SwitchStatement", typeof(ScriptStatement)); NonTerminal SwitchStatements = new NonTerminal("SwitchStatements", typeof(ScriptSwitchStatement)); NonTerminal SwitchCaseStatement = new NonTerminal("SwitchCaseStatement", typeof(ScriptSwitchCaseStatement)); NonTerminal SwitchDefaultStatement = new NonTerminal("SwitchDefaultStatement", typeof(ScriptSwitchDefaultStatement)); NonTerminal UsingStatement = new NonTerminal("UsingStatement", typeof(ScriptUsingStatement)); NonTerminal TryCatchFinallyStatement = new NonTerminal("TryCatchFinallyStatement", typeof(ScriptTryCatchFinallyStatement)); NonTerminal FlowControlStatement = new NonTerminal("FlowControl", typeof(ScriptFlowControlStatement)); NonTerminal ExprStatement = new NonTerminal("ExprStatement", typeof(ScriptStatement)); //Block NonTerminal BlockStatement = new NonTerminal("BlockStatement", typeof(ScriptStatement)); NonTerminal Statements = new NonTerminal("Statements(Compound)", typeof(ScriptCompoundStatement)); #endregion #region 2.4 Program and Functions NonTerminal Prog = new NonTerminal("Prog", typeof(ScriptProg)); NonTerminal Element = new NonTerminal("Element", typeof(ScriptAst)); NonTerminal Elements = new NonTerminal("Elements", typeof(ScriptElements)); NonTerminal FuncDef = new NonTerminal("FuncDef", typeof(ScriptFunctionDefinition)); NonTerminal FuncContract = new NonTerminal("FuncContract", typeof(ScriptFuncContract)); NonTerminal ParameterList = new NonTerminal("ParamaterList", typeof(ScriptFuncParameters)); NonTerminal FuncContractPre = new NonTerminal("Pre Conditions", typeof(ScriptFuncContractPre)); NonTerminal FuncContractPost = new NonTerminal("Post Conditions", typeof(ScriptFuncContractPost)); NonTerminal FuncContractInv = new NonTerminal("Invariant Conditions", typeof(ScriptFuncContractInv)); #endregion #endregion #region 3. BNF rules #region 3.1 Expressions ConstExpr.Rule = Symbol("true") | "false" | "null" | s | n; BinExpr.Rule = Expr + BinOp + Expr | IsExpr; UnaryExpr.Rule = LUnOp + Expr; IsExpr.Rule = Expr + @is + TypeExpr; TypeConvertExpr.Rule = LCb + Expr + RCb + Expr.Q(); AssignExpr.Rule = QualifiedName + "=" + Expr | QualifiedName + "++" | QualifiedName + "--" | QualifiedName + ":=" + Expr | QualifiedName + "+=" + Expr | QualifiedName + "-=" + Expr; //TODO: MetaFeatures; // <[ ] + > because of conflict a[1]>2 MetaExpr.Rule = LMb + Elements + RMb; GlobalList.Rule = "global" + LCb + ParameterList + RCb; FuncDefExpr.Rule = "function" + LCb + ParameterList + RCb + GlobalList.Q() + FuncContract.Q() + BlockStatement; Expr.Rule = ConstExpr | BinExpr | UnaryExpr | QualifiedName | AssignExpr | NewStmt | FuncDefExpr | NewArrStmt | ArrayConstructor | MObjectConstructor | TypeConvertExpr | MetaExpr ; NewStmt.Rule = "new" + TypeConstructor; NewArrStmt.Rule = "new" + TypeExpr + ArrayResolution; BinOp.Rule = Symbol("+") | "-" | "*" | "/" | "%" | "^" | "&" | "|" | "&&" | "||" | "==" | "!=" | greater | less | ">=" | "<="; LUnOp.Rule = Symbol("~") | "-" | "!" | "$"; ArrayConstructor.Rule = LSb + ExprList + RSb; MObjectPart.Rule = v + arrow + Expr; MObjectParts.Rule = MakePlusRule(MObjectParts, comma, MObjectPart); MObjectConstructor.Rule = LSb + MObjectParts + RSb; OptionalExpression.Rule = Expr.Q(); #endregion #region 3.2 QualifiedName TypeExpr.Rule = //MakePlusRule(TypeExpr, dot, v); v + GenericsPostfix.Q() | TypeExpr + dot + (v + GenericsPostfix.Q()); GenericsPostfix.Rule = LGb + TypeList + RGb; FunctionCall.Rule = LCb + ExprList.Q() + RCb; ArrayResolution.Rule = LSb + ExprList + RSb; QualifiedName.Rule = v + (GenericsPostfix | ArrayResolution | FunctionCall).Star() | QualifiedName + dot + v + (GenericsPostfix | ArrayResolution | FunctionCall).Star(); ExprList.Rule = MakePlusRule(ExprList, comma, Expr); TypeList.Rule = MakePlusRule(TypeList, comma, TypeExpr); TypeConstructor.Rule = TypeExpr + FunctionCall; #endregion #region 3.3 Statement Condition.Rule = LCb + Expr + RCb; IfStatement.Rule = "if" + Condition + Statement + ("else" + Statement).Q(); WhileStatement.Rule = "while" + Condition + Statement; ForStatement.Rule = "for" + LCb + OptionalExpression + semicolon + OptionalExpression + semicolon + OptionalExpression + RCb + Statement; ForEachStatement.Rule = "foreach" + LCb + v + "in" + Expr + RCb + Statement; UsingStatement.Rule = "using" + LCb + Expr + RCb + BlockStatement; TryCatchFinallyStatement.Rule = "try" + BlockStatement + "catch" + LCb + v + RCb + BlockStatement + "finally" + BlockStatement; SwitchStatement.Rule = "switch" + LCb + Expr + RCb + LFb + SwitchStatements + RFb; ExprStatement.Rule = Expr + semicolon; FlowControlStatement.Rule = "break" + semicolon | "continue" + semicolon | "return" + Expr + semicolon | "throw" + Expr + semicolon; Statement.Rule = semicolon | IfStatement //1. If | WhileStatement //2. While | ForStatement //3. For | ForEachStatement //4. ForEach | UsingStatement //5. Using | SwitchStatement //6. Switch | BlockStatement //7. Block | TryCatchFinallyStatement //8. TryCatch | ExprStatement //9. Expr | FlowControlStatement; //10. FlowControl Statements.SetOption(TermOptions.IsList); Statements.Rule = Statements + Statement | Empty; BlockStatement.Rule = LFb + Statements + RFb; SwitchStatements.Rule = SwitchCaseStatement.Star() + SwitchDefaultStatement.Q(); SwitchCaseStatement.Rule = Symbol("case") + Expr + colon + Statements; SwitchDefaultStatement.Rule = "default" + colon + Statements; #endregion #region 3.4 Prog FuncContract.Rule = LSb + FuncContractPre + semicolon + FuncContractPost + semicolon + FuncContractInv + semicolon + RSb; FuncContractPre.Rule = "pre" + LCb + ExprList.Q() + RCb; FuncContractPost.Rule = "post" + LCb + ExprList.Q() + RCb; FuncContractInv.Rule = "invariant" + LCb + ExprList.Q() + RCb; ParameterList.Rule = MakeStarRule(ParameterList, comma, v); FuncDef.Rule = "function" + v + LCb + ParameterList + RCb + GlobalList.Q() + FuncContract.Q() + BlockStatement; Element.Rule = Statement | FuncDef; Elements.SetOption(TermOptions.IsList); Elements.Rule = Elements + Element | Empty; Prog.Rule = Elements + Eof; Terminal Comment = new CommentTerminal("Comment", "/*", "*/"); NonGrammarTerminals.Add(Comment); Terminal LineComment = new CommentTerminal("LineComment", "//", "\n"); NonGrammarTerminals.Add(LineComment); #endregion #endregion #region 4. Set starting symbol if (!expressionGrammar) Root = Prog; // Set grammar root else Root = Expr; #endregion #region 5. Operators precedence RegisterOperators(1, "=", "+=", "-=", ":="); RegisterOperators(2, "|", "||"); RegisterOperators(3, "&", "&&"); RegisterOperators(4, "==", "!=", ">", "<", ">=", "<="); RegisterOperators(5, "is"); RegisterOperators(6, "+", "-"); RegisterOperators(7, "*", "/", "%"); RegisterOperators(8, Associativity.Right, "^"); RegisterOperators(9, "~", "!", "$", "++", "--"); RegisterOperators(10, "."); //RegisterOperators(10, Associativity.Right, ".",",", ")", "(", "]", "[", "{", "}"); //RegisterOperators(11, Associativity.Right, "else"); #endregion #region 6. Punctuation symbols RegisterPunctuation( "(", ")", "[", "]", "{", "}", ",", ";" ); #endregion }