| # Checking Java Push Parsing. -*- Autotest -*- |
| |
| # Copyright (C) 2013-2015, 2018-2021 Free Software Foundation, Inc. |
| |
| # This program is free software: you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation, either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <https://www.gnu.org/licenses/>. |
| |
| # The Java push parser tests are intended primarily |
| # to verify that the sequence of states that the parser |
| # traverses is the same as a pull parser would traverse. |
| |
| ################################################## |
| # Provide a way to generate data with and without push parsing |
| # so it is possible to capture the output for comparison |
| # (except the "trivial" tests). |
| # Use "both" rather than "push" so we can also set it to "pull" to |
| # get the "experr" data. |
| |
| m4_define([PUSHPULLFLAG],[-Dapi.push-pull=both]) |
| |
| # AT_CHECK_JAVA_GREP(FILE, [LINE], [COUNT=1]) |
| # ------------------------------------------- |
| # Check that FILE contains exactly COUNT lines matching ^LINE$ |
| # with grep. Unquoted so that COUNT can be a shell expression. |
| m4_define([AT_CHECK_JAVA_GREP], |
| [AT_CHECK_UNQUOTED([grep -c '^$2$' $1], [ignore], [m4_default([$3], [1]) |
| ])]) |
| |
| |
| ################################################## |
| |
| AT_BANNER([[Java Push Parsing Tests]]) |
| |
| # Define a single copy of the trivial parser grammar. |
| # This is missing main(), so two versions |
| # are instantiated with different main() procedures. |
| m4_define([AT_TRIVIAL_GRAMMAR], |
| [[ |
| %define api.parser.class {YYParser} |
| %define parse.error verbose |
| %define parse.trace |
| |
| %code imports { |
| import java.io.*; |
| import java.util.*; |
| } |
| |
| %% |
| |
| start: 'a' 'b' 'c' ; |
| |
| %% |
| ]]) |
| |
| # Define common code across to be included in |
| # class Main for the trivial parser tests. |
| m4_define([AT_TRIVIAL_COMMON],[[ |
| static class YYerror implements YYParser.Lexer |
| { |
| public Object getLVal() {return null;} |
| public int yylex () throws java.io.IOException { return 0; } |
| public void yyerror (String msg) { System.err.println(msg); } |
| } |
| |
| static YYParser parser = null; |
| static YYerror yyerror = null; |
| static int teststate = -1; |
| |
| static void setup() |
| throws IOException |
| { |
| yyerror = new YYerror(); |
| parser = new YYParser(yyerror); |
| parser.setDebugLevel(1); |
| teststate = -1; |
| } |
| |
| static String[] teststatename |
| = new String[]{"YYACCEPT","YYABORT","YYERROR","UNKNOWN","YYPUSH_MORE"}; |
| |
| static void check(int teststate, int expected, String msg) |
| { |
| System.err.println("teststate="+teststatename[teststate] |
| +"; expected="+teststatename[expected]); |
| if (teststate != expected) |
| { |
| System.err.println("unexpected state: "+msg); |
| System.exit(1); |
| } |
| } |
| ]]) |
| |
| m4_define([AT_TRIVIAL_PARSER],[[ |
| ]AT_TRIVIAL_GRAMMAR[ |
| |
| public class Main |
| { |
| |
| ]AT_TRIVIAL_COMMON[ |
| |
| static public void main (String[] args) |
| throws IOException |
| { |
| setup(); |
| |
| teststate = parser.push_parse('a', null); |
| check(teststate,YYParser.YYPUSH_MORE,"push_parse('a', null)"); |
| |
| setup(); |
| |
| teststate = parser.push_parse('a', null); |
| check(teststate,YYParser.YYPUSH_MORE,"push_parse('a', null)"); |
| teststate = parser.push_parse('b', null); |
| check(teststate,YYParser.YYPUSH_MORE,"push_parse('b', null)"); |
| teststate = parser.push_parse('c', null); |
| check(teststate,YYParser.YYPUSH_MORE,"push_parse('c', null)"); |
| teststate = parser.push_parse('\0', null); |
| check(teststate,YYParser.YYACCEPT,"push_parse('\\0', null)"); |
| |
| /* Reuse the parser instance and cause a failure */ |
| teststate = parser.push_parse('b', null); |
| check(teststate,YYParser.YYABORT,"push_parse('b', null)"); |
| |
| System.exit(0); |
| } |
| |
| } |
| ]]) |
| |
| m4_define([AT_TRIVIAL_PARSER_INITIAL_ACTION],[[ |
| ]AT_TRIVIAL_GRAMMAR[ |
| |
| public class Main |
| { |
| |
| ]AT_TRIVIAL_COMMON[ |
| |
| static public void main (String[] args) |
| throws IOException |
| { |
| setup(); |
| |
| teststate = parser.push_parse('a', null); |
| check(teststate,YYParser.YYPUSH_MORE,"push_parse('a', null)"); |
| teststate = parser.push_parse('b', null); |
| check(teststate,YYParser.YYPUSH_MORE,"push_parse('b', null)"); |
| teststate = parser.push_parse('c', null); |
| check(teststate,YYParser.YYPUSH_MORE,"push_parse('c', null)"); |
| teststate = parser.push_parse('\0', null); |
| check(teststate,YYParser.YYACCEPT,"push_parse('\\0', null)"); |
| |
| System.exit(0); |
| } |
| |
| } |
| ]]) |
| |
| ## ----------------------------------------------------- ## |
| ## Trivial Push Parser with api.push-pull verification. ## |
| ## ----------------------------------------------------- ## |
| |
| AT_SETUP([Trivial Push Parser with api.push-pull verification]) |
| AT_BISON_OPTION_PUSHDEFS |
| |
| AT_DATA([[input.y]], |
| [[%language "Java" |
| ]AT_TRIVIAL_PARSER[ |
| ]]) |
| |
| # Verify that the proper procedure(s) are generated for each case. |
| AT_BISON_CHECK([[-Dapi.push-pull=pull -o Main.java input.y]]) |
| AT_CHECK_JAVA_GREP([[Main.java]], |
| [[.*public boolean parse().*]], |
| [1]) |
| # If BISON_USE_PUSH_FOR_PULL is set, then we have one occurrence of |
| # this function, otherwise it should not be there. |
| AT_CHECK_JAVA_GREP([[Main.java]], |
| [[.*public int push_parse(int yylextoken, Object yylexval).*]], |
| [${BISON_USE_PUSH_FOR_PULL-0}]) |
| |
| AT_BISON_CHECK([[-Dapi.push-pull=both -o Main.java input.y]]) |
| AT_CHECK_JAVA_GREP([[Main.java]], |
| [[.*public boolean parse().*]], |
| [1]) |
| AT_CHECK_JAVA_GREP([[Main.java]], |
| [[.*public int push_parse(int yylextoken, Object yylexval).*]], |
| [1]) |
| |
| AT_BISON_CHECK([[-Dapi.push-pull=push -o Main.java input.y]]) |
| AT_CHECK_JAVA_GREP([[Main.java]], |
| [[.*public boolean parse().*]], |
| [0]) |
| AT_CHECK_JAVA_GREP([[Main.java]], |
| [[.*public int push_parse(int yylextoken, Object yylexval).*]], |
| [1]) |
| |
| AT_JAVA_COMPILE([[Main.java]]) |
| AT_JAVA_PARSER_CHECK([Main], 0, [], [stderr-nolog]) |
| AT_BISON_OPTION_POPDEFS |
| AT_CLEANUP |
| |
| |
| ## ------------------------------------------ ## |
| ## Trivial Push Parser with %initial-action. ## |
| ## ------------------------------------------ ## |
| |
| AT_SETUP([Trivial Push Parser with %initial-action]) |
| AT_BISON_OPTION_PUSHDEFS |
| AT_DATA([[input.y]], |
| [[%language "Java" |
| %initial-action { |
| System.err.println("Initial action invoked"); |
| } |
| ]AT_TRIVIAL_PARSER_INITIAL_ACTION[ |
| ]]) |
| AT_BISON_OPTION_POPDEFS |
| AT_BISON_CHECK([[-Dapi.push-pull=push -o Main.java input.y]]) |
| AT_CHECK_JAVA_GREP([[Main.java]], |
| [[System.err.println("Initial action invoked");]]) |
| AT_JAVA_COMPILE([[Main.java]]) |
| AT_JAVA_PARSER_CHECK([Main], 0, [], [stderr-nolog]) |
| # Verify that initial action is called exactly once. |
| AT_CHECK_JAVA_GREP( |
| [[stderr]], |
| [[Initial action invoked]], |
| [1]) |
| AT_CLEANUP |