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 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.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); }
// It is loosely based on R6RS specs. // See Grammar Errors tab in GrammarExplorer for remaining conflicts. public SchemeGrammar() { #region Terminals ConstantTerminal Constant = new ConstantTerminal("Constant"); Constant.Add("#T", 1); Constant.Add("#t", 1); Constant.Add("#F", null); Constant.Add("#f", null); Constant.Add("'()", null); Constant.Add(@"#\nul", '\u0000'); Constant.Add(@"#\alarm", '\u0007'); Constant.Add(@"#\backspace", '\b'); Constant.Add(@"#\tab", '\t'); Constant.Add(@"#\linefeed", '\n'); Constant.Add(@"#\vtab", '\v'); Constant.Add(@"#\page", '\f'); Constant.Add(@"#\return", '\r'); Constant.Add(@"#\esc", '\u001B'); Constant.Add(@"#\space", ' '); Constant.Add(@"#\delete", '\u007F'); // TODO: build SchemeCharLiteral // the following is nonsense, just to put something there var charLiteral = new StringLiteral("Char", "'", StringOptions.None); var stringLiteral = new StringLiteral("String", "\"", StringOptions.AllowsAllEscapes); //Identifiers. Note: added "-", just to allow IDs starting with "->" var SimpleIdentifier = new IdentifierTerminal("SimpleIdentifier", "_+-*/.@?!<>=", "_+-*/.@?!<>=$%&:^~"); // name extraChars extraFirstChars var Number = TerminalFactory.CreateSchemeNumber("Number"); var Byte = new NumberLiteral("Byte", NumberOptions.IntOnly); //Comments Terminal Comment = new CommentTerminal("Comment", "#|", "|#"); Terminal LineComment = new CommentTerminal("LineComment", ";", "\n"); NonGrammarTerminals.Add(Comment); //add comments explicitly to this list as it is not reachable from Root NonGrammarTerminals.Add(LineComment); #endregion #region NonTerminals var Module = new NonTerminal("Module"); var Library = new NonTerminal("Library"); var LibraryList = new NonTerminal("Library+"); var Script = new NonTerminal("Script"); var Abbreviation = new NonTerminal("Abbreviation"); var Vector = new NonTerminal("Vector"); var ByteList = new NonTerminal("ByteList"); var ByteVector = new NonTerminal("ByteVector"); var Datum = new NonTerminal("Datum"); //Datum in R6RS terms var DatumOpt = new NonTerminal("DatumOpt"); //Datum in R6RS terms var DatumList = new NonTerminal("Datum+"); var DatumListOpt = new NonTerminal("Datum*"); var Statement = new NonTerminal("Statement"); var Atom = new NonTerminal("Atom"); var CompoundDatum = new NonTerminal("CompoundDatum"); var AbbrevPrefix = new NonTerminal("AbbrevPrefix"); var LibraryName = new NonTerminal("LibraryName"); var LibraryBody = new NonTerminal("LibraryBody"); var ImportSection = new NonTerminal("ImportSection"); var ExportSection = new NonTerminal("ExportSection"); var ImportSpec = new NonTerminal("ImportSpec"); var ImportSpecList = new NonTerminal("ImportSpecList"); var ExportSpec = new NonTerminal("ExportSpec"); var ExportSpecList = new NonTerminal("ExportSpecList"); var LP = new NonTerminal("LP"); //"(" or "[" var RP = new NonTerminal("RP"); // ")" or "]" var Identifier = new NonTerminal("Identifier"); var IdentifierList = new NonTerminal("IdentifierList"); var IdentifierListOpt = new NonTerminal("IdentifierListOpt"); var PeculiarIdentifier = new NonTerminal("PeculiarIdentifier"); var LibraryVersion = new NonTerminal("LibraryVersion"); var VersionListOpt = new NonTerminal("VersionListOpt"); var FunctionCall = new NonTerminal("FunctionCall"); var FunctionRef = new NonTerminal("FunctionRef"); var SpecialForm = new NonTerminal("SpecialForm"); var DefineVarForm = new NonTerminal("DefineVarForm"); var DefineFunForm = new NonTerminal("DefineFunForm"); var LambdaForm = new NonTerminal("LambdaForm"); var IfForm = new NonTerminal("IfForm"); var CondForm = new NonTerminal("CondForm"); var CondClause = new NonTerminal("CondClause"); var CondClauseList = new NonTerminal("CondClauseList"); var CondElseOpt = new NonTerminal("CondElseOpt"); var BeginForm = new NonTerminal("BeginForm"); var LetForm = new NonTerminal("LetForm"); //not implemented var LetRecForm = new NonTerminal("LetRecForm"); //not implemented var LetPair = new NonTerminal("LetPair"); var LetPairList = new NonTerminal("LetPairList"); #endregion #region Rules base.Root = Module; LP.Rule = ToTerm("(") | "["; //R6RS allows mix & match () and [] RP.Rule = ToTerm(")") | "]"; // Module.Rule = LibraryListOpt + Script; -- this brings conflicts Module.Rule = LibraryList + Script | Script; LibraryList.Rule = MakePlusRule(LibraryList, Library); Script.Rule = ImportSection + DatumList | DatumList; //Library // the following doesn't work - brings conflicts that incorrectly resolved by default shifting //Library.Rule = LP + "library" + LibraryName + ExportSectionOpt + ImportSectionOpt + DatumListOpt + RP; Library.Rule = LP + "library" + LibraryName + LibraryBody + RP; //Note - we should be using DatumListOpt, but that brings 2 conflicts, so for now it is just DatumList //Note that the following style of BNF expressions is strongly discouraged - all productions should be of the same length, // so that the process of mapping child nodes to parent's properties is straightforward. LibraryBody.Rule = ExportSection + ImportSection + DatumList | ExportSection + DatumList | ImportSection + DatumList | DatumList; LibraryName.Rule = LP + IdentifierList + LibraryVersion.Q() + RP; LibraryVersion.Rule = LP + VersionListOpt + RP; //zero or more subversion numbers VersionListOpt.Rule = MakeStarRule(VersionListOpt, Number); ExportSection.Rule = LP + "export" + ExportSpecList + RP; ImportSection.Rule = LP + "import" + ImportSpecList + RP; ExportSpecList.Rule = MakePlusRule(ExportSpecList, ExportSpec); ImportSpecList.Rule = MakePlusRule(ImportSpecList, ImportSpec); ExportSpec.Rule = Identifier | LP + "rename" + LP + Identifier + Identifier + RP + RP; ImportSpec.Rule = LP + Identifier + RP; // - much more complex in R6RS //Datum Datum.Rule = Atom | CompoundDatum; DatumOpt.Rule = Empty | Datum; DatumList.Rule = MakePlusRule(DatumList, Datum); DatumListOpt.Rule = MakeStarRule(DatumListOpt, Datum); Atom.Rule = Number | Identifier | stringLiteral | Constant | charLiteral | "."; CompoundDatum.Rule = Statement | Abbreviation | Vector | ByteVector; Identifier.Rule = SimpleIdentifier | PeculiarIdentifier; IdentifierList.Rule = MakePlusRule(IdentifierList, Identifier); IdentifierListOpt.Rule = MakeStarRule(IdentifierListOpt, Identifier); //TODO: create PeculiarIdentifier custom terminal instead of var // or just custom SchemeIdentifier terminal PeculiarIdentifier.Rule = ToTerm("+") | "-" | "..."; // |"->" + subsequent; (should be!) Abbreviation.Rule = AbbrevPrefix + Datum; AbbrevPrefix.Rule = ToTerm("'") | "`" | ",@" | "," | "#'" | "#`" | "#,@" | "#,"; Vector.Rule = "#(" + DatumListOpt + ")"; ByteVector.Rule = "#vu8(" + ByteList + ")"; ByteList.Rule = MakeStarRule(ByteList, Byte); Statement.Rule = FunctionCall | SpecialForm; FunctionCall.Rule = LP + FunctionRef + DatumListOpt + RP; FunctionRef.Rule = Identifier | Statement; SpecialForm.Rule = DefineVarForm | DefineFunForm | LambdaForm | IfForm | CondForm | BeginForm | LetForm | LetRecForm; DefineVarForm.Rule = LP + "define" + Identifier + Datum + RP; DefineFunForm.Rule = LP + "define" + LP + Identifier + IdentifierListOpt + RP + DatumList + RP; LambdaForm.Rule = LP + "lambda" + LP + IdentifierListOpt + RP + DatumList + RP; IfForm.Rule = LP + "if" + Datum + Datum + DatumOpt + RP; CondForm.Rule = LP + "cond" + CondClauseList + CondElseOpt + RP; CondClauseList.Rule = MakePlusRule(CondClauseList, CondClause); CondClause.Rule = LP + Datum + DatumList + RP; CondElseOpt.Rule = Empty | LP + "else" + DatumList + RP; LetForm.Rule = LP + "let" + LP + LetPairList + RP + DatumList + RP; LetRecForm.Rule = LP + "letrec" + LP + LetPairList + RP + DatumList + RP; BeginForm.Rule = LP + "begin" + DatumList + RP; LetPairList.Rule = MakePlusRule(LetPairList, LetPair); LetPair.Rule = LP + Identifier + Datum + RP; #endregion //Register brace pairs RegisterBracePair("(", ")"); RegisterBracePair("[", "]"); MarkPunctuation(LP, RP); MarkTransient(Datum, CompoundDatum, Statement, SpecialForm, Atom); //Scheme is tail-recursive language base.LanguageFlags |= LanguageFlags.TailRecursive; }//constructor
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); }
public Gramatica() : base(caseSensitive: true) { #region ER NumberLiteral doble = new NumberLiteral("doble"); IdentifierTerminal id = new IdentifierTerminal("id"); StringLiteral cadena = TerminalFactory.CreateCSharpString("cadena"); StringLiteral carac = TerminalFactory.CreateCSharpChar("cadena"); ConstantTerminal booleano = new ConstantTerminal("booleano"); booleano.Add("true", true); booleano.Add("false", false); CommentTerminal comentario2 = new CommentTerminal("comentario2", "</", "/>"); CommentTerminal comentario1 = new CommentTerminal("comentario1", "-->", "\n", "\r\n"); base.NonGrammarTerminals.Add(comentario2); base.NonGrammarTerminals.Add(comentario1); #endregion #region Terminales var mas = ToTerm("+"); var menos = ToTerm("-"); var mul = ToTerm("*"); var div = ToTerm("/"); var mod = ToTerm("%"); var pot = ToTerm("^"); var parA = ToTerm("("); var parC = ToTerm(")"); var corA = ToTerm("["); var corC = ToTerm("]"); var llavA = ToTerm("{"); var llavC = ToTerm("}"); var pYc = ToTerm(";"); var dosPuntos = ToTerm(":"); var coma = ToTerm(","); var asig = ToTerm("="); var igual = ToTerm("="); var mayor = ToTerm(">"); var menor = ToTerm("<"); var mayorIgual = ToTerm(">="); var menorIgual = ToTerm("<="); var igualIgual = ToTerm("=="); var noIgual = ToTerm("!="); var diferecia = ToTerm("~"); var Mostrar = ToTerm("Mostrar"); var resInt = ToTerm("Entero"); var resDouble = ToTerm("Decimal"); var resString = ToTerm("Texto"); var resChar = ToTerm("Caracter"); var resBool = ToTerm("Booleano"); var resVoid = ToTerm("Vacio"); var OR = ToTerm("||"); var AND = ToTerm("&&"); var NOT = ToTerm("!"); var resReturn = ToTerm("Retorno"); var Es_verdadero = ToTerm("Es_verdadero"); var Es_false = ToTerm("Es_falso"); var Cambiar_A = ToTerm("Cambiar_A"); var Valor = ToTerm("Valor"); var No_cumple = ToTerm("No_cumple"); var Para = ToTerm("Para"); var Hasta_que = ToTerm("Hasta_que"); var Mientras = ToTerm("Mientras_que"); var Romper = ToTerm("Romper"); var Continuar = ToTerm("Continuar"); var DibujarAST = ToTerm("DibujarAST"); var DibujarEXP = ToTerm("DibujarEXP"); var DibujarTS = ToTerm("DibujarTS"); var Principal = ToTerm("Principal"); var Importar = ToTerm("Importar"); var Definir = ToTerm("Definir"); #endregion #region No Terminales NonTerminal S = new NonTerminal("S"), E = new NonTerminal("E"), EXPR = new NonTerminal("EXPR"), EXPL = new NonTerminal("EXPL"), PROGRAMA = new NonTerminal("PROGRAMA"), CUERPOS = new NonTerminal("CUERPOS"), CUERPO = new NonTerminal("CUERPO"), ATRIBUTOS = new NonTerminal("ATRIBUTOS"), ATRIBUTO = new NonTerminal("ATRIBUTO"), DECLARACION = new NonTerminal("DECLARACION"), ASIGNACION = new NonTerminal("ASIGNACION"), PRINCIPAL = new NonTerminal("PRINCIPAL"), METODO = new NonTerminal("METODO"), FUNCION = new NonTerminal("FUNCION"), TIPO = new NonTerminal("TIPO"), MOSTRAR = new NonTerminal("MOSTRAR"), MOST = new NonTerminal("MOST"), DIBUJAR = new NonTerminal("DIBUJAR"), LISTA_ID = new NonTerminal("LISTA_ID"), LISTA_PARAM = new NonTerminal("LISTA_PARAM"), DECLA = new NonTerminal("DECLA"), UNICO = new NonTerminal("UNICO"), UNICOS = new NonTerminal("UNICOS"), LLAMADA = new NonTerminal("LLAMADA"), LLAMFUNC = new NonTerminal("LLAMFUNC"), OPERANDO = new NonTerminal("OPERANDO"), RETORNO = new NonTerminal("RETORNO"), SI = new NonTerminal("SI"), SINO = new NonTerminal("SINO"), SINO_SI = new NonTerminal("SINO_SI"), SINOSI = new NonTerminal("SINOSI"), INTERRUMPIR = new NonTerminal("INTERRUMPIR"), CASO = new NonTerminal("CASO"), CASOS = new NonTerminal("CASOS"), DEFECTO = new NonTerminal("DEFECTO"), MIENTRAS = new NonTerminal("MIENTRAS"), PARA = new NonTerminal("PARA"), OP = new NonTerminal("OP"), HACER = new NonTerminal("HACER"), SALIR = new NonTerminal("SALIR"), DEFINIR = new NonTerminal("DEFINIR"), IMPORTAR = new NonTerminal("IMPORTAR"), IMPORTE = new NonTerminal("IMPORTE"); #endregion #region Gramatica S.Rule = PROGRAMA; PROGRAMA.Rule = CUERPO; CUERPO.Rule = MakePlusRule(CUERPO, CUERPOS); CUERPOS.Rule = METODO | FUNCION | PRINCIPAL | DEFINIR | IMPORTAR | DECLARACION | ASIGNACION; CUERPOS.ErrorRule = SyntaxError + llavC; CUERPOS.ErrorRule = SyntaxError + pYc; IMPORTAR.Rule = Importar + IMPORTE + pYc; IMPORTE.Rule = MakePlusRule(IMPORTE, ToTerm("."), id); DEFINIR.Rule = Definir + cadena + pYc | Definir + doble + pYc; ATRIBUTOS.Rule = MakePlusRule(ATRIBUTOS, ATRIBUTO) | Empty; ATRIBUTO.Rule = DECLARACION | ASIGNACION | DIBUJAR | MOSTRAR | LLAMFUNC | SALIR | SI | INTERRUMPIR | MIENTRAS | PARA | HACER | RETORNO; ATRIBUTO.ErrorRule = SyntaxError + pYc; ATRIBUTO.ErrorRule = SyntaxError + llavC; METODO.Rule = resVoid + id + parA + LISTA_PARAM + parC + llavA + ATRIBUTOS + llavC; FUNCION.Rule = TIPO + id + parA + LISTA_PARAM + parC + llavA + ATRIBUTOS + llavC; PRINCIPAL.Rule = resVoid + Principal + parA + parC + llavA + ATRIBUTOS + llavC; RETORNO.Rule = resReturn + EXPL + pYc; SALIR.Rule = Romper + pYc; DECLARACION.Rule = TIPO + LISTA_ID + pYc; DECLA.Rule = TIPO + id; ASIGNACION.Rule = TIPO + LISTA_ID + asig + EXPL + pYc | id + asig + EXPL + pYc; DIBUJAR.Rule = DibujarAST + parA + E + parC + pYc | DibujarEXP + parA + EXPL + parC + pYc | DibujarTS + parA + parC + pYc; MOSTRAR.Rule = Mostrar + parA + MOST + parC + pYc; MOST.Rule = MakePlusRule(MOST, coma, E); LISTA_ID.Rule = MakePlusRule(LISTA_ID, coma, id); LISTA_PARAM.Rule = MakePlusRule(LISTA_PARAM, coma, DECLA) | MakePlusRule(LISTA_PARAM, coma, E) | Empty; UNICO.Rule = MakePlusRule(UNICO, OPERANDO, UNICOS); UNICOS.Rule = E; LLAMADA.Rule = id + parA + LISTA_PARAM + parC; LLAMFUNC.Rule = LLAMADA + pYc; SI.Rule = Es_verdadero + parA + EXPL + parC + llavA + ATRIBUTOS + llavC + SINO; SINO.Rule = Es_false + llavA + ATRIBUTOS + llavC | Empty; INTERRUMPIR.Rule = Cambiar_A + parA + E + parC + llavA + CASOS + DEFECTO + llavC; CASOS.Rule = MakePlusRule(CASOS, CASO) | Empty; CASO.Rule = Valor + E + dosPuntos + ATRIBUTOS; DEFECTO.Rule = No_cumple + dosPuntos + ATRIBUTOS | Empty; MIENTRAS.Rule = Mientras + parA + EXPL + parC + llavA + ATRIBUTOS + llavC; PARA.Rule = Para + parA + ASIGNACION + EXPL + pYc + OP + parC + llavA + ATRIBUTOS + llavC; OP.Rule = ToTerm("++") | ToTerm("--"); HACER.Rule = Hasta_que + parA + EXPL + parC + llavA + ATRIBUTOS + llavC; OPERANDO.Rule = mas | menos | mul | div | pot | mod; TIPO.Rule = resInt | resDouble | resString | resChar | resBool; E.Rule = E + mas + E | E + menos + E | E + mul + E | E + div + E | E + mod + E | E + pot + E | parA + E + parC | menos + E | LLAMADA | id | doble | cadena | booleano | carac; EXPR.Rule = E + mayor + E | E + menor + E | E + mayorIgual + E | E + menorIgual + E | E + igualIgual + E | E + noIgual + E | E + diferecia + E | E; EXPL.Rule = EXPL + OR + EXPL | EXPL + AND + EXPL | NOT + EXPL | EXPR | parA + EXPL + parC; #endregion #region Preferencias this.Root = S; this.MarkTransient(TIPO, UNICOS, CUERPOS); this.RegisterOperators(1, Associativity.Left, mas, menos); this.RegisterOperators(2, Associativity.Left, mul, div, mod); this.RegisterOperators(3, Associativity.Right, pot); this.RegisterOperators(4, "==", "!=", "<", ">", "<=", ">="); this.RegisterOperators(5, Associativity.Left, OR); this.RegisterOperators(6, Associativity.Left, AND); this.RegisterOperators(7, Associativity.Left, NOT); this.RegisterOperators(8, "(", ")"); this.MarkPunctuation("(", ")", ",", ";", "[", "]", "=", ":", "{", "}"); #endregion }
// It is loosely based on R6RS specs. // See Grammar Errors tab in GrammarExplorer for remaining conflicts. public SchemeGrammar() { #region Terminals ConstantTerminal Constant = new ConstantTerminal("Constant"); Constant.Add("#T", 1); Constant.Add("#t", 1); Constant.Add("#F", null); Constant.Add("#f", null); Constant.Add("'()", null); Constant.Add(@"#\nul", '\u0000'); Constant.Add(@"#\alarm", '\u0007'); Constant.Add(@"#\backspace", '\b'); Constant.Add(@"#\tab", '\t'); Constant.Add(@"#\linefeed", '\n'); Constant.Add(@"#\vtab", '\v'); Constant.Add(@"#\page", '\f'); Constant.Add(@"#\return", '\r'); Constant.Add(@"#\esc", '\u001B'); Constant.Add(@"#\space", ' '); Constant.Add(@"#\delete", '\u007F'); // TODO: build SchemeCharLiteral // the following is nonsense, just to put something there var charLiteral = new StringLiteral("Char", "'", StringOptions.None); var stringLiteral = new StringLiteral("String", "\"", StringOptions.AllowsAllEscapes); //Identifiers. Note: added "-", just to allow IDs starting with "->" var SimpleIdentifier = new IdentifierTerminal("SimpleIdentifier", "_+-*/.@?!<>=", "_+-*/.@?!<>=$%&:^~"); // name extraChars extraFirstChars var Number = TerminalFactory.CreateSchemeNumber("Number"); var Byte = new NumberLiteral("Byte", NumberOptions.IntOnly); //Comments Terminal Comment = new CommentTerminal("Comment", "#|", "|#"); Terminal LineComment = new CommentTerminal("LineComment", ";", "\n"); NonGrammarTerminals.Add(Comment); //add comments explicitly to this list as it is not reachable from Root NonGrammarTerminals.Add(LineComment); #endregion #region NonTerminals var Module = new NonTerminal("Module"); var Library = new NonTerminal("Library"); var LibraryList = new NonTerminal("Library+"); var Script = new NonTerminal("Script"); var Abbreviation = new NonTerminal("Abbreviation"); var Vector = new NonTerminal("Vector"); var ByteList = new NonTerminal("ByteList"); var ByteVector = new NonTerminal("ByteVector"); var Datum = new NonTerminal("Datum"); //Datum in R6RS terms var DatumOpt = new NonTerminal("DatumOpt"); //Datum in R6RS terms var DatumList = new NonTerminal("Datum+"); var DatumListOpt = new NonTerminal("Datum*"); var Statement = new NonTerminal("Statement"); var Atom = new NonTerminal("Atom"); var CompoundDatum = new NonTerminal("CompoundDatum"); var AbbrevPrefix = new NonTerminal("AbbrevPrefix"); var LibraryName = new NonTerminal("LibraryName"); var LibraryBody = new NonTerminal("LibraryBody"); var ImportSection = new NonTerminal("ImportSection"); var ExportSection = new NonTerminal("ExportSection"); var ImportSpec = new NonTerminal("ImportSpec"); var ImportSpecList = new NonTerminal("ImportSpecList"); var ExportSpec = new NonTerminal("ExportSpec"); var ExportSpecList = new NonTerminal("ExportSpecList"); var LP = new NonTerminal("LP"); //"(" or "[" var RP = new NonTerminal("RP"); // ")" or "]" var Identifier = new NonTerminal("Identifier"); var IdentifierList = new NonTerminal("IdentifierList"); var IdentifierListOpt = new NonTerminal("IdentifierListOpt"); var PeculiarIdentifier = new NonTerminal("PeculiarIdentifier"); var LibraryVersion = new NonTerminal("LibraryVersion"); var VersionListOpt = new NonTerminal("VersionListOpt"); var FunctionCall = new NonTerminal("FunctionCall"); var FunctionRef = new NonTerminal("FunctionRef"); var SpecialForm = new NonTerminal("SpecialForm"); var DefineVarForm = new NonTerminal("DefineVarForm"); var DefineFunForm = new NonTerminal("DefineFunForm"); var LambdaForm = new NonTerminal("LambdaForm"); var IfForm = new NonTerminal("IfForm"); var CondForm = new NonTerminal("CondForm"); var CondClause = new NonTerminal("CondClause"); var CondClauseList = new NonTerminal("CondClauseList"); var CondElseOpt = new NonTerminal("CondElseOpt"); var BeginForm = new NonTerminal("BeginForm"); var LetForm = new NonTerminal("LetForm"); //not implemented var LetRecForm = new NonTerminal("LetRecForm"); //not implemented var LetPair = new NonTerminal("LetPair"); var LetPairList = new NonTerminal("LetPairList"); #endregion #region Rules base.Root = Module; LP.Rule = ToTerm("(") | "["; //R6RS allows mix & match () and [] RP.Rule = ToTerm(")") | "]"; // Module.Rule = LibraryListOpt + Script; -- this brings conflicts Module.Rule = LibraryList + Script | Script; LibraryList.Rule = MakePlusRule(LibraryList, Library); Script.Rule = ImportSection + DatumList | DatumList; //Library // the following doesn't work - brings conflicts that incorrectly resolved by default shifting //Library.Rule = LP + "library" + LibraryName + ExportSectionOpt + ImportSectionOpt + DatumListOpt + RP; Library.Rule = LP + "library" + LibraryName + LibraryBody + RP; //Note - we should be using DatumListOpt, but that brings 2 conflicts, so for now it is just DatumList //Note that the following style of BNF expressions is strongly discouraged - all productions should be of the same length, // so that the process of mapping child nodes to parent's properties is straightforward. LibraryBody.Rule = ExportSection + ImportSection + DatumList | ExportSection + DatumList | ImportSection + DatumList | DatumList; LibraryName.Rule = LP + IdentifierList + LibraryVersion.Q() + RP; LibraryVersion.Rule = LP + VersionListOpt + RP; //zero or more subversion numbers VersionListOpt.Rule = MakeStarRule(VersionListOpt, Number); ExportSection.Rule = LP + "export" + ExportSpecList + RP; ImportSection.Rule = LP + "import" + ImportSpecList + RP; ExportSpecList.Rule = MakePlusRule(ExportSpecList, ExportSpec); ImportSpecList.Rule = MakePlusRule(ImportSpecList, ImportSpec); ExportSpec.Rule = Identifier | LP + "rename" + LP + Identifier + Identifier + RP + RP; ImportSpec.Rule = LP + Identifier + RP; // - much more complex in R6RS //Datum Datum.Rule = Atom | CompoundDatum; DatumOpt.Rule = Empty | Datum; DatumList.Rule = MakePlusRule(DatumList, Datum); DatumListOpt.Rule = MakeStarRule(DatumListOpt, Datum); Atom.Rule = Number | Identifier | stringLiteral | Constant | charLiteral | "."; CompoundDatum.Rule = Statement | Abbreviation | Vector | ByteVector; Identifier.Rule = SimpleIdentifier | PeculiarIdentifier; IdentifierList.Rule = MakePlusRule(IdentifierList, Identifier); IdentifierListOpt.Rule = MakeStarRule(IdentifierListOpt, Identifier); //TODO: create PeculiarIdentifier custom terminal instead of var // or just custom SchemeIdentifier terminal PeculiarIdentifier.Rule = ToTerm("+") | "-" | "..."; // |"->" + subsequent; (should be!) Abbreviation.Rule = AbbrevPrefix + Datum; AbbrevPrefix.Rule = ToTerm("'") | "`" | ",@" | "," | "#'" | "#`" | "#,@" | "#,"; Vector.Rule = "#(" + DatumListOpt + ")"; ByteVector.Rule = "#vu8(" + ByteList + ")"; ByteList.Rule = MakeStarRule(ByteList, Byte); Statement.Rule = FunctionCall | SpecialForm; FunctionCall.Rule = LP + FunctionRef + DatumListOpt + RP; FunctionRef.Rule = Identifier | Statement; SpecialForm.Rule = DefineVarForm | DefineFunForm | LambdaForm | IfForm | CondForm | BeginForm | LetForm | LetRecForm; DefineVarForm.Rule = LP + "define" + Identifier + Datum + RP; DefineFunForm.Rule = LP + "define" + LP + Identifier + IdentifierListOpt + RP + DatumList + RP; LambdaForm.Rule = LP + "lambda" + LP + IdentifierListOpt + RP + DatumList + RP; IfForm.Rule = LP + "if" + Datum + Datum + DatumOpt + RP; CondForm.Rule = LP + "cond" + CondClauseList + CondElseOpt + RP; CondClauseList.Rule = MakePlusRule(CondClauseList, CondClause); CondClause.Rule = LP + Datum + DatumList + RP; CondElseOpt.Rule = Empty | LP + "else" + DatumList + RP; LetForm.Rule = LP + "let" + LP + LetPairList + RP + DatumList + RP; LetRecForm.Rule = LP + "letrec" + LP + LetPairList + RP + DatumList + RP; BeginForm.Rule = LP + "begin" + DatumList + RP; LetPairList.Rule = MakePlusRule(LetPairList, LetPair); LetPair.Rule = LP + Identifier + Datum + RP; #endregion //Register brace pairs RegisterBracePair("(", ")"); RegisterBracePair("[", "]"); MarkPunctuation(LP, RP); MarkTransient(Datum, CompoundDatum, Statement, SpecialForm, Atom); //Scheme is tail-recursive language base.LanguageFlags |= LanguageFlags.TailRecursive; } //constructor
public SeeNoSQLGrammar() : base(false) { //Terminals var lineComment = new CommentTerminal("LINE_COMMENT", "//", "\n", "\r\n"); var blockComment = new CommentTerminal("BLOCK_COMMENT", "/*", "*/"); NonGrammarTerminals.Add(lineComment); NonGrammarTerminals.Add(blockComment); var number = new NumberLiteral("number"); var intVal = new NumberLiteral("integer", NumberOptions.IntOnly); var stringLiteral = new StringLiteral("string", "'", StringOptions.AllowsDoubledQuote); var id = new IdentifierTerminal("id") {Priority = Terminal.HighestPriority}; var param = new IdentifierTerminal("param"); param.AddPrefix("@",IdOptions.None); param.Priority = Terminal.LowestPriority; var constantTerminal = new ConstantTerminal("constantTerminal"); constantTerminal.Add("true", true); constantTerminal.Add("false", false); constantTerminal.Add("null", null); constantTerminal.Add("MAX_STRING", new object()); constantTerminal.Add("MIN_STRING", null); constantTerminal.Priority = Terminal.HighestPriority; var ALL = ToTerm("ALL"); var ALLOW_STALE = ToTerm("ALLOW_STALE"); var AND = ToTerm("AND"); var BETWEEN = ToTerm("BETWEEN"); var COMMA = ToTerm(","); var DESCENDING = ToTerm("DESCENDING"); var DOCUMENT = ToTerm("DOCUMENT"); var FALSE = ToTerm("false"); var FROM = ToTerm("FROM"); var GROUP = ToTerm("GROUP"); var GROUP_LEVEL = ToTerm("GROUP_LEVEL"); var IN = ToTerm("IN"); var INCLUDE_DOCS = ToTerm("INCLUDE_DOCS"); var INCLUSIVE_END = ToTerm("INCLUSIVE_END"); var KEY = ToTerm("KEY"); var LIMIT = ToTerm("LIMIT"); var OR = ToTerm("OR"); var QUERYOPTIONS = ToTerm("QUERYOPTIONS"); var REDUCE = ToTerm("REDUCE"); var SKIP = ToTerm("SKIP"); var TRUE = ToTerm("true"); var UNION = ToTerm("UNION"); var USING = ToTerm("USING"); var VIEW = ToTerm("VIEW"); var WHERE = ToTerm("WHERE"); var WITH = ToTerm("WITH"); //Non-terminals var betweenStatement = new NonTerminal("between"); var binExpr = new NonTerminal("binExpr"); var binOp = new NonTerminal("binOp"); var constOperand = new NonTerminal("constOperand"); var documentStatement = new NonTerminal("documentStatement"); var expression = new NonTerminal("expression"); var fromStatement = new NonTerminal("from"); var keyArrayStatement = new NonTerminal("keyArray"); var keyList = new NonTerminal("keys"); var keyObjectStatement = new NonTerminal("keyObject"); var keyValueStatement = new NonTerminal("keyValue"); var keyStatement = new NonTerminal("key"); var query = new NonTerminal("query"); var queryOption = new NonTerminal("queryOption"); var queryOptionList = new NonTerminal("queryOptionList"); var queryOptions = new NonTerminal("queryOptions"); var stmt = new NonTerminal("stmt"); var unionStatement = new NonTerminal("unionStatement"); var term = new NonTerminal("term"); var view = new NonTerminal("view"); var whereStatement = new NonTerminal("where"); //Rules this.Root = query; query.Rule = MakePlusRule(query, unionStatement, stmt); stmt.Rule = fromStatement + queryOptions + keyStatement + whereStatement | fromStatement + queryOptions; unionStatement.Rule = UNION + ALL; term.Rule = id | stringLiteral | number | param | constOperand; binOp.Rule = ToTerm("=") | ">" | "<" | ">=" | "<=" | AND | OR | IN | BETWEEN; binExpr.Rule = expression + binOp + expression; expression.Rule = term | binExpr | betweenStatement | "(" + expression + ")"; constOperand.Rule = constantTerminal; view.Rule = VIEW + "(" + id + COMMA + id + ")"; queryOptions.Rule = Empty | USING + QUERYOPTIONS + "(" + queryOptionList + ")"; queryOption.Rule = ALLOW_STALE + binOp + constOperand | DESCENDING + binOp + constOperand | GROUP + binOp + constOperand | GROUP_LEVEL + binOp + intVal | INCLUDE_DOCS + binOp + constOperand | INCLUSIVE_END + binOp + constOperand | LIMIT + binOp + intVal | REDUCE + binOp + constOperand | SKIP + binOp + intVal; queryOptionList.Rule = MakePlusRule(queryOptionList, COMMA, queryOption); fromStatement.Rule = FROM + view | FROM + documentStatement; documentStatement.Rule = DOCUMENT + "(" + term + ")"; keyStatement.Rule = keyArrayStatement | keyObjectStatement | keyValueStatement; keyArrayStatement.Rule = WITH + KEY + "[" + keyList + "]"; keyObjectStatement.Rule = WITH + KEY + "{" + keyList + "}"; keyValueStatement.Rule = WITH + KEY + id; keyList.Rule = MakePlusRule(keyList, COMMA, id); whereStatement.Rule = Empty | WHERE + expression; betweenStatement.Rule = "(" + term + COMMA + term + ")"; //Operators RegisterOperators(10, "=", "<", ">", "<=", ">=", "BETWEEN"); RegisterOperators(9, "AND"); RegisterOperators(8, "OR"); RegisterOperators(7, "IN"); MarkPunctuation("[", "]", "(", ")", "{", "}", ","); MarkTransient(term,expression, binOp, constOperand, keyStatement); }
public Sintactico() : base(caseSensitive: false) { #region Regex #endregion #region Terminales /*-------- COMENTARIOS EN LÍNEA --------*/ var LineComment = new CommentTerminal("LineComment", ">>", "\n", "\r\n"); /*-------- COMENTARIOS EN BLOQUE --------*/ var BlockComment = new CommentTerminal("BlockComment", "<-", "->"); /*-------- NUMERO --------*/ var Real = new NumberLiteral("tkREAL", NumberOptions.AllowSign); /*-------- CADENA --------*/ var Cadena = new StringLiteral("tkSTR", "\""); /*-------- CARACTER --------*/ var Caracter = new StringLiteral("tkCHAR", "'", StringOptions.IsChar); /*-------- PUNTUACION --------*/ var SEMICOLON = ToTerm(";", "SEMICOLON"); var COMMA = ToTerm(",", "COMMA"); var DOT = ToTerm(".", "DOT"); var COLON = ToTerm(":", "COLON"); /*-------- AGRUPACION --------*/ var PARIZQ = ToTerm("(", "PARIZQ"); var PARDER = ToTerm(")", "PARDER"); var LLVIZQ = ToTerm("{", "LLVIZQ"); var LLVDER = ToTerm("}", "LLVDER"); var CORIZQ = ToTerm("[", "CORIZQ"); var CORDER = ToTerm("]", "CORDER"); /*-------- BINARIOS --------*/ var MAS = ToTerm("+", "MAS"); var MENOS = ToTerm("-", "MENOS"); var POR = ToTerm("*", "POR"); var DIVISION = ToTerm("/", "DIVISION"); var POTENCIA = ToTerm("^", "POTENCIA"); var AND = ToTerm("&&", "AND"); var OR = ToTerm("||", "OR"); var IGUAL = ToTerm("==", "IGUAL"); var DIFERENTE = ToTerm("!=", "DIFERENTE"); var MAYOR_IGUAL = ToTerm(">=", "MAYOR_IGUAL"); var MENOR_IGUAL = ToTerm("<=", "MENOR_IGUAL"); var MAYOR = ToTerm(">", "MAYOR"); var MENOR = ToTerm("<", "MENOR"); var ASIGNACION = ToTerm("=", "ASIGNACION"); /*-------- UNARIOS --------*/ var INCREMENTO = ToTerm("++", "INCREMENTO"); var DECREMENTO = ToTerm("--", "DECREMENTO"); var NOT = ToTerm("!", "NOT"); /*-------- RESERVADAS --------*/ /*-------- DEFINICION DE TIPOS --------*/ var INT = ToTerm("int", "tkINT"); var CHAR = ToTerm("char", "tkCHAR"); var STRING = ToTerm("string", "tkSTR"); var DOUBLE = ToTerm("double", "tkDOUBLE"); var BOOL = ToTerm("bool", "tkBOOL"); var VOID = ToTerm("void", "tkVOID"); var ARRAY = ToTerm("array", "tkARR"); ConstantTerminal CSTBOOL = new ConstantTerminal("CSTBOOL"); CSTBOOL.Add("true", true); CSTBOOL.Add("verdadero", true); CSTBOOL.Add("falso", false); CSTBOOL.Add("false", false); /*-------- CLASES --------*/ var PUBLICO = ToTerm("publico", "tkVISIBLE"); var PRIVADO = ToTerm("privado", "tkVISIBLE"); var OVERRIDE = ToTerm("override", "tkOVERR"); var IMPORTAR = ToTerm("importar", "IMPORTAR"); var NEW = ToTerm("new", "NEW"); var MAIN = ToTerm("main", "MAIN"); var RETURN = ToTerm("return", "RETURN"); var CLASE = ToTerm("clase", "CLASE"); /*-------- NATIVA --------*/ var PRINT = ToTerm("print", "PRINT"); var SHOW = ToTerm("show", "SHOW"); var ADDFIGURE = ToTerm("addfigure", "ADDFIG"); var CIRCLE = ToTerm("circle", "CIRCLE"); var TRI = ToTerm("triangle", "TRIAN"); var SQA = ToTerm("square", "SQA"); var LINE = ToTerm("line", "LINE"); var FIGURE = ToTerm("figure", "FIGURE"); /*-------- CONDICIONALES Y LOOPS --------*/ var IF = ToTerm("if", "IF"); var ELSE = ToTerm("else", "ELSE"); var FOR = ToTerm("for", "FOR"); var REPEAT = ToTerm("repeat", "REPEAT"); var WHILE = ToTerm("while", "WHILE"); var COMPROBAR = ToTerm("comprobar", "COMPROBAR"); var CASO = ToTerm("caso", "CASO"); var DEFECTO = ToTerm("defecto", "DEFECTO"); var SALIR = ToTerm("salir", "SALIR"); var HACER = ToTerm("hacer", "HACER"); var MIENTRAS = ToTerm("mientras", "MIENTRAS"); var CONTINUAR = ToTerm("continuar", "CONTINUAR"); /*-------- IDENTIFICADORES --------*/ var Identificador = new IdentifierTerminal("tkID"); var Variable = new IdentifierTerminal("tkVAR"); #endregion #region No terminales /*PRODUCCIONES INICIALES*/ NonTerminal INICIO = new NonTerminal("INICIO"), CLASE_STA = new NonTerminal("CLASE_STA"), CLASE_STA_LIST = new NonTerminal("CLASE_LST"), CLASE_STA_BODY = new NonTerminal("CLASE_BODY"), IMPORTAR_STA = new NonTerminal("IMPORTAR_STA"), IMPORTAR_STA_LIST = new NonTerminal("IMP_LST"), FUNCION = new NonTerminal("FUNCION"), METODO = new NonTerminal("METODO"), INSTRUCCION = new NonTerminal("INSTRUCCION"), INSTRUCCION_LIST = new NonTerminal("INST_LST"), VISIBILIDAD = new NonTerminal("VISIBILIDAD"), MAIN_STA = new NonTerminal("MAIN_STA"), OVER_STA = new NonTerminal("OVER_STA"), /*Contiene los tipos de datos utilizados*/ DATATYPE = new NonTerminal("DATATYPE"), /*Contiene una lista de variables*/ VARLIST = new NonTerminal("VARLIST"), /*Declara las variables normales*/ DECLARACION = new NonTerminal("DECLARACION"), /*Asigna variables normales*/ ASSIGNMENT = new NonTerminal("ASSIGNMENT"), /*Establece la dimensión de los arreglos*/ DIMENSION = new NonTerminal("DIMENSION"), DIMENSION_LIST = new NonTerminal("DIMENSION_LIST"), /*Establece el contenido de los arreglos al declararse*/ ARRCONTENT = new NonTerminal("ARRCONTENT"), ARRCONTENT_LIST = new NonTerminal("ARRCONTENT_LIST"), /*Específica la forma de las operaciones*/ OPER = new NonTerminal("OPER"), /*Lista de operaciones :v*/ OPERLIST = new NonTerminal("OPERLIST"), /*Producciones para if*/ IF_STA = new NonTerminal("IF_STA"), ELSE_STA = new NonTerminal("ELSE_STA"), /*Producciones para un FOR*/ FOR_STA = new NonTerminal("FOR_STA"), FOR_CND = new NonTerminal("FOR_CND"), /*Producciones para un REPEAT*/ REPEAT_STA = new NonTerminal("REPEAT_STA"), WHILE_STA = new NonTerminal("WHILE_STA"), /*Producciones para un SWITCH*/ SWITCH = new NonTerminal("SWITCH"), CASE_LST = new NonTerminal("CASE_LST"), CASE = new NonTerminal("CASE"), /*Producciones para un DO-WHILE*/ DO = new NonTerminal("DO"), /*Lista de parametros al declarar funcion/metodo*/ PAR_LST = new NonTerminal("PAR_LST"), PAR = new NonTerminal("PAR"), CALL = new NonTerminal("CALL"), /*Produccion para un RETURN STATEMENT*/ RTN_STA = new NonTerminal("RTN_STA"), /*Produccion para las figuras*/ FIGURES = new NonTerminal("FIGURES"); #endregion #region Producciones INICIO.Rule = MakePlusRule(INICIO, CLASE_STA); #region CLASE //ESTRUCTURA BASICA DE UN CLASE CLASE_STA.Rule = CLASE + Identificador + IMPORTAR_STA + LLVIZQ + CLASE_STA_LIST + LLVDER; //IMPORTACIONES IMPORTAR_STA_LIST.Rule = MakeListRule(IMPORTAR_STA_LIST, COMMA, Identificador); IMPORTAR_STA.Rule = IMPORTAR + IMPORTAR_STA_LIST | Empty; //CUERPO DE UNA CLASE, VARIABLES GLOBALES, FUNCIONES Y METODOS CLASE_STA_LIST.Rule = MakeStarRule(CLASE_STA_LIST, CLASE_STA_BODY); CLASE_STA_BODY.Rule = MAIN_STA | FUNCION | METODO | DECLARACION + SEMICOLON; //VISIBILIDAD DE UNA FUNCION, METODO O VARIABLE GLOBAL VISIBILIDAD.Rule = PUBLICO | PRIVADO | Empty; //SOBRECARGA DE MÉTODOS OVER_STA.Rule = OVERRIDE | Empty; //LISTA DE INSTRUCCIONES VÁLIDAS DENTRO DE FUNCIONES Y MÉTODOS INSTRUCCION_LIST.Rule = MakeStarRule(INSTRUCCION_LIST, INSTRUCCION); NonTerminal NATIVA = new NonTerminal("NATIVA") { Rule = PRINT + PARIZQ + OPER + PARDER + SEMICOLON | SHOW + PARIZQ + OPERLIST + PARDER + SEMICOLON }; INSTRUCCION.Rule = DECLARACION + SEMICOLON | ASSIGNMENT + SEMICOLON | IF_STA | FOR_STA | REPEAT_STA | WHILE_STA | SWITCH | DO | CONTINUAR + SEMICOLON | SALIR + SEMICOLON | RTN_STA + SEMICOLON | NATIVA | FIGURES; #endregion #region PARAMETROS PAR_LST.Rule = MakeListRule(PAR_LST, COMMA, PAR, TermListOptions.AllowEmpty); PAR.Rule = DATATYPE + Variable | DATATYPE + ARRAY + Variable + DIMENSION_LIST; // CALL.Rule = Variable + PARIZQ + OPERLIST + PARDER | Variable + PARIZQ + PARDER; #endregion #region FUNCION FUNCION.Rule = VISIBILIDAD + Identificador + DATATYPE + OVER_STA + PARIZQ + PAR_LST + PARDER + LLVIZQ + INSTRUCCION_LIST + LLVDER | VISIBILIDAD + Identificador + ARRAY + DATATYPE + DIMENSION_LIST + OVER_STA + PARIZQ + PAR_LST + PARDER + LLVIZQ + INSTRUCCION_LIST + LLVDER; #endregion #region METODO METODO.Rule = VISIBILIDAD + Identificador + VOID + OVER_STA + PARIZQ + PAR_LST + PARDER + LLVIZQ + INSTRUCCION_LIST + LLVDER; #endregion #region RETURN STATEMENT RTN_STA.Rule = RETURN + ASSIGNMENT; #endregion #region MAIN MAIN_STA.Rule = MAIN + PARIZQ + PARDER + LLVIZQ + INSTRUCCION_LIST + LLVDER; #endregion #region DECLARACION, ASIGNACION Y GET DE VARIABLES Y ARREGLOS DATATYPE.Rule = INT | CHAR | STRING | DOUBLE | BOOL | Identificador; //var, var , var VARLIST.Rule = MakeListRule(VARLIST, COMMA, Variable, TermListOptions.PlusList); //[oper][oper][oper] DIMENSION_LIST.Rule = MakePlusRule(DIMENSION_LIST, DIMENSION); DIMENSION.Rule = CORIZQ + OPER + CORDER; //{3,3} {{3,3},{3,3}} {{{3,3},{3,3}},{{3,3},{3,3}}} ARRCONTENT_LIST.Rule = MakeListRule(ARRCONTENT_LIST, COMMA, ARRCONTENT, TermListOptions.PlusList); ARRCONTENT.Rule = LLVIZQ + ARRCONTENT_LIST + LLVDER | LLVIZQ + OPERLIST + LLVDER; //int var, var, var; //int var, var = oper; //int array var, var, var[oper][oper]; //int array var, var, var[oper][oper] = {{3,3},{3,3}}; DECLARACION.Rule = VISIBILIDAD + DATATYPE + VARLIST | VISIBILIDAD + DATATYPE + VARLIST + ASIGNACION + OPER | VISIBILIDAD + DATATYPE + ARRAY + VARLIST + DIMENSION_LIST | VISIBILIDAD + DATATYPE + ARRAY + VARLIST + DIMENSION_LIST + ASIGNACION + ARRCONTENT; //var = oper; //var[oper] = oper; ASSIGNMENT.Rule = Variable + ASIGNACION + OPER | Variable + DIMENSION_LIST + ASIGNACION + OPER | OPER; #endregion #region OPERACIONES OPER.Rule = /*TRES NODOS*/ OPER + MAS + OPER | OPER + MENOS + OPER | OPER + POR + OPER | OPER + DIVISION + OPER | OPER + POTENCIA + OPER | OPER + IGUAL + OPER | OPER + DIFERENTE + OPER | OPER + MAYOR + OPER | OPER + MENOR + OPER | OPER + MAYOR_IGUAL + OPER | OPER + MENOR_IGUAL + OPER | OPER + DOT + OPER | OPER + OR + OPER | OPER + AND + OPER /*DOS NODOS*/ | NOT + OPER | OPER + INCREMENTO | OPER + DECREMENTO | NEW + Identificador + PARIZQ + PARDER | Variable + DIMENSION_LIST /*UN NODO*/ | PARIZQ + OPER + PARDER | Real | Caracter | Cadena | CSTBOOL | Variable | CALL; OPERLIST.Rule = MakeListRule(OPERLIST, COMMA, OPER); #endregion #region IF IF_STA.Rule = IF + PARIZQ + OPER + PARDER + LLVIZQ + INSTRUCCION_LIST + LLVDER + ELSE_STA; ELSE_STA.Rule = ELSE + LLVIZQ + INSTRUCCION_LIST + LLVDER | ELSE + IF_STA | Empty; #endregion #region FOR NonTerminal FOR_DEC = new NonTerminal("FOR_DEC") { Rule = INT + Variable + ASIGNACION + OPER | Variable + ASIGNACION + OPER }; NonTerminal FOR_ASS = new NonTerminal("FOR_ASS") { Rule = Variable + ASIGNACION + OPER | OPER }; FOR_STA.Rule = FOR + PARIZQ + FOR_CND + PARDER + LLVIZQ + INSTRUCCION_LIST + LLVDER; FOR_CND.Rule = FOR_DEC + SEMICOLON + OPER + SEMICOLON + FOR_ASS; #endregion #region REPEAT REPEAT_STA.Rule = REPEAT + PARIZQ + OPER + PARDER + LLVIZQ + INSTRUCCION_LIST + LLVDER; #endregion #region WHILE WHILE_STA.Rule = WHILE + PARIZQ + OPER + PARDER + LLVIZQ + INSTRUCCION_LIST + LLVDER; #endregion #region COMPROBAR SWITCH.Rule = COMPROBAR + PARIZQ + OPER + PARDER + LLVIZQ + CASE_LST + LLVDER; CASE_LST.Rule = MakePlusRule(CASE_LST, CASE); CASE.Rule = CASO + OPER + COLON + INSTRUCCION_LIST | DEFECTO + COLON + INSTRUCCION_LIST; #endregion #region DO-WHILE DO.Rule = HACER + LLVIZQ + INSTRUCCION_LIST + LLVDER + MIENTRAS + PARIZQ + OPER + PARDER + SEMICOLON; #endregion #region FIGURAS FIGURES.Rule = ADDFIGURE + PARIZQ + CIRCLE + PARIZQ + OPERLIST + PARDER + PARDER + SEMICOLON | ADDFIGURE + PARIZQ + TRI + PARIZQ + OPERLIST + PARDER + PARDER + SEMICOLON | ADDFIGURE + PARIZQ + SQA + PARIZQ + OPERLIST + PARDER + PARDER + SEMICOLON | ADDFIGURE + PARIZQ + LINE + PARIZQ + OPERLIST + PARDER + PARDER + SEMICOLON | FIGURE + PARIZQ + OPER + PARDER + SEMICOLON; #endregion #endregion #region Preferencias /*-------- INICIO --------*/ this.Root = INICIO; /*-------- COMENTARIOS IGNORADOS --------*/ NonGrammarTerminals.Add(LineComment); NonGrammarTerminals.Add(BlockComment); /*-------- PUNTUACIÓN Y AGRUPACIÓN --------*/ MarkPunctuation(SEMICOLON, COLON, /*DOT ,*/ COMMA, PARIZQ, PARDER, LLVIZQ, LLVDER, CORIZQ, CORDER); MarkPunctuation(IMPORTAR, CLASE, MAIN, IF, ELSE, FOR, COMPROBAR, CASO, DEFECTO, WHILE, REPEAT, ASIGNACION); MarkPunctuation(HACER, MIENTRAS, ARRAY); MarkPunctuation(ADDFIGURE); /*-------- ASOCIATIVIDAD --------*/ RegisterOperators(9, Associativity.Left, DOT); RegisterOperators(1, Associativity.Left, OR); RegisterOperators(2, Associativity.Left, AND); RegisterOperators(3, Associativity.Left, IGUAL, DIFERENTE, MAYOR, MAYOR_IGUAL, MENOR, MENOR_IGUAL); RegisterOperators(4, Associativity.Right, NOT); RegisterOperators(5, Associativity.Left, MAS, MENOS, DECREMENTO, INCREMENTO); RegisterOperators(6, Associativity.Left, POR, DIVISION); RegisterOperators(7, Associativity.Left, POTENCIA); RegisterOperators(8, Associativity.Left, PARIZQ, PARDER); /*-------- PALABRAS RESERVADAS --------*/ MarkReservedWords(INT.Text, CHAR.Text, STRING.Text, DOUBLE.Text, BOOL.Text, VOID.Text, ARRAY.Text, PUBLICO.Text, PRIVADO.Text, OVERRIDE.Text, IMPORTAR.Text, NEW.Text, MAIN.Text, RETURN.Text, PRINT.Text, SHOW.Text, IF.Text, ELSE.Text, FOR.Text, REPEAT.Text, WHILE.Text, COMPROBAR.Text, CASO.Text, DEFECTO.Text, SALIR.Text, HACER.Text, MIENTRAS.Text, CONTINUAR.Text, CLASE.Text, "false", "true", "verdadero", "falso", ADDFIGURE.Text, CIRCLE.Text, LINE.Text, SQA.Text, TRI.Text, FIGURE.Text); /*-------- NOTERMINAL TRANSIENT --------*/ MarkTransient(DATATYPE, ARRCONTENT, DIMENSION, INSTRUCCION, IMPORTAR_STA, OVER_STA, CLASE_STA_BODY, VISIBILIDAD); MarkTransient(ELSE_STA); #endregion }
/// <summary> /// Initializes a new instance of the <see cref="QueryGrammar"/> class. /// </summary> public QueryGrammar() : base(false) { // true means case sensitive GrammarComments = @"A Query Language based on JET where clauses. Case-insensitive."; // Terminals (Lexing) NumberLiteral number = new NumberLiteral("number"); StringLiteral STRING = new StringLiteral("STRING", "\""); //Let's allow big integers (with unlimited number of digits): number.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64, NumberLiteral.TypeCodeBigInt }; IdentifierTerminal Name = new IdentifierTerminal("Name"); //var Name = TerminalFactory.CreateSqlExtIdentifier(this, "id_simple"); CommentTerminal comment = new CommentTerminal("comment", "//", "\n", "\r"); //comment must be added to NonGrammarTerminals list; it is not used directly in grammar rules, // so we add it to this list to let Scanner know that it is also a valid terminal. NonGrammarTerminals.Add(comment); comment = new CommentTerminal("multilineComment", "/*", "*/"); NonGrammarTerminals.Add(comment); ConstantTerminal CONSTANT = new ConstantTerminal("CONSTANT"); CONSTANT.Add("NULL", null); // Non-Terminals (Parsing) NonTerminal query = new NonTerminal("Query"); NonTerminal tableExpression = new NonTerminal("TableExpression"); NonTerminal tableExpressions = new NonTerminal("TableExpressions"); NonTerminal table = new NonTerminal("Table"); NonTerminal column = new NonTerminal("Column"); NonTerminal tableOperator = new NonTerminal("TableOperator"); NonTerminal value = new NonTerminal("Value"); NonTerminal logicOp = new NonTerminal("LogicOp"); NonTerminal parameter = new NonTerminal("Parameter"); NonTerminal list = new NonTerminal("List"); NonTerminal enclosure = new NonTerminal("Enclosure"); NonTerminal closure = new NonTerminal("Closure"); NonTerminal logicExpression = new NonTerminal("logicExpression"); NonTerminal queryExpression = new NonTerminal("queryExpression"); NonTerminal betweenStmt = new NonTerminal("BetweenStmt"); NonTerminal expList = new NonTerminal("ExpList"); //keywords KeyTerm AND = ToTerm("AND"); KeyTerm OR = ToTerm("OR"); KeyTerm IN = ToTerm("IN"); KeyTerm BETWEEN = ToTerm("BETWEEN"); KeyTerm LIKE = ToTerm("LIKE"); KeyTerm NOT = ToTerm("NOT"); KeyTerm dot = ToTerm(".", "dot"); KeyTerm comma = ToTerm(",", "comma"); KeyTerm LeftSquareBrace = ToTerm("[", "LeftSquareBrace"); KeyTerm RightSquareBrace = ToTerm("]", "RightSquareBrace"); KeyTerm LeftCurlyBrace = ToTerm("{", "LeftSCurlyBrace"); KeyTerm RightCurlyBrace = ToTerm("}", "RightCurlyBrace"); KeyTerm LeftQuote = ToTerm("\"", "LeftQuote"); KeyTerm RightQuote = ToTerm("\"", "RightQuote"); //set precedence of operators. RegisterOperators(90, AND); RegisterOperators(80, OR); RegisterOperators(70, "=", ">", "<", "<>", ">=", "<=", "IN", "LIKE", "NOT LIKE", "IS", "IS NOT", "BETWEEN"); MarkPunctuation(",", "(", ")", "[", "]", ".", "\"", "{", "}"); logicExpression.Rule = tableExpression + logicOp + tableExpression | "(" + logicExpression + ")"; //queryExpression.Rule = MakePlusRule(queryExpression,logicOp,logicExpression); tableExpression.Rule = table + dot + column + tableOperator + value; tableExpression.ErrorRule = SyntaxError + ";"; betweenStmt.Rule = BETWEEN + value + "AND"; tableOperator.Rule = ToTerm("=") | ">" | "<" | "<>" | ">=" | "<=" | "LIKE" | "IN" | "NOT LIKE" | "IS" | "IS NOT" | betweenStmt; value.Rule = number | parameter | STRING | CONSTANT | expList; enclosure.Rule = ToTerm("(") | Empty; closure.Rule = ToTerm(")") | Empty; parameter.Rule = LeftQuote + "{" + Name + "}" + "\"" | "{" + Name + "}" | "#" + "{" + Name + "}" + "#"; logicOp.Rule = AND | OR; expList.Rule = "(" + list + ")"; list.Rule = MakePlusRule(list, comma, value); table.Rule = LeftSquareBrace + Name + RightSquareBrace; table.ErrorRule = SyntaxError + ";"; column.Rule = LeftSquareBrace + Name + RightSquareBrace; column.ErrorRule = SyntaxError + ";"; query.Rule = MakePlusRule(query, logicOp, logicExpression); Root = query; }
/// <summary> /// Initializes a new instance of the <see cref="QueryGrammar"/> class. /// </summary> public QueryGrammar() : base(false) // true means case sensitive { GrammarComments = @"A Query Language based on JET where clauses. Case-insensitive."; // Terminals (Lexing) NumberLiteral number = new NumberLiteral("number"); StringLiteral STRING = new StringLiteral("STRING", "\""); //Let's allow big integers (with unlimited number of digits): number.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64, NumberLiteral.TypeCodeBigInt }; IdentifierTerminal Name = new IdentifierTerminal("Name"); //var Name = TerminalFactory.CreateSqlExtIdentifier(this, "id_simple"); CommentTerminal comment = new CommentTerminal("comment", "//", "\n", "\r"); //comment must be added to NonGrammarTerminals list; it is not used directly in grammar rules, // so we add it to this list to let Scanner know that it is also a valid terminal. NonGrammarTerminals.Add(comment); comment = new CommentTerminal("multilineComment", "/*", "*/"); NonGrammarTerminals.Add(comment); ConstantTerminal CONSTANT = new ConstantTerminal("CONSTANT"); CONSTANT.Add("NULL", null); // Non-Terminals (Parsing) NonTerminal query = new NonTerminal("Query"); NonTerminal tableExpression = new NonTerminal("TableExpression"); NonTerminal tableExpressions = new NonTerminal("TableExpressions"); NonTerminal table = new NonTerminal("Table"); NonTerminal column = new NonTerminal("Column"); NonTerminal tableOperator = new NonTerminal("TableOperator"); NonTerminal value = new NonTerminal("Value"); NonTerminal logicOp = new NonTerminal("LogicOp"); NonTerminal parameter = new NonTerminal("Parameter"); NonTerminal list = new NonTerminal("List"); NonTerminal enclosure = new NonTerminal("Enclosure"); NonTerminal closure = new NonTerminal("Closure"); NonTerminal logicExpression = new NonTerminal("logicExpression"); NonTerminal queryExpression = new NonTerminal("queryExpression"); NonTerminal betweenStmt = new NonTerminal("BetweenStmt"); NonTerminal expList = new NonTerminal("ExpList"); //keywords KeyTerm AND = ToTerm("AND"); KeyTerm OR = ToTerm("OR"); KeyTerm IN = ToTerm("IN"); KeyTerm BETWEEN = ToTerm("BETWEEN"); KeyTerm LIKE = ToTerm("LIKE"); KeyTerm NOT = ToTerm("NOT"); KeyTerm dot = ToTerm(".", "dot"); KeyTerm comma = ToTerm(",", "comma"); KeyTerm LeftSquareBrace = ToTerm("[", "LeftSquareBrace"); KeyTerm RightSquareBrace = ToTerm("]", "RightSquareBrace"); KeyTerm LeftCurlyBrace = ToTerm("{", "LeftSCurlyBrace"); KeyTerm RightCurlyBrace = ToTerm("}", "RightCurlyBrace"); KeyTerm LeftQuote = ToTerm("\"", "LeftQuote"); KeyTerm RightQuote = ToTerm("\"", "RightQuote"); //set precedence of operators. RegisterOperators(90, AND); RegisterOperators(80, OR); RegisterOperators(70, "=", ">", "<", "<>", ">=", "<=", "IN", "LIKE", "NOT LIKE", "IS", "IS NOT", "BETWEEN"); MarkPunctuation(",", "(", ")", "[", "]", ".", "\"", "{", "}"); logicExpression.Rule = tableExpression + logicOp + tableExpression | "(" + logicExpression + ")"; //queryExpression.Rule = MakePlusRule(queryExpression,logicOp,logicExpression); tableExpression.Rule = table + dot + column + tableOperator + value; tableExpression.ErrorRule = SyntaxError + ";"; betweenStmt.Rule = BETWEEN + value + "AND"; tableOperator.Rule = ToTerm("=") | ">" | "<" | "<>" | ">=" | "<=" | "LIKE" | "IN" | "NOT LIKE" | "IS" | "IS NOT" | betweenStmt; value.Rule = number | parameter | STRING | CONSTANT | expList; enclosure.Rule = ToTerm("(") | Empty; closure.Rule = ToTerm(")") | Empty; parameter.Rule = LeftQuote + "{" + Name + "}" + "\"" | "{" + Name + "}" | "#" + "{" + Name + "}" + "#"; logicOp.Rule = AND | OR; expList.Rule = "(" + list + ")"; list.Rule = MakePlusRule(list, comma, value); table.Rule = LeftSquareBrace + Name + RightSquareBrace; table.ErrorRule = SyntaxError + ";"; column.Rule = LeftSquareBrace + Name + RightSquareBrace; column.ErrorRule = SyntaxError + ";"; query.Rule = MakePlusRule(query, logicOp, logicExpression); Root = query; }
// It is loosely based on R6RS specs. // See Grammar Errors tab in GrammarExplorer for remaining conflicts. public SchemeGrammar() { #region Terminals ConstantTerminal Constant = new ConstantTerminal("Constant"); Constant.Add("#T", 1); Constant.Add("#t", 1); Constant.Add("#F", null); Constant.Add("#f", null); Constant.Add("'()", null); Constant.Add(@"#\nul", '\u0000'); Constant.Add(@"#\alarm", '\u0007'); Constant.Add(@"#\backspace", '\b'); Constant.Add(@"#\tab", '\t'); Constant.Add(@"#\linefeed", '\n'); Constant.Add(@"#\vtab", '\v'); Constant.Add(@"#\page", '\f'); Constant.Add(@"#\return", '\r'); Constant.Add(@"#\esc", '\u001B'); Constant.Add(@"#\space", ' '); Constant.Add(@"#\delete", '\u007F'); // TODO: build SchemeCharLiteral // the following is nonsense, just to put something there var charLiteral = new StringLiteral("Char", "'", StringFlags.None); var stringLiteral = new StringLiteral("String", "\"", StringFlags.AllowsAllEscapes); //Identifiers. Note: added "-", just to allow IDs starting with "->" var SimpleIdentifier = new IdentifierTerminal("SimpleIdentifier", "_+-*/.@?!<>=", "_+-*/.@?!<>=$%&:^~"); // name extraChars extraFirstChars var Number = TerminalFactory.CreateSchemeNumber("Number"); var Byte = new NumberLiteral("Byte", NumberFlags.IntOnly); //Comments Terminal Comment = new CommentTerminal("Comment", "#|", "|#"); Terminal LineComment = new CommentTerminal("LineComment", ";", "\n"); NonGrammarTerminals.Add(Comment); //add comments explicitly to this list as it is not reachable from Root NonGrammarTerminals.Add(LineComment); #endregion #region NonTerminals var Module = new NonTerminal("Module"); var Library = new NonTerminal("Library"); var LibraryList = new NonTerminal("Library+"); var Script = new NonTerminal("Script"); var Abbreviation = new NonTerminal("Abbreviation"); var Vector = new NonTerminal("Vector"); var ByteList = new NonTerminal("ByteList"); var ByteVector = new NonTerminal("ByteVector"); var Datum = new NonTerminal("Datum"); //Datum in R6RS terms var DatumOpt = new NonTerminal("DatumOpt"); //Datum in R6RS terms var DatumList = new NonTerminal("Datum+", typeof(StatementListNode)); var DatumListOpt = new NonTerminal("Datum*", typeof(StatementListNode)); var Statement = new NonTerminal("Statement"); var Atom = new NonTerminal("Atom"); var CompoundDatum = new NonTerminal("CompoundDatum"); var AbbrevPrefix = new NonTerminal("AbbrevPrefix"); var LibraryName = new NonTerminal("LibraryName"); var LibraryBody = new NonTerminal("LibraryBody"); var ImportSection = new NonTerminal("ImportSection"); var ExportSection = new NonTerminal("ExportSection"); var ImportSpec = new NonTerminal("ImportSpec"); var ImportSpecList = new NonTerminal("ImportSpecList"); var ExportSpec = new NonTerminal("ExportSpec"); var ExportSpecList = new NonTerminal("ExportSpecList"); var LP = new NonTerminal("LP"); //"(" or "[" var RP = new NonTerminal("RP"); // ")" or "]" var Identifier = new NonTerminal("Identifier", typeof(VarRefNode)); var IdentifierList = new NonTerminal("IdentifierList"); var IdentifierListOpt = new NonTerminal("IdentifierListOpt"); var PeculiarIdentifier = new NonTerminal("PeculiarIdentifier"); var LibraryVersion = new NonTerminal("LibraryVersion"); var VersionListOpt = new NonTerminal("VersionListOpt"); var FunctionCall = new NonTerminal("FunctionCall", CreateFunctionCallNode); var FunctionRef = new NonTerminal("FunctionRef"); var SpecialForm = new NonTerminal("SpecialForm"); var DefineVarForm = new NonTerminal("DefineVarForm", CreateDefineVarNode); var DefineFunForm = new NonTerminal("DefineFunForm", CreateDefineFunNode); var LambdaForm = new NonTerminal("LambdaForm", CreateLambdaNode); var IfForm = new NonTerminal("IfForm", CreateIfThenElseNode); var CondForm = new NonTerminal("CondForm", CreateCondFormNode); var CondClause = new NonTerminal("CondClause", CreateCondClauseNode); var CondClauseList = new NonTerminal("CondClauseList"); var CondElseOpt = new NonTerminal("CondElseOpt"); var BeginForm = new NonTerminal("BeginForm", CreateBeginNode); var LetForm = new NonTerminal("LetForm"); //not implemented var LetRecForm = new NonTerminal("LetRecForm"); //not implemented var LetPair = new NonTerminal("LetPair"); var LetPairList = new NonTerminal("LetPairList"); #endregion #region Rules // // Using optional elements in Scheme grammar brings some nasty conflicts - by default the parser selects "shift" over reduce // which leads to failure to parse simple programs without libraries and export/import sections. // This trouble comes from that the fact that Scheme has soooooo many parenthesis. Therefore, using a single next symbol // as a lookahead (as it happens in LALR parsing) doesn't help much - the next symbol is almost always a parenthesis, // not some meaningful symbol. That's why in the following expressions I had to use explicit listing of variants, // instead of simply marking some elements as optional (see Module, Script, LibraryBody elements) - this clears the conflicts // but would make node construction more difficult. base.Root = Module; LP.Rule = Symbol("(") | "["; //R6RS allows mix & match () and [] RP.Rule = Symbol(")") | "]"; // Module.Rule = LibraryListOpt + Script; -- this brings conflicts Module.Rule = LibraryList + Script | Script; LibraryList.Rule = MakePlusRule(LibraryList, Library); Script.Rule = ImportSection + DatumList | DatumList; //Library // the following doesn't work - brings conflicts that incorrectly resolved by default shifting //Library.Rule = LP + "library" + LibraryName + ExportSectionOpt + ImportSectionOpt + DatumListOpt + RP; Library.Rule = LP + "library" + LibraryName + LibraryBody + RP; //Note - we should be using DatumListOpt, but that brings 2 conflicts, so for now it is just DatumList //Note that the following style of BNF expressions is strongly discouraged - all productions should be of the same length, // so that the process of mapping child nodes to parent's properties is straightforward. LibraryBody.Rule = ExportSection + ImportSection + DatumList | ExportSection + DatumList | ImportSection + DatumList | DatumList; LibraryName.Rule = LP + IdentifierList + LibraryVersion.Q() + RP; LibraryVersion.Rule = LP + VersionListOpt + RP; //zero or more subversion numbers VersionListOpt.Rule = MakeStarRule(VersionListOpt, Number); ExportSection.Rule = LP + "export" + ExportSpecList + RP; ImportSection.Rule = LP + "import" + ImportSpecList + RP; ExportSpecList.Rule = MakePlusRule(ExportSpecList, ExportSpec); ImportSpecList.Rule = MakePlusRule(ImportSpecList, ImportSpec); ExportSpec.Rule = Identifier | LP + "rename" + LP + Identifier + Identifier + RP + RP; ImportSpec.Rule = LP + Identifier + RP; // - much more complex in R6RS //Datum Datum.Rule = Atom | CompoundDatum; DatumOpt.Rule = Empty | Datum; DatumList.Rule = MakePlusRule(DatumList, Datum); DatumListOpt.Rule = MakeStarRule(DatumListOpt, Datum); Atom.Rule = Number | Identifier | stringLiteral | Constant | charLiteral | "."; CompoundDatum.Rule = Statement | Abbreviation | Vector | ByteVector; Identifier.Rule = SimpleIdentifier | PeculiarIdentifier; IdentifierList.Rule = MakePlusRule(IdentifierList, Identifier); IdentifierListOpt.Rule = MakeStarRule(IdentifierListOpt, Identifier); //TODO: create PeculiarIdentifier custom terminal instead of var // or just custom SchemeIdentifier terminal PeculiarIdentifier.Rule = Symbol("+") | "-" | "..."; // |"->" + subsequent; (should be!) Abbreviation.Rule = AbbrevPrefix + Datum; AbbrevPrefix.Rule = Symbol("'") | "`" | ",@" | "," | "#'" | "#`" | "#,@" | "#,"; Vector.Rule = "#(" + DatumListOpt + ")"; ByteVector.Rule = "#vu8(" + ByteList + ")"; ByteList.Rule = MakeStarRule(ByteList, Byte); Statement.Rule = FunctionCall | SpecialForm; FunctionCall.Rule = LP + FunctionRef + DatumListOpt + RP; FunctionRef.Rule = Identifier | Statement; SpecialForm.Rule = DefineVarForm | DefineFunForm | LambdaForm | IfForm | CondForm | BeginForm | LetForm | LetRecForm; DefineVarForm.Rule = LP + "define" + Identifier + Datum + RP; DefineFunForm.Rule = LP + "define" + LP + Identifier + IdentifierListOpt + RP + DatumList + RP; LambdaForm.Rule = LP + "lambda" + LP + IdentifierListOpt + RP + DatumList + RP; IfForm.Rule = LP + "if" + Datum + Datum + DatumOpt + RP; CondForm.Rule = LP + "cond" + CondClauseList + CondElseOpt + RP; CondClauseList.Rule = MakePlusRule(CondClauseList, CondClause); CondClause.Rule = LP + Datum + DatumList + RP; CondElseOpt.Rule = Empty | LP + "else" + DatumList + RP; LetForm.Rule = LP + "let" + LP + LetPairList + RP + DatumList + RP; LetRecForm.Rule = LP + "letrec" + LP + LetPairList + RP + DatumList + RP; BeginForm.Rule = LP + "begin" + DatumList + RP; LetPairList.Rule = MakePlusRule(LetPairList, LetPair); LetPair.Rule = LP + Identifier + Datum + RP; #endregion //Register brace pairs RegisterBracePair("(", ")"); RegisterBracePair("[", "]"); RegisterPunctuation(LP, RP); //Filters and other stuff BraceMatchFilter filter = new BraceMatchFilter(); TokenFilters.Add(filter); //Scheme is tail-recursive language base.LanguageFlags = LanguageFlags.BubbleNodes | LanguageFlags.TailRecursive | LanguageFlags.SupportsInterpreter | LanguageFlags.SupportsConsole; //keywords - just for colorizer base.AddKeywords("define", "lambda", "cond", "if", "begin", "let"); }
public Gramatica() { #region ER StringLiteral CADENA = new StringLiteral("cadena", "'"); var ENTERO = new NumberLiteral("entero"); var DECIMAL = new RegexBasedTerminal("decimal", "[0-9]+'.'[0-9]+"); IdentifierTerminal ID = new IdentifierTerminal("id"); ConstantTerminal BOOLEANO = new ConstantTerminal("booleano"); BOOLEANO.Add("true", true); BOOLEANO.Add("false", false); CommentTerminal comentarioLinea = new CommentTerminal("comentarioLinea", "//", "\n", "\r\n"); CommentTerminal comentarioBloque = new CommentTerminal("comentarioBloque", "(*", "*)"); #endregion #region Terminales var PROGRAM = ToTerm("program"); var USES = ToTerm("uses"); var BEGIN = ToTerm("begin"); var END = ToTerm("end"); var WRITE = ToTerm("write"); var WRITELN = ToTerm("writeln"); var READLN = ToTerm("readln"); var EXIT = ToTerm("exit"); var GRAFICARTS = ToTerm("graficar_ts"); var SETLENGTH = ToTerm("setlength"); var VAR = ToTerm("var"); var CONST = ToTerm("const"); var TYPE = ToTerm("type"); var VOID = ToTerm("void"); var INTEGER = ToTerm("integer"); var DOUBLE = ToTerm("double"); var REAL = ToTerm("real"); var CHAR = ToTerm("char"); var STRING = ToTerm("string"); var OBJECT = ToTerm("object"); var IF = ToTerm("if"); var THEN = ToTerm("then"); var ELSE = ToTerm("else"); var CASE = ToTerm("case"); var OF = ToTerm("of"); var AND = ToTerm("and"); var OR = ToTerm("or"); var NOT = ToTerm("not"); var WHILE = ToTerm("while"); var FOR = ToTerm("for"); var TO = ToTerm("to"); var DO = ToTerm("do"); var REPEAT = ToTerm("repeat"); var UNTIL = ToTerm("until"); var BREAK = ToTerm("break"); var CONTINUE = ToTerm("continue"); var ARRAY = ToTerm("array"); var FUNCTION = ToTerm("function"); var PROCEDURE = ToTerm("procedure"); var PTCOMA = ToTerm(";"); var PTO = ToTerm("."); var COMA = ToTerm(","); var PARIZQ = ToTerm("("); var PARDER = ToTerm(")"); var COMILLA = ToTerm("'"); var DOSPTS = ToTerm(":"); var CORIZQ = ToTerm("["); var CORDER = ToTerm("]"); var MAS = ToTerm("+"); var MENOS = ToTerm("-"); var POR = ToTerm("*"); var DIV = ToTerm("/"); var MOD = ToTerm("%"); var MAYQUE = ToTerm(">"); var MENQUE = ToTerm("<"); var MAYIGQUE = ToTerm(">="); var MENIGQUE = ToTerm("<="); var DIF = ToTerm("<>"); var IGUAL = ToTerm("="); RegisterOperators(1, IGUAL, DIF, MENQUE, MENIGQUE, MAYQUE, MAYIGQUE); RegisterOperators(2, MAS, MENOS, OR); RegisterOperators(3, POR, DIV, MOD, AND); RegisterOperators(4, NOT); NonGrammarTerminals.Add(comentarioLinea); NonGrammarTerminals.Add(comentarioBloque); #endregion #region No Terminales NonTerminal inicio = new NonTerminal("inicio"); NonTerminal inicio_bloques = new NonTerminal("inicio_bloques"); NonTerminal bloque_general = new NonTerminal("bloque_general"); NonTerminal bloque_uses = new NonTerminal("bloque_uses"); NonTerminal lista_uses = new NonTerminal("lista_uses"); NonTerminal bloques = new NonTerminal("bloques"); NonTerminal bloques2 = new NonTerminal("bloques2"); NonTerminal bloque_principal = new NonTerminal("bloque_principal"); NonTerminal bloque_variables = new NonTerminal("bloque_variables"); NonTerminal bloque_variables2 = new NonTerminal("bloque_variables2"); NonTerminal declaraciones_var = new NonTerminal("declaraciones_var"); NonTerminal declaracion_var = new NonTerminal("declaracion_var"); NonTerminal lista_ids = new NonTerminal("lista_ids"); NonTerminal tipo_var = new NonTerminal("tipo_var"); NonTerminal bloque_tipos = new NonTerminal("bloque_tipos"); NonTerminal declaraciones_tipos = new NonTerminal("declaraciones_tipos"); NonTerminal declaracion_tipos = new NonTerminal("declaracion_tipos"); NonTerminal tipo_index = new NonTerminal("tipo_index"); NonTerminal index = new NonTerminal("index"); NonTerminal tipo_object = new NonTerminal("tipo_object"); NonTerminal bloque_constantes = new NonTerminal("bloque_constantes"); NonTerminal definiciones_const = new NonTerminal("definiciones_const"); NonTerminal definicion_const = new NonTerminal("definicion_const"); NonTerminal asignacion = new NonTerminal("asignacion"); NonTerminal lista_expresiones = new NonTerminal("lista_expresiones"); NonTerminal instruccion = new NonTerminal("instruccion"); NonTerminal instrucciones = new NonTerminal("instrucciones"); NonTerminal instruccion_sin_ptc = new NonTerminal("instruccion_sin_ptc"); NonTerminal bloque_compuesto = new NonTerminal("bloque_compuesto"); NonTerminal print = new NonTerminal("print"); NonTerminal lista_exprs = new NonTerminal("lista_exprs"); NonTerminal read = new NonTerminal("read"); NonTerminal length_array = new NonTerminal("length_array"); NonTerminal graficar = new NonTerminal("graficar_ts"); NonTerminal salir = new NonTerminal("salir"); NonTerminal sent_if = new NonTerminal("sent_if"); NonTerminal sent_if2 = new NonTerminal("sent_if2"); NonTerminal sent_case = new NonTerminal("sent_case"); NonTerminal lista_casos = new NonTerminal("lista_casos"); NonTerminal caso = new NonTerminal("caso"); NonTerminal ciclo_for = new NonTerminal("ciclo_for"); NonTerminal ciclo_while = new NonTerminal("ciclo_while"); NonTerminal ciclo_repeat = new NonTerminal("ciclo_repeat"); NonTerminal bloque_funcion = new NonTerminal("bloque_funcion"); NonTerminal argumentos_header = new NonTerminal("argumentos_header"); NonTerminal argumentos_header2 = new NonTerminal("argumentos_header2"); NonTerminal cuerpo_funcion = new NonTerminal("cuerpo_funcion"); NonTerminal lista_argumentos = new NonTerminal("lista_argumentos"); NonTerminal lista_argumentos2 = new NonTerminal("lista_argumentos2"); NonTerminal argumentos = new NonTerminal("argumentos"); NonTerminal llamada_funcion = new NonTerminal("llamada_funcion"); NonTerminal bloque_procedimiento = new NonTerminal("bloque_procedimiento"); NonTerminal llamada_procedimiento = new NonTerminal("llamada_procedimiento"); NonTerminal expresion = new NonTerminal("expresion"); NonTerminal expresion_imprimible = new NonTerminal("expresion_imprimible"); NonTerminal dato = new NonTerminal("dato"); #endregion #region Gramatica inicio.Rule = inicio_bloques; inicio_bloques.Rule = PROGRAM + ID + ";" + bloque_principal | PROGRAM + ID + ";" + bloques + bloque_principal; bloques.Rule = this.MakePlusRule(bloques, bloques2); //bloques.Rule = bloques + bloques2 //| bloques2; bloques2.Rule = bloque_funcion | bloque_procedimiento | bloque_variables | bloque_tipos | bloque_constantes; bloque_principal.Rule = BEGIN + instrucciones + END + "."; //---------------------- DECLARACIONES DE VARIABLES---------------------------- bloque_variables.Rule = bloque_constantes + bloque_variables2 | bloque_variables2; bloque_variables2.Rule = VAR + declaraciones_var; declaraciones_var.Rule = this.MakePlusRule(declaraciones_var, declaracion_var); //declaraciones_var.Rule = declaraciones_var + declaracion_var //| declaracion_var; declaracion_var.Rule = lista_ids + DOSPTS + tipo_var + PTCOMA | ID + DOSPTS + ARRAY + CORIZQ + tipo_index + CORDER + OF + tipo_var + PTCOMA | ID + DOSPTS + tipo_var + IGUAL + expresion + PTCOMA; lista_ids.Rule = this.MakeListRule(lista_ids, ToTerm(","), ID); //lista_ids=lista_ids ',' id //| id tipo_var.Rule = INTEGER | DOUBLE | REAL | CHAR | STRING | PARIZQ + expresion + PARDER | ID; //---------------------- DECLARACIONES DE TIPOS---------------------------- bloque_tipos.Rule = TYPE + declaraciones_tipos; declaraciones_tipos.Rule = this.MakePlusRule(declaraciones_tipos, declaracion_tipos); //declaraciones_tipos=declaraciones_tipos declaracion_tipos //| declaracion_tipos declaracion_tipos.Rule = lista_ids + IGUAL + tipo_var + PTCOMA //declarando un tipo simple | ID + IGUAL + ARRAY + CORIZQ + tipo_index + CORDER + OF + tipo_var + PTCOMA //declarando un tipo array | ID + IGUAL + ARRAY + OF + tipo_var + PTCOMA //declarando un tipo array dinamico | tipo_object + PTCOMA; tipo_index.Rule = this.MakeListRule(tipo_index, ToTerm(","), index); //tipo_index.Rule = tipo_index + COMA index //| index index.Rule = dato + PTO + PTO + dato; tipo_object.Rule = ID + IGUAL + OBJECT + VAR + bloque_variables2 + END; //----------------------------------BLOQUE DE CONSTANTES ---------------------------------------- bloque_constantes.Rule = CONST + definiciones_const; definiciones_const.Rule = definiciones_const + definicion_const | definicion_const; definicion_const.Rule = ID + IGUAL + dato + PTCOMA; //---------------------------------- - ASIGNACIONES - ACCESOS---------------------------------------- asignacion.Rule = ID + DOSPTS + IGUAL + expresion | ID + CORIZQ + lista_expresiones + CORDER + DOSPTS + IGUAL + expresion | ID + DOSPTS + IGUAL + ID + CORIZQ + lista_expresiones + CORDER; lista_expresiones.Rule = this.MakeListRule(lista_expresiones, ToTerm(","), expresion); //lista_expresiones=lista_expresiones ',' expresion //| expresion //---------------------------------------------------------------------------------------------------- //instrucciones.Rule = this.MakePlusRule(instrucciones, instruccion); instrucciones.Rule = instrucciones + instruccion | instruccion; instruccion.Rule = print + ";" | read + PTCOMA | asignacion + PTCOMA | sent_if + PTCOMA | sent_case + PTCOMA | ciclo_for + PTCOMA | ciclo_while + PTCOMA | ciclo_repeat + PTCOMA | bloque_compuesto + PTCOMA | llamada_funcion + PTCOMA | llamada_procedimiento + PTCOMA | length_array + PTCOMA | graficar + PTCOMA | salir + PTCOMA; instruccion_sin_ptc.Rule = print | read | asignacion | sent_if | sent_case | ciclo_for | ciclo_while | ciclo_repeat | bloque_compuesto | llamada_funcion | llamada_procedimiento | length_array | graficar | salir; bloque_compuesto.Rule = BEGIN + instrucciones + END; print.Rule = WRITE + "(" + lista_exprs + ")" | WRITELN + "(" + lista_exprs + ")" | WRITELN; lista_exprs.Rule = lista_exprs + COMA + expresion_imprimible | expresion_imprimible; read.Rule = READLN + PARIZQ + dato + PARDER; length_array.Rule = SETLENGTH + PARIZQ + ID + COMA + lista_expresiones + PARDER; graficar.Rule = GRAFICARTS + PARIZQ + PARDER | GRAFICARTS; salir.Rule = EXIT + PARIZQ + lista_expresiones + PARDER | EXIT; //---------------------------------------- CONDICIONES Y CICLOS---------------------------------------- sent_if.Rule = IF + expresion + THEN + sent_if; sent_if2.Rule = instruccion | instruccion_sin_ptc + ELSE + sent_if | instruccion_sin_ptc + ELSE + instruccion; sent_case.Rule = CASE + PARIZQ + expresion + PARDER + OF + lista_casos + END + PTCOMA | CASE + PARIZQ + expresion + PARDER + OF + lista_casos + ELSE + instruccion + END + PTCOMA; lista_casos.Rule = this.MakePlusRule(lista_casos, caso); //lista_casos=lista_casos caso //| caso caso.Rule = expresion + DOSPTS + instruccion; ciclo_for.Rule = FOR + asignacion + TO + dato + DO + instruccion; ciclo_while.Rule = WHILE + PARIZQ + expresion + PARDER + DO + instruccion; ciclo_repeat.Rule = REPEAT + instrucciones + UNTIL + expresion; //--------------------------------------------------FUNCIONES-------------------------------------------------- bloque_funcion.Rule = FUNCTION + ID + argumentos_header + DOSPTS + tipo_var + PTCOMA + cuerpo_funcion; argumentos_header.Rule = PARIZQ + argumentos_header2 | Empty; argumentos_header2.Rule = lista_argumentos + PARDER | PARDER; cuerpo_funcion.Rule = bloque_variables2 + bloque_compuesto + PTCOMA | bloque_compuesto + PTCOMA; lista_argumentos.Rule = argumentos + lista_argumentos2; lista_argumentos2.Rule = PTCOMA + argumentos + lista_argumentos2 | Empty; argumentos.Rule = VAR + lista_ids + DOSPTS + tipo_var | lista_ids + DOSPTS + tipo_var; llamada_funcion.Rule = ID + DOSPTS + IGUAL + ID + PARIZQ + lista_argumentos + PARDER | ID + DOSPTS + IGUAL + ID + PARIZQ + PARDER; //------------------------------------------------PROCEDIMIENTOS----------------------------------------------- bloque_procedimiento.Rule = PROCEDURE + ID + argumentos_header + PTCOMA + cuerpo_funcion; llamada_procedimiento.Rule = ID + PARIZQ + lista_argumentos + PARDER | ID + PARIZQ + PARDER; //------------------------------------------------ OPERACIONES Y EXPRESIONES---------------------------------------------- expresion.Rule = expresion + MAS + expresion | expresion + MENOS + expresion | expresion + POR + expresion | expresion + DIV + expresion | expresion + MOD + expresion | expresion + IGUAL + expresion | expresion + DIF + expresion | expresion + MAYQUE + expresion | expresion + MENQUE + expresion | expresion + MAYIGQUE + expresion | expresion + MENIGQUE + expresion | expresion + AND + expresion | expresion + OR + expresion | NOT + expresion | PARIZQ + expresion + PARDER | dato; expresion_imprimible.Rule = expresion + DOSPTS + ENTERO + DOSPTS + ENTERO | expresion; dato.Rule = ID | CADENA | ENTERO | DECIMAL | BOOLEANO; #endregion #region Preferencias this.Root = inicio; MarkPunctuation("(", ")", ";", ".", ","); #endregion }
public PythonGrammar() { #region Declare Terminals ConstantTerminal Constants = new ConstantTerminal("Constants"); Constants.Add("True", true); Constants.Add("False", false); IdentifierTerminal Identifier = new IdentifierTerminal("Identifier"); Terminal Comment = new CommentTerminal("Comment", "#", "\n"); NonGrammarTerminals.Add(Comment); Terminal comma = Symbol(",", "comma"); //commaQ is optional trailing comma in lists; it causes several conflicts in this grammar // so we get rid of it (by assigning it Empty value) //NonTerminal commaQ = comma.Q(); //this causes several conflicts NonTerminal commaQ = Empty; Terminal dot = Symbol(".", "dot"); Terminal LBr = Symbol("["); Terminal RBr = Symbol("]"); Terminal bQuote = Symbol("`"); Terminal ellipsis = Symbol("..."); Terminal colon = Symbol(":"); Terminal NAME = Identifier; Terminal NEWLINE = Grammar.NewLine; Terminal INDENT = Grammar.Indent; Terminal DEDENT = Grammar.Dedent; Terminal semicolon = Symbol(";"); Terminal EOF = Grammar.Eof; Terminal NUMBER = TerminalFactory.CreatePythonNumber("NUMBER"); #endregion #region Declare NonTerminals StringLiteral STRING = TerminalFactory.CreatePythonString("String"); NonTerminal single_input = new NonTerminal("single_input"); NonTerminal file_input = new NonTerminal("file_input"); NonTerminal eval_input = new NonTerminal("eval_input"); NonTerminal decorator = new NonTerminal("decorator"); NonTerminal funcdef = new NonTerminal("funcdef"); NonTerminal parameters = new NonTerminal("parameters"); NonTerminal varargslist = new NonTerminal("varargslist"); NonTerminal vararg = new NonTerminal("vararg"); NonTerminal fpdef = new NonTerminal("fpdef"); NonTerminal fpdef_ext = new NonTerminal("fpdef_ext"); NonTerminal fplist = new NonTerminal("fplist"); NonTerminal stmt = new NonTerminal("stmt"); NonTerminal simple_stmt = new NonTerminal("simple_stmt"); NonTerminal small_stmt = new NonTerminal("small_stmt"); NonTerminal expr_stmt = new NonTerminal("expr_stmt"); NonTerminal yield_or_testlist = new NonTerminal("yield_or_testlist"); NonTerminal augassign = new NonTerminal("augassign"); NonTerminal print_stmt = new NonTerminal("print_stmt"); NonTerminal del_stmt = new NonTerminal("del_stmt"); NonTerminal pass_stmt = new NonTerminal("pass_stmt"); NonTerminal flow_stmt = new NonTerminal("flow_stmt"); NonTerminal break_stmt = new NonTerminal("break_stmt"); NonTerminal continue_stmt = new NonTerminal("continue_stmt"); NonTerminal return_stmt = new NonTerminal("return_stmt"); NonTerminal yield_stmt = new NonTerminal("yield_stmt"); NonTerminal raise_stmt = new NonTerminal("raise_stmt"); NonTerminal import_stmt = new NonTerminal("import_stmt"); NonTerminal import_name = new NonTerminal("import_name"); NonTerminal import_from = new NonTerminal("import_from"); NonTerminal import_as_name = new NonTerminal("import_as_name"); NonTerminal dotted_as_name = new NonTerminal("dotted_as_name"); NonTerminal import_as_names = new NonTerminal("import_as_names"); NonTerminal dotted_as_names = new NonTerminal("dotted_as_names"); NonTerminal dotted_name = new NonTerminal("dotted_name"); NonTerminal global_stmt = new NonTerminal("global_stmt"); NonTerminal exec_stmt = new NonTerminal("exec_stmt"); NonTerminal assert_stmt = new NonTerminal("assert_stmt"); NonTerminal compound_stmt = new NonTerminal("compound_stmt"); NonTerminal if_stmt = new NonTerminal("if_stmt"); NonTerminal else_clause = new NonTerminal("else_clause"); NonTerminal while_stmt = new NonTerminal("while_stmt"); NonTerminal for_stmt = new NonTerminal("for_stmt"); NonTerminal try_stmt = new NonTerminal("try_stmt"); NonTerminal finally_block = new NonTerminal("finally_block"); NonTerminal with_stmt = new NonTerminal("with_stmt"); NonTerminal with_var = new NonTerminal("with_var"); NonTerminal except_clause = new NonTerminal("except_clause"); NonTerminal suite = new NonTerminal("suite"); NonTerminal testlist_safe = new NonTerminal("testlist_safe"); NonTerminal old_test = new NonTerminal("old_test"); NonTerminal old_lambdef = new NonTerminal("old_lambdef"); NonTerminal test = new NonTerminal("test"); NonTerminal testlist = new NonTerminal("testlist"); NonTerminal testlist1 = new NonTerminal("testlist1"); NonTerminal or_test = new NonTerminal("or_test"); NonTerminal and_test = new NonTerminal("and_test"); NonTerminal not_test = new NonTerminal("not_test"); NonTerminal comparison = new NonTerminal("comparison"); NonTerminal comp_op = new NonTerminal("comp_op"); NonTerminal expr = new NonTerminal("expr"); NonTerminal xor_expr = new NonTerminal("xor_expr"); NonTerminal and_expr = new NonTerminal("and_expr"); NonTerminal shift_expr = new NonTerminal("shift_expr"); NonTerminal arith_expr = new NonTerminal("arith_expr"); NonTerminal shift_op = new NonTerminal("shift_op"); NonTerminal sum_op = new NonTerminal("sum_op"); NonTerminal mul_op = new NonTerminal("mul_op"); NonTerminal term = new NonTerminal("term"); NonTerminal factor = new NonTerminal("factor"); NonTerminal power = new NonTerminal("power"); NonTerminal atom = new NonTerminal("atom"); NonTerminal listmaker = new NonTerminal("listmaker"); NonTerminal testlist_gexp = new NonTerminal("testlist_gexp"); NonTerminal lambdef = new NonTerminal("lambdef"); NonTerminal trailer = new NonTerminal("trailer"); NonTerminal subscriptlist = new NonTerminal("subscriptlist"); NonTerminal subscript = new NonTerminal("subscript"); NonTerminal sliceop = new NonTerminal("sliceop"); NonTerminal exprlist = new NonTerminal("exprlist"); NonTerminal dictmaker = new NonTerminal("dictmaker"); NonTerminal dict_elem = new NonTerminal("dict_elem"); NonTerminal classdef = new NonTerminal("classdef"); NonTerminal arglist = new NonTerminal("arglist"); NonTerminal argument = new NonTerminal("argument"); NonTerminal list_iter = new NonTerminal("list_iter"); NonTerminal list_for = new NonTerminal("list_for"); NonTerminal list_if = new NonTerminal("list_if"); NonTerminal gen_iter = new NonTerminal("gen_iter"); NonTerminal gen_for = new NonTerminal("gen_for"); NonTerminal gen_if = new NonTerminal("gen_if"); NonTerminal encoding_decl = new NonTerminal("encoding_decl"); NonTerminal yield_expr = new NonTerminal("yield_expr"); #endregion #region RULES // The commented rules before each statement are original grammar rules // copied from the grammar file. //Set grammar root base.Root = file_input; //file_input: (NEWLINE | stmt)* ENDMARKER file_input.Rule = NEWLINE.Q() + stmt.Star();// +EOF; //EOF is added by default as a lookahead //single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE single_input.Rule = NEWLINE | simple_stmt | compound_stmt + NEWLINE; //eval_input: testlist NEWLINE* ENDMARKER eval_input.Rule = NEWLINE.Q() + WithStar(testlist + NEWLINE); // +EOF; //changed this //decorators: decorator+ //decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE decorator.Rule = "@" + dotted_name + WithQ("(" + arglist.Q() + ")") + NEWLINE; //funcdef: [decorators] 'def' NAME parameters ':' suite funcdef.Rule = decorator.Star() + "def" + NAME + parameters + ":" + suite; // parameters: '(' [varargslist] ')' parameters.Rule = "(" + varargslist.Q() + ")"; /* varargslist: ((fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']) */ fpdef_ext.Rule = fpdef + WithQ("=" + test); /* varargslist.Expression = WithStar(fpdef_ext + comma) + WithQ("*" + NAME + WithQ (comma + "**" + NAME) | "**" + NAME) | fpdef_ext.Plus(comma) + commaQ; */ // ambiguous varargslist.Rule = vararg.Plus(comma) + commaQ; vararg.Rule = fpdef_ext | "*" + NAME | "**" + NAME; // added this to grammar // fpdef: NAME | '(' fplist ')' fpdef.Rule = NAME | "(" + fplist + ")"; //fplist: fpdef (',' fpdef)* [','] fplist.Rule = fpdef.Plus(comma) + commaQ; //stmt: simple_stmt | compound_stmt stmt.Rule = simple_stmt | compound_stmt; //simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE simple_stmt.Rule = small_stmt.Plus(semicolon) + semicolon.Q() + NEWLINE; /* small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt) */ small_stmt.Rule = expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt; /* expr_stmt: testlist (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist))*) */ //Note!: the following is a less strict expression, it allows augassign to appear multiple times // in non-first position; the after-parse analysis should catch this expr_stmt.Rule = testlist + WithStar( (augassign|"=") + yield_or_testlist); yield_or_testlist.Rule = yield_expr | testlist; /* augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') */ augassign.Rule = Symbol("+=") | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "**=" | "//="; //# For normal assignments, additional restrictions enforced by the interpreter /* print_stmt: 'print' ( [ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ] ) */ print_stmt.Rule = "print" + (Empty | testlist | ">>" + testlist); //modified slightly using testlist //del_stmt: 'del' exprlist del_stmt.Rule = "del" + exprlist; //pass_stmt: 'pass' pass_stmt.Rule = "pass"; //flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt flow_stmt.Rule = break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt; //break_stmt: 'break' break_stmt.Rule = "break"; // continue_stmt: 'continue' continue_stmt.Rule = "continue"; // return_stmt: 'return' [testlist] return_stmt.Rule = "return" + testlist.Q(); // yield_stmt: yield_expr yield_stmt.Rule = yield_expr; // raise_stmt: 'raise' [test [',' test [',' test]]] raise_stmt.Rule = "raise" + WithQ( test + WithQ("," + test + WithQ("," + test))); // import_stmt: import_name | import_from import_stmt.Rule = import_name | import_from; // import_name: 'import' dotted_as_names import_name.Rule = "import" + dotted_as_names; // import_from: ('from' ('.'* dotted_name | '.'+) // 'import' ('*' | '(' import_as_names ')' | import_as_names)) // import_from.Expression = Symbol("from") + (dot.Star() + dotted_name | dot.Plus()) + //ambiguious import_from.Rule = Symbol("from") + dot.Star() + (dotted_name | dot) + "import" + (Symbol("*") | "(" + import_as_names + ")" | import_as_names); // import_as_name: NAME ['as' NAME] import_as_name.Rule = NAME + WithQ("as" + NAME); // dotted_as_name: dotted_name ['as' NAME] dotted_as_name.Rule = dotted_name + WithQ("as" + NAME); // import_as_names: import_as_name (',' import_as_name)* [','] import_as_names.Rule = import_as_name.Plus(comma) + commaQ; // dotted_as_names: dotted_as_name (',' dotted_as_name)* dotted_as_names.Rule = dotted_as_name.Plus(comma); // dotted_name: NAME ('.' NAME)* dotted_name.Rule = NAME.Plus(dot); // global_stmt: 'global' NAME (',' NAME)* global_stmt.Rule = "global" + NAME.Plus(comma); // exec_stmt: 'exec' expr ['in' test [',' test]] exec_stmt.Rule = "exec" + expr + WithQ("in" + test.Plus(comma)); // assert_stmt: 'assert' test [',' test] assert_stmt.Rule = "assert" + test.Plus(comma); // compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef compound_stmt.Rule = if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef; // if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] if_stmt.Rule = "if" + test + ":" + suite + WithStar("elif" + test + ":" + suite) + else_clause.Q(); else_clause.Rule = "else" + colon + suite; // while_stmt: 'while' test ':' suite ['else' ':' suite] while_stmt.Rule = "while" + test + ":" + suite + else_clause.Q(); // for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] for_stmt.Rule = "for" + exprlist + "in" + testlist + ":" + suite + else_clause.Q(); /* try_stmt: ('try' ':' suite ((except_clause ':' suite)+ ['else' ':' suite] ['finally' ':' suite] | 'finally' ':' suite)) */ try_stmt.Rule = "try" + colon + suite + ( (except_clause + ":" + suite)+ else_clause.Q() + finally_block.Q() | finally_block ); finally_block.Rule = "finally" + colon + suite; // with_stmt: 'with' test [ with_var ] ':' suite with_stmt.Rule = "with" + test + with_var.Q() + ":" + suite; // with_var: 'as' expr with_var.Rule = "as" + expr; // NB compile.c makes sure that the default except clause is last // except_clause: 'except' [test [('as' | ',') test]] except_clause.Rule = "except" + WithQ(test + WithQ( (Symbol("as") | ",") + test)); // suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT suite.Rule = simple_stmt | NEWLINE + INDENT + stmt.Plus() + DEDENT; //# Backward compatibility cruft to support: //# [ x for x in lambda: True, lambda: False if x() ] //# even while also allowing: //# lambda x: 5 if x else 2 //# (But not a mix of the two) // testlist_safe: old_test [(',' old_test)+ [',']] testlist_safe.Rule = old_test.Plus(comma) + commaQ; // old_test: or_test | old_lambdef old_test.Rule = or_test | old_lambdef; // old_lambdef: 'lambda' [varargslist] ':' old_test old_lambdef.Rule = "lambda" + varargslist.Q() + ":" + old_test; // test: or_test ['if' or_test 'else' test] | lambdef test.Rule = or_test + WithQ("if" + or_test + "else" + test) | lambdef; // or_test: and_test ('or' and_test)* or_test.Rule = and_test + WithStar("or" + and_test); // and_test: not_test ('and' not_test)* and_test.Rule = not_test + WithStar("and" + not_test); // not_test: 'not' not_test | comparison not_test.Rule = "not" + not_test | comparison; // comparison: expr (comp_op expr)* comparison.Rule = expr + WithStar(comp_op + expr); // comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' comp_op.Rule = Symbol("<")|">"|"=="|">="|"<="|"<>"|"!="|"in"| Symbol("not") + "in"|"is"|Symbol("is") + "not"; // expr: xor_expr ('|' xor_expr)* expr.Rule = xor_expr.Plus(Symbol("|")); // xor_expr: and_expr ('^' and_expr)* xor_expr.Rule = and_expr.Plus(Symbol("^")); // and_expr: shift_expr ('&' shift_expr)* and_expr.Rule = shift_expr.Plus(Symbol("&")); // shift_expr: arith_expr (('<<'|'>>') arith_expr)* shift_expr.Rule = arith_expr.Plus(shift_op); // shift_op.Rule = Symbol("<<")|">>"; // arith_expr: term (('+'|'-') term)* arith_expr.Rule = term.Plus(sum_op); sum_op.Rule = Symbol("+") | "-"; // term: factor (('*'|'/'|'%'|'//') factor)* term.Rule = factor.Plus(mul_op); mul_op.Rule = Symbol("*")|"/"|"%"|"//"; // factor: ('+'|'-'|'~') factor | power factor.Rule = (Symbol("+")|"-"|"~") + factor | power; // power: atom trailer* ['**' factor] power.Rule = atom + trailer.Star() + WithQ("**" + factor); /* atom: ('(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+) */ atom.Rule = "(" + WithQ(yield_expr|testlist_gexp) + ")" | "[" + listmaker.Q() + "]" | "{" + dictmaker.Q() + "}" | "`" + testlist1 + "`" | NAME | NUMBER | STRING; //.Plus(); //removed "+" - seems strange at least // listmaker: test ( list_for | (',' test)* [','] ) // listmaker.Expression = test + ( list_for | WithStar("," + test) + commaQ ); // ambigouous // listmaker.Expression = test + list_for.Q() | testlist; // modified version listmaker.Rule = test + list_for.Q() + testlist.Q() + commaQ; // modified version // testlist_gexp: test ( gen_for | (',' test)* [','] ) // testlist_gexp.Expression = test + ( gen_for | test.Star(comma) + commaQ ); // ambiguous testlist_gexp.Rule = test + gen_for | test.Plus(comma) + commaQ; // modified version // lambdef: 'lambda' [varargslist] ':' test lambdef.Rule = "lambda" + varargslist.Q() + ":" + test; // trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME trailer.Rule = "(" + arglist.Q() + ")" | "[" + subscriptlist + "]" | "." + NAME; // subscriptlist: subscript (',' subscript)* [','] subscriptlist.Rule = subscript.Plus(comma) + commaQ; // subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop] subscript.Rule = "..." | test | test.Q() + ":" + test.Q() + sliceop.Q(); // sliceop: ':' [test] sliceop.Rule = ":" + test.Q(); // exprlist: expr (',' expr)* [','] exprlist.Rule = expr.Plus(comma) + commaQ; // testlist: test (',' test)* [','] testlist.Rule = test.Plus(comma) + commaQ; // dictmaker: test ':' test (',' test ':' test)* [','] dictmaker.Rule = dict_elem.Plus(comma) + commaQ; dict_elem.Rule = test + ":" + test; // classdef: 'class' NAME ['(' [testlist] ')'] ':' suite classdef.Rule = "class" + NAME + WithQ("(" + testlist.Q() + ")") + ":" + suite; // arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test) arglist.Rule = WithStar(argument + comma) + (argument + commaQ | "*" + test + WithQ(comma + "**" + test) | "**" + test); // argument: test [gen_for] | test '=' test # Really [keyword '='] test argument.Rule = test + gen_for.Q() | test + "=" + test; //# Really [keyword "="] test // list_iter: list_for | list_if list_iter.Rule = list_for | list_if; // list_for: 'for' exprlist 'in' testlist_safe [list_iter] list_for.Rule = "for" + exprlist + "in" + testlist_safe + list_iter.Q(); // list_if: 'if' old_test [list_iter] list_if.Rule = "if" + old_test + list_iter.Q(); // gen_iter: gen_for | gen_if gen_iter.Rule = gen_for | gen_if; // gen_for: 'for' exprlist 'in' or_test [gen_iter] gen_for.Rule = "for" + exprlist + "in" + or_test + gen_iter.Q(); // gen_if: 'if' old_test [gen_iter] gen_if.Rule = "if" + old_test + gen_iter.Q(); // testlist1: test (',' test)* testlist1.Rule = test.Plus(comma); // # not used in grammar, but may appear in "node" passed from Parser to Compiler // encoding_decl: NAME encoding_decl.Rule = NAME; // yield_expr: 'yield' [testlist] yield_expr.Rule = "yield" + testlist.Q(); #endregion RegisterPunctuation( "(", ")", ",", ":" ); TokenFilters.Add(new CodeOutlineFilter(true)); id.AddKeywords("and", "del", "from", "not", "while", "as", "elif", "global", "or", "with", "assert", "else", "if", "pass", "yield", "break", "except", "import", "print", "class", "exec", "in", "raise", "continue", "finally", "is", "return", "def", "for", "lambda", "try"); }