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("<", ">", "(", ")"); }
private static StringLiteral CreateScriptNetString(string name) { StringLiteral term = new StringLiteral(name, TermOptions.None); term.AddStartEnd("'", ScanFlags.AllowAllEscapes); term.AddStartEnd("\"", ScanFlags.AllowAllEscapes); term.AddPrefixFlag("@", ScanFlags.DisableEscapes | ScanFlags.AllowLineBreak | ScanFlags.AllowDoubledQuote); return term; }
public BasicGrammar() { #region Initialisation // BASIC is not case sensitive... this.CaseSensitive = false; // By default, new-line characters are ignored. Because BASIC uses // line breaks to delimit lines, we need to know where the line breaks // are. The following line is required for this. this.TokenFilters.Add(new CodeOutlineFilter(false)); // Define the Terminals Terminal number = new NumberLiteral("NUMBER"); VariableIdentifierTerminal variable = new VariableIdentifierTerminal(); Terminal stringLiteral = new StringLiteral("STRING", "\"", ScanFlags.None); //Important: do not add comment term to base.NonGrammarTerminals list - we do use this terminal in grammar rules Terminal comment = new CommentTerminal("Comment", "REM", "\n"); Terminal comma = Symbol(",", "comma"); // Make sure reserved keywords of the BASIC language aren't mistaken // for variables. Only the keywords ending with '$' could be mistaken // for variables. variable.AddKeywords( "inkey$", "left$", "right$", "mid$", "chr$", "space$", "str$", "string$" ); // Define the non-terminals NonTerminal PROGRAM = new NonTerminal("PROGRAM", typeof(ProgramNode)); NonTerminal LINE = new NonTerminal("LINE", typeof(LineNode)); NonTerminal STATEMENT_LIST = new NonTerminal("STATEMENT_LIST", typeof(StatementListNode)); NonTerminal STATEMENT = new NonTerminal("STATEMENT", typeof(StatementNode)); NonTerminal COMMAND = new NonTerminal("COMMAND", typeof(StatementNode)); //TODO: create command node NonTerminal PRINT_STMT = new NonTerminal("PRINT_STMT", typeof(PrintStmtNode)); NonTerminal INPUT_STMT = new NonTerminal("INPUT_STMT", typeof(InputStmtNode)); NonTerminal IF_STMT = new NonTerminal("IF_STMT", typeof(IfElseStmtNode)); //TODO: join IfStmtNode and IfElseStmtNode in one NonTerminal ELSE_CLAUSE_OPT = new NonTerminal("ELSE_CLAUSE_OPT", typeof(GenericJsBasicNode)); NonTerminal EXPR = new NonTerminal("EXPRESSION", typeof(ExpressionNode)); NonTerminal EXPR_LIST = new NonTerminal("EXPRESSION_LIST", typeof(ExprListNode)); NonTerminal BINARY_OP = new NonTerminal("BINARY_OP", typeof(BinaryOpNode)); NonTerminal BINARY_EXPR = new NonTerminal("BINARY_EXPR", typeof(GenericJsBasicNode)); //TODO: create Binary_expr node NonTerminal BRANCH_STMT = new NonTerminal("BRANCH_STMT", typeof(BranchStmtNode)); NonTerminal ASSIGN_STMT = new NonTerminal("ASSIGN_STMT", typeof(AssignStmtNode)); NonTerminal FOR_STMT = new NonTerminal("FOR_STMT", typeof(ForStmtNode)); NonTerminal STEP_OPT = new NonTerminal("STEP_OPT", typeof(GenericJsBasicNode)); //TODO: create step specifier node NonTerminal NEXT_STMT = new NonTerminal("NEXT_STMT", typeof(NextStmtNode)); NonTerminal LOCATE_STMT = new NonTerminal("LOCATE_STMT", typeof(LocateStmtNode)); NonTerminal WHILE_STMT = new NonTerminal("WHILE_STMT", typeof(WhileStmtNode)); NonTerminal WEND_STMT = new NonTerminal("WEND_STMT", typeof(WendStmtNode)); NonTerminal SWAP_STMT = new NonTerminal("SWAP_STMT", typeof(SwapStmtNode)); NonTerminal GLOBAL_FUNCTION_EXPR = new NonTerminal("GLOBAL_FUNCTION_EXPR", typeof(GlobalFunctionExpr)); NonTerminal ARG_LIST = new NonTerminal("ARG_LIST", typeof(GenericJsBasicNode)); NonTerminal FUNC_NAME = new NonTerminal("FUNC_NAME", typeof(GenericJsBasicNode)); NonTerminal COMMENT_STMT = new NonTerminal("COMMENT_STMT", typeof(RemStmtNode)); NonTerminal GLOBAL_VAR_EXPR = new NonTerminal("GLOBAL_VAR_EXPR", typeof(GenericJsBasicNode)); // Set the PROGRAM to be the root node of BASIC programs. // A program is a bunch of lines this.Root = PROGRAM; #endregion #region Grammar declaration // A program is a collection of lines PROGRAM.Rule = MakePlusRule(PROGRAM, null, 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 | number + NewLine | number + STATEMENT_LIST + NewLine; // A statement list is 1 or more statements separated by the ':' character STATEMENT_LIST.Rule = MakePlusRule(STATEMENT_LIST, Symbol(":"), STATEMENT); // A statement can be one of a number of types STATEMENT.Rule = EXPR | ASSIGN_STMT | PRINT_STMT | INPUT_STMT | IF_STMT | COMMENT_STMT | BRANCH_STMT | COMMAND | FOR_STMT | NEXT_STMT | LOCATE_STMT | SWAP_STMT | WHILE_STMT | WEND_STMT; // The different statements are defined here PRINT_STMT.Rule = "print" + EXPR_LIST; INPUT_STMT.Rule = "input" + EXPR_LIST + variable; IF_STMT.Rule = "if" + EXPR + "then" + STATEMENT_LIST + ELSE_CLAUSE_OPT; ELSE_CLAUSE_OPT.Rule = Empty | "else" + STATEMENT_LIST; BRANCH_STMT.Rule = "goto" + number | "gosub" + number | "return"; ASSIGN_STMT.Rule = variable + "=" + EXPR; LOCATE_STMT.Rule = "locate" + EXPR + comma + EXPR; SWAP_STMT.Rule = "swap" + EXPR + comma + EXPR; COMMAND.Rule = Symbol("end") | "cls"; COMMENT_STMT.Rule = comment; // An expression is a number, or a variable, a string, or the result of a binary comparison. EXPR.Rule = number | variable | stringLiteral | BINARY_EXPR | GLOBAL_VAR_EXPR | GLOBAL_FUNCTION_EXPR | "(" + EXPR + ")"; BINARY_EXPR.Rule = EXPR + BINARY_OP + EXPR; BINARY_OP.Rule = Symbol("+") | "-" | "*" | "/" | "=" | "<=" | ">=" | "<" | ">" | "<>" | "and" | "or"; //let's do operator precedence right here RegisterOperators(50, "*", "/"); RegisterOperators(40, "+", "-"); RegisterOperators(30, "=", "<=", ">=", "<", ">", "<>"); RegisterOperators(20, "and", "or"); // Used by print and input to allow a bunch of expressions separated by whitespace, // or be empty, for example: // print // print "Hi" // print "Hi " a$ // All of these match "print" EXPR_LIST EXPR_LIST.Rule = MakeStarRule(EXPR_LIST, null, EXPR); FOR_STMT.Rule = "for" + ASSIGN_STMT + "to" + EXPR + STEP_OPT; STEP_OPT.Rule = Empty | "step" + number; NEXT_STMT.Rule = "next" + variable; WHILE_STMT.Rule = "while" + EXPR; WEND_STMT.Rule = "wend"; //TODO: check number of arguments for particular function in node constructor GLOBAL_FUNCTION_EXPR.Rule = FUNC_NAME + "(" + ARG_LIST + ")"; FUNC_NAME.Rule = Symbol("len") | "left$" | "mid$" | "right$" | "abs" | "asc" | "chr$" | "csrlin$" | "cvi" | "cvs" | "cvd" | "exp" | "fix" | "log" | "pos" | "sgn" | "sin" | "cos" | "tan" | "instr" | "space$" | "spc" | "sqr" | "str$" | "string$" | "val" | "cint"; ARG_LIST.Rule = MakePlusRule(ARG_LIST, comma, EXPR); GLOBAL_VAR_EXPR.Rule = Symbol("rnd") | "timer" | "inkey$" | "csrlin"; // By registering these strings as "punctuation", we exclude them from // appearing in as nodes in the compiled node tree. RegisterPunctuation("(", ")", ","); #endregion }
public static StringLiteral CreateCSharpChar(string name) { StringLiteral term = new StringLiteral(name, TermOptions.None); term.AddStartEnd("'", ScanFlags.IsChar); return term; }
public static StringLiteral CreateVbString(string name) { StringLiteral term = new StringLiteral(name, TermOptions.SpecialIgnoreCase); term.AddStartEnd("\"", ScanFlags.DisableEscapes | ScanFlags.AllowDoubledQuote); term.AddSuffixCodes("$", TypeCode.String); term.AddSuffixCodes("c", TypeCode.Char); return term; }
public static StringLiteral CreatePythonString(string name) { StringLiteral term = new StringLiteral(name, TermOptions.SpecialIgnoreCase); term.AddStartEnd("'", ScanFlags.AllowAllEscapes); term.AddStartEnd("'''", ScanFlags.AllowAllEscapes | ScanFlags.AllowLineBreak); term.AddStartEnd("\"", ScanFlags.AllowAllEscapes); term.AddStartEnd("\"\"\"", ScanFlags.AllowAllEscapes | ScanFlags.AllowLineBreak); term.AddPrefixFlag("u", ScanFlags.AllowAllEscapes); term.AddPrefixFlag("r", ScanFlags.DisableEscapes ); term.AddPrefixFlag("ur", ScanFlags.DisableEscapes); return term; }
public FlGrammar() { // turn off case sensitivity CaseSensitive = false; // define all the non-terminals var program = new NonTerminal("program", typeof(ProgramNode)); var statementList = new NonTerminal("statementList", typeof(StatementNode)); var statement = new NonTerminal("statement", typeof(SkipNode)); var expression = new NonTerminal("expression", typeof(ExpressionNode)); var binaryOperator = new NonTerminal("binaryOperator", typeof(SkipNode)); var variableDeclaration = new NonTerminal("variableDeclaration", typeof(VariableDeclarationNode)); var variableAssignment = new NonTerminal("variableAssignment", typeof(VariableAssignmentNode)); var ifStatement = new NonTerminal("ifStatement", typeof(IfStatementNode)); var elseStatement = new NonTerminal("elseStatement", typeof(ElseStatementNode)); // define all the terminals var variable = new IdentifierTerminal("variable"); variable.AddKeywords("set", "var" , "to", "if", "freight", "cost", "is", "loop", "through", "order"); var number = new NumberLiteral("number"); var stringLiteral = new StringLiteral("string", "\"", ScanFlags.None); RegisterPunctuation(";", "[", "]", "(", ")"); //var lpar = new Terminal("("); //var rpar = new Terminal(")"); //var lbr = new Terminal("{"); //var rbr = new Terminal("}"); // specify the non-terminal which is the root of the AST //Root = program; //binaryOperator.Rule = Symbol("+") | "-" | "*" | "/" | "<" | "==" | "!=" | ">" | "<=" | ">=" | "is"; //program.Rule = statementList; //statementList.Rule = MakeStarRule(statementList, null, statement); //statement.Rule = variableDeclaration + ";" | variableAssignment + ";" | expression + ";" | ifStatement; //variableAssignment.Rule = variable + "=" + expression; //variableDeclaration.Rule = Symbol("var") + variable; //ifStatement.Rule = Symbol("if") + "(" + expression + ")" // + "{" + expression + "}" // + elseStatement; //elseStatement.Rule = Empty | "else" + "{" + expression + "}"; //expression.Rule = number | variable | stringLiteral // | expression + binaryOperator + expression // | "(" + expression + ")"; Root = program; binaryOperator.Rule = Symbol("+") | "-" | "*" | "/" | "<" | "==" | "!=" | ">" | "<=" | ">=" | "is"; program.Rule = statementList; statementList.Rule = MakeStarRule(statementList, null, statement); statement.Rule = variableDeclaration + ";" | variableAssignment + ";" | expression + ";" | ifStatement; variableAssignment.Rule = variable + "=" + expression; variableDeclaration.Rule = Symbol("var") + variable; ifStatement.Rule = "if" + Symbol("(") + expression + Symbol(")") + Symbol("{") + statementList + Symbol("}") + elseStatement; elseStatement.Rule = Empty | "else" + Symbol("{") + statementList + Symbol("}"); expression.Rule = number | variable | stringLiteral | expression + binaryOperator + expression | "(" + expression + ")"; }