d: create alias Symbol for YYParse.Symbol

* data/skeletons/lalr1.d: Here.
* doc/bison.texi: Document it.
* examples/d/calc/calc.y, examples/d/simple/calc.y: Adjust.
* tests/calc.at, tests/d.at, tests/scanner.at: Test it.
This commit is contained in:
Adela Vais
2020-12-10 22:49:28 +02:00
committed by Akim Demaille
parent 848a17fa33
commit 13bb2b78b3
8 changed files with 62 additions and 52 deletions

View File

@@ -447,6 +447,14 @@ m4_define([b4_var_decls],
m4_define([b4_var_decl], m4_define([b4_var_decl],
[ protected $1;]) [ protected $1;])
# b4_public_types_declare
# -----------------------
# Define the public types: token, semantic value, location, and so forth.
# Depending on %define token_lex, may be output in the header or source file.
m4_define([b4_public_types_declare],
[[
alias Symbol = ]b4_parser_class[.Symbol;
]])
# b4_symbol_type_define # b4_symbol_type_define
# --------------------- # ---------------------

View File

@@ -75,7 +75,7 @@ public interface Lexer
* to the next token and prepares to return the semantic value * to the next token and prepares to return the semantic value
* ]b4_locations_if([and beginning/ending positions ])[of the token. * ]b4_locations_if([and beginning/ending positions ])[of the token.
* @@return the token identifier corresponding to the next token. */ * @@return the token identifier corresponding to the next token. */
]b4_parser_class[.Symbol yylex (); Symbol yylex ();
/** /**
* Entry point for error reporting. Emits an error * Entry point for error reporting. Emits an error
@@ -95,6 +95,8 @@ public interface Lexer
]])[ ]])[
} }
]b4_public_types_declare[
]b4_locations_if([b4_position_type_if([[ ]b4_locations_if([b4_position_type_if([[
static assert(__traits(compiles, static assert(__traits(compiles,
(new ]b4_position_type[[1])[0]=(new ]b4_position_type[[1])[0]), (new ]b4_position_type[[1])[0]=(new ]b4_position_type[[1])[0]),

View File

@@ -14011,9 +14011,9 @@ This method is defined by the user to emit an error message. The first
parameter is omitted if location tracking is not active. parameter is omitted if location tracking is not active.
@end deftypemethod @end deftypemethod
@deftypemethod {Lexer} {YYParser.Symbol} yylex() @deftypemethod {Lexer} {Symbol} yylex()
Return the next token. The return value is of type YYParser.Symbol, which Return the next token. The return value is of type @code{Symbol}, which
binds together the TokenKind, the semantic value and the location. binds together the kind, the semantic value and the location.
@end deftypemethod @end deftypemethod
@deftypemethod {Lexer} {YYPosition} getStartPos() @deftypemethod {Lexer} {YYPosition} getStartPos()

View File

@@ -114,7 +114,7 @@ if (isInputRange!R && is(ElementType!R : dchar))
return semanticVal_; return semanticVal_;
} }
Calc.Symbol yylex() Symbol yylex()
{ {
import std.uni : isWhite, isNumber; import std.uni : isWhite, isNumber;
@@ -127,7 +127,7 @@ if (isInputRange!R && is(ElementType!R : dchar))
} }
if (input.empty) if (input.empty)
return Calc.Symbol(TokenKind.YYEOF, YYLocation(startPos, endPos)); return Symbol(TokenKind.YYEOF, YYLocation(startPos, endPos));
// Numbers. // Numbers.
if (input.front.isNumber) if (input.front.isNumber)
@@ -143,7 +143,7 @@ if (isInputRange!R && is(ElementType!R : dchar))
} }
start = end; start = end;
end.column += lenChars; end.column += lenChars;
return Calc.Symbol(TokenKind.NUM, semanticVal_.ival, YYLocation(startPos, endPos)); return Symbol(TokenKind.NUM, semanticVal_.ival, YYLocation(startPos, endPos));
} }
// Individual characters // Individual characters
@@ -153,17 +153,17 @@ if (isInputRange!R && is(ElementType!R : dchar))
end.column++; end.column++;
switch (ch) switch (ch)
{ {
case '+': return Calc.Symbol(TokenKind.PLUS, YYLocation(startPos, endPos)); case '+': return Symbol(TokenKind.PLUS, YYLocation(startPos, endPos));
case '-': return Calc.Symbol(TokenKind.MINUS, YYLocation(startPos, endPos)); case '-': return Symbol(TokenKind.MINUS, YYLocation(startPos, endPos));
case '*': return Calc.Symbol(TokenKind.STAR, YYLocation(startPos, endPos)); case '*': return Symbol(TokenKind.STAR, YYLocation(startPos, endPos));
case '/': return Calc.Symbol(TokenKind.SLASH, YYLocation(startPos, endPos)); case '/': return Symbol(TokenKind.SLASH, YYLocation(startPos, endPos));
case '(': return Calc.Symbol(TokenKind.LPAR, YYLocation(startPos, endPos)); case '(': return Symbol(TokenKind.LPAR, YYLocation(startPos, endPos));
case ')': return Calc.Symbol(TokenKind.RPAR, YYLocation(startPos, endPos)); case ')': return Symbol(TokenKind.RPAR, YYLocation(startPos, endPos));
case '\n': case '\n':
{ {
end.line++; end.line++;
end.column = 1; end.column = 1;
return Calc.Symbol(TokenKind.EOL, YYLocation(startPos, endPos)); return Symbol(TokenKind.EOL, YYLocation(startPos, endPos));
} }
default: assert(0); default: assert(0);
} }

View File

@@ -109,7 +109,7 @@ if (isInputRange!R && is(ElementType!R : dchar))
return semanticVal_; return semanticVal_;
} }
Calc.Symbol yylex() Symbol yylex()
{ {
import std.uni : isWhite, isNumber; import std.uni : isWhite, isNumber;
@@ -118,13 +118,13 @@ if (isInputRange!R && is(ElementType!R : dchar))
input.popFront; input.popFront;
if (input.empty) if (input.empty)
return Calc.Symbol(TokenKind.YYEOF); return Symbol(TokenKind.YYEOF);
// Numbers. // Numbers.
if (input.front.isNumber) if (input.front.isNumber)
{ {
import std.conv : parse; import std.conv : parse;
return Calc.Symbol(TokenKind.NUM, input.parse!int); return Symbol(TokenKind.NUM, input.parse!int);
} }
// Individual characters // Individual characters
@@ -132,13 +132,13 @@ if (isInputRange!R && is(ElementType!R : dchar))
input.popFront; input.popFront;
switch (ch) switch (ch)
{ {
case '+': return Calc.Symbol(TokenKind.PLUS); case '+': return Symbol(TokenKind.PLUS);
case '-': return Calc.Symbol(TokenKind.MINUS); case '-': return Symbol(TokenKind.MINUS);
case '*': return Calc.Symbol(TokenKind.STAR); case '*': return Symbol(TokenKind.STAR);
case '/': return Calc.Symbol(TokenKind.SLASH); case '/': return Symbol(TokenKind.SLASH);
case '(': return Calc.Symbol(TokenKind.LPAR); case '(': return Symbol(TokenKind.LPAR);
case ')': return Calc.Symbol(TokenKind.RPAR); case ')': return Symbol(TokenKind.RPAR);
case '\n': return Calc.Symbol(TokenKind.EOL); case '\n': return Symbol(TokenKind.EOL);
default: assert(0); default: assert(0);
} }
} }

View File

@@ -590,7 +590,7 @@ class CalcLexer(R) : Lexer
return res; return res;
} }
YYParser.Symbol yylex () Symbol yylex ()
{]AT_LOCATION_IF([[ {]AT_LOCATION_IF([[
location.begin = location.end;]])[ location.begin = location.end;]])[
@@ -606,13 +606,13 @@ class CalcLexer(R) : Lexer
// EOF. // EOF.
if (input.empty) if (input.empty)
return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[EOF]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); return Symbol(TokenKind.]AT_TOKEN_PREFIX[EOF]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
// Numbers. // Numbers.
if (input.front.isNumber) if (input.front.isNumber)
{ {
semanticVal_.ival = parseInt; semanticVal_.ival = parseInt;
return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[NUM, semanticVal_.ival]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); return Symbol(TokenKind.]AT_TOKEN_PREFIX[NUM, semanticVal_.ival]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
} }
// Individual characters // Individual characters
@@ -630,22 +630,22 @@ class CalcLexer(R) : Lexer
if (c == '#') if (c == '#')
{ {
stderr.writeln (]AT_LOCATION_IF([location, ": ", ])["syntax error: invalid character: '#'"); stderr.writeln (]AT_LOCATION_IF([location, ": ", ])["syntax error: invalid character: '#'");
return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[YYerror]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); return Symbol(TokenKind.]AT_TOKEN_PREFIX[YYerror]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
} }
switch (c) switch (c)
{ {
case '+': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[PLUS]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); case '+': return Symbol(TokenKind.]AT_TOKEN_PREFIX[PLUS]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
case '-': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[MINUS]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); case '-': return Symbol(TokenKind.]AT_TOKEN_PREFIX[MINUS]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
case '*': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[STAR]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); case '*': return Symbol(TokenKind.]AT_TOKEN_PREFIX[STAR]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
case '/': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[SLASH]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); case '/': return Symbol(TokenKind.]AT_TOKEN_PREFIX[SLASH]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
case '(': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[LPAR]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); case '(': return Symbol(TokenKind.]AT_TOKEN_PREFIX[LPAR]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
case ')': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[RPAR]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); case ')': return Symbol(TokenKind.]AT_TOKEN_PREFIX[RPAR]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
case '\n': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[EOL]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); case '\n': return Symbol(TokenKind.]AT_TOKEN_PREFIX[EOL]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
case '=': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[EQUAL]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); case '=': return Symbol(TokenKind.]AT_TOKEN_PREFIX[EQUAL]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
case '^': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[POW]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); case '^': return Symbol(TokenKind.]AT_TOKEN_PREFIX[POW]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
case '!': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[NOT]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); case '!': return Symbol(TokenKind.]AT_TOKEN_PREFIX[NOT]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
default: return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[YYUNDEF]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[); default: return Symbol(TokenKind.]AT_TOKEN_PREFIX[YYUNDEF]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
} }
} }
} }

View File

@@ -81,7 +81,7 @@ class CalcLexer(R) : Lexer
YYSemanticType semanticVal_; YYSemanticType semanticVal_;
YYSemanticType semanticVal() @property { return semanticVal_; } YYSemanticType semanticVal() @property { return semanticVal_; }
YYParser.Symbol yylex() Symbol yylex()
{ {
$2 $2
} }
@@ -143,16 +143,16 @@ AT_KEYWORDS([d])
AT_CHECK_D_MINIMAL_W_LEXER([ AT_CHECK_D_MINIMAL_W_LEXER([
%define api.token.raw true %define api.token.raw true
%union { int ival; }], [return YYParser.Symbol(TokenKind.END);]) %union { int ival; }], [return Symbol(TokenKind.END);])
AT_CHECK_D_GREP([[ END = 3,]]) AT_CHECK_D_GREP([[ END = 3,]])
AT_CHECK_D_MINIMAL_W_LEXER([ AT_CHECK_D_MINIMAL_W_LEXER([
%define api.token.raw false %define api.token.raw false
%union { int ival; }], [return YYParser.Symbol(TokenKind.END);]) %union { int ival; }], [return Symbol(TokenKind.END);])
AT_CHECK_D_GREP([[ END = 258,]]) AT_CHECK_D_GREP([[ END = 258,]])
AT_CHECK_D_MINIMAL_W_LEXER([ AT_CHECK_D_MINIMAL_W_LEXER([
%union { int ival; }], [return YYParser.Symbol(TokenKind.END);]) %union { int ival; }], [return Symbol(TokenKind.END);])
AT_CHECK_D_GREP([[ END = 3,]]) AT_CHECK_D_GREP([[ END = 3,]])
AT_CLEANUP AT_CLEANUP

View File

@@ -121,12 +121,12 @@ class YYLexer(R) : Lexer
return semanticVal_; return semanticVal_;
} }
YYParser.Symbol yylex () Symbol yylex ()
{ {
import std.uni : isNumber; import std.uni : isNumber;
// Handle EOF. // Handle EOF.
if (input.empty) if (input.empty)
return YYParser.Symbol(TokenKind.END); return Symbol(TokenKind.END);
auto c = input.front; auto c = input.front;
input.popFront; input.popFront;
@@ -136,13 +136,13 @@ class YYLexer(R) : Lexer
{ {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
semanticVal_.val = c - '0'; semanticVal_.val = c - '0';
return YYParser.Symbol(TokenKind.NUM, semanticVal_.val); return Symbol(TokenKind.NUM, semanticVal_.val);
case '+': return YYParser.Symbol(TokenKind.PLUS); case '+': return Symbol(TokenKind.PLUS);
case '-': return YYParser.Symbol(TokenKind.MINUS); case '-': return Symbol(TokenKind.MINUS);
case '*': return YYParser.Symbol(TokenKind.STAR); case '*': return Symbol(TokenKind.STAR);
case '/': return YYParser.Symbol(TokenKind.SLASH); case '/': return Symbol(TokenKind.SLASH);
case '(': return YYParser.Symbol(TokenKind.LPAR); case '(': return Symbol(TokenKind.LPAR);
case ')': return YYParser.Symbol(TokenKind.RPAR); case ')': return Symbol(TokenKind.RPAR);
default: assert(0); default: assert(0);
} }
} }