Skip to content

Commit 700c703

Browse files
author
hornik
committed
Fix PR#18855 issues 1,3,4 and 5. By Duncan Murdoch.
git-svn-id: https://svn.r-project.org/R/trunk@87712 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent 91da00d commit 700c703

File tree

4 files changed

+158
-77
lines changed

4 files changed

+158
-77
lines changed

doc/NEWS.Rd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,9 @@
562562
\item When \command{R CMD check} aims at getting the time+date from a
563563
world clock, it is more robust against unexpected non-error results,
564564
thanks to \I{Michael Chirico}'s \PR{18852}.
565+
566+
\item The \code{tools::parseLatex()} parser made several parsing
567+
errors (\PR{18855}).
565568
}
566569
}
567570
}

src/library/tools/src/gramLatex.c

Lines changed: 108 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ enum yysymbol_kind_t
352352
YYSYMBOL_Items = 18, /* Items */
353353
YYSYMBOL_nonMath = 19, /* nonMath */
354354
YYSYMBOL_Item = 20, /* Item */
355-
YYSYMBOL_environment = 21, /* environment */
356-
YYSYMBOL_22_1 = 22, /* $@1 */
355+
YYSYMBOL_begin = 21, /* begin */
356+
YYSYMBOL_environment = 22, /* environment */
357357
YYSYMBOL_math = 23, /* math */
358358
YYSYMBOL_displaymath = 24, /* displaymath */
359359
YYSYMBOL_block = 25 /* block */
@@ -685,18 +685,18 @@ union yyalloc
685685
#endif /* !YYCOPY_NEEDED */
686686

687687
/* YYFINAL -- State number of the termination state. */
688-
#define YYFINAL 25
688+
#define YYFINAL 27
689689
/* YYLAST -- Last index in YYTABLE. */
690-
#define YYLAST 122
690+
#define YYLAST 131
691691

692692
/* YYNTOKENS -- Number of terminals. */
693693
#define YYNTOKENS 16
694694
/* YYNNTS -- Number of nonterminals. */
695695
#define YYNNTS 10
696696
/* YYNRULES -- Number of rules. */
697-
#define YYNRULES 25
697+
#define YYNRULES 27
698698
/* YYNSTATES -- Number of states. */
699-
#define YYNSTATES 42
699+
#define YYNSTATES 47
700700

701701
/* YYMAXUTOK -- Last valid token kind. */
702702
#define YYMAXUTOK 267
@@ -748,7 +748,7 @@ static const yytype_uint8 yyrline[] =
748748
{
749749
0, 183, 183, 184, 185, 188, 189, 190, 191, 192,
750750
193, 195, 196, 198, 199, 200, 201, 202, 203, 204,
751-
206, 206, 210, 212, 214, 215
751+
205, 207, 211, 215, 219, 221, 223, 224
752752
};
753753
#endif
754754

@@ -767,7 +767,8 @@ static const char *const yytname[] =
767767
"\"end of file\"", "error", "\"invalid token\"", "END_OF_INPUT",
768768
"ERROR", "MACRO", "TEXT", "COMMENT", "BEGIN", "END", "VERB", "VERB2",
769769
"TWO_DOLLARS", "'{'", "'}'", "'$'", "$accept", "Init", "Items",
770-
"nonMath", "Item", "environment", "$@1", "math", "displaymath", "block", YY_NULLPTR
770+
"nonMath", "Item", "begin", "environment", "math", "displaymath",
771+
"block", YY_NULLPTR
771772
};
772773

773774
static const char *
@@ -791,99 +792,101 @@ yysymbol_name (yysymbol_kind_t yysymbol)
791792
STATE-NUM. */
792793
static const yytype_int8 yypact[] =
793794
{
794-
32, -13, -13, -13, -13, -13, -12, -13, -13, 109,
795-
54, 109, 5, 43, -13, -13, -13, -13, -13, 0,
796-
14, -13, -13, 65, 98, -13, -13, -13, -13, -13,
797-
-4, -13, -13, -13, -13, -13, 87, 76, -1, 3,
798-
2, -13
795+
23, -13, -13, -13, -13, -13, -13, -12, -13, -13,
796+
118, 48, 118, 7, 36, -13, 60, -13, -13, -13,
797+
-13, 2, 108, -13, -13, 72, 96, -13, -13, -13,
798+
-13, -13, -4, 84, -3, -13, -13, -13, -13, 12,
799+
0, -13, 5, 14, -13, 18, -13
799800
};
800801

801802
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
802803
Performed when YYTABLE does not specify something else to do. Zero
803804
means the default is an error. */
804805
static const yytype_int8 yydefact[] =
805806
{
806-
0, 4, 3, 15, 13, 14, 0, 16, 17, 0,
807-
0, 0, 0, 0, 5, 18, 6, 7, 19, 0,
808-
0, 11, 25, 0, 0, 1, 2, 8, 9, 10,
809-
0, 23, 12, 24, 22, 20, 0, 0, 0, 0,
810-
0, 21
807+
0, 4, 3, 20, 15, 13, 14, 0, 16, 17,
808+
0, 0, 0, 0, 0, 5, 0, 18, 6, 7,
809+
19, 0, 0, 11, 27, 0, 0, 1, 2, 8,
810+
9, 10, 0, 0, 0, 25, 12, 26, 24, 0,
811+
0, 21, 0, 0, 23, 0, 22
811812
};
812813

813814
/* YYPGOTO[NTERM-NUM]. */
814815
static const yytype_int8 yypgoto[] =
815816
{
816-
-13, -13, -7, 12, -9, -13, -13, -6, -5, -13
817+
-13, -13, -6, 9, -10, -13, -13, -11, -8, -13
817818
};
818819

819820
/* YYDEFGOTO[NTERM-NUM]. */
820821
static const yytype_int8 yydefgoto[] =
821822
{
822-
0, 12, 13, 20, 14, 15, 36, 16, 17, 18
823+
0, 13, 14, 22, 15, 16, 17, 18, 19, 20
823824
};
824825

825826
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
826827
positive, shift that token. If negative, reduce the rule whose
827828
number is the opposite. If YYTABLE_NINF, syntax error. */
828829
static const yytype_int8 yytable[] =
829830
{
830-
21, 19, 21, 23, 27, 25, 30, 28, 29, 40,
831-
35, 32, 39, 0, 27, 32, 41, 28, 29, 3,
832-
4, 5, 6, 24, 7, 8, 31, 10, 27, 37,
833-
0, 28, 29, 1, 0, 2, 0, 3, 4, 5,
834-
6, 0, 7, 8, 9, 10, 26, 11, 3, 4,
835-
5, 6, 0, 7, 8, 9, 10, 0, 11, 3,
836-
4, 5, 6, 0, 7, 8, 9, 10, 22, 11,
837-
3, 4, 5, 6, 0, 7, 8, 9, 10, 33,
838-
11, 3, 4, 5, 6, 38, 7, 8, 9, 10,
839-
0, 11, 3, 4, 5, 6, 0, 7, 8, 9,
840-
10, 0, 11, 3, 4, 5, 6, 0, 7, 8,
841-
0, 10, 0, 34, 3, 4, 5, 6, 0, 7,
842-
8, 0, 10
831+
23, 21, 23, 30, 29, 25, 31, 27, 34, 39,
832+
33, 41, 36, 43, 30, 29, 36, 31, 42, 44,
833+
45, 26, 30, 29, 1, 31, 2, 3, 4, 5,
834+
6, 7, 46, 8, 9, 10, 11, 0, 12, 28,
835+
3, 4, 5, 6, 7, 0, 8, 9, 10, 11,
836+
0, 12, 3, 4, 5, 6, 7, 0, 8, 9,
837+
10, 11, 24, 12, 3, 4, 5, 6, 7, 32,
838+
8, 9, 10, 11, 0, 12, 3, 4, 5, 6,
839+
7, 0, 8, 9, 10, 11, 37, 12, 3, 4,
840+
5, 6, 7, 40, 8, 9, 10, 11, 0, 12,
841+
3, 4, 5, 6, 7, 0, 8, 9, 0, 11,
842+
0, 38, 3, 4, 5, 6, 7, 0, 8, 9,
843+
35, 11, 3, 4, 5, 6, 7, 0, 8, 9,
844+
0, 11
843845
};
844846

845847
static const yytype_int8 yycheck[] =
846848
{
847-
9, 13, 11, 10, 13, 0, 6, 13, 13, 6,
848-
14, 20, 13, -1, 23, 24, 14, 23, 23, 5,
849-
6, 7, 8, 11, 10, 11, 12, 13, 37, 36,
850-
-1, 37, 37, 1, -1, 3, -1, 5, 6, 7,
851-
8, -1, 10, 11, 12, 13, 3, 15, 5, 6,
852-
7, 8, -1, 10, 11, 12, 13, -1, 15, 5,
853-
6, 7, 8, -1, 10, 11, 12, 13, 14, 15,
854-
5, 6, 7, 8, -1, 10, 11, 12, 13, 14,
855-
15, 5, 6, 7, 8, 9, 10, 11, 12, 13,
856-
-1, 15, 5, 6, 7, 8, -1, 10, 11, 12,
857-
13, -1, 15, 5, 6, 7, 8, -1, 10, 11,
858-
-1, 13, -1, 15, 5, 6, 7, 8, -1, 10,
859-
11, -1, 13
849+
10, 13, 12, 14, 14, 11, 14, 0, 6, 13,
850+
16, 14, 22, 13, 25, 25, 26, 25, 6, 14,
851+
6, 12, 33, 33, 1, 33, 3, 4, 5, 6,
852+
7, 8, 14, 10, 11, 12, 13, -1, 15, 3,
853+
4, 5, 6, 7, 8, -1, 10, 11, 12, 13,
854+
-1, 15, 4, 5, 6, 7, 8, -1, 10, 11,
855+
12, 13, 14, 15, 4, 5, 6, 7, 8, 9,
856+
10, 11, 12, 13, -1, 15, 4, 5, 6, 7,
857+
8, -1, 10, 11, 12, 13, 14, 15, 4, 5,
858+
6, 7, 8, 9, 10, 11, 12, 13, -1, 15,
859+
4, 5, 6, 7, 8, -1, 10, 11, -1, 13,
860+
-1, 15, 4, 5, 6, 7, 8, -1, 10, 11,
861+
12, 13, 4, 5, 6, 7, 8, -1, 10, 11,
862+
-1, 13
860863
};
861864

862865
/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
863866
state STATE-NUM. */
864867
static const yytype_int8 yystos[] =
865868
{
866-
0, 1, 3, 5, 6, 7, 8, 10, 11, 12,
867-
13, 15, 17, 18, 20, 21, 23, 24, 25, 13,
868-
19, 20, 14, 18, 19, 0, 3, 20, 23, 24,
869-
6, 12, 20, 14, 15, 14, 22, 18, 9, 13,
870-
6, 14
869+
0, 1, 3, 4, 5, 6, 7, 8, 10, 11,
870+
12, 13, 15, 17, 18, 20, 21, 22, 23, 24,
871+
25, 13, 19, 20, 14, 18, 19, 0, 3, 20,
872+
23, 24, 9, 18, 6, 12, 20, 14, 15, 13,
873+
9, 14, 6, 13, 14, 6, 14
871874
};
872875

873876
/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
874877
static const yytype_int8 yyr1[] =
875878
{
876879
0, 16, 17, 17, 17, 18, 18, 18, 18, 18,
877880
18, 19, 19, 20, 20, 20, 20, 20, 20, 20,
878-
22, 21, 23, 24, 25, 25
881+
20, 21, 22, 22, 23, 24, 25, 25
879882
};
880883

881884
/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
882885
static const yytype_int8 yyr2[] =
883886
{
884887
0, 2, 2, 1, 1, 1, 1, 1, 2, 2,
885888
2, 1, 2, 1, 1, 1, 1, 1, 1, 1,
886-
0, 10, 3, 3, 3, 2
889+
1, 4, 6, 5, 3, 3, 3, 2
887890
};
888891

889892

@@ -1826,28 +1829,42 @@ yyparse (void)
18261829
{ yyval = yyvsp[0]; }
18271830
break;
18281831

1829-
case 20: /* $@1: %empty */
1830-
{ xxSetInVerbEnv(yyvsp[-1]); }
1832+
case 20: /* Item: ERROR */
1833+
{ YYABORT; }
18311834
break;
18321835

1833-
case 21: /* environment: BEGIN '{' TEXT '}' $@1 Items END '{' TEXT '}' */
1834-
{ yyval = xxenv(yyvsp[-7], yyvsp[-4], yyvsp[-1], &(yyloc));
1835-
RELEASE_SV(yyvsp[-9]); RELEASE_SV(yyvsp[-3]); }
1836+
case 21: /* begin: BEGIN '{' TEXT '}' */
1837+
{ xxSetInVerbEnv(yyvsp[-1]);
1838+
yyval = yyvsp[-1];
1839+
RELEASE_SV(yyvsp[-3]); }
18361840
break;
18371841

1838-
case 22: /* math: '$' nonMath '$' */
1842+
case 22: /* environment: begin Items END '{' TEXT '}' */
1843+
{ yyval = xxenv(yyvsp[-5], yyvsp[-4], yyvsp[-1], &(yyloc));
1844+
if (!yyval) YYABORT;
1845+
RELEASE_SV(yyvsp[-3]);
1846+
}
1847+
break;
1848+
1849+
case 23: /* environment: begin END '{' TEXT '}' */
1850+
{ yyval = xxenv(yyvsp[-4], NULL, yyvsp[-1], &(yyloc));
1851+
if (!yyval) YYABORT;
1852+
RELEASE_SV(yyvsp[-3]);}
1853+
break;
1854+
1855+
case 24: /* math: '$' nonMath '$' */
18391856
{ yyval = xxmath(yyvsp[-1], &(yyloc), FALSE); }
18401857
break;
18411858

1842-
case 23: /* displaymath: TWO_DOLLARS nonMath TWO_DOLLARS */
1859+
case 25: /* displaymath: TWO_DOLLARS nonMath TWO_DOLLARS */
18431860
{ yyval = xxmath(yyvsp[-1], &(yyloc), TRUE); }
18441861
break;
18451862

1846-
case 24: /* block: '{' Items '}' */
1863+
case 26: /* block: '{' Items '}' */
18471864
{ yyval = xxblock(yyvsp[-1], &(yyloc)); }
18481865
break;
18491866

1850-
case 25: /* block: '{' '}' */
1867+
case 27: /* block: '{' '}' */
18511868
{ yyval = xxblock(NULL, &(yyloc)); }
18521869
break;
18531870

@@ -2118,14 +2135,23 @@ static SEXP xxenv(SEXP begin, SEXP body, SEXP end, YYLTYPE *lloc)
21182135
#if DEBUGVALS
21192136
Rprintf("xxenv(begin=%p, body=%p, end=%p)", begin, body, end);
21202137
#endif
2138+
if (strcmp(CHAR(STRING_ELT(begin, 0)),
2139+
CHAR(STRING_ELT(end, 0))) != 0) {
2140+
char buffer[PARSE_ERROR_SIZE];
2141+
snprintf(buffer, sizeof(buffer), "\\begin{%s} at %d:%d ended by \\end{%s}",
2142+
CHAR(STRING_ELT(begin, 0)), lloc->first_line, lloc->first_column,
2143+
CHAR(STRING_ELT(end, 0)));
2144+
yyerror(buffer);
2145+
return NULL;
2146+
}
2147+
21212148
PRESERVE_SV(ans = allocVector(VECSXP, 2));
21222149
SET_VECTOR_ELT(ans, 0, begin);
21232150
RELEASE_SV(begin);
2124-
if (!isNull(body)) {
2151+
if (body && !isNull(body)) {
21252152
SET_VECTOR_ELT(ans, 1, PairToVectorList(CDR(body)));
21262153
RELEASE_SV(body);
21272154
}
2128-
/* FIXME: check that begin and end match */
21292155
setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, parseState.SrcFile));
21302156
setAttrib(ans, R_LatexTagSymbol, mkString("ENVIRONMENT"));
21312157
if (!isNull(end))
@@ -2403,6 +2429,8 @@ static SEXP ParseLatex(ParseStatus *status, SEXP srcfile)
24032429

24042430
parseState.Value = R_NilValue;
24052431

2432+
PRESERVE_SV(yylval = mkString(""));
2433+
24062434
if (yyparse()) *status = PARSE_ERROR;
24072435
else *status = PARSE_OK;
24082436

@@ -2761,13 +2789,25 @@ static int mkVerb2(const char *s, int c)
27612789
char *st1 = NULL;
27622790
unsigned int nstext = INITBUFSIZE;
27632791
char *stext = st0, *bp = st0;
2764-
int delim = '}';
2792+
int depth = 1;
2793+
const char *macro = s;
27652794

27662795
while (*s) TEXT_PUSH(*s++);
27672796

2768-
TEXT_PUSH(c);
2769-
while (((c = xxgetc()) != delim) && c != R_EOF) TEXT_PUSH(c);
2770-
if (c != R_EOF) TEXT_PUSH(c);
2797+
do {
2798+
TEXT_PUSH(c);
2799+
c = xxgetc();
2800+
if (c == '{') depth++;
2801+
else if (c == '}') depth--;
2802+
} while (depth > 0 && c != R_EOF);
2803+
2804+
if (c == R_EOF) {
2805+
char buffer[256];
2806+
snprintf(buffer, sizeof(buffer), "unexpected END_OF_INPUT\n'%s' is still open", macro);
2807+
yyerror(buffer);
2808+
return ERROR;
2809+
} else
2810+
TEXT_PUSH(c);
27712811

27722812
PRESERVE_SV(yylval = mkString2(stext, bp - stext));
27732813
if(st1) free(st1);

0 commit comments

Comments
 (0)