From 7ddeb166c05a68ebea9b4976373694337614c5ae Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 23 Mar 2023 09:28:54 -0600 Subject: yacc tool updates The yacc tool now recognizes the bison syntax of using --header, --defines and --graph options in YACCFLAGS without supplying an option argument. Note that byacc doesn't allow leaving off the option argument, and would error out in such cases. Fixes #4326 The yacc tool now recognizes -H as a partial synonym for --header. It only works in the no-option-argument form - giving an option argument will likely break things. Fixes #4327 Tests are expanded to cover these. The graph file name (-g) is now generated relative to the requested target file name, not to the source name, to match actual current behavior. This is rare case - only kicks in if target explicitly requested with a different base name than source - in this case SCons would emit a different name than bison produces. Unlikely to affect any real usage - you would have to set up the condition described, and additionally use the graph file as a source for some other build target. The default file suffix for graph files is set to .gv, which is current for Bison as of 3.8. The previous suffix for Bison, dating back to 2.4, was .dot, which is still the suffix byacc uses. Docs updated to better describe when you need to set this. The former default, .vcg, has not been used since 2006. Documentation updated for the two header suffix construction variables to better describe (I hope) what these mean and when to set them. Other doc updates as well. Signed-off-by: Mats Wichmann --- CHANGES.txt | 9 +++ SCons/Tool/Tool.xml | 26 +++++-- SCons/Tool/yacc.py | 35 ++++++---- SCons/Tool/yacc.xml | 92 +++++++++++++------------ test/YACC/BISONFLAGS.py | 49 ++++++++++++- test/YACC/YACCFLAGS-fixture/myyacc.py | 125 ++++++++++++++++++++++------------ test/YACC/YACCFLAGS.py | 2 +- 7 files changed, 230 insertions(+), 108 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d4ad973..2977fa8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -23,6 +23,15 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER calls dunder method __call__. Invoke instance directly." - Python 3.9 dropped the alias base64.decodestring, deprecated since 3.1. Only used in msvs.py. Use base64.decodebytes instead. + - The yacc tool now understands the bison behavior of --header, + --defines and --graph being called without option-argument as being + synonyms for -d (first two) and -g. -H also recognized as a synonym + for -d. Default value for $YACCVCGFILESUFFIX changed to '.gv' + to match current bison default (since bison 3.8). The graph file name + (-g) is now generated relative to the requested target file name, + not to the source file name, to match actual current behavior (only + affects if target explicitly requested with a different base name + than source). Docs updated. Fixes #4326 and #4327. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/Tool/Tool.xml b/SCons/Tool/Tool.xml index de71efb..d25d7a5 100644 --- a/SCons/Tool/Tool.xml +++ b/SCons/Tool/Tool.xml @@ -37,10 +37,19 @@ Example: # builds foo.c -env.CFile(target = 'foo.c', source = 'foo.l') +env.CFile(target='foo.c', source='foo.l') + # builds bar.c -env.CFile(target = 'bar', source = 'bar.y') +env.CFile(target='bar', source='bar.y') + + +Note that for yacc files, +the output file name is derived from target, +or from the source file name if a target is not specified; +the traditional yacc default name +y.tab.c is not used. + @@ -59,10 +68,19 @@ Example: # builds foo.cc -env.CXXFile(target = 'foo.cc', source = 'foo.ll') +env.CXXFile(target='foo.cc', source='foo.ll') + # builds bar.cc -env.CXXFile(target = 'bar', source = 'bar.yy') +env.CXXFile(target='bar', source='bar.yy') + + +Note that for yacc files, +the output file name is derived from target, +or from the source file name if a target is not specified; +the traditional yacc default name +y.tab.cc is not used. + diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py index 67ecd86..d408e62 100644 --- a/SCons/Tool/yacc.py +++ b/SCons/Tool/yacc.py @@ -23,8 +23,11 @@ """Tool-specific initialization for yacc. -This tool should support multiple yacc implementations, -but is in actuality biased towards GNU Bison. +This tool should support multiple yacc implementations, but is in actuality +biased towards GNU Bison. In particular, it forces the output file name (thus +avoiding the default convention of y.tab.c or foo.tab.c), so the tool *must* +support the -o option, which pure POSIX yacc does not. byacc should be okay +as an alternative to bison. There normally shouldn't be any need to import this module directly. It will usually be imported through the generic SCons.Tool.Tool() @@ -64,15 +67,17 @@ def _yaccEmitter(target, source, env, ysuf, hsuf) -> tuple: target = [targetBase + ".m"] # the extension is ".m". # If -d is specified on the command line, yacc will emit a .h - # or .hpp file with the same name as the .c or .cpp output file. - if '-d' in flags: + # or .hpp file with the same base name as the .c or .cpp output file. + # if '-d' in flags: # add bison options -H, --header, --defines (obsolete) + if "-d" in flags or "-H" in flags or "--header" in flags or "--defines" in flags: target.append(targetBase + env.subst(hsuf, target=target, source=source)) - # If -g is specified on the command line, yacc will emit a .vcg - # file with the same base name as the .y, .yacc, .ym or .yy file. - if "-g" in flags: - base, ext = os.path.splitext(to_String(source[0])) - target.append(base + env.subst("$YACCVCGFILESUFFIX")) + # If -g is specified on the command line, yacc will emit a graph + # file with the same base name as the .c or .cpp output file. + # TODO: should this be handled like -v? i.e. a side effect, not target + # if "-g" in flags: # add bison option --graph + if "-g" in flags or "--graph" in flags: + target.append(targetBase + env.subst("$YACCVCGFILESUFFIX")) # If -v is specified yacc will create the output debug file # which is not really source for any process, but should @@ -82,11 +87,13 @@ def _yaccEmitter(target, source, env, ysuf, hsuf) -> tuple: env.Clean(target[0], targetBase + '.output') # With --defines and --graph, the file to write is defined by the option - # argument. Extract this and include in the list of targets. - # NOTE: a filename passed to the command this way is not modified by SCons, - # and so will be interpreted relative to the project top directory at - # execution time, while the name added to the target list will be + # argument, if present (the no-option-argument cases were caught above). + # Extract this and include in the list of targets. + # NOTE: a filename passed to the command this way is not modified by + # SCons, and so will be interpreted relative to the project top directory + # at execution time, while the name added to the target list will be # interpreted relative to the SConscript directory - a possible mismatch. + # Better to use YACC_HEADER_FILE and YACC_GRAPH_FILE to pass these. # # These are GNU bison-only options. # Since bison 3.8, --header is the preferred name over --defines @@ -185,7 +192,7 @@ def generate(env) -> None: env['YACCCOM'] = '$YACC $YACCFLAGS $_YACC_HEADER $_YACC_GRAPH -o $TARGET $SOURCES' env['YACCHFILESUFFIX'] = '.h' env['YACCHXXFILESUFFIX'] = '.hpp' - env['YACCVCGFILESUFFIX'] = '.vcg' + env['YACCVCGFILESUFFIX'] = '.gv' env['_YACC_HEADER'] = '${YACC_HEADER_FILE and "--header=" + str(YACC_HEADER_FILE)}' env['_YACC_GRAPH'] = '${YACC_GRAPH_FILE and "--graph=" + str(YACC_GRAPH_FILE)}' diff --git a/SCons/Tool/yacc.xml b/SCons/Tool/yacc.xml index 9ccc4e6..cf466a2 100644 --- a/SCons/Tool/yacc.xml +++ b/SCons/Tool/yacc.xml @@ -115,6 +115,7 @@ with the suffix defined by &cv-link-YACCHFILESUFFIX; if the yacc source file ends in a .y suffix, or a file with the suffix defined by &cv-link-YACCHXXFILESUFFIX; if the yacc source file ends in a .yy suffix. +The header will have the same base name as the requested target. @@ -131,22 +132,31 @@ with the suffix .output. Also recognized are GNU &bison; options - and its deprecated synonym -, + +(and its deprecated synonym ), which is similar to -but the output filename is named by the option argument; -and , +but gives the option to explicitly name the output header file +through an option argument; +and , which is similar to -but the output filename is named by the option argument. +but gives the option to explicitly name the output graph file +through an option argument. +The file suffixes described for + and above +are not applied if these are used in the option=argument form. Note that files specified by and may not be properly handled -by &SCons; in all situations. Consider using -&cv-link-YACC_HEADER_FILE; and &cv-link-YACC_GRAPH_FILE; instead. +by &SCons; in all situations, and using those in &cv-YACCFLAGS; +should be considered legacy support only. +Consider using &cv-link-YACC_HEADER_FILE; +and &cv-link-YACC_GRAPH_FILE; instead +if the files need to be explicitly named +(new in version 4.4.0). @@ -159,6 +169,7 @@ Will be emitted as a command-line option. Use this in preference to including in &cv-link-YACCFLAGS; directly. +New in version 4.4.0. @@ -171,6 +182,7 @@ Will be emitted as a command-line option. Use this in preference to including in &cv-link-YACCFLAGS; directly. +New in version 4.4.0. @@ -179,14 +191,13 @@ command-line option. Use this in preference to including The suffix of the C header file generated by the parser generator -when the - -option is used. -Note that setting this variable does not cause -the parser generator to generate a header -file with the specified suffix, -it exists to allow you to specify -what suffix the parser generator will use of its own accord. +when the option +(or without an option-argument) +is used in &cv-link-YACCFLAGS;. +Note that setting this variable informs &SCons; +how to construct the header filename for tracking purposes, +it does not affect the actual generated filename. +Set this to match what your parser generator produces. The default value is .h. @@ -198,22 +209,14 @@ The default value is The suffix of the C++ header file generated by the parser generator -when the - -option is used. -Note that setting this variable does not cause -the parser generator to generate a header -file with the specified suffix, -it exists to allow you to specify -what suffix the parser generator will use of its own accord. -The default value is -.hpp, -except on Mac OS X, -where the default is -${TARGET.suffix}.h. -because the default &bison; parser generator just -appends .h -to the name of the generated C++ file. +when the option +(or without an option-argument) +is used in &cv-link-YACCFLAGS;. +Note that setting this variable informs &SCons; +how to construct the header filename for tracking purposes, +it does not affect the actual generated filename. +Set this to match what your parser generator produces. +The default value is .hpp. @@ -222,17 +225,22 @@ to the name of the generated C++ file. The suffix of the file -containing the VCG grammar automaton definition -when the - -option is used. -Note that setting this variable does not cause -the parser generator to generate a VCG -file with the specified suffix, -it exists to allow you to specify -what suffix the parser generator will use of its own accord. -The default value is -.vcg. +containing a graph of the grammar automaton +when the option +(or without an option-argument) +is used in &cv-link-YACCFLAGS;. +Note that setting this variable informs &SCons; +how to construct the graph filename for tracking purposes, +it does not affect the actual generated filename. +Various yacc tools have emitted various formats +at different times. +Set this to match what your parser generator produces. +The default value is .gv. + + +Changed in version 4.X.Y: the default value +changed from .vcg (&bison; stopped generating +.vcg output with version 2.4, in 2006). diff --git a/test/YACC/BISONFLAGS.py b/test/YACC/BISONFLAGS.py index cae673d..9b8cf03 100644 --- a/test/YACC/BISONFLAGS.py +++ b/test/YACC/BISONFLAGS.py @@ -47,12 +47,13 @@ test = TestSCons.TestSCons() test.subdir('sub1') test.subdir('sub2') +test.subdir('sub3') test.dir_fixture('YACCFLAGS-fixture') test.write('SConstruct', """\ DefaultEnvironment(tools=[]) -SConscript(dirs=['sub1', 'sub2']) +SConscript(dirs=['sub1', 'sub2', 'sub3']) """) # this SConscript is for the options-in-flags version @@ -90,8 +91,50 @@ env.CFile( """ % locals()) test.write(['sub2', 'aaa.y'], "aaa.y\nYACCFLAGS\n") +# this SConscript is to try various other flag combos +test.write(['sub3', 'SConscript'], """\ +import sys + +env = Environment( + YACC=r'%(_python_)s myyacc.py', + YACCFLAGS='-x --header=header.h --graph=graph.g', + tools=['yacc', '%(linker)s', '%(compiler)s'], +) + +def check(targets, expected): + t = [str(target) for target in targets] + assert t == expected, t + +targs1 = env.CFile('trg1', source='aaa.y', YACCFLAGS='-d') +check(targs1, ['trg1.c', 'trg1.h']) + +targs2 = env.CXXFile('trg2', source='aaa.yy', YACCFLAGS='-d') +check(targs2, ['trg2.cc', 'trg2.hpp']) + +targs3 = env.CFile('trg3', source='aaa.y', YACCFLAGS='--defines=zot.q') +check(targs3, ['trg3.c', 'zot.q']) + +targs4 = env.CFile('trg4', source='aaa.y', YACCFLAGS='--header') +check(targs4, ['trg4.c', 'trg4.h']) + +targs5 = env.CFile('trg5', source='aaa.y', YACCFLAGS='-H') +check(targs5, ['trg5.c', 'trg5.h']) + +targs6 = env.CFile('trg6', source='aaa.y', YACCFLAGS='-g') +check(targs6, ['trg6.c', 'trg6.gv']) + +targs7 = env.CFile('trg7', source='aaa.y', YACCFLAGS='-g -H') +check(targs7, ['trg7.c', 'trg7.h', 'trg7.gv']) + +targs8 = env.CFile('trg8', source='aaa.y', YACCFLAGS='--graph --header') +check(targs8, ['trg8.c', 'trg8.h', 'trg8.gv']) +""" % locals()) + +test.write(['sub3', 'aaa.y'], "aaa.y\nYACCFLAGS\n") +test.write(['sub3', 'aaa.yy'], "aaa.yy\nYACCFLAGS\n") + test.run('.', stderr=None) -test.must_match(['sub1', 'aaa.c'], "aaa.y\n -x --header=header.h --graph=graph.g\n") +test.must_match(['sub1', 'aaa.c'], "aaa.y\n-x --header=header.h --graph=graph.g\n") # NOTE: this behavior is "wrong" but we're keeping it for compat: # the generated files should go into 'sub1', not the topdir. @@ -109,7 +152,7 @@ test.must_match(['graph.g'], 'yacc graph\n') sub2 = Path('sub2') headerfile = sub2 / 'header.h' graphfile = sub2 / 'graph.g' -yaccflags = f"aaa.y\n -x --header={headerfile} --graph={graphfile}\n" +yaccflags = f"aaa.y\n-x --header={headerfile} --graph={graphfile}\n" test.must_match(['sub2', 'aaa.c'], yaccflags) test.must_match(['sub2', 'header.h'], 'yacc header\n') test.must_match(['sub2', 'graph.g'], 'yacc graph\n') diff --git a/test/YACC/YACCFLAGS-fixture/myyacc.py b/test/YACC/YACCFLAGS-fixture/myyacc.py index 3bc1375..8b793a1 100644 --- a/test/YACC/YACCFLAGS-fixture/myyacc.py +++ b/test/YACC/YACCFLAGS-fixture/myyacc.py @@ -1,65 +1,102 @@ -import getopt +#!/usr/bin/python +# +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +""" +Mock yacc/bison command for testing yacc tool with options +""" + +import argparse +import os import sys from pathlib import Path -def make_side_effect(path, text): +# Sentinels to make sure we pick the defaults +HEADER_DEFAULT = "_header_compute" +GRAPH_DEFAULT = "_graph_compute" +REPORT_DEFAULT = "_report_compute" + + +def make_side_effect(path, text, outfile): + if path == HEADER_DEFAULT: + file, ext = os.path.splitext(outfile) + if ext in [".y", ".yacc"]: + path = file + ".h" + elif ext in [".ym"]: + path = file + ".h.m" + elif ext in [".yy"]: + path = file + ".hpp" + else: # just guess + path = file + ".h" + if path == GRAPH_DEFAULT: + path = os.path.splitext(outfile)[0] + ".gv" + if path == REPORT_DEFAULT: + path = os.path.splitext(outfile)[0] + ".output" + p = Path(path) - if str(p.parent) != '.': + if str(p.parent) != ".": p.parent.mkdir(parents=True, exist_ok=True) with p.open(mode="wb") as f: f.write(text) def fake_yacc(): - make_header = None - make_graph = None + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument("-g", "--graph", nargs="?", const=GRAPH_DEFAULT) + parser.add_argument("-d", dest="graph", action="store_const", const=HEADER_DEFAULT) + parser.add_argument("-v", "--verbose", action="store_const", const=REPORT_DEFAULT) + parser.add_argument("-x", action="store_true") # accept, do nothing + parser.add_argument("-H", "--header", "--defines", nargs="?", const=HEADER_DEFAULT) + parser.add_argument("-o", "--output", dest="out", required=True) + parser.add_argument("-I", dest="i_arguments", default=[], action="append") + parser.add_argument("files", nargs="+") + args = parser.parse_args() + # print(f"DEBUG: {args}") - longopts = ["defines=", "header=", "graph="] - cmd_opts, args = getopt.getopt(sys.argv[1:], 'o:I:x', longopts) - opt_string = '' - i_arguments = '' - - for opt, arg in cmd_opts: - if opt == '-o': - out = arg - elif opt == '-I': - i_arguments = f'{i_arguments} {arg}' - elif opt in ('--defines', '--header'): - make_header = arg - opt_string = f'{opt_string} {opt}={arg}' - elif opt == '--graph': - make_graph = arg - opt_string = f'{opt_string} {opt}={arg}' + # Synthesize "opt_string", which, when this script used getopt, was + # collected in the arg processing loop - from some arguments. The tests + # expect this to be subbed in for YACCFLAGS in making the output file. + opt_list = [] + skip = False + for arg in sys.argv[1:]: + if skip: + skip = False + elif arg == "-o": + skip = True + elif arg.startswith("-I"): + pass else: - opt_string = f'{opt_string} {opt}' + opt_list.append(arg) + # The original didn't use the file argument(s) so we have to get rid of. + for file in args.files: + if file in opt_list: + opt_list.remove(file) + opt_string = " ".join(opt_list) + + # Now we need to do something similar for i_arguments, which is easier + i_arguments = " ".join(args.i_arguments) - with open(out, 'wb') as ofp: - for a in args: - with open(a, 'rb') as ifp: + with open(args.out, "wb") as ofp: + for file in args.files: + with open(file, "rb") as ifp: contents = ifp.read() - contents = contents.replace(b'YACCFLAGS', opt_string.encode()) - contents = contents.replace(b'YACC', b'myyacc.py') - contents = contents.replace(b'I_ARGS', i_arguments.encode()) + contents = contents.replace(b"YACCFLAGS", opt_string.encode()) + contents = contents.replace(b"YACC", b"myyacc.py") + contents = contents.replace(b"I_ARGS", i_arguments.encode()) ofp.write(contents) - # Extra bits: - if make_header: - make_side_effect(make_header, b"yacc header\n") - if make_graph: - make_side_effect(make_graph, b"yacc graph\n") + # Make extra output files + if args.header: + make_side_effect(args.header, b"yacc header\n", args.out) + if args.graph: + make_side_effect(args.graph, b"yacc graph\n", args.out) + if args.verbose: + make_side_effect(args.verbose, b"yacc debug\n", args.out) -if __name__ == '__main__': +if __name__ == "__main__": fake_yacc() sys.exit(0) - -# If -d is specified on the command line, yacc will emit a .h -# or .hpp file with the same name as the .c or .cpp output file. - -# If -g is specified on the command line, yacc will emit a .vcg -# file with the same base name as the .y, .yacc, .ym or .yy file. - -# If -v is specified yacc will create the output debug file -# which is not really source for any process, but should -# be noted and also be cleaned (issue #2558) diff --git a/test/YACC/YACCFLAGS.py b/test/YACC/YACCFLAGS.py index 1f3ad78..7a07072 100644 --- a/test/YACC/YACCFLAGS.py +++ b/test/YACC/YACCFLAGS.py @@ -56,7 +56,7 @@ env.CFile(target='out/aaa', source='in/aaa.y') test.write(['in', 'aaa.y'], "aaa.y\nYACCFLAGS\nI_ARGS\n") test.run('.', stderr=None) -test.must_match(['out', 'aaa.c'], "aaa.y\n -x\n out in\n") +test.must_match(['out', 'aaa.c'], "aaa.y\n-x\nout in\n") test.pass_test() -- cgit v0.12 From 2ef22690e2c81db7e82b0526bc935854e4e85e8e Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 6 May 2023 08:00:27 -0600 Subject: yacc changes: add RELEASE, drop doc note Per review requests Signed-off-by: Mats Wichmann --- RELEASE.txt | 9 ++++++--- SCons/Tool/Tool.xml | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/RELEASE.txt b/RELEASE.txt index c2244f2..e475755 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -26,13 +26,16 @@ DEPRECATED FUNCTIONALITY CHANGED/ENHANCED EXISTING FUNCTIONALITY --------------------------------------- -- List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug +- The yacc tool now understands the bison behavior of --header, --defines + and --graph being called without an option-argument as being synonyms + for -d (first two) and -g. -H also recognized as a synonym for -d. + Default value for $YACCVCGFILESUFFIX changed to '.gv' to match + current bison default (since bison 3.8). Set this variable to '.dot' + if using byacc. FIXES ----- - - Fixed: when using the mingw tool, if an msys2 Python is used (os.sep is '/' rather than the Windows default '\'), certain Configure checks could fail due to the construction of the path to run the compiled check. diff --git a/SCons/Tool/Tool.xml b/SCons/Tool/Tool.xml index d25d7a5..086d989 100644 --- a/SCons/Tool/Tool.xml +++ b/SCons/Tool/Tool.xml @@ -43,13 +43,13 @@ env.CFile(target='foo.c', source='foo.l') env.CFile(target='bar', source='bar.y') - + -- cgit v0.12 From e327282f5086730fc045d99c5efbc7a2be0839b4 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 8 May 2023 09:23:46 -0600 Subject: Fixup usage of new mock yacc tool When the mock tool was revised to use argparse instead of getopt, it stumbled across the problem that argparse apparently doesn't deal with a single-letter option and its option-argument not having a space between them until Python 3.8 - 3.6 and 3.7 failed the test. Change to use the space in the test/mock tool. Signed-off-by: Mats Wichmann --- test/YACC/YACCFLAGS-fixture/myyacc.py | 2 +- test/YACC/YACCFLAGS.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/YACC/YACCFLAGS-fixture/myyacc.py b/test/YACC/YACCFLAGS-fixture/myyacc.py index 8b793a1..7461501 100644 --- a/test/YACC/YACCFLAGS-fixture/myyacc.py +++ b/test/YACC/YACCFLAGS-fixture/myyacc.py @@ -67,7 +67,7 @@ def fake_yacc(): elif arg == "-o": skip = True elif arg.startswith("-I"): - pass + skip = True else: opt_list.append(arg) # The original didn't use the file argument(s) so we have to get rid of. diff --git a/test/YACC/YACCFLAGS.py b/test/YACC/YACCFLAGS.py index 7a07072..f7a3cfb 100644 --- a/test/YACC/YACCFLAGS.py +++ b/test/YACC/YACCFLAGS.py @@ -48,7 +48,7 @@ test.write('SConstruct', """ DefaultEnvironment(tools=[]) env = Environment( YACC=r'%(_python_)s myyacc.py', - YACCFLAGS='-x -I${TARGET.dir} -I${SOURCE.dir}', + YACCFLAGS='-x -I ${TARGET.dir} -I ${SOURCE.dir}', tools=['yacc', '%(linker)s', '%(compiler)s'], ) env.CFile(target='out/aaa', source='in/aaa.y') -- cgit v0.12 From 34d0aedbec2df177264c023c554c2f5cbb966ccc Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 8 May 2023 12:20:08 -0600 Subject: yacc tool: further doc tweak [skip appveyor] Signed-off-by: Mats Wichmann --- SCons/Tool/yacc.py | 2 +- SCons/Tool/yacc.xml | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py index d408e62..9751742 100644 --- a/SCons/Tool/yacc.py +++ b/SCons/Tool/yacc.py @@ -53,7 +53,7 @@ YaccAction = SCons.Action.Action("$YACCCOM", "$YACCCOMSTR") if sys.platform == 'win32': BINS = ['bison', 'yacc', 'win_bison'] else: - BINS = ["bison", "yacc"] + BINS = ["bison", "yacc", "byacc"] # for byacc, yacc is normally a link def _yaccEmitter(target, source, env, ysuf, hsuf) -> tuple: diff --git a/SCons/Tool/yacc.xml b/SCons/Tool/yacc.xml index cf466a2..cc70adb 100644 --- a/SCons/Tool/yacc.xml +++ b/SCons/Tool/yacc.xml @@ -48,7 +48,7 @@ See its __doc__ string for a discussion of the format. -Sets construction variables for the &yacc; parse generator. +Sets construction variables for the &yacc; parser generator. @@ -109,13 +109,19 @@ and adds those to the target list. -If a option is present, +If the option is present in &cv-YACCFLAGS; &scons; assumes that the call will also create a header file with the suffix defined by &cv-link-YACCHFILESUFFIX; if the yacc source file ends in a .y suffix, or a file with the suffix defined by &cv-link-YACCHXXFILESUFFIX; if the yacc source file ends in a .yy suffix. The header will have the same base name as the requested target. +This is only correct if the executable is bison +(or win_bison). +If using Berkeley yacc (byacc), +y.tab.h is always written - +avoid the in this case and +use &cv-link-YACC_HEADER_FILE; instead. -- cgit v0.12 From 201be7ebc3e65094b189ff82d75cfef3fb695321 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 9 May 2023 08:45:34 -0600 Subject: yacc tool: comment out other doc note A review request suggested removing the note in CFile/CXXFile tool doc on yacc filenames. I removed only the CFile one, this does the CXXFile one as well. Signed-off-by: Mats Wichmann --- SCons/Tool/Tool.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SCons/Tool/Tool.xml b/SCons/Tool/Tool.xml index 086d989..25e4625 100644 --- a/SCons/Tool/Tool.xml +++ b/SCons/Tool/Tool.xml @@ -74,13 +74,13 @@ env.CXXFile(target='foo.cc', source='foo.ll') env.CXXFile(target='bar', source='bar.yy') - + -- cgit v0.12 From 157c5f8354abc5ed247c84c424cdc5e171729021 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 17 May 2023 20:59:16 -0700 Subject: added YACC_GRAPH_FILE_SUFFIX to represent it's the graph file and not be tied to the suffix string. It will respect the previous value if it's not set. Added test for such --- CHANGES.txt | 4 +- RELEASE.txt | 5 +- SCons/Tool/yacc.py | 9 ++-- SCons/Tool/yacc.xml | 15 ++++++ test/YACC/YACC_GRAPH_FILE_SUFFIX.py | 96 +++++++++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 test/YACC/YACC_GRAPH_FILE_SUFFIX.py diff --git a/CHANGES.txt b/CHANGES.txt index 2977fa8..367a498 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -23,10 +23,12 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER calls dunder method __call__. Invoke instance directly." - Python 3.9 dropped the alias base64.decodestring, deprecated since 3.1. Only used in msvs.py. Use base64.decodebytes instead. + - Obsoleted YACCVCGFILESUFFIX, it's being replaced by YACC_GRAPH_FILE_SUFFIX. + If YACC_GRAPH_FILE_SUFFIX is not set, it will respect YACCVCGFILESUFFIX. - The yacc tool now understands the bison behavior of --header, --defines and --graph being called without option-argument as being synonyms for -d (first two) and -g. -H also recognized as a synonym - for -d. Default value for $YACCVCGFILESUFFIX changed to '.gv' + for -d. Default value for $YACC_GRAPH_FILE_SUFFIX changed to '.gv' to match current bison default (since bison 3.8). The graph file name (-g) is now generated relative to the requested target file name, not to the source file name, to match actual current behavior (only diff --git a/RELEASE.txt b/RELEASE.txt index e475755..095a85c 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -25,11 +25,12 @@ DEPRECATED FUNCTIONALITY CHANGED/ENHANCED EXISTING FUNCTIONALITY --------------------------------------- - +- Obsoleted YACCVCGFILESUFFIX, it's being replaced by YACC_GRAPH_FILE_SUFFIX. + If YACC_GRAPH_FILE_SUFFIX is not set, it will respect YACCVCGFILESUFFIX. - The yacc tool now understands the bison behavior of --header, --defines and --graph being called without an option-argument as being synonyms for -d (first two) and -g. -H also recognized as a synonym for -d. - Default value for $YACCVCGFILESUFFIX changed to '.gv' to match + Default value for $YACC_GRAPH_FILE_SUFFIX changed to '.gv' to match current bison default (since bison 3.8). Set this variable to '.dot' if using byacc. diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py index 9751742..7a4ddfc 100644 --- a/SCons/Tool/yacc.py +++ b/SCons/Tool/yacc.py @@ -68,16 +68,18 @@ def _yaccEmitter(target, source, env, ysuf, hsuf) -> tuple: # If -d is specified on the command line, yacc will emit a .h # or .hpp file with the same base name as the .c or .cpp output file. - # if '-d' in flags: # add bison options -H, --header, --defines (obsolete) + # if '-d' in flags: + # or bison options -H, --header, --defines (obsolete) if "-d" in flags or "-H" in flags or "--header" in flags or "--defines" in flags: target.append(targetBase + env.subst(hsuf, target=target, source=source)) # If -g is specified on the command line, yacc will emit a graph # file with the same base name as the .c or .cpp output file. # TODO: should this be handled like -v? i.e. a side effect, not target - # if "-g" in flags: # add bison option --graph + # if "-g" in flags: + # or bison option --graph if "-g" in flags or "--graph" in flags: - target.append(targetBase + env.subst("$YACCVCGFILESUFFIX")) + target.append(targetBase + env.subst("$YACC_GRAPH_FILE_SUFFIX")) # If -v is specified yacc will create the output debug file # which is not really source for any process, but should @@ -193,6 +195,7 @@ def generate(env) -> None: env['YACCHFILESUFFIX'] = '.h' env['YACCHXXFILESUFFIX'] = '.hpp' env['YACCVCGFILESUFFIX'] = '.gv' + env['YACC_GRAPH_FILE_SUFFIX'] = '$YACCVCGFILESUFFIX' env['_YACC_HEADER'] = '${YACC_HEADER_FILE and "--header=" + str(YACC_HEADER_FILE)}' env['_YACC_GRAPH'] = '${YACC_GRAPH_FILE and "--graph=" + str(YACC_GRAPH_FILE)}' diff --git a/SCons/Tool/yacc.xml b/SCons/Tool/yacc.xml index cc70adb..3d4fa33 100644 --- a/SCons/Tool/yacc.xml +++ b/SCons/Tool/yacc.xml @@ -58,6 +58,7 @@ Sets construction variables for the &yacc; parser generator. YACCHFILESUFFIX YACCHXXFILESUFFIX YACCVCGFILESUFFIX +YACC_GRAPH_FILE_SUFFIX YACCCOMSTR @@ -230,6 +231,20 @@ The default value is .hpp. +Obsoleted. Use &cv-link-ACC_GRAPH_FILE_SUFFIX;. + + +Changed in version 4.X.Y + + + + + + + +Previously specified by &cv-link-YACCVCGFILESUFFIX;. + + The suffix of the file containing a graph of the grammar automaton when the option diff --git a/test/YACC/YACC_GRAPH_FILE_SUFFIX.py b/test/YACC/YACC_GRAPH_FILE_SUFFIX.py new file mode 100644 index 0000000..58e7628 --- /dev/null +++ b/test/YACC/YACC_GRAPH_FILE_SUFFIX.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# +# MIT License +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +Test setting the YACC_GRAPH_FILE_SUFFIX variable. +Also that if both YACCVCGFILESUFFIX and YACC_GRAPH_FILE_SUFFIX are set, +then YACCVCGFILESUFFIX will be ignored. +""" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.write('myyacc.py', """\ +import getopt +import os.path +import sys + +vcg = None +opts, args = getopt.getopt(sys.argv[1:], 'go:') +for o, a in opts: + if o == '-g': + vcg = 1 + elif o == '-o': + outfile = open(a, 'wb') +for f in args: + with open(f, 'rb') as infile: + for l in [l for l in infile.readlines() if l != b'/*yacc*/\\n']: + outfile.write(l) +outfile.close() +if vcg: + base, ext = os.path.splitext(args[0]) + with open(base + '.graph_suffix', 'wb') as outfile: + outfile.write((" ".join(sys.argv) + '\\n').encode()) +sys.exit(0) +""") + +test.write('SConstruct', """ +DefaultEnvironment(tools=[]) +env = Environment( + tools=['default', 'yacc'], + YACC=r'%(_python_)s myyacc.py', + YACCVCGFILESUFFIX='.vcg_obsolete', + YACC_GRAPH_FILE_SUFFIX='.graph_suffix', +) +env.CXXFile(target='aaa', source='aaa.yy') +env.CXXFile(target='bbb', source='bbb.yy', YACCFLAGS='-g') +""" % locals()) + +test.write('aaa.yy', "aaa.yy\n/*yacc*/\n") +test.write('bbb.yy', "bbb.yy\n/*yacc*/\n") + +test.run(arguments='.') + +test.must_match('aaa.cc', "aaa.yy\n") +test.must_not_exist('aaa.vcg') +test.must_not_exist('aaa.graph_suffix') + +test.must_match('bbb.cc', "bbb.yy\n") +test.must_not_exist('bbb.vcg') +test.must_not_exist('bbb.vcg_obsolete') +test.must_contain('bbb.graph_suffix', "myyacc.py -g -o bbb.cc bbb.yy\n") + +test.up_to_date(arguments='.') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From dc7407bb002b20c781e1d40b6678d1df7f2818fc Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 19 May 2023 08:24:11 -0600 Subject: Fix doc typo referencing YACC_GRAPH_FILE_SUFFIX [skip appveyor] Signed-off-by: Mats Wichmann --- CHANGES.txt | 6 ++++-- SCons/Tool/yacc.xml | 15 +++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index dfdba44..f99e8ac 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,10 @@ NOTE: 4.3.0 now requires Python 3.6.0 and above. Python 3.5.x is no longer suppo RELEASE VERSION/DATE TO BE FILLED IN LATER + From William Deegan: + - Obsoleted YACCVCGFILESUFFIX, being replaced by YACC_GRAPH_FILE_SUFFIX. + If YACC_GRAPH_FILE_SUFFIX is not set, it will respect YACCVCGFILESUFFIX. + From Mats Wichmann - C scanner's dictifyCPPDEFINES routine did not understand the possible combinations of CPPDEFINES - not aware of a "name=value" string either @@ -32,8 +36,6 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER not to the source file name, to match actual current behavior (only affects if target explicitly requested with a different base name than source). Docs updated. Fixes #4326 and #4327. - Obsoleted YACCVCGFILESUFFIX, being replaced by YACC_GRAPH_FILE_SUFFIX. - If YACC_GRAPH_FILE_SUFFIX is not set, it will respect YACCVCGFILESUFFIX. - SCons test runner now uses pathlib to normalize and compare paths to test files. - Minor doc fixes: signature of Alias() now matches implementation diff --git a/SCons/Tool/yacc.xml b/SCons/Tool/yacc.xml index 3d4fa33..82725db 100644 --- a/SCons/Tool/yacc.xml +++ b/SCons/Tool/yacc.xml @@ -231,10 +231,14 @@ The default value is .hpp. -Obsoleted. Use &cv-link-ACC_GRAPH_FILE_SUFFIX;. +Obsoleted. Use &cv-link-YACC_GRAPH_FILE_SUFFIX; instead. +The value is used only if &cv-YACC_GRAPH_FILE_SUFFIX; is not set. +The default value is .gv. -Changed in version 4.X.Y +Changed in version 4.X.Y: deprecated. The default value +changed from .vcg (&bison; stopped generating +.vcg output with version 2.4, in 2006). @@ -256,13 +260,8 @@ it does not affect the actual generated filename. Various yacc tools have emitted various formats at different times. Set this to match what your parser generator produces. -The default value is .gv. - - -Changed in version 4.X.Y: the default value -changed from .vcg (&bison; stopped generating -.vcg output with version 2.4, in 2006). +New in version 4.X.Y. -- cgit v0.12 From 34552173661b13419cec50628604ad37b19856f2 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 18 Jun 2023 16:06:35 -0700 Subject: [ci skip] Added info on byacc difference to CHANGES.txt --- CHANGES.txt | 9 +++++---- RELEASE.txt | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6276443..9bd0fbe 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -80,10 +80,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER --defines and --graph being called without option-argument as being synonyms for -d (first two) and -g. -H also recognized as a synonym for -d. Default value for $YACC_GRAPH_FILE_SUFFIX changed to '.gv' - to match current bison default (since bison 3.8). The graph file name - (-g) is now generated relative to the requested target file name, - not to the source file name, to match actual current behavior (only - affects if target explicitly requested with a different base name + to match current bison default (since bison 3.8). Set this variable + to '.dot' if using byacc. The graph file name (-g) is now generated + relative to the requested target file name, not to the source file + name, to match actual current behavior (only affects if target + explicitly requested with a different base name than source). Docs updated. Fixes #4326 and #4327. diff --git a/RELEASE.txt b/RELEASE.txt index 45a5f4b..ee27081 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -44,7 +44,7 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY for -d (first two) and -g. -H also recognized as a synonym for -d. Default value for $YACC_GRAPH_FILE_SUFFIX changed to '.gv' to match current bison default (since bison 3.8). Set this variable to '.dot' - if using byacc. + if using byacc. Fixes #4326 and #4327. FIXES ----- -- cgit v0.12