diff --git a/data/skeletons/d.m4 b/data/skeletons/d.m4 index d2fa6e29..0aae111e 100644 --- a/data/skeletons/d.m4 +++ b/data/skeletons/d.m4 @@ -208,6 +208,32 @@ b4_symbol_foreach([b4_token_enum])dnl m4_define([b4_symbol_translate], [[_($1)]]) + +# _b4_token_constructor_define +# ---------------------------- +# Define make_symbol for a value type. +m4_define([_b4_token_constructor_define], +[b4_token_visible_if([$1], +[[ + static auto ]b4_symbol([$1], [id])[(]b4_symbol_if([$1], [has_type], +[b4_union_if([b4_symbol([$1], [type]], +[[typeof(YYSemanticType.]b4_symbol([$1], [type])[]])) [val]])dnl +[]b4_locations_if([b4_symbol_if([$1], [has_type], [[, ]])[Location l]])[) + { + return Symbol(TokenKind.]b4_symbol([$1], [id])[]b4_symbol_if([$1], [has_type], + [[, val]])[]b4_locations_if([[, l]])[); + }]])]) + +# b4_token_constructor_define +# --------------------------- +# Define the overloaded versions of make_symbol for all the value types. +m4_define([b4_token_constructor_define], +[[ + /* Implementation of token constructors for each symbol type visible to + * the user. The code generates static methods that have the same names + * as the TokenKinds. + */]b4_symbol_foreach([_b4_token_constructor_define])]) + ## -------------- ## ## Symbol kinds. ## ## -------------- ## @@ -593,5 +619,6 @@ m4_define([b4_symbol_type_define], SymbolKind token() { return kind; } Value value() { return value_; }]b4_locations_if([[ Location location() { return location_; }]])[ +]b4_token_ctor_if([b4_token_constructor_define])[ } ]]) diff --git a/tests/calc.at b/tests/calc.at index 042cac7b..7475535d 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -519,6 +519,16 @@ m4_copy([_AT_DATA_CALC_Y(c)], [_AT_DATA_CALC_Y(c++)]) ## Calc in D. ## ## ----------- ## +# AT_YYLEX_RETURN_VAL +# ------------------- +# Produce the return value for yylex(). +m4_define([AT_YYLEX_RETURN_VAL], +[return dnl +AT_TOKEN_CTOR_IF( + [[Symbol.]AT_TOKEN_PREFIX[$1](m4_ifval([$2], [$2])[]AT_LOCATION_IF([m4_ifval([$2], [, ])[location]])[);]], + [[Symbol(TokenKind.]AT_TOKEN_PREFIX[$1]m4_ifval([$2], [, $2])[]AT_LOCATION_IF([[, location]])[);]])] +) + # AT_CALC_MAIN(d). m4_define([AT_CALC_MAIN(d)], [[int main (string[] args) @@ -595,11 +605,10 @@ if (isInputRange!R && is (ElementType!R : dchar)) // EOF. if (input.empty) - return Symbol(TokenKind.]AT_TOKEN_PREFIX[EOF]AT_LOCATION_IF([[, location]])[); - + ]AT_YYLEX_RETURN_VAL([EOF])[ // Numbers. if (input.front.isNumber) - return Symbol(TokenKind.]AT_TOKEN_PREFIX[NUM, parseInt]AT_LOCATION_IF([[, location]])[); + ]AT_YYLEX_RETURN_VAL([NUM], [parseInt])[ // Individual characters auto c = input.front;]AT_LOCATION_IF([[ @@ -616,22 +625,22 @@ if (isInputRange!R && is (ElementType!R : dchar)) if (c == '#') { stderr.writeln (]AT_LOCATION_IF([location, ": ", ])["syntax error: invalid character: '#'"); - return Symbol(TokenKind.]AT_TOKEN_PREFIX[YYerror]AT_LOCATION_IF([[, location]])[); + ]AT_YYLEX_RETURN_VAL([YYerror])[ } switch (c) { - case '+': return Symbol(TokenKind.]AT_TOKEN_PREFIX[PLUS]AT_LOCATION_IF([[, location]])[); - case '-': return Symbol(TokenKind.]AT_TOKEN_PREFIX[MINUS]AT_LOCATION_IF([[, location]])[); - case '*': return Symbol(TokenKind.]AT_TOKEN_PREFIX[STAR]AT_LOCATION_IF([[, location]])[); - case '/': return Symbol(TokenKind.]AT_TOKEN_PREFIX[SLASH]AT_LOCATION_IF([[, location]])[); - case '(': return Symbol(TokenKind.]AT_TOKEN_PREFIX[LPAR]AT_LOCATION_IF([[, location]])[); - case ')': return Symbol(TokenKind.]AT_TOKEN_PREFIX[RPAR]AT_LOCATION_IF([[, location]])[); - case '\n': return Symbol(TokenKind.]AT_TOKEN_PREFIX[EOL]AT_LOCATION_IF([[, location]])[); - case '=': return Symbol(TokenKind.]AT_TOKEN_PREFIX[EQUAL]AT_LOCATION_IF([[, location]])[); - case '^': return Symbol(TokenKind.]AT_TOKEN_PREFIX[POW]AT_LOCATION_IF([[, location]])[); - case '!': return Symbol(TokenKind.]AT_TOKEN_PREFIX[NOT]AT_LOCATION_IF([[, location]])[); - default: return Symbol(TokenKind.]AT_TOKEN_PREFIX[YYUNDEF]AT_LOCATION_IF([[, location]])[); + case '+': ]AT_YYLEX_RETURN_VAL([PLUS])[ + case '-': ]AT_YYLEX_RETURN_VAL([MINUS])[ + case '*': ]AT_YYLEX_RETURN_VAL([STAR])[ + case '/': ]AT_YYLEX_RETURN_VAL([SLASH])[ + case '(': ]AT_YYLEX_RETURN_VAL([LPAR])[ + case ')': ]AT_YYLEX_RETURN_VAL([RPAR])[ + case '\n': ]AT_YYLEX_RETURN_VAL([EOL])[ + case '=': ]AT_YYLEX_RETURN_VAL([EQUAL])[ + case '^': ]AT_YYLEX_RETURN_VAL([POW])[ + case '!': ]AT_YYLEX_RETURN_VAL([NOT])[ + default: ]AT_YYLEX_RETURN_VAL([YYUNDEF])[ } } } @@ -1499,7 +1508,8 @@ AT_CHECK_CALC_LALR1_D([%locations %define parse.lac full %define parse.error det #AT_CHECK_CALC_LALR1_D([%locations %define parse.error detailed %debug %verbose %parse-param {semantic_value *result}{int *count}{int *nerrs}]) #AT_CHECK_CALC_LALR1_D([%locations %define parse.error detailed %debug %define api.prefix {calc} %verbose %parse-param {semantic_value *result}{int *count}{int *nerrs}]) -AT_CHECK_CALC_LALR1_D([%define parse.error custom %define api.value.type union]) +AT_CHECK_CALC_LALR1_D([%define api.token.constructor %locations %define parse.error custom %define api.value.type union]) +AT_CHECK_CALC_LALR1_D([%define api.token.constructor %locations %define parse.error detailed]) # ----------------------- # # LALR1 Java Calculator. #