From eef386427863e27a40cb22a424ddb5ceeb6c7a56 Mon Sep 17 00:00:00 2001 From: Mike Mazur Date: Thu, 31 Jul 2008 01:27:33 +0000 Subject: Fix issue 1860; exception thrown in the parser on if/if-else/for/while/do-while statements with no body. --- .../DotNetEngine/Compiler/LSL/CSCodeGenerator.cs | 14 ++- .../DotNetEngine/Compiler/LSL/lsl.parser.cs | 10 +- .../Shared/CodeTools/CSCodeGenerator.cs | 14 ++- .../ScriptEngine/Shared/CodeTools/lsl.parser.cs | 10 +- .../Shared/CodeTools/CSCodeGeneratorTest.cs | 125 +++++++++++++++++++++ 5 files changed, 153 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs index f129859..631aa54 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs @@ -388,14 +388,18 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL private string GenerateStatement(Statement s) { string retstr = String.Empty; - - // Jump label prints its own colon, we don't need a semicolon. - bool printSemicolon = !(s.kids.Top is JumpLabel); + bool printSemicolon = true; retstr += Indent(); - foreach (SYMBOL kid in s.kids) - retstr += GenerateNode(kid); + if (0 < s.kids.Count) + { + // Jump label prints its own colon, we don't need a semicolon. + printSemicolon = !(s.kids.Top is JumpLabel); + + foreach (SYMBOL kid in s.kids) + retstr += GenerateNode(kid); + } if (printSemicolon) retstr += GenerateLine(";"); diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/lsl.parser.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/lsl.parser.cs index 178eed1..14c090d 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/lsl.parser.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/lsl.parser.cs @@ -359,7 +359,7 @@ public override int yynum { get { return 114; }} public StateChange(Parser yyp):base(yyp){}} //%+IfStatement+115 public class IfStatement : SYMBOL{ - private void AddStatement ( Statement s ){ if ( s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); + private void AddStatement ( Statement s ){ if (0< s . kids . Count && s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); else kids . Add ( s ); } public IfStatement (Parser yyp, Expression e , Statement ifs ):base(((LSLSyntax @@ -369,7 +369,7 @@ public class IfStatement : SYMBOL{ public IfStatement (Parser yyp, Expression e , Statement ifs , Statement es ):base(((LSLSyntax )yyp)){ kids . Add ( e ); AddStatement ( ifs ); - if ( es . kids . Top is IfStatement ) kids . Add ( es . kids . Pop ()); + if (0< es . kids . Count && es . kids . Top is IfStatement ) kids . Add ( es . kids . Pop ()); else AddStatement ( es ); } @@ -380,7 +380,7 @@ public IfStatement(Parser yyp):base(yyp){}} public class WhileStatement : SYMBOL{ public WhileStatement (Parser yyp, Expression e , Statement s ):base(((LSLSyntax )yyp)){ kids . Add ( e ); - if ( s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); + if (0< s . kids . Count && s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); else kids . Add ( s ); } @@ -390,7 +390,7 @@ public WhileStatement(Parser yyp):base(yyp){}} //%+DoWhileStatement+117 public class DoWhileStatement : SYMBOL{ public DoWhileStatement (Parser yyp, Expression e , Statement s ):base(((LSLSyntax -)yyp)){ if ( s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); +)yyp)){ if (0< s . kids . Count && s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); else kids . Add ( s ); kids . Add ( e ); } @@ -404,7 +404,7 @@ public class ForLoop : SYMBOL{ )yyp)){ kids . Add ( flsa ); kids . Add ( e ); kids . Add ( flsb ); - if ( s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); + if (0< s . kids . Count && s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); else kids . Add ( s ); } diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 3bdad4d..2226673 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs @@ -388,14 +388,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private string GenerateStatement(Statement s) { string retstr = String.Empty; - - // Jump label prints its own colon, we don't need a semicolon. - bool printSemicolon = !(s.kids.Top is JumpLabel); + bool printSemicolon = true; retstr += Indent(); - foreach (SYMBOL kid in s.kids) - retstr += GenerateNode(kid); + if (0 < s.kids.Count) + { + // Jump label prints its own colon, we don't need a semicolon. + printSemicolon = !(s.kids.Top is JumpLabel); + + foreach (SYMBOL kid in s.kids) + retstr += GenerateNode(kid); + } if (printSemicolon) retstr += GenerateLine(";"); diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs index e9b3886..9778245 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs @@ -359,7 +359,7 @@ public override int yynum { get { return 114; }} public StateChange(Parser yyp):base(yyp){}} //%+IfStatement+115 public class IfStatement : SYMBOL{ - private void AddStatement ( Statement s ){ if ( s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); + private void AddStatement ( Statement s ){ if (0< s . kids . Count && s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); else kids . Add ( s ); } public IfStatement (Parser yyp, Expression e , Statement ifs ):base(((LSLSyntax @@ -369,7 +369,7 @@ public class IfStatement : SYMBOL{ public IfStatement (Parser yyp, Expression e , Statement ifs , Statement es ):base(((LSLSyntax )yyp)){ kids . Add ( e ); AddStatement ( ifs ); - if ( es . kids . Top is IfStatement ) kids . Add ( es . kids . Pop ()); + if (0< es . kids . Count && es . kids . Top is IfStatement ) kids . Add ( es . kids . Pop ()); else AddStatement ( es ); } @@ -380,7 +380,7 @@ public IfStatement(Parser yyp):base(yyp){}} public class WhileStatement : SYMBOL{ public WhileStatement (Parser yyp, Expression e , Statement s ):base(((LSLSyntax )yyp)){ kids . Add ( e ); - if ( s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); + if (0< s . kids . Count && s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); else kids . Add ( s ); } @@ -390,7 +390,7 @@ public WhileStatement(Parser yyp):base(yyp){}} //%+DoWhileStatement+117 public class DoWhileStatement : SYMBOL{ public DoWhileStatement (Parser yyp, Expression e , Statement s ):base(((LSLSyntax -)yyp)){ if ( s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); +)yyp)){ if (0< s . kids . Count && s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); else kids . Add ( s ); kids . Add ( e ); } @@ -404,7 +404,7 @@ public class ForLoop : SYMBOL{ )yyp)){ kids . Add ( flsa ); kids . Add ( e ); kids . Add ( flsb ); - if ( s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); + if (0< s . kids . Count && s . kids . Top is CompoundStatement ) kids . Add ( s . kids . Pop ()); else kids . Add ( s ); } diff --git a/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGeneratorTest.cs b/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGeneratorTest.cs index 9547b0b..6e4d029 100644 --- a/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGeneratorTest.cs +++ b/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGeneratorTest.cs @@ -1395,6 +1395,131 @@ default } [Test] + public void TestWhileLoopWithNoBody() + { + string input = @"default +{ + state_entry() + { + while(1<0); + } +}"; + + string expected = @" + public void default_event_state_entry() + { + while (1 < 0) + ; + } +"; + + CSCodeGenerator cg = new CSCodeGenerator(); + string output = cg.Convert(input); + Assert.AreEqual(expected, output); + } + + [Test] + public void TestDoWhileLoopWithNoBody() + { + string input = @"default +{ + state_entry() + { + do; + while(1<0); + } +}"; + + string expected = @" + public void default_event_state_entry() + { + do + ; + while (1 < 0); + } +"; + + CSCodeGenerator cg = new CSCodeGenerator(); + string output = cg.Convert(input); + Assert.AreEqual(expected, output); + } + + [Test] + public void TestIfWithNoBody() + { + string input = @"default +{ + state_entry() + { + if(1<0); + } +}"; + + string expected = @" + public void default_event_state_entry() + { + if (1 < 0) + ; + } +"; + + CSCodeGenerator cg = new CSCodeGenerator(); + string output = cg.Convert(input); + Assert.AreEqual(expected, output); + } + + [Test] + public void TestIfElseWithNoBody() + { + string input = @"default +{ + state_entry() + { + if(1<0); + else; + } +}"; + + string expected = @" + public void default_event_state_entry() + { + if (1 < 0) + ; + else + ; + } +"; + + CSCodeGenerator cg = new CSCodeGenerator(); + string output = cg.Convert(input); + Assert.AreEqual(expected, output); + } + + [Test] + public void TestForLoopWithNoBody() + { + string input = @"default +{ + state_entry() + { + for(x = 4; 1<0; x += 2); + } +}"; + + string expected = @" + public void default_event_state_entry() + { + for (x = 4; 1 < 0; x += 2) + ; + } +"; + + CSCodeGenerator cg = new CSCodeGenerator(); + string output = cg.Convert(input); + Assert.AreEqual(expected, output); + } + + [Test] [ExpectedException("Tools.CSToolsException")] public void TestSyntaxError() { -- cgit v1.1