Permalink
Browse files

Better error messages. Closes #4

  • Loading branch information...
1 parent 2fff408 commit 2b1312f9f8ff05a2d06ca38416d51cb926bd6069 @rampelstinskin committed Feb 15, 2012
View
@@ -166,25 +166,43 @@ module Program
match (parser.ParseStart(code))
{
| None =>
- WriteLine($"Fail: \"$code\"");
- def (pos, rules) = parser.Parser.GetErrors();
+ WriteLine($"Fail:\n\"$code\"");
+ def (pos, tokens) = parser.Parser.GetErrors();
def (line, pos) = parser.ParsingSource.PositionToLineColumn(pos);
- foreach (rule in rules)
- WriteLine($" $line:$pos $(rule.Grammar.Name).$(rule.Name)");
+ foreach (token in tokens)
+ WriteLine($" $line:$pos expected \"$(token.Name)\" in rule $(token.Rule.Grammar.Name).$(token.Rule.Name)");
+
| Some(ast) =>
//WriteLine($"Ok: \"$code\" AST: $(printAst(ast))");
_ = ast;
- WriteLine("OK");
+ WriteLine($"OK:\n\"$code\"");
}
+ WriteLine();
}
test(<#
namespace Ns1
{
+ using N2ParserExtensions.N2ParserExtension1
+ type X - A.B;
+}
+ #>);
+
+ test(<#
+namespace Ns1
+{
+ using N2ParserExtensions.N2ParserExtension1;
+ type X - A.B;
+}
+ #>);
+
+ test(<#
+namespace Ns1
+{
using N2ParserExtensions.N2ParserExtension1;
type X = A.B;
}
#>);
- _ = ReadLine();
+ _ = ReadKey();
}
}
@@ -14,6 +14,14 @@ namespace Nemerle.Parser
{
partial internal class GrammarCompiler
{
+ private _tokenDescriptors : Hashtable[RuleDefinition, list[string]] = Hashtable();
+ [Memoize]
+ public GetTokenDescriptor(name : string, rd : RuleDefinition) : PExpr
+ {
+ _ = _tokenDescriptors.Update(rd, [], names => name :: names);
+ <[ $(GrammarImplTB.Name : dyn).$(GrammarDescriptorImplTB.Name : dyn).$(DecorateRuleClassName(rd) : dyn).$($"_token_$(name)_" : dyn) ]>
+ }
+
public DefineDescriptors() : void
{
foreach (rd in ParsedGrammar.Rules)
@@ -31,6 +39,9 @@ namespace Nemerle.Parser
}
]>;
def tb = GrammarDescriptorImplTB.DefineNestedType(descriptorClass);
+ when (_tokenDescriptors.Contains(rd))
+ foreach (name in _tokenDescriptors[rd])
+ tb.Define(<[decl: public static $($"_token_$(name)_" : dyn) : Nemerle.Parser.TokenDescriptor = Nemerle.Parser.TokenDescriptor(_staticDescriptor, $(name : string)) ]>);
match (GetRuleType(rd.Name))
{
| RuleType.NType(type) => tb.Define(<[decl: public ResultType() : $(type : typed) { mutable res; res } ]>)
@@ -16,7 +16,20 @@ namespace Nemerle.Parser
{
private DefineParsingErrors() : void
{
- def rules = ParsedGrammar.Rules.Filter(rd => !(rd is RuleDefinition.ExternalRule));
+ def rules = ParsedGrammar.Rules.Filter(rd =>
+ match (rd : RuleDefinition)
+ {
+ | ExtentionPoint
+ | Regular
+ | ExternalRule
+ => false
+
+ | ExtentionPrefix
+ | ExtentionPostfix
+ | Simple
+ => true
+ });
+
def getErrors = rules.Map(rd =>
{
def name = DecorateRuleName(rd);
@@ -27,13 +40,13 @@ namespace Nemerle.Parser
descriptors.Clear();
}
when (pos == $(name : dyn))
- descriptors.Add(GrammarDescriptorImpl.$(DecorateRuleClassName(rd) : dyn).StaticDescriptor);
+ descriptors.Add($(DecorateTokenDescriptor(rd) : dyn));
]>
});
- def clear = rules.Map(rd => <[ $(DecorateRuleName(rd) : dyn) = -1; ]>);
+ def clear = rules.Map(rd => <[ $(DecorateRuleName(rd) : dyn) = -2; $(DecorateTokenDescriptor(rd) : dyn) = null; ]>);
_ = ParsingErrorsTB.DefineWithSource(<[decl:
- public override GetErrors(pos : ref int, descriptors : SCG.List[RuleDescriptor]) : void
+ public override GetErrors(pos : ref int, descriptors : SCG.List[Nemerle.Parser.TokenDescriptor]) : void
{
_ = pos;
_ = descriptors;
@@ -49,7 +62,10 @@ namespace Nemerle.Parser
]>);
foreach (rd in rules)
+ {
_ = ParsingErrorsTB.DefineWithSource(<[decl: public mutable $(DecorateRuleName(rd) : dyn) : int ]>);
+ _ = ParsingErrorsTB.DefineWithSource(<[decl: public mutable $(DecorateTokenDescriptor(rd) : dyn) : Nemerle.Parser.TokenDescriptor ]>);
+ }
}
}
}
@@ -25,6 +25,11 @@ namespace Nemerle.Parser
DecorateRuleName(rd.Name)
}
+ public DecorateTokenDescriptor(rd : RuleDefinition) : string
+ {
+ DecorateRuleName(rd.Name) + "_token_descriptor_"
+ }
+
public DecorateRuleClassName(rd : RuleDefinition) : string
{
match (rd)
@@ -32,8 +32,7 @@ namespace Nemerle.Parser
if (newPos > 0)
$setResult;
else
- when (_grammar._parsingErrors.$(_grammarCompiller.DecorateRuleName(rd) : dyn) < pos)
- _grammar._parsingErrors.$(_grammarCompiller.DecorateRuleName(rd) : dyn) = pos;
+ $(SetParsingErrorCode($"#$(rd.Name)"));
newPos;
]>)
}
@@ -31,8 +31,7 @@ namespace Nemerle.Parser
if (newPos > 0)
$setResult;
else
- when (_grammar._parsingErrors.$(_grammarCompiller.DecorateRuleName(rd) : dyn) < pos)
- _grammar._parsingErrors.$(_grammarCompiller.DecorateRuleName(rd) : dyn) = pos;
+ $(SetParsingErrorCode($"#$(rd.Name)"));
newPos
]>)
}
@@ -28,7 +28,15 @@ namespace Nemerle.Parser
def exprs = rule.str.Select(makeCharCheckCode);
def condExpr = exprs.Aggregate((e1, e2) => <[ $e1 && $e2 ]>);
- <[ if ($check < text.Length && $condExpr) pos + $(len : int) else -1 ]>
+ <[
+ if ($check < text.Length && $condExpr)
+ pos + $(len : int)
+ else
+ {
+ $(SetParsingErrorCode(rule.str));
+ -1
+ }
+ ]>
}
else
<[ pos ]>
@@ -45,8 +45,7 @@ namespace Nemerle.Parser
$(names.Result : dyn) = result;
}
else
- when (_parsingErrors.$(_grammarCompiller.DecorateRuleName(rd) : dyn) < pos)
- _parsingErrors.$(_grammarCompiller.DecorateRuleName(rd) : dyn) = pos;
+ $(SetParsingErrorCode($"#$(rd.Name)"));
newPos
}
@@ -0,0 +1,36 @@
+using Nemerle.Collections;
+using Nemerle.Text;
+using Nemerle.Utility;
+using Nemerle.Compiler;
+using Nemerle.Compiler.Parsetree;
+using Nemerle.Compiler.Typedtree;
+
+using System;
+using System.Linq;
+using SCG = System.Collections.Generic;
+
+namespace Nemerle.Parser
+{
+ partial internal class RuleCompiler
+ {
+ public SetParsingErrorCode(name : string) : PExpr
+ {
+ def isSimple = _ruleDefinition is RuleDefinition.Simple;
+ def (posName, tokenName) = if (isSimple)
+ ( <[ _parsingErrors.$(_grammarCompiller.DecorateRuleName(_ruleDefinition) : dyn) ]>
+ , <[ _parsingErrors.$(_grammarCompiller.DecorateTokenDescriptor(_ruleDefinition) : dyn) ]>
+ )
+ else
+ ( <[ _grammar._parsingErrors.$(_grammarCompiller.DecorateRuleName(_ruleDefinition) : dyn) ]>
+ , <[ _grammar._parsingErrors.$(_grammarCompiller.DecorateTokenDescriptor(_ruleDefinition) : dyn) ]>
+ );
+ <[
+ when ($posName < pos)
+ {
+ $posName = pos;
+ $tokenName = $(_grammarCompiller.GetTokenDescriptor(name, _ruleDefinition));
+ }
+ ]>
+ }
+ }
+}
@@ -254,6 +254,9 @@
<Compile Include="Compiler\RuleCompiler\MakeHandlerCall.n">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Compiler\RuleCompiler\SetParsingErrorCode.n">
+ <SubType>Code</SubType>
+ </Compile>
<Compile Include="Compiler\RuleCompiler\TestCharConditionCode.n">
<SubType>Code</SubType>
</Compile>
@@ -0,0 +1,18 @@
+using Nemerle;
+using Nemerle.Collections;
+using Nemerle.Text;
+using Nemerle.Utility;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Nemerle.Parser
+{
+ [Record]
+ public class TokenDescriptor
+ {
+ public Rule : RuleDescriptor { get; }
+ public Name : string { get; }
+ }
+}
@@ -60,7 +60,7 @@ namespace Nemerle.Parser.Internal
}
}
- public GetErrors() : int * SCG.List[RuleDescriptor]
+ public GetErrors() : int * SCG.List[TokenDescriptor]
{
mutable pos = -1;
def rules = SCG.List();
@@ -11,7 +11,7 @@ namespace Nemerle.Parser.Internal
{
public abstract class ParsingErrors
{
- public abstract GetErrors(pos : ref int, descriptors : SCG.List[RuleDescriptor]) : void;
+ public abstract GetErrors(pos : ref int, descriptors : SCG.List[TokenDescriptor]) : void;
public abstract Clear() : void;
}
}
@@ -67,6 +67,9 @@
<Compile Include="Descriptors\RuleDescriptor.n">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Descriptors\TokenDescriptor.n">
+ <SubType>Code</SubType>
+ </Compile>
<Compile Include="GrammarsAttribute.n">
<SubType>Code</SubType>
</Compile>
View
@@ -76,9 +76,11 @@ module Program
{
| None =>
WriteLine($"Fail: \"$text\"");
- def (pos, rules) = parser.Parser.GetErrors();
- foreach (rule in rules)
- WriteLine($" $pos $(rule.Grammar.Name).$(rule.Name)");
+ def (pos, tokens) = parser.Parser.GetErrors();
+ def (line, pos) = parser.ParsingSource.PositionToLineColumn(pos);
+ foreach (token in tokens)
+ WriteLine($" $line:$pos expected \"$(token.Name)\" in rule $(token.Rule.Grammar.Name).$(token.Rule.Name)");
+
| Some(ast) =>
def printAst(ast : ExprAst)
{

0 comments on commit 2b1312f

Please sign in to comment.