# Checking Java Push Parsing. -*- Autotest -*- # Copyright (C) 2013-2015, 2018-2022 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 . # 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