1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
#!/usr/bin/perl
#
# Format output generated by flex 2.5.31
#
# Usage:
# flex -o$output $input
# perl fix-flex $output > $tmp
# mv $tmp $output
#
# (C) Copyright 2004-2014 Dave Beckett http://www.dajobe.org/
# (C) Copyright 2004 University of Bristol
#
my $line_offset = 1; # #line directives always refer to the NEXT line
print <<'EOT';
#ifdef HAVE_CONFIG_H
#include <raptor_config.h>
#endif
EOT
$line_offset += 4; # added 4 lines above to output
my $debug = 0;
# Lexer symbol prefix such as 'turtle_lexer_'
my $prefix = undef;
# Current function or undef if out of function
my $cur_function = undef;
# State for current function for rules to use.
my(%fn_state);
while(<>) {
# find lexer prefix
if(!defined($prefix) && /^void\s*(.+?)restart\s*\(.*;$/) {
$prefix = $1;
warn "$.: Lexer prefix $prefix\n"
if $debug > 0;
}
# Remove generated yy_fatal_error declaration and definition to avoid warnings about unused/non-defined static function
# declaration
if(/^static void( yynoreturn)? yy_fatal_error\s*\(.*\)\s*\;\s*$/) {
$line_offset--; # skipped 1 line
next;
}
# definition
if(/^static void( yynoreturn)? yy_fatal_error\s*\(.*\)\s*[^\;]\s*$/) {
do {
$_=<>;
$line_offset--; # skipped 1 line
} while(!/^}/);
$line_offset--; # skipped 1 line
next;
}
# Replace calls to yy_fatal_error("msg", yyscanner) to YY_FATAL_ERROR("msg") macro
s/(^\s*)yy_fatal_error\s*\(\s*(\".*\")\s*,\s*yyscanner\s*\)/$1YY_FATAL_ERROR($2)/;
# flex has %option nounistd however it does not work in 2.5.31
# It is safe to add yet another wrapper.
if(m%^(\#include \<unistd.h\>)$%) {
$_=<<"EOT";
#ifndef YY_NO_UNISTD_H
$1
#endif
EOT
$line_offset += 2; # added 2 lines to output
}
# Fix .[ch] line references because we have added lines to it
my $line = $. + $line_offset;
s/^#line \d+ (\".*\.[ch]\")/#line $line $1/;
# Fix signed / unsigned comparison gcc 4.x warning:
# int n : in the macro YY_INPUT definition
# (size_t)num_to_read : which is silly since num_to_read is an int!
s/yyg->yy_n_chars, \(size_t\) num_to_read \)/yyg->yy_n_chars, num_to_read \)/;
# Match prefixed functions and a couple of static ones starting yy_
if(!defined($cur_function) && /^.*?((?:${prefix}|yy_)\w+)\s+\((.*)$/) {
my($f,$rest)=($1,$2);
if($rest !~ /;$/) {
$cur_function=$1;
warn "$.: Now in $cur_function: $_\n"
if $debug > 1;
%fn_state=();
}
} elsif(defined($cur_function) && /^\}/) {
warn "$.: End of $cur_function\n"
if $debug > 1;
$cur_function = undef;
%fn_state=();
}
# Fix declaration of signed 'i' operating over range of yy_size_t
if($cur_function eq $prefix."_scan_bytes") {
s/int i;/yy_size_t i;/;
}
# Add $prefix_cleanup() call at the end of $prefix_lex_destroy()
# find the start of lex_destroy function definition and capture prefix
# look for lexer_free(yyscanner, yyscanner) statement within the function and place the cleanup call before it
if($cur_function eq $prefix."lex_destroy") {
if(/(^\s*)(${prefix}free\s*\(\s*yyscanner\s*,\s*yyscanner\s*\)\s*\;)\s*$/) {
$_=<<"EOT";
$1/* clean up leaks if any before freeing yyscanner */
$1${prefix}cleanup(yyscanner);
$1$2
EOT
$line_offset += 2; # added 2 lines to output
}
}
# Fix ${prefix}_scan_bytes to take a yy_size_t len arg, not int.
# declaration
s/(${prefix}_scan_bytes|yy_scan_bytes)\s+\( const char \*bytes, int len , yyscan_t yyscanner \);/\1 \( const char \*bytes, yy_size_t len , yyscan_t yyscanner \);/;
# definition
s/^YY_BUFFER_STATE (${prefix}_scan_bytes|yy_scan_bytes)\s+\(const char \* yybytes, int _yybytes_len , yyscan_t yyscanner\)/YY_BUFFER_STATE \1 \(const char \* yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner\)/;
if($cur_function eq $prefix."_switch_to_buffer" ||
$cur_function eq $prefix."restart" ||
$cur_function eq $prefix."push_buffer_state") {
if(!exists($fn_state{'seen_ensure'})) {
s%(^\s*if\s*\(\s*!\s*)YY_CURRENT_BUFFER(\s*\)\s*\{.*$)%${1}yyg->yy_buffer_stack${2}%;
if(m%^\s*${prefix}ensure_buffer_stack\s*\(%) {
$fn_state{'seen_ensure'} = 1;
}
} else {
# In condition with whitespace
s%(\s+)YY_CURRENT_BUFFER(\s+)%${1}YY_CURRENT_BUFFER_LVALUE${2}%;
# In parameter or condition
s%([,\(])YY_CURRENT_BUFFER([,\)])%${1}YY_CURRENT_BUFFER_LVALUE${2}%;
}
}
if($cur_function eq 'yy_get_next_buffer') {
if(!exists($fn_state{'seen_yyinput'}) &&
m%^\s*YY_INPUT\(%) {
$fn_state{'seen_yyinput'} = 1;
} elsif(exists($fn_state{'seen_yyinput'})) {
# Remove dead code after YY_INPUT - which is a return NULL
s%^\s*YY_CURRENT_BUFFER_LVALUE->yy_n_chars\s*=\s*yyg->yy_n_chars;%%;
}
}
if($cur_function eq $prefix.'pop_buffer_state') {
# Change last if use of YY_CURRENT_BUFFER macro to unconditional value
s%^(\s*if \(\s*)YY_CURRENT_BUFFER(\s*\)\s*\{.*)$%${1}YY_CURRENT_BUFFER_LVALUE${2}%;
}
print;
}
|