diff --git a/Irony.Samples/MyC/MyCGrammarExtended.cs b/Irony.Samples/MyC/MyCGrammarExtended.cs index 70b835e..6671945 100644 --- a/Irony.Samples/MyC/MyCGrammarExtended.cs +++ b/Irony.Samples/MyC/MyCGrammarExtended.cs @@ -7,7 +7,7 @@ namespace Demo { // Extended MyC Grammar. // For use in testing macros, conditional compilation, includes - [Language("My C", "1.0", "My C Programming Language")] + [Language("MyC-Extended", "1.0", "MyC Language, extended")] public class MyCGrammarExtended : Irony.Parsing.Grammar { public MyCGrammarExtended() { #region Declare Terminals Here diff --git a/Irony.Samples/Playground_Grammar.cs b/Irony.Samples/Playground_Grammar.cs index 501c98e..1dbf45c 100644 --- a/Irony.Samples/Playground_Grammar.cs +++ b/Irony.Samples/Playground_Grammar.cs @@ -8,28 +8,96 @@ using Irony.Interpreter.Ast; namespace Irony.Samples.TestBed { - public class HTMLGrammar : Irony.Parsing.Grammar { - public HTMLGrammar() { - KeyTerm leftAnguralBracket = new KeyTerm("<", "LeftAngularBarakcet"); - KeyTerm rightAnguralBracket = new KeyTerm(">", "RightAngularBarakcet"); - KeyTerm leftAngularBracketEndTag = new KeyTerm("", "RightAngularBracketEndTag"); - - - NonTerminal element = new NonTerminal("Element"); - NonTerminal emptyElementTag = new NonTerminal("EmptyElementTag"); - NonTerminal startTag = new NonTerminal("StartTag"); - NonTerminal content = new NonTerminal("Content"); - NonTerminal endTag = new NonTerminal("EndTag"); - RegexBasedTerminal name = new RegexBasedTerminal("Name", "\\w+"); - - element.Rule = emptyElementTag | startTag + content + endTag; - emptyElementTag.Rule = leftAnguralBracket + name + rightAngularBracketEndTag; - startTag.Rule = leftAnguralBracket + name + rightAnguralBracket; - endTag.Rule = leftAngularBracketEndTag + name + rightAnguralBracket; - content.Rule = MakeStarRule(content, element); - - this.Root = element; + [Language("QueryLanguage", "1.0", "A Query Language based on JET where clauses")] + public class QueryGrammar : Grammar { + + /// + /// Initializes a new instance of the class. + /// + 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; } } } diff --git a/Irony/Parsing/Scanner/SourceStream.cs b/Irony/Parsing/Scanner/SourceStream.cs index e80abf6..317395c 100644 --- a/Irony/Parsing/Scanner/SourceStream.cs +++ b/Irony/Parsing/Scanner/SourceStream.cs @@ -138,6 +138,8 @@ private void SetNewPosition(int newPosition) { int col = Location.Column; int line = Location.Line; while(p < newPosition) { + if (p >= _textLength) + break; var curr = _chars[p]; switch (curr) { case '\n': line++; col = 0; break; diff --git a/Microsoft.VisualStudio.TestTools.CppUnitTestFramework.CppUnitTestExtension.pdb/4B5DB1DDEF544449A37DD17CF9B843421/Microsoft.VisualStudio.TestTools.CppUnitTestFramework.CppUnitTestExtension.pdb b/Microsoft.VisualStudio.TestTools.CppUnitTestFramework.CppUnitTestExtension.pdb/4B5DB1DDEF544449A37DD17CF9B843421/Microsoft.VisualStudio.TestTools.CppUnitTestFramework.CppUnitTestExtension.pdb deleted file mode 100644 index 2192b9e..0000000 Binary files a/Microsoft.VisualStudio.TestTools.CppUnitTestFramework.CppUnitTestExtension.pdb/4B5DB1DDEF544449A37DD17CF9B843421/Microsoft.VisualStudio.TestTools.CppUnitTestFramework.CppUnitTestExtension.pdb and /dev/null differ