mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
2007-03-07 Paolo Bonzini <bonzini@gnu.org>
* data/java.m4 (b4_single_class_if): Remove.
(b4_abstract_if): Look at "%define abstract".
(b4_lexer_if): New.
(b4_union_name): Rename...
(b4_yystype): ... to this. Map to "%define stype".
(b4_rhs_value, b4_parse_param_decl, b4_lex_param_decl,
b4_maybe_throws): Fix quoting.
(b4_lex_param_call): Move below to keep b4_*_param_decl close.
* data/lalr1.java (Lexer interface): Always define.
(Lexer interface within parser class): Remove.
(YYLexer class): New, used when "%code lexer" is present.
(constructor): When "%code lexer" is used, pass %lex-param
to the lexer constructor.
(yylex, yyparse): Remove %lex-param from method invocations
(YYStack, yyaction, yyparse): Rename b4_union_name to b4_yystype.
* doc/bison.texinfo (Java Bison Interface): Mention "%define
abstract". Rename "%define union_name" to "%define stype".
Rename method names according to previous patch.
(Java Scanner Interface): Describe "%code lexer" instead of
"%pure-parser" and "%define single_class".
(Java Differences): Mention "%code lexer".
* tests/java.at (_AT_DATA_JAVA_CALC_Y): Remove final argument.
Include scanner here, using macros from tests/local.at.
(AT_DATA_CALC_Y): Remove final argument.
(_AT_CHECK_JAVA_CALC): Likewise.
(AT_CHECK_JAVA_CALC): Likewise. Test all four combinations
of %locations and %error-verbose.
(main): Test with and without %lex-param.
* tests/local.at (_AT_BISON_OPTION_PUSHDEFS): Push AT_LEXPARAM_IF.
(AT_BISON_OPTION_POPDEFS): Pop it.
This commit is contained in:
35
ChangeLog
35
ChangeLog
@@ -1,3 +1,38 @@
|
|||||||
|
2007-03-07 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* data/java.m4 (b4_single_class_if): Remove.
|
||||||
|
(b4_abstract_if): Look at "%define abstract".
|
||||||
|
(b4_lexer_if): New.
|
||||||
|
(b4_union_name): Rename...
|
||||||
|
(b4_yystype): ... to this. Map to "%define stype".
|
||||||
|
(b4_rhs_value, b4_parse_param_decl, b4_lex_param_decl,
|
||||||
|
b4_maybe_throws): Fix quoting.
|
||||||
|
(b4_lex_param_call): Move below to keep b4_*_param_decl close.
|
||||||
|
* data/lalr1.java (Lexer interface): Always define.
|
||||||
|
(Lexer interface within parser class): Remove.
|
||||||
|
(YYLexer class): New, used when "%code lexer" is present.
|
||||||
|
(constructor): When "%code lexer" is used, pass %lex-param
|
||||||
|
to the lexer constructor.
|
||||||
|
(yylex, yyparse): Remove %lex-param from method invocations
|
||||||
|
(YYStack, yyaction, yyparse): Rename b4_union_name to b4_yystype.
|
||||||
|
|
||||||
|
* doc/bison.texinfo (Java Bison Interface): Mention "%define
|
||||||
|
abstract". Rename "%define union_name" to "%define stype".
|
||||||
|
Rename method names according to previous patch.
|
||||||
|
(Java Scanner Interface): Describe "%code lexer" instead of
|
||||||
|
"%pure-parser" and "%define single_class".
|
||||||
|
(Java Differences): Mention "%code lexer".
|
||||||
|
|
||||||
|
* tests/java.at (_AT_DATA_JAVA_CALC_Y): Remove final argument.
|
||||||
|
Include scanner here, using macros from tests/local.at.
|
||||||
|
(AT_DATA_CALC_Y): Remove final argument.
|
||||||
|
(_AT_CHECK_JAVA_CALC): Likewise.
|
||||||
|
(AT_CHECK_JAVA_CALC): Likewise. Test all four combinations
|
||||||
|
of %locations and %error-verbose.
|
||||||
|
(main): Test with and without %lex-param.
|
||||||
|
* tests/local.at (_AT_BISON_OPTION_PUSHDEFS): Push AT_LEXPARAM_IF.
|
||||||
|
(AT_BISON_OPTION_POPDEFS): Pop it.
|
||||||
|
|
||||||
2007-03-07 Juan Manuel Guerrero <juan.guerrero@gmx.de>
|
2007-03-07 Juan Manuel Guerrero <juan.guerrero@gmx.de>
|
||||||
|
|
||||||
DJGPP spefic issue. Inhibit the use of disallowed characters for
|
DJGPP spefic issue. Inhibit the use of disallowed characters for
|
||||||
|
|||||||
67
data/java.m4
67
data/java.m4
@@ -38,17 +38,18 @@ b4_percent_define_default([[public]], [[false]])
|
|||||||
m4_define([b4_public_if],
|
m4_define([b4_public_if],
|
||||||
[b4_percent_define_flag_if([public], [$1], [$2])])
|
[b4_percent_define_flag_if([public], [$1], [$2])])
|
||||||
|
|
||||||
# b4_single_class_if(TRUE, FALSE)
|
|
||||||
# -------------------------------
|
|
||||||
b4_percent_define_default([[single_class]], [[false]])
|
|
||||||
m4_define([b4_single_class_if],
|
|
||||||
[b4_percent_define_flag_if([single_class], [$1], [$2])])
|
|
||||||
|
|
||||||
|
|
||||||
# b4_abstract_if(TRUE, FALSE)
|
# b4_abstract_if(TRUE, FALSE)
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
|
b4_percent_define_default([[abstract]], [[false]])
|
||||||
m4_define([b4_abstract_if],
|
m4_define([b4_abstract_if],
|
||||||
[b4_pure_if([$2], [b4_single_class_if([$2], [$1])])])
|
[b4_percent_define_flag_if([abstract], [$1], [$2])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_lexer_if(TRUE, FALSE)
|
||||||
|
# ------------------------
|
||||||
|
m4_define([b4_lexer_if],
|
||||||
|
[b4_percent_code_ifdef([[lexer]], [$1], [$2])])
|
||||||
|
|
||||||
|
|
||||||
# b4_identification
|
# b4_identification
|
||||||
@@ -126,8 +127,8 @@ m4_define([b4_case], [ case $1:
|
|||||||
## Default values. ##
|
## Default values. ##
|
||||||
## ---------------- ##
|
## ---------------- ##
|
||||||
|
|
||||||
m4_define([b4_union_name], [b4_percent_define_get([[union_name]])])
|
m4_define([b4_yystype], [b4_percent_define_get([[stype]])])
|
||||||
b4_percent_define_default([[union_name]], [[Object]])])
|
b4_percent_define_default([[stype]], [[Object]])])
|
||||||
|
|
||||||
m4_define_default([[b4_prefix]], [[YY]])])
|
m4_define_default([[b4_prefix]], [[YY]])])
|
||||||
b4_percent_define_default([[parser_class_name]], [b4_prefix[]Parser])])
|
b4_percent_define_default([[parser_class_name]], [b4_prefix[]Parser])])
|
||||||
@@ -165,7 +166,7 @@ m4_define([b4_lhs_value], [yyval])
|
|||||||
# In this simple implementation, %token and %type have class names
|
# In this simple implementation, %token and %type have class names
|
||||||
# between the angle brackets.
|
# between the angle brackets.
|
||||||
m4_define([b4_rhs_value],
|
m4_define([b4_rhs_value],
|
||||||
[(m4_ifval([$3], [($3)])[](yystack.valueAt ($1-($2))))])
|
[(m4_ifval($3, [($3)])[](yystack.valueAt ($1-($2))))])
|
||||||
|
|
||||||
# b4_lhs_location()
|
# b4_lhs_location()
|
||||||
# -----------------
|
# -----------------
|
||||||
@@ -199,25 +200,14 @@ m4_define([b4_parse_param], b4_parse_param))
|
|||||||
m4_define([b4_lex_param_decl],
|
m4_define([b4_lex_param_decl],
|
||||||
[m4_ifset([b4_lex_param],
|
[m4_ifset([b4_lex_param],
|
||||||
[b4_remove_comma([$1],
|
[b4_remove_comma([$1],
|
||||||
[m4_map([b4_lex_param_decl_1], [b4_lex_param])])],
|
b4_param_decls(b4_lex_param))],
|
||||||
[$1])])
|
[$1])])
|
||||||
|
|
||||||
m4_define([b4_lex_param_decl_1], [, $1])
|
m4_define([b4_param_decls],
|
||||||
m4_define([b4_remove_comma], [m4_ifval([$1], [$1, ], [])m4_cdr([m4_cdr($@)])])
|
[m4_map([b4_param_decl], [$@])])
|
||||||
|
m4_define([b4_param_decl], [, $1])
|
||||||
|
|
||||||
|
m4_define([b4_remove_comma], [m4_ifval($1, [$1, ], [])m4_shiftn(2, $@)])
|
||||||
|
|
||||||
# b4_lex_param_call
|
|
||||||
# -------------------
|
|
||||||
# Extra initialisations of the constructor.
|
|
||||||
m4_define([b4_lex_param_call],
|
|
||||||
[m4_ifset([b4_lex_param],
|
|
||||||
[b4_remove_comma([$1],
|
|
||||||
[b4_lex_param_calls(b4_lex_param)])],
|
|
||||||
[$1])])
|
|
||||||
m4_define([b4_lex_param_calls],
|
|
||||||
[m4_map([b4_lex_param_call_1], [$@])])
|
|
||||||
m4_define([b4_lex_param_call_1], [, $2])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -227,11 +217,22 @@ m4_define([b4_lex_param_call_1], [, $2])
|
|||||||
m4_define([b4_parse_param_decl],
|
m4_define([b4_parse_param_decl],
|
||||||
[m4_ifset([b4_parse_param],
|
[m4_ifset([b4_parse_param],
|
||||||
[b4_remove_comma([$1],
|
[b4_remove_comma([$1],
|
||||||
[m4_map([b4_parse_param_decl_1],
|
b4_param_decls(b4_parse_param))],
|
||||||
[b4_parse_param])])],
|
|
||||||
[$1])])
|
[$1])])
|
||||||
|
|
||||||
m4_define([b4_parse_param_decl_1], [, $1])
|
|
||||||
|
|
||||||
|
# b4_lex_param_call
|
||||||
|
# -------------------
|
||||||
|
# Delegating the lexer parameters to the lexer constructor.
|
||||||
|
m4_define([b4_lex_param_call],
|
||||||
|
[m4_ifset([b4_lex_param],
|
||||||
|
[b4_remove_comma([$1],
|
||||||
|
b4_param_calls(b4_lex_param))],
|
||||||
|
[$1])])
|
||||||
|
m4_define([b4_param_calls],
|
||||||
|
[m4_map([b4_param_call], [$@])])
|
||||||
|
m4_define([b4_param_call], [, $2])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -241,12 +242,15 @@ m4_define([b4_parse_param_decl_1], [, $1])
|
|||||||
m4_define([b4_parse_param_cons],
|
m4_define([b4_parse_param_cons],
|
||||||
[m4_ifset([b4_parse_param],
|
[m4_ifset([b4_parse_param],
|
||||||
[b4_constructor_calls(b4_parse_param)])])
|
[b4_constructor_calls(b4_parse_param)])])
|
||||||
|
|
||||||
m4_define([b4_constructor_calls],
|
m4_define([b4_constructor_calls],
|
||||||
[m4_map([b4_constructor_call], [$@])])
|
[m4_map([b4_constructor_call], [$@])])
|
||||||
m4_define([b4_constructor_call],
|
m4_define([b4_constructor_call],
|
||||||
[this.$2 = $2;
|
[this.$2 = $2;
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# b4_parse_param_vars
|
# b4_parse_param_vars
|
||||||
# -------------------
|
# -------------------
|
||||||
# Extra instance variables.
|
# Extra instance variables.
|
||||||
@@ -255,14 +259,17 @@ m4_define([b4_parse_param_vars],
|
|||||||
[
|
[
|
||||||
/* User arguments. */
|
/* User arguments. */
|
||||||
b4_var_decls(b4_parse_param)])])
|
b4_var_decls(b4_parse_param)])])
|
||||||
|
|
||||||
m4_define([b4_var_decls],
|
m4_define([b4_var_decls],
|
||||||
[m4_map_sep([b4_var_decl], [
|
[m4_map_sep([b4_var_decl], [
|
||||||
], [$@])])
|
], [$@])])
|
||||||
m4_define([b4_var_decl],
|
m4_define([b4_var_decl],
|
||||||
[ protected final $1;])
|
[ protected final $1;])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# b4_maybe_throws(THROWS)
|
# b4_maybe_throws(THROWS)
|
||||||
# -----------------------
|
# -----------------------
|
||||||
# Expand to either an empty string or "throws THROWS".
|
# Expand to either an empty string or "throws THROWS".
|
||||||
m4_define([b4_maybe_throws],
|
m4_define([b4_maybe_throws],
|
||||||
[m4_ifval([$1], [throws $1])])
|
[m4_ifval($1, [throws $1])])
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ b4_token_enums(b4_tokens)
|
|||||||
return new ]b4_location_type[ (rhs.locationAt (0).end);
|
return new ]b4_location_type[ (rhs.locationAt (0).end);
|
||||||
}]])
|
}]])
|
||||||
|
|
||||||
b4_pure_if([[/**
|
/**
|
||||||
* Communication interface between the scanner and the Bison-generated
|
* Communication interface between the scanner and the Bison-generated
|
||||||
* parser <tt>]b4_parser_class_name[</tt>.
|
* parser <tt>]b4_parser_class_name[</tt>.
|
||||||
*/
|
*/
|
||||||
@@ -121,30 +121,15 @@ b4_token_enums(b4_tokens)
|
|||||||
/**
|
/**
|
||||||
* Method to retrieve the semantic value of the last scanned token.
|
* Method to retrieve the semantic value of the last scanned token.
|
||||||
* @@return the semantic value of the last scanned token. */
|
* @@return the semantic value of the last scanned token. */
|
||||||
]b4_union_name[ getLVal ();]], [[
|
]b4_yystype[ getLVal ();]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A place where the scanner can store the beginning position of the
|
|
||||||
* last scanned token. */
|
|
||||||
]b4_locations_if([b4_position_type[ yystartpos;]])[
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A place where the scanner can store the ending position of the last
|
|
||||||
* scanned token, i.e. the first position beyond the last scanned token. */
|
|
||||||
]b4_locations_if([b4_position_type[ yyendpos;]])[
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A place where the scanner can store the semantic value of the
|
|
||||||
* last scanned token. */
|
|
||||||
protected ]b4_union_name[ yylval;]])
|
|
||||||
|
|
||||||
b4_single_class_if([], [[/**
|
|
||||||
* Entry point for the scanner. Returns the token identifier corresponding
|
* Entry point for the scanner. Returns the token identifier corresponding
|
||||||
* to the next token and ]b4_pure_if([prepares to return], [stores])[
|
* to the next token and ]b4_pure_if([prepares to return], [stores])[
|
||||||
* the semantic value]b4_locations_if([ and beginning/ending positions])[
|
* the semantic value]b4_locations_if([ and beginning/ending positions])[
|
||||||
* of the token.
|
* of the token.
|
||||||
* @@return the token identifier corresponding to the next token. */
|
* @@return the token identifier corresponding to the next token. */
|
||||||
abstract int yylex (]b4_lex_param_decl) b4_maybe_throws([b4_lex_throws])[;
|
int yylex () ]b4_maybe_throws([b4_lex_throws])[;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point for error reporting. Emits an error
|
* Entry point for error reporting. Emits an error
|
||||||
@@ -154,20 +139,35 @@ b4_token_enums(b4_tokens)
|
|||||||
* ]b4_locations_if([loc], [[The location of the element to which the
|
* ]b4_locations_if([loc], [[The location of the element to which the
|
||||||
* error message is related]])[
|
* error message is related]])[
|
||||||
* @@param s The string for the error message. */
|
* @@param s The string for the error message. */
|
||||||
abstract void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s);]])
|
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s);]
|
||||||
b4_pure_if([}
|
}
|
||||||
|
|
||||||
/** The object doing lexical analysis for us. */
|
b4_lexer_if([[private class YYLexer implements Lexer {
|
||||||
private Lexer yylex;])
|
]b4_percent_code_get([[lexer]])[
|
||||||
b4_parse_param_vars[
|
}
|
||||||
|
|
||||||
|
]])[/** The object doing lexical analysis for us. */
|
||||||
|
private Lexer yylexer;
|
||||||
|
]
|
||||||
|
b4_parse_param_vars
|
||||||
|
|
||||||
|
b4_lexer_if([[
|
||||||
|
/**
|
||||||
|
* Instantiates the Bison-generated parser.
|
||||||
|
*/
|
||||||
|
public ]b4_parser_class_name (b4_parse_param_decl([b4_lex_param_decl])[) {
|
||||||
|
this.yylexer = new YYLexer(]b4_lex_param_call[);
|
||||||
|
]b4_parse_param_cons[
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates the Bison-generated parser. ]b4_pure_if([
|
* Instantiates the Bison-generated parser.
|
||||||
* @@param yylex The scanner that will supply tokens to the parser.])[
|
* @@param yylex The scanner that will supply tokens to the parser.
|
||||||
*/
|
*/
|
||||||
public ]b4_parser_class_name[ (]b4_parse_param_decl([b4_pure_if([Lexer yylex])])[) {
|
b4_lexer_if([[protected]], [[public]]) b4_parser_class_name[ (]b4_parse_param_decl([[Lexer yylexer]])[) {
|
||||||
]b4_pure_if(this.yylex = yylex;)
|
this.yylexer = yylexer;
|
||||||
b4_parse_param_cons[
|
]b4_parse_param_cons[
|
||||||
}
|
}
|
||||||
|
|
||||||
private java.io.PrintStream yyDebugStream = System.err;
|
private java.io.PrintStream yyDebugStream = System.err;
|
||||||
@@ -199,19 +199,19 @@ b4_token_enums(b4_tokens)
|
|||||||
*/
|
*/
|
||||||
public final void setDebugLevel(int level) { yydebug = level; }
|
public final void setDebugLevel(int level) { yydebug = level; }
|
||||||
|
|
||||||
]b4_pure_if([[
|
private final int yylex () ]b4_maybe_throws([b4_lex_throws]) [{
|
||||||
private final int yylex (]b4_lex_param_decl) b4_maybe_throws([b4_lex_throws]) [{
|
return yylexer.yylex ();
|
||||||
return yylex.yylex (]b4_lex_param_call[);
|
|
||||||
}
|
}
|
||||||
protected final void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s) {
|
protected final void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s) {
|
||||||
yylex.yyerror (]b4_locations_if([loc, ])[s);
|
yylexer.yyerror (]b4_locations_if([loc, ])[s);
|
||||||
}]])
|
}
|
||||||
b4_locations_if([
|
|
||||||
|
]b4_locations_if([
|
||||||
protected final void yyerror (String s) {
|
protected final void yyerror (String s) {
|
||||||
yyerror ((Location)null, s);
|
yylexer.yyerror ((Location)null, s);
|
||||||
}
|
}
|
||||||
protected final void yyerror (]b4_position_type[ loc, String s) {
|
protected final void yyerror (]b4_position_type[ loc, String s) {
|
||||||
yyerror (new ]b4_location_type[ (loc), s);
|
yylexer.yyerror (new ]b4_location_type[ (loc), s);
|
||||||
}])
|
}])
|
||||||
|
|
||||||
[protected final void yycdebug (String s) {
|
[protected final void yycdebug (String s) {
|
||||||
@@ -222,12 +222,12 @@ b4_token_enums(b4_tokens)
|
|||||||
private final class YYStack {
|
private final class YYStack {
|
||||||
private int[] stateStack = new int[16];
|
private int[] stateStack = new int[16];
|
||||||
]b4_locations_if([[private ]b4_location_type[[] locStack = new ]b4_location_type[[16];]])[
|
]b4_locations_if([[private ]b4_location_type[[] locStack = new ]b4_location_type[[16];]])[
|
||||||
private ]b4_union_name[[] valueStack = new ]b4_union_name[[16];
|
private ]b4_yystype[[] valueStack = new ]b4_yystype[[16];
|
||||||
|
|
||||||
public int size = 16;
|
public int size = 16;
|
||||||
public int height = -1;
|
public int height = -1;
|
||||||
|
|
||||||
public final void push (int state, ]b4_union_name[ value]dnl
|
public final void push (int state, ]b4_yystype[ value]dnl
|
||||||
b4_locations_if([, ]b4_location_type[ loc])[) {
|
b4_locations_if([, ]b4_location_type[ loc])[) {
|
||||||
height++;
|
height++;
|
||||||
if (size == height)
|
if (size == height)
|
||||||
@@ -240,7 +240,7 @@ b4_token_enums(b4_tokens)
|
|||||||
System.arraycopy (locStack, 0, newLocStack, 0, height);
|
System.arraycopy (locStack, 0, newLocStack, 0, height);
|
||||||
locStack = newLocStack;]])
|
locStack = newLocStack;]])
|
||||||
|
|
||||||
b4_union_name[[] newValueStack = new ]b4_union_name[[size * 2];
|
b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
|
||||||
System.arraycopy (valueStack, 0, newValueStack, 0, height);
|
System.arraycopy (valueStack, 0, newValueStack, 0, height);
|
||||||
valueStack = newValueStack;
|
valueStack = newValueStack;
|
||||||
|
|
||||||
@@ -273,7 +273,7 @@ b4_token_enums(b4_tokens)
|
|||||||
return locStack[height - i];
|
return locStack[height - i];
|
||||||
}
|
}
|
||||||
|
|
||||||
]])[public final ]b4_union_name[ valueAt (int i) {
|
]])[public final ]b4_yystype[ valueAt (int i) {
|
||||||
return valueStack[height - i];
|
return valueStack[height - i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +330,7 @@ b4_token_enums(b4_tokens)
|
|||||||
|
|
||||||
private int yyaction (int yyn, YYStack yystack, int yylen)
|
private int yyaction (int yyn, YYStack yystack, int yylen)
|
||||||
{
|
{
|
||||||
]b4_union_name[ yyval;
|
]b4_yystype[ yyval;
|
||||||
]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
|
]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
|
||||||
|
|
||||||
/* If YYLEN is nonzero, implement the default value of the action:
|
/* If YYLEN is nonzero, implement the default value of the action:
|
||||||
@@ -410,7 +410,7 @@ b4_token_enums(b4_tokens)
|
|||||||
`--------------------------------*/
|
`--------------------------------*/
|
||||||
|
|
||||||
private void yy_symbol_print (String s, int yytype,
|
private void yy_symbol_print (String s, int yytype,
|
||||||
]b4_union_name[ yyvaluep]dnl
|
]b4_yystype[ yyvaluep]dnl
|
||||||
b4_locations_if([, Object yylocationp])[)
|
b4_locations_if([, Object yylocationp])[)
|
||||||
{
|
{
|
||||||
if (yydebug > 0)
|
if (yydebug > 0)
|
||||||
@@ -452,7 +452,7 @@ b4_token_enums(b4_tokens)
|
|||||||
]b4_location_type[ yyloc;])
|
]b4_location_type[ yyloc;])
|
||||||
|
|
||||||
/// Semantic value of the lookahead.
|
/// Semantic value of the lookahead.
|
||||||
b4_union_name[ yylval = null;
|
b4_yystype[ yylval = null;
|
||||||
|
|
||||||
int yyresult;
|
int yyresult;
|
||||||
|
|
||||||
@@ -497,13 +497,11 @@ m4_popdef([b4_at_dollar])])dnl
|
|||||||
if (yychar == yyempty_)
|
if (yychar == yyempty_)
|
||||||
{
|
{
|
||||||
yycdebug ("Reading a token: ");
|
yycdebug ("Reading a token: ");
|
||||||
yychar = yylex (]b4_lex_param_call[);]
|
yychar = yylex ();]
|
||||||
b4_locations_if([
|
b4_locations_if([[
|
||||||
b4_pure_if([yylloc = new ]b4_location_type[(yylex.getStartPos (),
|
yylloc = new ]b4_location_type[(yylexer.getStartPos (),
|
||||||
yylex.getEndPos ());],
|
yylexer.getEndPos ());]])
|
||||||
[yylloc = new ]b4_location_type[(this.yystartpos,
|
yylval = yylexer.getLVal ();[
|
||||||
this.yyendpos);]);])
|
|
||||||
b4_pure_if([yylval = yylex.getLVal ()], [yylval = this.yylval]);[
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert token to internal form. */
|
/* Convert token to internal form. */
|
||||||
|
|||||||
@@ -8380,7 +8380,10 @@ Remember that, according to the Java language specification, the name
|
|||||||
of the @file{.java} file should match the name of the class in this
|
of the @file{.java} file should match the name of the class in this
|
||||||
case.
|
case.
|
||||||
|
|
||||||
All these files are documented using Javadoc.
|
Similarly, a declaration @samp{%define "abstract"} will make your
|
||||||
|
class abstract.
|
||||||
|
|
||||||
|
You can create documentation for generated parsers using Javadoc.
|
||||||
|
|
||||||
@node Java Semantic Values
|
@node Java Semantic Values
|
||||||
@subsection Java Semantic Values
|
@subsection Java Semantic Values
|
||||||
@@ -8404,7 +8407,7 @@ superclass of all the semantic values using the @samp{%define} directive.
|
|||||||
For example, after the following declaration:
|
For example, after the following declaration:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
%define "union_name" "ASTNode"
|
%define "stype" "ASTNode"
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
@@ -8483,7 +8486,7 @@ Run the syntactic analysis, and return @code{true} on success,
|
|||||||
@code{false} otherwise.
|
@code{false} otherwise.
|
||||||
@end deftypemethod
|
@end deftypemethod
|
||||||
|
|
||||||
@deftypemethod {YYParser} {boolean} yyrecovering ()
|
@deftypemethod {YYParser} {boolean} recovering ()
|
||||||
During the syntactic analysis, return @code{true} if recovering
|
During the syntactic analysis, return @code{true} if recovering
|
||||||
from a syntax error. @xref{Error Recovery}.
|
from a syntax error. @xref{Error Recovery}.
|
||||||
@end deftypemethod
|
@end deftypemethod
|
||||||
@@ -8510,33 +8513,39 @@ Interface}); the parser uses it to report a parser error occurring at
|
|||||||
|
|
||||||
@node Java Scanner Interface
|
@node Java Scanner Interface
|
||||||
@subsection Java Scanner Interface
|
@subsection Java Scanner Interface
|
||||||
@c - prefix for yylex.
|
@c - %code lexer
|
||||||
@c - Pure interface to yylex
|
|
||||||
@c - %lex-param
|
@c - %lex-param
|
||||||
|
@c - Lexer interface
|
||||||
|
|
||||||
There are two possible ways to interface a Bison-generated Java parser
|
|
||||||
with a scanner.
|
|
||||||
|
|
||||||
@cindex pure parser, in Java
|
|
||||||
Contrary to C parsers, Java parsers do not use global variables; the
|
Contrary to C parsers, Java parsers do not use global variables; the
|
||||||
state of the parser is always local to an instance of the parser class.
|
state of the parser is always local to an instance of the parser class.
|
||||||
Therefore, all Java parsers are ``pure'' in the C sense. The
|
Therefore, all Java parsers are ``pure'', and the @code{%pure-parser}
|
||||||
@code{%pure-parser} directive can still be used in Java, and it
|
directive does not do anything when used in Java.
|
||||||
will control whether the lexer resides in a separate class than the
|
|
||||||
Bison-generated parser (therefore, Bison generates a class that is
|
|
||||||
``purely'' a parser), or in the same class. The interface to the scanner
|
|
||||||
is similar, though the two cases present a slightly different naming.
|
|
||||||
|
|
||||||
For the @code{%pure-parser} case, the scanner implements an interface
|
The scanner always resides in a separate class than the parser.
|
||||||
called @code{Lexer} and defined within the parser class (e.g.,
|
Still, Java also two possible ways to interface a Bison-generated Java
|
||||||
@code{YYParser.Lexer}. The constructor of the parser object accepts
|
parser with a scanner, that is, the scanner may reside in a separate file
|
||||||
an object implementing the interface. The interface specifies
|
than the Bison grammar, or in the same file. The interface
|
||||||
the following methods.
|
to the scanner is similar in the two cases.
|
||||||
|
|
||||||
@deftypemethod {Lexer} {void} error (Location @var{l}, String @var{m})
|
In the first case, where the scanner in the same file as the grammar, the
|
||||||
|
scanner code has to be placed in @code{%code lexer} blocks. If you want
|
||||||
|
to pass parameters from the parser constructor to the scanner constructor,
|
||||||
|
specify them with @code{%lex-param}; they are passed before
|
||||||
|
@code{%parse-param}s to the constructor.
|
||||||
|
|
||||||
|
In the second case, the scanner has to implement interface @code{Lexer},
|
||||||
|
which is defined within the parser class (e.g., @code{YYParser.Lexer}).
|
||||||
|
The constructor of the parser object will then accept an object
|
||||||
|
implementing the interface; @code{%lex-param} is not used in this
|
||||||
|
case.
|
||||||
|
|
||||||
|
In both cases, the scanner has to implement the following methods.
|
||||||
|
|
||||||
|
@deftypemethod {Lexer} {void} yyerror (Location @var{l}, String @var{m})
|
||||||
As explained in @pxref{Java Parser Interface}, this method is defined
|
As explained in @pxref{Java Parser Interface}, this method is defined
|
||||||
by the user to emit an error message. The first parameter is not used
|
by the user to emit an error message. The first parameter is omitted
|
||||||
unless location tracking is active. Its type can be changed using
|
if location tracking is not active. Its type can be changed using
|
||||||
@samp{%define "location_type" "@var{class-name}".}
|
@samp{%define "location_type" "@var{class-name}".}
|
||||||
@end deftypemethod
|
@end deftypemethod
|
||||||
|
|
||||||
@@ -8549,9 +8558,9 @@ interface. Invocations of @samp{%lex-param @{@var{type1}
|
|||||||
|
|
||||||
@deftypemethod {Lexer} {Position} getStartPos ()
|
@deftypemethod {Lexer} {Position} getStartPos ()
|
||||||
@deftypemethodx {Lexer} {Position} getEndPos ()
|
@deftypemethodx {Lexer} {Position} getEndPos ()
|
||||||
Return respectively the first position of the last token that yylex
|
Return respectively the first position of the last token that
|
||||||
returned, and the first position beyond it. These methods are not
|
@code{yylex} returned, and the first position beyond it. These
|
||||||
needed unless location tracking is active.
|
methods are not needed unless location tracking is active.
|
||||||
|
|
||||||
The return type can be changed using @samp{%define "position_type"
|
The return type can be changed using @samp{%define "position_type"
|
||||||
"@var{class-name}".}
|
"@var{class-name}".}
|
||||||
@@ -8561,7 +8570,7 @@ The return type can be changed using @samp{%define "position_type"
|
|||||||
Return respectively the first position of the last token that yylex
|
Return respectively the first position of the last token that yylex
|
||||||
returned, and the first position beyond it.
|
returned, and the first position beyond it.
|
||||||
|
|
||||||
The return type can be changed using @samp{%define "union_name"
|
The return type can be changed using @samp{%define "stype"
|
||||||
"@var{class-name}".}
|
"@var{class-name}".}
|
||||||
@end deftypemethod
|
@end deftypemethod
|
||||||
|
|
||||||
@@ -8599,19 +8608,10 @@ The field's type can be changed using @samp{%define "position_type"
|
|||||||
Return respectively the first position of the last token that yylex
|
Return respectively the first position of the last token that yylex
|
||||||
returned, and the first position beyond it.
|
returned, and the first position beyond it.
|
||||||
|
|
||||||
The field's type can be changed using @samp{%define "union_name"
|
The field's type can be changed using @samp{%define "stype"
|
||||||
"@var{class-name}".}
|
"@var{class-name}".}
|
||||||
@end deftypecv
|
@end deftypecv
|
||||||
|
|
||||||
By default the class generated for a non-pure Java parser is abstract,
|
|
||||||
and the methods @code{yylex} and @code{yyerror} shall be placed in a
|
|
||||||
subclass (possibly defined in the additional code section). It is
|
|
||||||
also possible, using the @code{%define "single_class"} declaration, to
|
|
||||||
define the scanner in the same class as the parser; when this
|
|
||||||
declaration is present, the class is not declared as abstract.
|
|
||||||
In order to place the declarations for the scanner inside the
|
|
||||||
parser class, you should use @code{%code} sections.
|
|
||||||
|
|
||||||
@node Java Differences
|
@node Java Differences
|
||||||
@subsection Differences between C/C++ and Java Grammars
|
@subsection Differences between C/C++ and Java Grammars
|
||||||
|
|
||||||
@@ -8621,10 +8621,10 @@ section summarizes this differences.
|
|||||||
|
|
||||||
@itemize
|
@itemize
|
||||||
@item
|
@item
|
||||||
Since Java lacks a preprocessor, the @code{YYERROR}, @code{YYACCEPT},
|
Java lacks a preprocessor, so the @code{YYERROR}, @code{YYACCEPT},
|
||||||
@code{YYABORT} symbols (@pxref{Table of Symbols}) cannot obviously be
|
@code{YYABORT} symbols (@pxref{Table of Symbols}) cannot obviously be
|
||||||
macros. Instead, they should be preceded in an action with
|
macros. Instead, they should be preceded by @code{return} when they
|
||||||
@code{return}. The actual definition of these symbols should be
|
appear in an action. The actual definition of these symbols is
|
||||||
opaque to the Bison grammar, and it might change in the future. The
|
opaque to the Bison grammar, and it might change in the future. The
|
||||||
only meaningful operation that you can do, is to return them.
|
only meaningful operation that you can do, is to return them.
|
||||||
|
|
||||||
@@ -8636,19 +8636,25 @@ corresponds to these C macros.}.
|
|||||||
|
|
||||||
@item
|
@item
|
||||||
The prolog declarations have a different meaning than in C/C++ code.
|
The prolog declarations have a different meaning than in C/C++ code.
|
||||||
@table @code
|
@table @asis
|
||||||
@item %code
|
@item @code{%code imports}
|
||||||
@code{%code imports} blocks are placed at the beginning of the Java
|
blocks are placed at the beginning of the Java source code. They may
|
||||||
source code. They may include copyright notices. For a @code{package}
|
include copyright notices. For a @code{package} declarations, it is
|
||||||
declarations, it is suggested to use @code{%define package} instead.
|
suggested to use @code{%define package} instead.
|
||||||
|
|
||||||
@code{%code} blocks are placed inside the parser class. If @code{%define
|
@item unqualified @code{%code}
|
||||||
single_class} is being used, the definitions of @code{yylex} and
|
blocks are placed inside the parser class.
|
||||||
@code{yyerror} should be placed here. Subroutines for the parser actions
|
|
||||||
may be included in this kind of block.
|
@item @code{%code lexer}
|
||||||
|
blocks, if specified, should include the implementation of the
|
||||||
|
scanner. If there is no such block, the scanner can be any class
|
||||||
|
that implements the appropriate interface (see @pxref{Java Scanner
|
||||||
|
Interface}).
|
||||||
|
@end item
|
||||||
|
|
||||||
Other @code{%code} blocks are not supported in Java parsers.
|
Other @code{%code} blocks are not supported in Java parsers.
|
||||||
@end table
|
The epilogue has the same meaning as in C/C++ code and it can
|
||||||
|
be used to define other classes used by the parser.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@c ================================================= FAQ
|
@c ================================================= FAQ
|
||||||
|
|||||||
278
tests/java.at
278
tests/java.at
@@ -25,7 +25,7 @@ AT_BANNER([[Java Calculator.]])
|
|||||||
# ------------------------- #
|
# ------------------------- #
|
||||||
|
|
||||||
|
|
||||||
# _AT_DATA_JAVA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES], [BISON-EPILOGUE])
|
# _AT_DATA_JAVA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
# Produce `calc.y'. Don't call this macro directly, because it contains
|
# Produce `calc.y'. Don't call this macro directly, because it contains
|
||||||
# some occurrences of `$1' etc. which will be interpreted by m4. So
|
# some occurrences of `$1' etc. which will be interpreted by m4. So
|
||||||
@@ -37,11 +37,12 @@ m4_define([_AT_DATA_JAVA_CALC_Y],
|
|||||||
AT_DATA([Calc.y],
|
AT_DATA([Calc.y],
|
||||||
[[/* Infix notation calculator--calc */
|
[[/* Infix notation calculator--calc */
|
||||||
%language "Java"
|
%language "Java"
|
||||||
%name-prefix "Calc"]
|
%name-prefix "Calc"
|
||||||
%define parser_class_name "Calc"
|
%define parser_class_name "Calc"
|
||||||
%define public
|
%define public
|
||||||
|
|
||||||
$4[
|
]$4[
|
||||||
|
|
||||||
%code imports {
|
%code imports {
|
||||||
import java.io.StreamTokenizer;
|
import java.io.StreamTokenizer;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -93,52 +94,130 @@ exp:
|
|||||||
| '!' { $$ = new Integer (0); return YYERROR; }
|
| '!' { $$ = new Integer (0); return YYERROR; }
|
||||||
| '-' error { $$ = new Integer (0); return YYERROR; }
|
| '-' error { $$ = new Integer (0); return YYERROR; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
]AT_LEXPARAM_IF([[
|
||||||
|
%code lexer {
|
||||||
|
]],
|
||||||
|
[[
|
||||||
%%
|
%%
|
||||||
|
class CalcLexer implements Calc.Lexer {
|
||||||
|
]])[
|
||||||
|
StreamTokenizer st;
|
||||||
|
|
||||||
class Position {
|
public ]AT_LEXPARAM_IF([[YYLexer]], [[CalcLexer]]) (InputStream is)
|
||||||
public int line;
|
{
|
||||||
|
st = new StreamTokenizer (new InputStreamReader (is));
|
||||||
public Position ()
|
st.resetSyntax ();
|
||||||
{
|
st.eolIsSignificant (true);
|
||||||
line = 0;
|
st.whitespaceChars (9, 9);
|
||||||
}
|
st.whitespaceChars (32, 32);
|
||||||
|
st.wordChars (48, 57);
|
||||||
public Position (int l)
|
|
||||||
{
|
|
||||||
line = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getHashCode ()
|
|
||||||
{
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals (Position l)
|
|
||||||
{
|
|
||||||
return l.line == line;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString ()
|
|
||||||
{
|
|
||||||
return Integer.toString (line);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int lineno ()
|
|
||||||
{
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
]$5
|
AT_LOCATION_IF([[
|
||||||
])
|
Position yystartpos;
|
||||||
|
Position yyendpos = new Position (1);
|
||||||
|
|
||||||
|
public Position getStartPos() {
|
||||||
|
return yystartpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Position getEndPos() {
|
||||||
|
return yyendpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void yyerror (Calc.Location l, String s)
|
||||||
|
{
|
||||||
|
if (l == null)
|
||||||
|
System.err.println (s);
|
||||||
|
else
|
||||||
|
System.err.println (l.begin + ": " + s);
|
||||||
|
}
|
||||||
|
]], [[
|
||||||
|
public void yyerror (String s)
|
||||||
|
{
|
||||||
|
System.err.println (s);
|
||||||
|
}
|
||||||
|
]])[
|
||||||
|
|
||||||
|
Integer yylval;
|
||||||
|
|
||||||
|
public Object getLVal() {
|
||||||
|
return yylval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int yylex () throws IOException {
|
||||||
|
int ttype = st.nextToken ();
|
||||||
|
]AT_LOCATION_IF([[yystartpos = yyendpos;]])[
|
||||||
|
if (ttype == st.TT_EOF)
|
||||||
|
return Calc.EOF;
|
||||||
|
|
||||||
|
else if (ttype == st.TT_EOL)
|
||||||
|
{
|
||||||
|
]AT_LOCATION_IF([[yyendpos = new Position (yyendpos.lineno () + 1);]])[
|
||||||
|
return (int) '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (ttype == st.TT_WORD)
|
||||||
|
{
|
||||||
|
yylval = new Integer (st.sval);
|
||||||
|
return Calc.NUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
return st.ttype;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]AT_LEXPARAM_IF([[
|
||||||
|
};
|
||||||
|
%%]], [[
|
||||||
|
}]])
|
||||||
|
|
||||||
|
[
|
||||||
|
class Position {
|
||||||
|
public int line;
|
||||||
|
|
||||||
|
public Position ()
|
||||||
|
{
|
||||||
|
line = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Position (int l)
|
||||||
|
{
|
||||||
|
line = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getHashCode ()
|
||||||
|
{
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals (Position l)
|
||||||
|
{
|
||||||
|
return l.line == line;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
return Integer.toString (line);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int lineno ()
|
||||||
|
{
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
]])
|
||||||
])# _AT_DATA_JAVA_CALC_Y
|
])# _AT_DATA_JAVA_CALC_Y
|
||||||
|
|
||||||
|
|
||||||
# AT_DATA_CALC_Y([BISON-OPTIONS], [BISON-EPILOGUE])
|
# AT_DATA_CALC_Y([BISON-OPTIONS])
|
||||||
# -------------------------------------------------
|
# -------------------------------------------------
|
||||||
# Produce `calc.y'.
|
# Produce `calc.y'.
|
||||||
m4_define([AT_DATA_JAVA_CALC_Y],
|
m4_define([AT_DATA_JAVA_CALC_Y],
|
||||||
[_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1], [$2])
|
[_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@@ -196,7 +275,7 @@ mv at-expout expout]])
|
|||||||
AT_CHECK([cat stderr], 0, [expout])
|
AT_CHECK([cat stderr], 0, [expout])
|
||||||
])
|
])
|
||||||
|
|
||||||
# _AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-CODE], [BISON-EPILOGUE])
|
# _AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-CODE])
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
# Start a testing chunk which compiles `calc' grammar with
|
# Start a testing chunk which compiles `calc' grammar with
|
||||||
# BISON-DIRECTIVES, and performs several tests over the parser.
|
# BISON-DIRECTIVES, and performs several tests over the parser.
|
||||||
@@ -209,7 +288,7 @@ AT_BISON_OPTION_PUSHDEFS([$1])
|
|||||||
AT_DATA_JAVA_CALC_Y([$1
|
AT_DATA_JAVA_CALC_Y([$1
|
||||||
%code {
|
%code {
|
||||||
$2
|
$2
|
||||||
}], [$3])
|
}])
|
||||||
|
|
||||||
AT_CHECK([bison -o Calc.java Calc.y])
|
AT_CHECK([bison -o Calc.java Calc.y])
|
||||||
AT_JAVA_COMPILE([Calc.java])
|
AT_JAVA_COMPILE([Calc.java])
|
||||||
@@ -288,14 +367,16 @@ AT_CLEANUP
|
|||||||
])# _AT_CHECK_JAVA_CALC
|
])# _AT_CHECK_JAVA_CALC
|
||||||
|
|
||||||
|
|
||||||
# AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-EPILOGUE])
|
# AT_CHECK_JAVA_CALC([BISON-DIRECTIVES])
|
||||||
# --------------------------------------------------------
|
# --------------------------------------------------------
|
||||||
# Start a testing chunk which compiles `calc' grammar with
|
# Start a testing chunk which compiles `calc' grammar with
|
||||||
# BISON-DIRECTIVES, and performs several tests over the parser.
|
# BISON-DIRECTIVES, and performs several tests over the parser.
|
||||||
# Run the test with and without %error-verbose.
|
# Run the test with and without %error-verbose.
|
||||||
m4_define([AT_CHECK_JAVA_CALC],
|
m4_define([AT_CHECK_JAVA_CALC],
|
||||||
[_AT_CHECK_JAVA_CALC([$1], [$2], [$3])
|
[_AT_CHECK_JAVA_CALC([$1], [$2])
|
||||||
_AT_CHECK_JAVA_CALC([%error-verbose $1], [$2], [$3])
|
_AT_CHECK_JAVA_CALC([%error-verbose $1], [$2])
|
||||||
|
_AT_CHECK_JAVA_CALC([%locations $1], [$2])
|
||||||
|
_AT_CHECK_JAVA_CALC([%error-verbose %locations $1], [$2])
|
||||||
])# AT_CHECK_JAVA_CALC
|
])# AT_CHECK_JAVA_CALC
|
||||||
|
|
||||||
|
|
||||||
@@ -303,113 +384,18 @@ _AT_CHECK_JAVA_CALC([%error-verbose $1], [$2], [$3])
|
|||||||
# Simple LALR Calculator. #
|
# Simple LALR Calculator. #
|
||||||
# ------------------------ #
|
# ------------------------ #
|
||||||
|
|
||||||
dnl AT_CHECK_JAVA_CALC([], [])
|
AT_CHECK_JAVA_CALC([], [[
|
||||||
|
|
||||||
AT_CHECK_JAVA_CALC([%define single_class %locations], [[
|
|
||||||
StreamTokenizer st;
|
|
||||||
|
|
||||||
public Calc (InputStream is)
|
|
||||||
{
|
|
||||||
Reader r = new InputStreamReader (is);
|
|
||||||
st = new StreamTokenizer(r);
|
|
||||||
st.resetSyntax ();
|
|
||||||
st.eolIsSignificant (true);
|
|
||||||
st.whitespaceChars (9, 9);
|
|
||||||
st.whitespaceChars (32, 32);
|
|
||||||
st.wordChars (48, 57);
|
|
||||||
|
|
||||||
yyendpos = new Position (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int yylex () throws IOException {
|
|
||||||
int ttype = st.nextToken ();
|
|
||||||
yystartpos = yyendpos;
|
|
||||||
if (ttype == st.TT_EOF)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
else if (ttype == st.TT_EOL)
|
|
||||||
{
|
|
||||||
yyendpos = new Position (yyendpos.lineno () + 1);
|
|
||||||
return (int) '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (ttype == st.TT_WORD)
|
|
||||||
{
|
|
||||||
yylval = new Integer (st.sval);
|
|
||||||
return NUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
return st.ttype;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void yyerror (Location l, String s)
|
|
||||||
{
|
|
||||||
if (l == null)
|
|
||||||
System.err.println (s);
|
|
||||||
else
|
|
||||||
System.err.println (l.begin + ": " + s);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main (String args[]) throws IOException
|
|
||||||
{
|
|
||||||
new Calc (System.in).parse ();
|
|
||||||
}
|
|
||||||
]])
|
|
||||||
|
|
||||||
AT_CHECK_JAVA_CALC([%pure-parser], [[
|
|
||||||
public static void main (String args[]) throws IOException
|
public static void main (String args[]) throws IOException
|
||||||
{
|
{
|
||||||
CalcLexer l = new CalcLexer (System.in);
|
CalcLexer l = new CalcLexer (System.in);
|
||||||
Calc p = new Calc (l);
|
Calc p = new Calc (l);
|
||||||
p.parse ();
|
p.parse ();
|
||||||
}
|
}
|
||||||
]], [[
|
|
||||||
class CalcLexer implements Calc.Lexer {
|
|
||||||
Integer yylval;
|
|
||||||
|
|
||||||
StreamTokenizer st;
|
|
||||||
|
|
||||||
public Object getLVal ()
|
|
||||||
{
|
|
||||||
return yylval;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CalcLexer (InputStream is)
|
|
||||||
{
|
|
||||||
Reader r = new InputStreamReader (is);
|
|
||||||
st = new StreamTokenizer(r);
|
|
||||||
st.resetSyntax ();
|
|
||||||
st.eolIsSignificant (true);
|
|
||||||
st.whitespaceChars (9, 9);
|
|
||||||
st.whitespaceChars (32, 32);
|
|
||||||
st.wordChars (48, 57);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int yylex () throws IOException {
|
|
||||||
int ttype = st.nextToken ();
|
|
||||||
if (ttype == st.TT_EOF)
|
|
||||||
return Calc.EOF;
|
|
||||||
|
|
||||||
else if (ttype == st.TT_EOL)
|
|
||||||
return (int) '\n';
|
|
||||||
|
|
||||||
else if (ttype == st.TT_WORD)
|
|
||||||
{
|
|
||||||
yylval = new Integer (st.sval);
|
|
||||||
return Calc.NUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
return st.ttype;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void yyerror (String s)
|
|
||||||
{
|
|
||||||
System.err.println (s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
dnl AT_CHECK_JAVA_CALC([%pure-parser %locations], [])
|
AT_CHECK_JAVA_CALC([%lex-param { InputStream is } ], [[
|
||||||
|
public static void main (String args[]) throws IOException
|
||||||
|
{
|
||||||
|
new Calc (System.in).parse ();
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ m4_pushdef([AT_GLR_CC_IF],
|
|||||||
# Using yacc.c?
|
# Using yacc.c?
|
||||||
m4_pushdef([AT_YACC_IF],
|
m4_pushdef([AT_YACC_IF],
|
||||||
[m4_bmatch([$3], [%language\|%glr-parser\|%skeleton], [$2], [$1])])
|
[m4_bmatch([$3], [%language\|%glr-parser\|%skeleton], [$2], [$1])])
|
||||||
|
m4_pushdef([AT_LEXPARAM_IF],
|
||||||
|
[m4_bmatch([$3], [%lex-param], [$1], [$2])])
|
||||||
m4_pushdef([AT_PARAM_IF],
|
m4_pushdef([AT_PARAM_IF],
|
||||||
[m4_bmatch([$3], [%parse-param], [$1], [$2])])
|
[m4_bmatch([$3], [%parse-param], [$1], [$2])])
|
||||||
m4_pushdef([AT_LOCATION_IF],
|
m4_pushdef([AT_LOCATION_IF],
|
||||||
@@ -128,6 +130,7 @@ m4_popdef([AT_GLR_OR_PARAM_IF])
|
|||||||
m4_popdef([AT_PURE_AND_LOC_IF])
|
m4_popdef([AT_PURE_AND_LOC_IF])
|
||||||
m4_popdef([AT_LOCATION_IF])
|
m4_popdef([AT_LOCATION_IF])
|
||||||
m4_popdef([AT_PARAM_IF])
|
m4_popdef([AT_PARAM_IF])
|
||||||
|
m4_popdef([AT_LEXPARAM_IF])
|
||||||
m4_popdef([AT_YACC_IF])
|
m4_popdef([AT_YACC_IF])
|
||||||
m4_popdef([AT_GLR_IF])
|
m4_popdef([AT_GLR_IF])
|
||||||
m4_popdef([AT_SKEL_CC_IF])
|
m4_popdef([AT_SKEL_CC_IF])
|
||||||
|
|||||||
Reference in New Issue
Block a user