mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
examples: d: demonstrate location tracking
* examples/d/calc/calc.y: Track locations. * examples/d/calc/calc.test: Check locations.
This commit is contained in:
committed by
Akim Demaille
parent
8032dde383
commit
6e1d83c8a8
@@ -33,4 +33,19 @@ run 0 5
|
||||
cat >input <<EOF
|
||||
1 + 2 * * 3
|
||||
EOF
|
||||
run 1 "err: syntax error, unexpected *, expecting + or - or ( or number"
|
||||
run 1 "err: 1.9: syntax error, unexpected *, expecting + or - or ( or number"
|
||||
|
||||
cat >input <<EOF
|
||||
1111 + 1111 2222
|
||||
EOF
|
||||
run 1 "err: 1.13-16: syntax error, unexpected number"
|
||||
|
||||
cat >input <<EOF
|
||||
1 +
|
||||
EOF
|
||||
run 1 "err: 1.4-2.0: syntax error, unexpected end of line, expecting + or - or ( or number"
|
||||
|
||||
cat >input <<EOF
|
||||
99 009
|
||||
EOF
|
||||
run 1 "err: 1.4-6: syntax error, unexpected number"
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
%define api.parser.class {Calc}
|
||||
%define parse.error verbose
|
||||
|
||||
%locations
|
||||
|
||||
%union {
|
||||
int ival;
|
||||
}
|
||||
@@ -94,13 +96,16 @@ class CalcLexer(R) : Lexer
|
||||
|
||||
this(R r) { input = r; }
|
||||
|
||||
YYPosition start;
|
||||
YYPosition end;
|
||||
|
||||
// Should be a local in main, shared with %parse-param.
|
||||
int exit_status = 0;
|
||||
|
||||
public void yyerror (string s)
|
||||
void yyerror(YYLocation loc, string s)
|
||||
{
|
||||
exit_status = 1;
|
||||
stderr.writeln (s);
|
||||
stderr.writeln(loc.toString(), ": ", s);
|
||||
}
|
||||
|
||||
YYSemanticType semanticVal_;
|
||||
@@ -116,24 +121,39 @@ class CalcLexer(R) : Lexer
|
||||
|
||||
// Skip initial spaces
|
||||
while (!input.empty && input.front != '\n' && isWhite (input.front))
|
||||
{
|
||||
start = end;
|
||||
end.column++;
|
||||
input.popFront;
|
||||
}
|
||||
|
||||
if (input.empty)
|
||||
return TokenKind.YYEOF;
|
||||
|
||||
// Numbers.
|
||||
if (input.front.isNumber)
|
||||
{
|
||||
int lenChars = 0;
|
||||
auto copy = input;
|
||||
import std.conv : parse;
|
||||
semanticVal_.ival = input.parse!int;
|
||||
while (!input.empty && copy.front != input.front)
|
||||
{
|
||||
import std.conv : parse;
|
||||
semanticVal_.ival = input.parse!int;
|
||||
return TokenKind.NUM;
|
||||
lenChars++;
|
||||
copy.popFront;
|
||||
}
|
||||
start = end;
|
||||
end.column += lenChars;
|
||||
return TokenKind.NUM;
|
||||
}
|
||||
|
||||
// Individual characters
|
||||
auto ch = input.front;
|
||||
input.popFront;
|
||||
start = end;
|
||||
end.column++;
|
||||
switch (ch)
|
||||
{
|
||||
{
|
||||
case '=': return TokenKind.EQ;
|
||||
case '+': return TokenKind.PLUS;
|
||||
case '-': return TokenKind.MINUS;
|
||||
@@ -141,9 +161,24 @@ class CalcLexer(R) : Lexer
|
||||
case '/': return TokenKind.SLASH;
|
||||
case '(': return TokenKind.LPAR;
|
||||
case ')': return TokenKind.RPAR;
|
||||
case '\n': return TokenKind.EOL;
|
||||
default: assert(0);
|
||||
case '\n':
|
||||
{
|
||||
end.line++;
|
||||
end.column = 1;
|
||||
return TokenKind.EOL;
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
YYPosition startPos() const
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
YYPosition endPos() const
|
||||
{
|
||||
return end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user