diff --git a/src/backend/parser/Makefile b/src/backend/parser/Makefile
index f14febdbda..3a2459cb72 100644
--- a/src/backend/parser/Makefile
+++ b/src/backend/parser/Makefile
@@ -40,7 +40,6 @@ gram.c: BISON_CHECK_CMD = $(PERL) $(srcdir)/check_keywords.pl $< $(top_srcdir)/s
 
 
 scan.c: FLEXFLAGS = -CF -p -p
-scan.c: FLEX_NO_BACKUP=yes
 scan.c: FLEX_FIX_WARNING=yes
 
 
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index e1cae859e8..13ec8daf9c 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -241,9 +241,7 @@ whitespace_with_newline	({horiz_whitespace}*{newline}{special_whitespace}*)
  * beyond the quote proper.
  */
 quote			'
-quotestop		{quote}{whitespace}*
 quotecontinue	{quote}{whitespace_with_newline}{quote}
-quotefail		{quote}{whitespace}*"-"
 
 /* Bit string
  * It is tempting to scan the string for only those characters
@@ -292,7 +290,6 @@ xqinside		[^']+
 dolq_start		[A-Za-z\200-\377_]
 dolq_cont		[A-Za-z\200-\377_0-9]
 dolqdelim		\$({dolq_start}{dolq_cont}*)?\$
-dolqfailed		\${dolq_start}{dolq_cont}*
 dolqinside		[^$]+
 
 /* Double quote
@@ -306,8 +303,6 @@ xdinside		[^"]+
 
 /* Unicode escapes */
 uescape			[uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}[^']{quote}
-/* error rule to avoid backup */
-uescapefail		[uU][eE][sS][cC][aA][pP][eE]{whitespace}*"-"|[uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}[^']|[uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}|[uU][eE][sS][cC][aA][pP][eE]{whitespace}*|[uU][eE][sS][cC][aA][pP]|[uU][eE][sS][cC][aA]|[uU][eE][sS][cC]|[uU][eE][sS]|[uU][eE]|[uU]
 
 /* Quoted identifier with Unicode escapes */
 xuistart		[uU]&{dquote}
@@ -315,13 +310,6 @@ xuistart		[uU]&{dquote}
 /* Quoted string with Unicode escapes */
 xusstart		[uU]&{quote}
 
-/* Optional UESCAPE after a quoted string or identifier with Unicode escapes. */
-xustop1		{uescapefail}?
-xustop2		{uescape}
-
-/* error rule to avoid backup */
-xufailed		[uU]&
-
 
 /* C-style comments
  *
@@ -398,8 +386,6 @@ integer			{digit}+
 decimal			(({digit}*\.{digit}+)|({digit}+\.{digit}*))
 decimalfail		{digit}+\.\.
 real			({integer}|{decimal})[Ee][-+]?{digit}+
-realfail1		({integer}|{decimal})[Ee]
-realfail2		({integer}|{decimal})[Ee][-+]
 
 param			\${integer}
 
@@ -476,9 +462,7 @@ other			.
 					startlit();
 					addlitchar('b', yyscanner);
 				}
-<xb>{quotestop}	|
-<xb>{quotefail} {
-					yyless(1);
+<xb>{quote}		{
 					BEGIN(INITIAL);
 					yylval->str = litbufdup(yyscanner);
 					return BCONST;
@@ -505,9 +489,7 @@ other			.
 					startlit();
 					addlitchar('x', yyscanner);
 				}
-<xh>{quotestop}	|
-<xh>{quotefail} {
-					yyless(1);
+<xh>{quote}		{
 					BEGIN(INITIAL);
 					yylval->str = litbufdup(yyscanner);
 					return XCONST;
@@ -568,9 +550,7 @@ other			.
 					BEGIN(xus);
 					startlit();
 				}
-<xq,xe>{quotestop}	|
-<xq,xe>{quotefail} {
-					yyless(1);
+<xq,xe>{quote}	{
 					BEGIN(INITIAL);
 					/*
 					 * check that the data remains valid if it might have been
@@ -583,26 +563,21 @@ other			.
 					yylval->str = litbufdup(yyscanner);
 					return SCONST;
 				}
-<xus>{quotestop} |
-<xus>{quotefail} {
-					/* throw back all but the quote */
-					yyless(1);
+<xus>{quote}	{
 					/* xusend state looks for possible UESCAPE */
 					BEGIN(xusend);
 				}
 <xusend>{whitespace} {
 					/* stay in xusend state over whitespace */
 				}
-<xusend><<EOF>> |
-<xusend>{other} |
-<xusend>{xustop1} {
+<xusend>{other} {
 					/* no UESCAPE after the quote, throw back everything */
 					yyless(0);
 					BEGIN(INITIAL);
 					yylval->str = litbuf_udeescape('\\', yyscanner);
 					return SCONST;
 				}
-<xusend>{xustop2} {
+<xusend>{uescape} {
 					/* found UESCAPE after the end quote */
 					BEGIN(INITIAL);
 					if (!check_uescapechar(yytext[yyleng - 2]))
@@ -708,13 +683,6 @@ other			.
 					BEGIN(xdolq);
 					startlit();
 				}
-{dolqfailed}	{
-					SET_YYLLOC();
-					/* throw back all but the initial "$" */
-					yyless(1);
-					/* and treat it as {other} */
-					return yytext[0];
-				}
 <xdolq>{dolqdelim} {
 					if (strcmp(yytext, yyextra->dolqstart) == 0)
 					{
@@ -738,9 +706,6 @@ other			.
 <xdolq>{dolqinside} {
 					addlit(yytext, yyleng, yyscanner);
 				}
-<xdolq>{dolqfailed} {
-					addlit(yytext, yyleng, yyscanner);
-				}
 <xdolq>.		{
 					/* This is only needed for $ inside the quoted text */
 					addlitchar(yytext[0], yyscanner);
@@ -770,16 +735,13 @@ other			.
 					return IDENT;
 				}
 <xui>{dquote} {
-					yyless(1);
 					/* xuiend state looks for possible UESCAPE */
 					BEGIN(xuiend);
 				}
 <xuiend>{whitespace} {
 					/* stay in xuiend state over whitespace */
 				}
-<xuiend><<EOF>> |
-<xuiend>{other} |
-<xuiend>{xustop1} {
+<xuiend>{other} {
 					/* no UESCAPE after the quote, throw back everything */
 					char	   *ident;
 					int			identlen;
@@ -796,7 +758,7 @@ other			.
 					yylval->str = ident;
 					return IDENT;
 				}
-<xuiend>{xustop2}	{
+<xuiend>{uescape} {
 					/* found UESCAPE after the end quote */
 					char	   *ident;
 					int			identlen;
@@ -825,18 +787,6 @@ other			.
 				}
 <xd,xui><<EOF>>		{ yyerror("unterminated quoted identifier"); }
 
-{xufailed}	{
-					char	   *ident;
-
-					SET_YYLLOC();
-					/* throw back all but the initial u/U */
-					yyless(1);
-					/* and treat it as {identifier} */
-					ident = downcase_truncate_identifier(yytext, yyleng, true);
-					yylval->str = ident;
-					return IDENT;
-				}
-
 {typecast}		{
 					SET_YYLLOC();
 					return TYPECAST;
@@ -1018,23 +968,6 @@ other			.
 					yylval->str = pstrdup(yytext);
 					return FCONST;
 				}
-{realfail1}		{
-					/*
-					 * throw back the [Ee], and figure out whether what
-					 * remains is an {integer} or {decimal}.
-					 */
-					yyless(yyleng - 1);
-					SET_YYLLOC();
-					return process_integer_literal(yytext, yylval);
-				}
-{realfail2}		{
-					/* throw back the [Ee][+-], and proceed as above */
-					yyless(yyleng - 2);
-					SET_YYLLOC();
-					return process_integer_literal(yytext, yylval);
-				}
-
-
 {identifier}	{
 					int			kwnum;
 					char	   *ident;
