PL/1 parsing issues

I have Enterprise edition SonarQube server version 8.1.0.31237
SonarPLI analyzer 1.10 (build 1880)
Sonarscanner version 4.5.0.2216

When attempting to analyze our code for PL/1 (which is supported) we receive an error that it cannot parse the code. But some of the PL/1 code goes through fine. There does not seem to be a logical pattern.

16:18:49.901 WARN: %INCLUDE to a relative path, or to a non-existing file "indirect_partition" at H{file=F:\xxx\release\19.2.1\kernel\tools\copy_kernel_to.pl1, line=134, column=1}
16:18:49.911 ERROR: Unable to parse file: copy_kernel_to.pl1
16:18:49.911 ERROR: Parse error at line 48 column 43:

38:                fixed bin (15), fixed bin (15), fixed bin (15));
39: declare s$close entry(fixed bin (15), fixed bin (15));
40: declare s$delete_file entry (char (256) var in, fixed bin (15));
41: declare s$detach_port entry(fixed bin (15), fixed bin (15));
42: declare s$error entry (fixed bin (15), char (32) varying,
43:                char (*) varying);
44: declare s$expand_module_name entry (char (66) var, char (66) var,
45:                fixed bin (15));
46: declare s$get_master_disk entry (char (66) var, char (66) var, fixed bin (15));
47: declare s$get_open_file_info entry (fixed bin (15) in,
48:                1 like file_stat_template, char (65) var,
                                              ^
49:                fixed bin (15));
50: declare s$open entry (fixed bin (15), fixed bin (15), fixed bin (15),
51:                fixed bin (15), fixed bin (15), fixed bin (15),
52:                char (32) var, fixed bin (15));
53: 
54: declare s$parse_command entry (char (32) varying, fixed bin (15),
55:                char (*) varying, char (*) varying,
56:                char (*) varying, char (*) varying, bit (1) aligned,
57:                char (*) varying, fixed bin (15), bit (1) aligned,
58:                char (*) varying, char (*) varying,

16:18:49.927 DEBUG: 'incl/create_dict_constants.incl.pl1' generated metadata with charset 'UTF-8'
16:18:49.992 WARN: %INCLUDE to a relative path, or to a non-existing file "system_io_constants" at H{file=F:\xxx\release\19.2.1\kernel\tools\mm_edit_.pl1, line=121, column=10}
16:18:49.993 WARN: %INCLUDE to a relative path, or to a non-existing file "term_control_opcodes" at H{file=F:\xxx\release\19.2.1\kernel\tools\mm_edit_.pl1, line=122, column=10}
16:18:49.993 WARN: %INCLUDE to a relative path, or to a non-existing file "merge_info.incl.pl1" at H{file=F:\xxx\release\19.2.1\kernel\tools\mm_edit_.pl1, line=142, column=1}
16:18:50.049 ERROR: Unable to parse file: mm_edit_.pl1
16:18:50.050 ERROR: Parse error at line 510 column 47:

500:      call s$seq_write (DEFAULT_OUTPUT_PORT_ID, length (wvarch), (wvarch),
501:                       code);
502:      return;
503: 
504: end write_line;
505: 
506: add_a_line: proc (csv) inline;
507: 
508: dcl csv char (*) var;
509: 
510: declare   add_new_line entry (1 like ma_info, bin (15) in, char (*) var);
                                                   ^
511: 
512: 
513:      call add_new_line (ma_info, 1, (csv));
514:      ma_info.difflines (1) = ma_info.difflines (1) + 1;
515: 
516: end add_a_line;
517: 
518: end mm_edit_;
519: 

16:18:50.066 WARN: %INCLUDE to a relative path, or to a non-existing file "lock_info" at H{file=F:\xxx\release\19.2.1\kernel\tools\set_lock_timing.pl1, line=120, column=10}
16:18:50.067 WARN: %INCLUDE to a relative path, or to a non-existing file "os_links_template" at H{file=F:\xxx\release\19.2.1\kernel\tools\set_lock_timing.pl1, line=121, column=10}
16:18:50.101 DEBUG: 'set_lock_timing.pl1' generated metadata with charset 'UTF-8'
16:18:50.260 WARN: %INCLUDE to a relative path, or to a non-existing file "system_io_constants" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=59, column=1}
16:18:50.260 WARN: %INCLUDE to a relative path, or to a non-existing file "window_term_opcodes" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=60, column=1}
16:18:50.260 WARN: %INCLUDE to a relative path, or to a non-existing file "window_term_info" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=61, column=1}
16:18:50.261 WARN: %INCLUDE to a relative path, or to a non-existing file "term_control_opcodes" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=62, column=1}
16:18:50.261 WARN: %INCLUDE to a relative path, or to a non-existing file "video_request_defs" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=63, column=1}
16:18:50.261 WARN: %INCLUDE to a relative path, or to a non-existing file "req_names" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=64, column=1}
16:18:50.261 WARN: %INCLUDE to a relative path, or to a non-existing file "function_key_codes" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=65, column=1}
16:18:50.261 WARN: %INCLUDE to a relative path, or to a non-existing file "function_key_names" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=66, column=1}
16:18:50.262 WARN: %INCLUDE to a relative path, or to a non-existing file "bif_dcls" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=67, column=1}
16:18:50.262 WARN: %INCLUDE to a relative path, or to a non-existing file "subrs" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=68, column=1}
16:18:50.262 WARN: %INCLUDE to a relative path, or to a non-existing file "ioctl" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=69, column=1}
16:18:50.262 WARN: %INCLUDE to a relative path, or to a non-existing file "os_return_codes" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=70, column=1}
16:18:50.262 WARN: %INCLUDE to a relative path, or to a non-existing file "os_error_codes" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=71, column=1}
16:18:50.263 WARN: %INCLUDE to a relative path, or to a non-existing file "terminal_info" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=115, column=10}
16:18:50.263 WARN: %INCLUDE to a relative path, or to a non-existing file "terminal_modes_inner" at H{file=F:\xxx\release\19.2.1\kernel\tools\test_legacy_input.pl1, line=863, column=1}
16:18:50.282 ERROR: Unable to parse file: test_legacy_input.pl1
16:18:50.283 ERROR: Parse error at line 223 column 43:

213: 
214:           else if last_n_chars_is('hex')
215:           then do;
216:                display_nls = FALSE;
217:           end;
218: 
219:           if input_index >= input_count
220:           then do;
221:                goto switch_read_mode(new_reads);
222:             
223:                switch_read_mode(GEN_READS):;
                                               ^
224:                     call set_attr(IEXTEN | USE_BDI, GENERIC_INPUT_MODE);
225:                     escape_valid = TRUE;
226:                     fkey_valid = FALSE;
227:                     newline_valid = FALSE;
228:                     translated = TRUE;
229:                     binary_ok = FALSE;
230:                     goto end_switch_read_mode;
231:             
232:                switch_read_mode(KEY_READS):;
233:                     call set_attr(IFKEY | USE_BDI, FUNCTION_KEY_INPUT_MODE);

16:18:50.297 ERROR: Unable to parse file: pddl_tests/results/t7.incl.pl1
16:18:50.297 ERROR: Parse error at line 5 column 1:

 1: /* Begin include file . . . . . t7.incl.pl1 */
 2: /* Generated from t7.incl.pddl */
 3: 
 4: $if ^defined (__INCLUDED_T7__)
 5: $define __INCLUDED_T7__
    ^
 6: 
 7: dcl 1 sf                      shortmap based,
 8:       2 a                     bit (1),
 9:       2 b                     bit (31);
10: 
11: dcl 1 lf                      shortmap based,
12:       2 c                     bit (1),
13:       2 d                     bit (31);
14: 
15: dcl 1 fieldSs                 shortmap based,

Hi,

Let’s face it, SonarQube is stronger on Java than on PL/I.
We can have a look at the parsing issues you hit and see how we can improve our parser.

The IBM reference for the ENTRY attribute is suspicious and I created a ticket to adapt our parser.

This parsing error is due to the exact same problem as the previous one.

Could you please explain that one? Which kind of PL/I statement is that?

Same thing here. I don’t understand what those statements are.

Thanks for that information.

It was just odd that we have the same functions in other projects that did not have parsing errors and was able to be scanned and uploaded fine.

The foo(x): is a label array. Intended to be like a “C” switch label. The ‘;’ is because you might have 2 or more labels in a row, and Pl/1 doesn’t allow that, so having an empty statement due to the semicolon prevents a syntax error (IIRC).

The $if stuff is an extension in our product code, to allow us to do things like the “C” preprocessor.

Does that help explain?

Thanks for your reply.

It seems we have a problem with label arrays. I created a ticket to improve our parser.

I’m afraid we can’t do much on that one…

Thanks a lot for your feedback!