Skip to content

Commit

Permalink
bugfix issue #332
Browse files Browse the repository at this point in the history
  • Loading branch information
b3b00 committed Dec 30, 2022
1 parent 8d09fbe commit 93e678b
Show file tree
Hide file tree
Showing 5 changed files with 289 additions and 1 deletion.
131 changes: 131 additions & 0 deletions ParserTests/Issue332/Issue332Parser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
using System.Collections.Generic;
using sly.lexer;
using sly.parser.generator;
using sly.parser.parser;

namespace ParserTests.Issue332;


[ParserRoot("root")]
public class Issue332Parser
{
[Production("root: statement*")]
public object Root(List<object> statement) => "foo";

[Production("statement: LPAREN statement RPAREN")]
public object BOLCK1(Token<Issue332Token> l, object statement, Token<Issue332Token> r) =>
null;



#region expr

[Operation((int) Issue332Token.LESSER, Affix.InFix, Associativity.Right, 50)]
[Operation((int) Issue332Token.GREATER, Affix.InFix, Associativity.Right, 50)]
[Operation((int) Issue332Token.EQUALS, Affix.InFix, Associativity.Right, 50)]
[Operation((int) Issue332Token.DIFFERENT, Affix.InFix, Associativity.Right, 50)]
public object binaryComparisonExpression(object left, Token<Issue332Token> operatorToken,
object right) => null;

[Operation((int)Issue332Token.CONCAT, Affix.InFix, Associativity.Right, 100)]
public object DotExpr(object left, Token<Issue332Token> oper, object right) => null
;

[Operation((int)Issue332Token.PLUS, Affix.InFix, Associativity.Right, 20)]
[Operation((int)Issue332Token.MINUS, Affix.InFix, Associativity.Right, 20)]
public object BE1(object left, Token<Issue332Token> oper, object right) => null
;

[Operation((int)Issue332Token.TIMES, Affix.InFix, Associativity.Right, 70)]
[Operation((int)Issue332Token.DIVIDE, Affix.InFix, Associativity.Right, 70)]
public object BE2(object left, Token<Issue332Token> oper, object right) => null;

[Operation((int)Issue332Token.AND, Affix.InFix, Associativity.Right, 50)]
[Operation((int)Issue332Token.OR, Affix.InFix, Associativity.Right, 50)]
[Operation((int)Issue332Token.XOR, Affix.InFix, Associativity.Right, 50)]
public object Bool1(object left, Token<Issue332Token> oper, object right) => null;


[Operation((int)Issue332Token.NOT, Affix.PreFix, Associativity.Right, 100)]
public object Bool2(Token<Issue332Token> oper, object expr) => null;

[Operation((int)Issue332Token.MINUS, Affix.PreFix, Associativity.Right, 100)]
public object MINUS(Token<Issue332Token> oper, object expr) => null;


#endregion

#region primany

[Operand]
[Production("operand: primary")]
public object Operand(object prim) => prim;

[Production("primary: LPAREN primary RPAREN")]
public object LR(Token<Issue332Token> l, object prim, Token<Issue332Token> r) =>
prim as object;

[Production("primary: STRING")]
public object STRING(Token<Issue332Token> token) => null;

[Production("primary: INT")]
public object INT(Token<Issue332Token> token) => null;

[Production("primary: CHAR")]
public object CHAR(Token<Issue332Token> token) => null;

[Production("primary: DOUBLE")]
public object DOUBLE(Token<Issue332Token> token) => null ;

[Production("primary: Issue332Parser_expressions")]
public object Bool(object expr) => null;


[Production("primary: IDENTFIER")]
public object IDENTIFIER(Token<Issue332Token> id) => null;

[Production("primary: TRUE")]
public object BoolTrue(Token<Issue332Token> token) => null;

[Production("primary: FALSE")]
public object BoolFalse(Token<Issue332Token> token) => null;

#endregion



[Production("set: IDENTFIER SET[d] Issue332Parser_expressions")]
public object Set( Token<Issue332Token> id, object value) => null;

[Production("statement: set")]
public object SET(object a) => null;

[Production("statement : IF[d] ifblock (ELIF ifblock)* (ELSE block)?")]
public object IF(object ifBlock, List<Group<Issue332Token, object>> elif,
ValueOption<Group<Issue332Token, object>> Else) => null;

[Production("ifblock: Issue332Parser_expressions block")]
public object IFBLOCK(object a, object block) => null;

[Production("block: INDENT[d] statement* UINDENT[d]")]
public object Block(List<object> statements) => null;

[Production("statement: FOR set Issue332Parser_expressions statement block")]
public object FOR(Token<Issue332Token> a, object set, object expr, object statement, object block) =>null;

[Production("statement: WHILE Issue332Parser_expressions block")]
public object WHILE(Token<Issue332Token> a, object expr, object block) => null;

[Production("statement: IDENTFIER DIRECT[d] IDENTFIER")]
public object DIRECT(Token<Issue332Token> id1, Token<Issue332Token> id2) => null;

[Production("statement: FUNC[d] IDENTFIER LPAREN[d] RPAREN[d] block")]
public object STAT_FUNC( Token<Issue332Token> id, object block) => null;

[Production("statement: CLASS[d] IDENTFIER set*")]
public object CLASS(Token<Issue332Token> id, List<object> sets) => null;

[Production("statement: IDENTFIER SET[d] IDENTFIER LPAREN RPAREN")]
public object INSTANTIATE(Token<Issue332Token> id, Token<Issue332Token> a, Token<Issue332Token> otherid, Token<Issue332Token> b,
Token<Issue332Token> c) => null;
}
29 changes: 29 additions & 0 deletions ParserTests/Issue332/Issue332Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using NFluent;
using ParserTests.Issue311;
using sly.buildresult;
using sly.lexer;
using sly.parser;
using sly.parser.generator;
using Xunit;

namespace ParserTests.Issue332;

public class Issue332Tests
{
[Fact]
public void TestIssue328()
{
ParserBuilder<Issue332Token, object> Parser = new ParserBuilder<Issue332Token, object>();
Issue332Parser oparser = new Issue332Parser();
var r = Parser.BuildParser(oparser,ParserType.EBNF_LL_RECURSIVE_DESCENT);
Check.That(r).Not.IsOk();
Check.That(r.Errors).Not.IsEmpty();
var error = r.Errors.First();
Check.That(error.Code).IsEqualTo(ErrorCodes.PARSER_LEFT_RECURSIVE);

}

}
102 changes: 102 additions & 0 deletions ParserTests/Issue332/Issue332Token.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using sly.lexer;

namespace ParserTests.Issue332;

[Lexer(IndentationAWare = true)]
public enum Issue332Token
{
[Lexeme(GenericToken.KeyWord, "IF")] [Lexeme(GenericToken.KeyWord, "if")]
IF = 1,

[Lexeme(GenericToken.KeyWord, "ELIF")] [Lexeme(GenericToken.KeyWord, "elif")]
ELIF = 2,

[Lexeme(GenericToken.KeyWord, "ELSE")] [Lexeme(GenericToken.KeyWord, "else")]
ELSE = 3,

[Lexeme(GenericToken.KeyWord, "WHILE")] [Lexeme(GenericToken.KeyWord, "while")]
WHILE = 4,

[Lexeme(GenericToken.KeyWord, "FOR")] [Lexeme(GenericToken.KeyWord, "for")]
FOR = 5,

[Lexeme(GenericToken.KeyWord, "TRUE")] [Lexeme(GenericToken.KeyWord, "true")]
TRUE = 6,

[Lexeme(GenericToken.KeyWord, "FALSE")] [Lexeme(GenericToken.KeyWord, "false")]
FALSE = 7,

[Lexeme(GenericToken.KeyWord, "NOT")] [Lexeme(GenericToken.KeyWord, "not")]
NOT = 8,

[Lexeme(GenericToken.KeyWord, "AND")] [Lexeme(GenericToken.KeyWord, "and")]
AND = 9,

[Lexeme(GenericToken.KeyWord, "OR")] [Lexeme(GenericToken.KeyWord, "or")]
OR = 10,

[Lexeme(GenericToken.KeyWord,"XOR")][Lexeme(GenericToken.KeyWord,"xor")]
XOR = 11,

[Sugar("//")]
ANNOTATION = 12,
//[Lexeme(GenericToken.KeyWord, "CLASS")] [Lexeme(GenericToken.KeyWord, "print")]
//PRINT = 12,

[Sugar("\n")]
HUANHANG = 13,

[Lexeme(GenericToken.KeyWord,"CLASS")][Lexeme(GenericToken.KeyWord,"class")]
CLASS = 14,

[Lexeme(GenericToken.KeyWord,"FUNC")][Lexeme(GenericToken.KeyWord,"func")]
FUNC = 15,

#region literals 20 -> 29
[Lexeme(GenericToken.Identifier)] IDENTFIER = 20,
[Lexeme(GenericToken.String)] STRING = 21,
[Lexeme(GenericToken.Int)] INT = 22,
[Lexeme(GenericToken.Double)] DOUBLE = 23,
[Lexeme(GenericToken.Char)] CHAR = 24,
#endregion

#region operators 30 -> 49

[Sugar("<-")] SET = 40,

[Sugar("->")] DIS_SET = 41,

[Sugar( ">")] GREATER = 30,

[Sugar( "<")] LESSER = 31,

[Sugar( "==")] EQUALS = 32,

[Sugar( "!=")] DIFFERENT = 33,

[Sugar( ".")] CONCAT = 34,

[Sugar( "-*")] DIRECT = 35,

[Sugar("*-")] DIS_DIRECT = 43,

[Sugar( "+")] PLUS = 36,

[Sugar( "-")] MINUS = 37,

[Sugar( "*")] TIMES = 38,

[Sugar( "/")] DIVIDE = 39,

#endregion

#region sugar 50 ->

[Sugar( "(")] LPAREN = 50,

[Sugar( ")")] RPAREN = 51,

EOF = 0

#endregion
}
18 changes: 17 additions & 1 deletion samples/ParserExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
using indented;
using jsonparser;
using jsonparser.JsonModel;
using NFluent;
using ParserTests;
using ParserTests.Issue239;
using ParserTests.Issue332;
using ParserTests.lexer;
using simpleExpressionParser;
using SimpleTemplate;
Expand Down Expand Up @@ -1134,7 +1136,8 @@ private static void TestTemplateFor()

private static void Main(string[] args)
{
TestTemplateFor();
TestIssue332();
//TestTemplateFor();
// testErrors();
//TestContextualParser();
//TestTokenCallBacks();
Expand Down Expand Up @@ -1300,6 +1303,19 @@ private static void TestIssue239()
;
}

private static void TestIssue332()
{
ParserBuilder<Issue332Token, object> Parser = new ParserBuilder<Issue332Token, object>();
Issue332Parser oparser = new Issue332Parser();
var r = Parser.BuildParser(oparser,ParserType.EBNF_LL_RECURSIVE_DESCENT);
Check.That(r).Not.IsOk();
foreach (var error in r.Errors)
{
Console.WriteLine(error.Message);
}

}

private static List<Token<ExpressionToken>> postProcess(List<Token<ExpressionToken>> tokens)
{
var mayLeft = new List<ExpressionToken>()
Expand Down
10 changes: 10 additions & 0 deletions sly/parser/generator/ExpressionRulesGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ public BuildResult<ParserConfiguration<IN, OUT>> BuildExpressionRules(

configuration.UsesOperations = operationsByPrecedence.Any<KeyValuePair<int, List<OperationMetaData<IN>>>>();
result.Result = configuration;
var rec = LeftRecursionChecker<IN, OUT>.CheckLeftRecursion(configuration);
if (rec.foundRecursion)
{
var recs = string.Join("\n", rec.recursions.Select<List<string>, string>(x => string.Join(" > ",x)));
result.AddError(new ParserInitializationError(ErrorLevel.FATAL,
I18N.Instance.GetText(I18n,I18NMessage.LeftRecursion,recs),
ErrorCodes.PARSER_LEFT_RECURSIVE));
return result;
}

return result;
}

Expand Down

0 comments on commit 93e678b

Please sign in to comment.