Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

329 lines
14 KiB

  1. // TABLE.H -- contains tables used by lexer and parser
  2. //
  3. // Copyright (c) 1988-1990, Microsoft Corporation. All rights reserved.
  4. //
  5. // Purpose:
  6. // This include file contains parser tables and lexer tables.
  7. //
  8. // Revision History:
  9. // 04-Dec-1989 SB Add proper proto's for PFV fn's which actions[] refers to
  10. // 08-Oct-1989 SB Modified nameStates[][] to handle OS/2 1.2 quoted names
  11. // 31-Jul-1989 SB changed entries in nameStates to symbolic BKS (seen Bkslash)
  12. // 20-May-1989 SB changed nameStates[][] to 16x14 to handle at end of the
  13. // dependency lines
  14. // 13-Jun-1988 rj Modified stringStates to handle \nl as in xmake (v1.5)
  15. // ALL VALUES USED IN THESE TABLES ARE DEFINED IN GRAMMAR.H
  16. // WHEN PRODUCTIONS CHANGE, UPDATE THE FOLLOWING TABLE
  17. //
  18. // The first element in a production line is the number of symbols on
  19. // the right-hand-side of the production arrow. If the first element
  20. // is 0, the nonterminal to the left of the arrow goes to the null string.
  21. // Table entries beginning w/ "DO" are actions to be carried out at
  22. // that particular point in the production. All other entries are
  23. // either tokens or non-terminals.
  24. const UCHAR prod0[] = {0}; // MAKEFILE -> prod0 | prod1 | prod2
  25. const UCHAR prod1[] = {2,
  26. BLANKLINES,
  27. MAKEFILE};
  28. const UCHAR prod2[] = {5,
  29. NEWLINE,
  30. NAME,
  31. DONAME,
  32. BODY,
  33. MAKEFILE};
  34. const UCHAR prod3[] = {5, // BODY -> prod3 | prod4
  35. NAMELIST,
  36. SEPARATOR,
  37. DOLASTNAME,
  38. BUILDINFO,
  39. DOBUILDCMDS};
  40. const UCHAR prod4[] = {3,
  41. EQUALS,
  42. VALUE,
  43. DOMACRO};
  44. const UCHAR prod5[] = {0}; // NAMELIST -> prod5 | prod6
  45. const UCHAR prod6[] = {3,
  46. NAME,
  47. DONAMELIST,
  48. NAMELIST};
  49. const UCHAR prod7[] = {0}; // COMMANDS -> prod7 | prod8 | prod9
  50. const UCHAR prod8[] = {1,
  51. MOREBUILDLINES};
  52. const UCHAR prod9[] = {4,
  53. SEMICOLON,
  54. STRING,
  55. DONAMELIST,
  56. MOREBUILDLINES};
  57. const UCHAR prod10[] = {4, // MOREBUILDLINES -> prod10 | prod 11
  58. NEWLINESPACE, // | prod12
  59. STRING,
  60. DONAMELIST,
  61. MOREBUILDLINES};
  62. const UCHAR prod11[] = {0};
  63. const UCHAR prod12[] = {2,
  64. NEWLINE,
  65. MOREBUILDLINES};
  66. const UCHAR prod13[] = {0}; // BLANKLINES -> prod13 | prod14 |
  67. const UCHAR prod14[] = {2, // | prod15
  68. NEWLINE,
  69. BLANKLINES};
  70. const UCHAR prod15[] = {2,
  71. NEWLINESPACE,
  72. BLANKLINES};
  73. const UCHAR prod16[] = {1,
  74. DODEPENDS}; // BUILDINFO -> prod16 | prod17
  75. const UCHAR prod17[] = {3,
  76. NAMELIST,
  77. DODEPENDS,
  78. COMMANDS};
  79. const UCHAR prod18[] = {1, COLON}; // SEPARATOR -> prod18 | prod19
  80. const UCHAR prod19[] = {1, DOUBLECOLON};
  81. const UCHAR * const productions[] = {
  82. prod0,
  83. prod1,
  84. prod2,
  85. prod3,
  86. prod4,
  87. prod5,
  88. prod6,
  89. prod7,
  90. prod8,
  91. prod9,
  92. prod10,
  93. prod11,
  94. prod12,
  95. prod13,
  96. prod14,
  97. prod15,
  98. prod16,
  99. prod17,
  100. prod18,
  101. prod19
  102. };
  103. // When either of the high bit (AMBIG_MASK) of something that isn't an ERROR
  104. // condition is set, it means that there are two productions that apply for
  105. // that entry, the one given, and the one given plus one. The next token
  106. // token must be examined to know which production to use.
  107. // name newline newline semi colon double equals $
  108. // white colon colon
  109. // space
  110. static const UCHAR table[8][8] = {
  111. {SEPRTR,1 |AMBIG_MASK, 1, SYNTAX, NOTARG, NOTARG, MACRO, 0},
  112. {SYNTAX,13|AMBIG_MASK, 15, SYNTAX, SYNTAX, SYNTAX, SYNTAX, 13},
  113. {PARSER,11|AMBIG_MASK, 10, PARSER, SYNTAX, SYNTAX, SYNTAX, 11},
  114. {PARSER,7, 8, 9, SYNTAX, SYNTAX, SYNTAX, 7},
  115. {3, SEPEQU, SEPEQU, SEPRTR, 3, 3, 4, SEPEQU},
  116. {6, 5, 5, 5, 5, 5, NAMES, 5},
  117. {17, 16, 17, 17, SYNTAX, SYNTAX, SYNTAX, 16},
  118. {PARSER,SEPRTR, SEPRTR, SEPRTR, 18, 19, SYNTAX, SEPRTR}};
  119. static const UCHAR useAlternate[3][8] = {
  120. {YES, NO, NO, YES, YES, YES, YES, NO},
  121. {NO, YES, YES, NO, NO, NO, NO, YES},
  122. {NO, YES, YES, NO, NO, NO, NO, NO}};
  123. void makeName(void);
  124. void addItemToList(void);
  125. void makeMacro(void);
  126. void assignDependents(void);
  127. void endNameList(void);
  128. void assignBuildCommands(void);
  129. static PFV const actions[] = {
  130. makeName,
  131. addItemToList,
  132. makeMacro,
  133. assignDependents,
  134. endNameList,
  135. assignBuildCommands};
  136. // state tables for lexer's name and string recognizers
  137. // values are defined in grammar.h
  138. //
  139. // d
  140. // e
  141. // f m
  142. // a a c B
  143. // u | | | | | | | | | |c h| | @ | F |
  144. // l | # | = | \ | : |WS |NL | $ | ( | ) |r a| * | < | D |
  145. // t | | | | | |EOF| | | |o r| | ? | R |
  146. extern const UCHAR stringStates[13][14] = {
  147. { 1, 2, 1, 3, 1, 2, OK, 4, 1, 1, 1, 1, 1, 1}, // 0 in col 0
  148. { 1, 1, 1, 3, 1, 2, OK, 4, 1, 1, 1, 1, 1, 1}, // 1 default
  149. { 1, 1, 1, 3, 1, 2, OK, 4, 1, 1, 1, 1, 1, 1}, // 2 whitespace
  150. { 1, 1, 1, 1, 1, 2, 0, 4, 1, 1, 1, 1, 1, 1}, // 3 line cont.
  151. {CHR,CHR,CHR,CHR,CHR,BAD,BAD,1, 5, CHR,1, 1, 1, 1}, // 4 macro inv.
  152. {CHR,CHR,CHR,CHR,CHR,NAM,PAR,CHR,CHR,NAM,6, 11, 8, 6}, // 5 found (
  153. {CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, 6, BAD,BAD,6}, // 6 legal name
  154. {CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, BAD,BAD,BAD,BAD}, // 7 ext sp mac
  155. {CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, BAD,BAD,BAD,7}, // 8 sp ch aft(
  156. {10, 10, SEQ,10, 10, 10, PAR,10, 10, SEQ,10, 10, 10, 10}, // 9 found a :
  157. {10, 10, 12, 10, 10, 10, PAR,10, 10, EQU,10, 10, 10, 10}, //10 macro subs
  158. {CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, BAD, 8, BAD,7}, //11 found $(*
  159. {12, 12, 12, 12, 12, 12, PAR,12, 12, 2, 12, 12, 12, 12}}; //12 look for )
  160. // In the above table, the columns hold the next state to go to
  161. // for the given input symbol and the lines represent the states
  162. // themselves.
  163. //
  164. // WS stands for whitespace, meaning space or tab
  165. // NL stands for newline, EOF stands for end of file
  166. // macrochar is any alphanumeric character or underscore
  167. // * is used in the special macros $* and $** ($** is the only
  168. // two-letter macro that doesn't require parentheses, thus
  169. // we must treat it specially)
  170. // @ < ? are characters found in special macros (they are not
  171. // allowed in the names of a user-defined macros)
  172. // BFDR are modifiers to special macros which may be appended
  173. // to the macro name (but they necessitate the use of
  174. // parentheses in the macro invocation)
  175. // # is the comment char. # is a comment anywhere on a macro
  176. // definition line, but is only a comment if it appears in
  177. // column 0 of a build line. If we're lexing the tools
  178. // initialization file, then semicolon is also a comment char
  179. // if it appears in column 0. (Note that the only way
  180. // to have a pound sign appear in the makefile and NOT be
  181. // considered a comment is to define a macro "$A = #" on
  182. // the commandline that invokes nmake.)
  183. // default is anything not contained in the above groups and not
  184. // appearing above a column in the table
  185. //
  186. // OK means that we accept the string
  187. // all other mnemonic values are error codes (see end of grammar.h)
  188. // the states: there is no state to handle comments -- if we see a
  189. // comment char and we're not ignoring comments, we eat
  190. // the comment and get another input symbol before consulting
  191. // the state table
  192. //
  193. // 0 initial state -- for all practical purposes, we can
  194. // assume that we're in column 0. If we're getting a
  195. // macro value, we don't care what column we're in.
  196. // If we're getting a build line, the only way we won't
  197. // be in column 0 is if we're getting a command following
  198. // a semicolon on the target-dependency line. If the
  199. // use puts a comment char here, I think it's reasonable
  200. // to treat it as a comment, since it comes at the beginning
  201. // of the build command, even though the command itself
  202. // doesn't start in column 0.
  203. // We return to the initial state after seeing space-
  204. // backslash-newline.
  205. //
  206. // 1 on any input symbol that isn't a backslash, comment char,
  207. // or whitespace, we move here whenever we're not in a
  208. // comment, or a macro definition
  209. //
  210. // 2 if the input symbol is whitespace, we move here whenever
  211. // we're not in a comment or a macro definition.
  212. //
  213. // 3 We move here from states 0, 1, or 2 when we've seen a
  214. // backslash, because if it's followed by a newline, we
  215. // continue getting the string from the next line of the file.
  216. // If the next character is a backslash, followed by a newline,
  217. // there's a kludge in lexer.c that ignores the second back-
  218. // slash.
  219. // (The above applies to v. 1.5. v. 1.0 requires whitespace
  220. // before a backslash.)
  221. //
  222. // 4 we move here when we see a dollar sign -- this is where
  223. // all the error checking starts. We make sure that the
  224. // macro name is legal, that the substitution sequences
  225. // are specified correctly (if any is specified at all),
  226. // and that parens match up. If our next input is $, a
  227. // special-macro char, or a legal char in a user-defined-
  228. // macro name, we go back to state 1.
  229. //
  230. // 5 found an open paren
  231. //
  232. // 6 found a legal macrochar
  233. //
  234. // 7 go here for an extended special macro, and from here we
  235. // look for a close paren (out of order w/ 8)
  236. //
  237. // 8 we found a special-macro char after the open paren
  238. // If we find a special-macro modifier
  239. // after the special macro char following the open paren
  240. // then we go to 7
  241. //
  242. // 9 found a colon (meaning that the user is going to do
  243. // some substitution in the macro value)
  244. // 10 any character that isn't newline, right paren, or EOF
  245. // brings us here,a nd we loop until we see an equals sign.
  246. // Newline, EOF, or right paren generate error messages.
  247. //
  248. // 11 we move here from state 5 if we see an asterisk, because
  249. // we have to check for a second asterisk. A second *
  250. // takes us to state 8 (because a modifier may follow **).
  251. // If we find a modifier here (instead of a 2nd *), we go
  252. // to state 7.
  253. //
  254. // 12 found an equals sign, so we loop, picking up characters
  255. // for the replacement string, until we find a close paren.
  256. // Newline, EOF generate error messages.
  257. // The following table is used to recognize names
  258. // It differs from the previous one in that we don't have to deal
  259. // w/ continuations or comments, and we don't allow special macros
  260. // (other than the dynamic dependency macros) to be used as part
  261. // of names.
  262. //
  263. // d
  264. // e
  265. // f m
  266. // a a c
  267. // u | | | | | | | | | |c h| | | |
  268. // l | # | = | ; | : |WS |NL | $ | ( | ) |r a| { | } | \ | "
  269. // t | | | | | |EOF| | | |o r| | | |
  270. extern const UCHAR nameStates[19][15] = {
  271. {1, OK, OK, OK, 1, OK, OK, 2, 1, 1, 1, 8, 1, BKS,16}, // 0 initial state
  272. {1, OK, OK, OK, OK, OK, OK, 2, 1, 1, 1, 8, 1, BKS,QUO},// 1 do normal name
  273. {CHR,BAD,CHR,CHR,CHR,BAD,BAD,1, 3, CHR,1, CHR,CHR,CHR,CHR},// 2 handle macro
  274. {CHR,PAR,CHR,CHR,NAM,NAM,PAR,CHR,CHR,NAM,4, CHR,CHR,CHR,CHR},// 3 do macro name
  275. {CHR,PAR,CHR,CHR,5, PAR,PAR,CHR,CHR,1, 4, CHR,CHR,CHR,CHR},// 4 do mac (name)
  276. {6, 6, SEQ,6, 6, 6, PAR,6, 6, EQU,6, 6, 6, 6 ,6}, // 5 found : do sub
  277. {6, 6, 7, 6, 6, 6, SEQ,6, 6, SEQ,6, 6, 6, 6 ,6}, // 6 read until =
  278. {7, 7, 7, 7, 7, 7, SEQ,7, 7, 1, 7, 7, 7, 7 ,7}, // 7 read until )
  279. {8, OK, 8, 8, 8, 8, OK, 9, 8, 8, 8, 8, 18, 8 ,8}, // 8 do path list
  280. {CHR,BAD,CHR,CHR,CHR,BAD,BAD,8, 10, CHR,8, CHR,CHR,CHR,CHR},// 9 do macro in {}
  281. {CHR,PAR,CHR,CHR,NAM,10, PAR,CHR,CHR,NAM,11, CHR,CHR,CHR,CHR},//10 do macro name
  282. {CHR,PAR,CHR,CHR,12, PAR,PAR,CHR,CHR,8, 11, CHR,CHR,CHR,CHR},//11 do mac (name)
  283. {13, 13, SEQ,13, 13, 13, PAR,13, 13, EQU,13, 13, 13, 13 ,13}, //12 found : do sub
  284. {13, 13, 14, 13, 13, 13, SEQ,13, 13, SEQ,13, 13, 13, 13 ,13}, //13 read until =
  285. {14, 14, 14, 14, 14, 14, SEQ,14, 14, 8, 14, 14, 14, 14 ,14}, //14 read until )
  286. {1, OK, OK, OK, OK, OK, OK, 2, 1, 1, 1, 8, 1, 1 ,1}, //15 \ found so ...
  287. {16, 16, 16, 16, 16, 16, NOQ,2, 16, 16, 16, 8, 16, BKS,17}, //16 quoted name
  288. {OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK ,OK}, //17 quoted name
  289. {1, OK, OK, OK, OK, OK, OK, 2, 1, 1, 1, 8, 1, BKS,16}};//18 read after {}
  290. // manis :- changed state[8][7]'s value from 10 to 9
  291. // changed state[9][10]'s value from 1 to 8.....(25th jan 88)
  292. //
  293. // this is to allow macros inside path portions of rules, e.g.
  294. // {$(abc)}.c{$(def)}.obj: .......
  295. // or foo : {$a;$(bcd);efg\hijk\}lmn.opq .......
  296. // georgiop: added state 18 to handle quoted names following path lists
  297. // e.g., {whatever}"foo" [DS #4296, 10/30/96]
  298. // We now enter state 18 as soon as a path list is read. (We used
  299. // to return to state 1 in that case and generate an error as
  300. // soon as the quotes were encountered)
  301. // Also changed state[8][5] from OK to 8 in order to allow paths
  302. // containing white space. [DS #14575]