Skip to content

Commit 1b6d329

Browse files
committed
Better diagnostic output
Print the place in the code where the (ambiguous) parser error was emitted (currently only for GCC and MSVC)
1 parent 59cc67e commit 1b6d329

File tree

2 files changed

+49
-26
lines changed

2 files changed

+49
-26
lines changed

generator/parser/parser.cpp

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,28 @@
5252
#include <iostream>
5353
#include <vector>
5454

55+
#if defined(_MSC_VER) || defined(__GNUC__)
56+
#include <sstream>
57+
58+
std::string _joinLocation(const char* name, int line)
59+
{
60+
std::stringstream ss;
61+
ss << name << ":" << line;
62+
return ss.str();
63+
}
64+
65+
#define PARSER_METHOD_NAME _joinLocation(__FUNCTION__, __LINE__).c_str()
66+
#else
67+
#define PARSER_METHOD_NAME ""
68+
#endif
69+
70+
71+
#define SYNTAX_ERROR() syntaxError(PARSER_METHOD_NAME)
72+
5573
#define ADVANCE(tk, descr) \
5674
{ \
5775
if (token_stream.lookAhead() != tk) { \
58-
tokenRequiredError(tk); \
76+
tokenRequiredError(tk, PARSER_METHOD_NAME); \
5977
return false; \
6078
} \
6179
nextToken(); \
@@ -64,7 +82,7 @@
6482
#define ADVANCE_NR(tk, descr) \
6583
do { \
6684
if (token_stream.lookAhead() != tk) { \
67-
tokenRequiredError(tk); \
85+
tokenRequiredError(tk, PARSER_METHOD_NAME); \
6886
} \
6987
else \
7088
nextToken(); \
@@ -165,7 +183,7 @@ bool Parser::parseWinDeclSpec(WinDeclSpecAST *&node)
165183
return true;
166184
}
167185

168-
void Parser::tokenRequiredError(int token)
186+
void Parser::tokenRequiredError(int token, const char* functionName)
169187
{
170188
QString err;
171189

@@ -176,11 +194,10 @@ void Parser::tokenRequiredError(int token)
176194
err += token_name(token_stream.lookAhead());
177195
err += "''";
178196

179-
180-
reportError(err);
197+
reportError(err, functionName);
181198
}
182199

183-
void Parser::syntaxError()
200+
void Parser::syntaxError(const char* functionName)
184201
{
185202
QString err;
186203

@@ -189,10 +206,10 @@ void Parser::syntaxError()
189206
err += token_name(token_stream.lookAhead());
190207
err += "''";
191208

192-
reportError(err);
209+
reportError(err, functionName);
193210
}
194211

195-
void Parser::reportError(const QString& msg)
212+
void Parser::reportError(const QString& msg, const char* functionName)
196213
{
197214
if (!_M_block_errors)
198215
{
@@ -208,6 +225,10 @@ void Parser::reportError(const QString& msg)
208225
errmsg.setColumn(column);
209226
errmsg.setFileName(fileName);
210227
errmsg.setMessage(QLatin1String("** PARSER ERROR ") + msg);
228+
if (functionName && *functionName) {
229+
errmsg.setMessage(errmsg.message() + " in " + functionName);
230+
}
231+
211232
control->reportError(errmsg);
212233
}
213234
}
@@ -852,7 +873,7 @@ bool Parser::parseOperatorFunctionId(OperatorFunctionIdAST *&node)
852873

853874
if (!parseSimpleTypeSpecifier(ast->type_specifier))
854875
{
855-
syntaxError();
876+
SYNTAX_ERROR();
856877
return false;
857878
}
858879

@@ -886,7 +907,7 @@ bool Parser::parseTemplateArgumentList(const ListNode<TemplateArgumentAST*> *&no
886907
{
887908
if (reportError)
888909
{
889-
syntaxError();
910+
SYNTAX_ERROR();
890911
break;
891912
}
892913

@@ -1642,7 +1663,7 @@ bool Parser::parseTemplateParameterList(const ListNode<TemplateParameterAST*> *&
16421663

16431664
if (!parseTemplateParameter(param))
16441665
{
1645-
syntaxError();
1666+
SYNTAX_ERROR();
16461667
break;
16471668
}
16481669
else
@@ -1721,7 +1742,7 @@ bool Parser::parseTypeParameter(TypeParameterAST *&node)
17211742

17221743
if(!parseTypeId(ast->type_id))
17231744
{
1724-
//syntaxError();
1745+
//SYNTAX_ERROR();
17251746
rewind(start);
17261747
return false;
17271748
}
@@ -1758,7 +1779,7 @@ bool Parser::parseTypeParameter(TypeParameterAST *&node)
17581779

17591780
if (!parseTypeId(ast->type_id))
17601781
{
1761-
syntaxError();
1782+
SYNTAX_ERROR();
17621783
return false;
17631784
}
17641785
}
@@ -1857,7 +1878,7 @@ bool Parser::parseInitDeclaratorList(const ListNode<InitDeclaratorAST*> *&node)
18571878

18581879
if (!parseInitDeclarator(decl))
18591880
{
1860-
syntaxError();
1881+
SYNTAX_ERROR();
18611882
break;
18621883
}
18631884
node = snoc(node, decl, _M_pool);
@@ -2933,7 +2954,7 @@ bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
29332954
block_errors(blocked);
29342955

29352956
if (!node)
2936-
syntaxError();
2957+
SYNTAX_ERROR();
29372958

29382959
return node != 0;
29392960
}
@@ -3203,7 +3224,7 @@ bool Parser::parseSwitchStatement(StatementAST *&node)
32033224
StatementAST *stmt = 0;
32043225
if (!parseCompoundStatement(stmt))
32053226
{
3206-
syntaxError();
3227+
SYNTAX_ERROR();
32073228
return false;
32083229
}
32093230

@@ -3490,7 +3511,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node)
34903511
const ListNode<InitDeclaratorAST*> *declarators = 0;
34913512
if (!parseInitDeclaratorList(declarators))
34923513
{
3493-
syntaxError();
3514+
SYNTAX_ERROR();
34943515
return false;
34953516
}
34963517

@@ -3534,7 +3555,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node)
35343555
rewind(startDeclarator);
35353556
if (!parseInitDeclaratorList(declarators))
35363557
{
3537-
syntaxError();
3558+
SYNTAX_ERROR();
35383559
return false;
35393560
}
35403561
}
@@ -3546,7 +3567,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node)
35463567
TypeSpecifierAST* trailingReturnTypeSpec = 0;
35473568
if (!parseTypeSpecifier(trailingReturnTypeSpec)) {
35483569
// todo: replace "auto" return type? But I doubt we can handle these return types anyway.
3549-
syntaxError();
3570+
SYNTAX_ERROR();
35503571
return false;
35513572
}
35523573
maybeFunctionDefinition = true;
@@ -3575,7 +3596,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node)
35753596
{
35763597
if (!maybeFunctionDefinition)
35773598
{
3578-
syntaxError();
3599+
SYNTAX_ERROR();
35793600
return false;
35803601
}
35813602

@@ -3602,7 +3623,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node)
36023623
} // end switch
36033624
}
36043625

3605-
syntaxError();
3626+
SYNTAX_ERROR();
36063627
return false;
36073628
}
36083629

@@ -3670,7 +3691,7 @@ bool Parser::parseTryBlockStatement(StatementAST *&node)
36703691
StatementAST *stmt = 0;
36713692
if (!parseCompoundStatement(stmt))
36723693
{
3673-
syntaxError();
3694+
SYNTAX_ERROR();
36743695
return false;
36753696
}
36763697

@@ -3699,7 +3720,7 @@ bool Parser::parseTryBlockStatement(StatementAST *&node)
36993720
StatementAST *body = 0;
37003721
if (!parseCompoundStatement(body))
37013722
{
3702-
syntaxError();
3723+
SYNTAX_ERROR();
37033724
return false;
37043725
}
37053726
}
@@ -3758,6 +3779,8 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
37583779
CHECK('}');
37593780
break;
37603781

3782+
// case '[': // TODO: parse lambda expression
3783+
37613784
default:
37623785
if (!parseName(ast->name, true)) // this can also be a template
37633786
return false;

generator/parser/parser.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ class Parser
6262
TranslationUnitAST *parse(const char *contents, std::size_t size, pool *p);
6363

6464
private:
65-
void reportError(const QString& msg);
66-
void syntaxError();
67-
void tokenRequiredError(int expected);
65+
void reportError(const QString& msg, const char* functionName = nullptr);
66+
void syntaxError(const char* functionName = nullptr);
67+
void tokenRequiredError(int expected, const char* functionName = nullptr);
6868

6969
public:
7070
bool skipFunctionBody(StatementAST *&node);

0 commit comments

Comments
 (0)