2020-09-30 17:12:29 +02:00

340 lines
12 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*** TABLE.H -- contains tables used by lexer and parser ***********************
*
* Copyright (c) 1988-1990, Microsoft Corporation. All rights reserved.
*
* Purpose:
* This include file contains parser tables and lexer tables.
*
* Revision History:
* 04-Dec-1989 SB Add proper proto's for PFV fn's which actions[] refers to
* 08-Oct-1989 SB Modified nameStates[][] to handle OS/2 1.2 quoted names
* 31-Jul-1989 SB changed entries in nameStates to symbolic BKS (seen Bkslash)
* 20-May-1989 SB changed nameStates[][] to 16x14 to handle at end of the
* dependency lines
* 13-Jun-1988 rj Modified stringStates to handle \nl as in xmake (v1.5)
*
*******************************************************************************/
/*
* ALL VALUES USED IN THESE TABLES ARE DEFINED IN GRAMMAR.H
* WHEN PRODUCTIONS CHANGE, UPDATE THE FOLLOWING TABLE
*
* The first element in a production line is the number of symbols on
* the right-hand-side of the production arrow. If the first element
* is 0, the nonterminal to the left of the arrow goes to the null string.
* Table entries beginning w/ "DO" are actions to be carried out at
* that particular point in the production. All other entries are
* either tokens or non-terminals.
*/
UCHAR prod0[] = {0}; /* MAKEFILE -> prod0 | prod1 | prod2 */
UCHAR prod1[] = {2,
BLANKLINES,
MAKEFILE};
UCHAR prod2[] = {5,
NEWLINE,
NAME,
DONAME,
BODY,
MAKEFILE};
UCHAR prod3[] = {5, /* BODY -> prod3 | prod4 */
NAMELIST,
SEPARATOR,
DOLASTNAME,
BUILDINFO,
DOBUILDCMDS};
UCHAR prod4[] = {3,
EQUALS,
VALUE,
DOMACRO};
UCHAR prod5[] = {0}; /* NAMELIST -> prod5 | prod6 */
UCHAR prod6[] = {3,
NAME,
DONAMELIST,
NAMELIST};
UCHAR prod7[] = {0}; /* COMMANDS -> prod7 | prod8 | prod9 */
UCHAR prod8[] = {1,
MOREBUILDLINES};
UCHAR prod9[] = {4,
SEMICOLON,
STRING,
DONAMELIST,
MOREBUILDLINES};
UCHAR prod10[] = {4, /* MOREBUILDLINES -> prod10 | prod 11 */
NEWLINESPACE, /* | prod12 */
STRING,
DONAMELIST,
MOREBUILDLINES};
UCHAR prod11[] = {0};
UCHAR prod12[] = {2,
NEWLINE,
MOREBUILDLINES};
UCHAR prod13[] = {0}; /* BLANKLINES -> prod13 | prod14 | */
UCHAR prod14[] = {2, /* | prod15 */
NEWLINE,
BLANKLINES};
UCHAR prod15[] = {2,
NEWLINESPACE,
BLANKLINES};
UCHAR prod16[] = {1,
DODEPENDS}; /* BUILDINFO -> prod16 | prod17 */
UCHAR prod17[] = {3,
NAMELIST,
DODEPENDS,
COMMANDS};
UCHAR prod18[] = {1, COLON}; /* SEPARATOR -> prod18 | prod19 */
UCHAR prod19[] = {1, DOUBLECOLON};
UCHAR *productions[] = {
prod0,
prod1,
prod2,
prod3,
prod4,
prod5,
prod6,
prod7,
prod8,
prod9,
prod10,
prod11,
prod12,
prod13,
prod14,
prod15,
prod16,
prod17,
prod18,
prod19};
/*
* When either of the high bit (AMBIG_MASK) of something that isn't an ERROR
* condition is set, it means that there are two productions that apply for
* that entry, the one given, and the one given plus one. The next token
* token must be examined to know which production to use.
*/
/* name newline newline semi colon double equals $
* white colon colon
* space
*/
static UCHAR table[8][8] = {
{SEPRTR,1 |AMBIG_MASK, 1, SYNTAX, NOTARG, NOTARG, MACRO, 0},
{SYNTAX,13|AMBIG_MASK, 15, SYNTAX, SYNTAX, SYNTAX, SYNTAX, 13},
{PARSER,11|AMBIG_MASK, 10, PARSER, SYNTAX, SYNTAX, SYNTAX, 11},
{PARSER,7, 8, 9, SYNTAX, SYNTAX, SYNTAX, 7},
{3, SEPEQU, SEPEQU, SEPRTR, 3, 3, 4, SEPEQU},
{6, 5, 5, 5, 5, 5, NAMES, 5},
{17, 16, 17, 17, SYNTAX, SYNTAX, SYNTAX, 16},
{PARSER,SEPRTR, SEPRTR, SEPRTR, 18, 19, SYNTAX, SEPRTR}};
static UCHAR useAlternate[3][8] = {
{YES, NO, NO, YES, YES, YES, YES, NO},
{NO, YES, YES, NO, NO, NO, NO, YES},
{NO, YES, YES, NO, NO, NO, NO, NO}};
void NEAR makeName(void);
void NEAR addItemToList(void);
void NEAR makeMacro(void);
void NEAR assignDependents(void);
void NEAR endNameList(void);
void NEAR assignBuildCommands(void);
static PFV actions[] = {
makeName,
addItemToList,
makeMacro,
assignDependents,
endNameList,
assignBuildCommands};
/*
* state tables for lexer's name and string recognizers
* values are defined in grammar.h
*
* d
* e
* f m
* a a c B
* u | | | | | | | | | |c h| | @ | F |
* l | # | = | \ | : |WS |NL | $ | ( | ) |r a| * | < | D |
* t | | | | | |EOF| | | |o r| | ? | R |
*/
UCHAR stringStates[13][14] = {
{ 1, 2, 1, 3, 1, 2, OK, 4, 1, 1, 1, 1, 1, 1}, /* 0 in col 0 */
{ 1, 1, 1, 3, 1, 2, OK, 4, 1, 1, 1, 1, 1, 1}, /* 1 default */
{ 1, 1, 1, 3, 1, 2, OK, 4, 1, 1, 1, 1, 1, 1}, /* 2 whitespace*/
{ 1, 1, 1, 1, 1, 2, 0, 4, 1, 1, 1, 1, 1, 1}, /* 3 line cont.*/
{CHR,CHR,CHR,CHR,CHR,BAD,BAD,1, 5, CHR,1, 1, 1, 1}, /* 4 macro inv.*/
{CHR,CHR,CHR,CHR,CHR,NAM,PAR,CHR,CHR,NAM,6, 11, 8, 6}, /* 5 found ( */
{CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, 6, BAD,BAD,6}, /* 6 legal name*/
{CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, BAD,BAD,BAD,BAD}, /* 7 ext sp mac*/
{CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, BAD,BAD,BAD,7}, /* 8 sp ch aft(*/
{10, 10, SEQ,10, 10, 10, PAR,10, 10, SEQ,10, 10, 10, 10}, /* 9 found a : */
{10, 10, 12, 10, 10, 10, PAR,10, 10, EQU,10, 10, 10, 10}, /*10 macro subs*/
{CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, BAD, 8, BAD,7}, /*11 found $(* */
{12, 12, 12, 12, 12, 12, PAR,12, 12, 2, 12, 12, 12, 12}}; /*12 look for )*/
/*
* In the above table, the columns hold the next state to go to
* for the given input symbol and the lines represent the states
* themselves.
*
* WS stands for whitespace, meaning space or tab
* NL stands for newline, EOF stands for end of file
* macrochar is any alphanumeric character or underscore
* * is used in the special macros $* and $** ($** is the only
* two-letter macro that doesn't require parentheses, thus
* we must treat it specially)
* @ < ? are characters found in special macros (they are not
* allowed in the names of a user-defined macros)
* BFDR are modifiers to special macros which may be appended
* to the macro name (but they necessitate the use of
* parentheses in the macro invocation)
* # is the comment char. # is a comment anywhere on a macro
* definition line, but is only a comment if it appears in
* column 0 of a build line. If we're lexing the tools
* initialization file, then semicolon is also a comment char
* if it appears in column 0. (Note that the only way
* to have a pound sign appear in the makefile and NOT be
* considered a comment is to define a macro "$A = #" on
* the commandline that invokes nmake.)
* default is anything not contained in the above groups and not
* appearing above a column in the table
*
* OK means that we accept the string
* all other mnemonic values are error codes (see end of grammar.h)
*/
/*
* the states: there is no state to handle comments -- if we see a
* comment char and we're not ignoring comments, we eat
* the comment and get another input symbol before consulting
* the state table
*
* 0 initial state -- for all practical purposes, we can
* assume that we're in column 0. If we're getting a
* macro value, we don't care what column we're in.
* If we're getting a build line, the only way we won't
* be in column 0 is if we're getting a command following
* a semicolon on the target-dependency line. If the
* use puts a comment char here, I think it's reasonable
* to treat it as a comment, since it comes at the beginning
* of the build command, even though the command itself
* doesn't start in column 0.
* We return to the initial state after seeing space-
* backslash-newline.
*
* 1 on any input symbol that isn't a backslash, comment char,
* or whitespace, we move here whenever we're not in a
* comment, or a macro definition
*
* 2 if the input symbol is whitespace, we move here whenever
* we're not in a comment or a macro definition.
*
* 3 We move here from states 0, 1, or 2 when we've seen a
* backslash, because if it's followed by a newline, we
* continue getting the string from the next line of the file.
* If the next character is a backslash, followed by a newline,
* there's a kludge in lexer.c that ignores the second back-
* slash.
* (The above applies to v. 1.5. v. 1.0 requires whitespace
* before a backslash.)
*
* 4 we move here when we see a dollar sign -- this is where
* all the error checking starts. We make sure that the
* macro name is legal, that the substitution sequences
* are specified correctly (if any is specified at all),
* and that parens match up. If our next input is $, a
* special-macro char, or a legal char in a user-defined-
* macro name, we go back to state 1.
*
* 5 found an open paren
*
* 6 found a legal macrochar
*
* 7 go here for an extended special macro, and from here we
* look for a close paren (out of order w/ 8)
*
* 8 we found a special-macro char after the open paren
* If we find a special-macro modifier
* after the special macro char following the open paren
* then we go to 7
*
* 9 found a colon (meaning that the user is going to do
* some substitution in the macro value)
*/
/*
* 10 any character that isn't newline, right paren, or EOF
* brings us here,a nd we loop until we see an equals sign.
* Newline, EOF, or right paren generate error messages.
*
* 11 we move here from state 5 if we see an asterisk, because
* we have to check for a second asterisk. A second *
* takes us to state 8 (because a modifier may follow **).
* If we find a modifier here (instead of a 2nd *), we go
* to state 7.
*
* 12 found an equals sign, so we loop, picking up characters
* for the replacement string, until we find a close paren.
* Newline, EOF generate error messages.
*/
/* The following table is used to recognize names
* It differs from the previous one in that we don't have to deal
* w/ continuations or comments, and we don't allow special macros
* (other than the dynamic dependency macros) to be used as part
* of names.
*
* d
* e
* f m
* a a c
* u | | | | | | | | | |c h| | | |
* l | # | = | ; | : |WS |NL | $ | ( | ) |r a| { | } | \ | "
* t | | | | | |EOF| | | |o r| | | |
*
*/
UCHAR nameStates[18][15] = {
{1, OK, OK, OK, 1, OK, OK, 2, 1, 1, 1, 8, 1, BKS,16}, /* 0 initial state */
{1, OK, OK, OK, OK, OK, OK, 2, 1, 1, 1, 8, 1, BKS,QUO},/* 1 do normal name*/
{CHR,BAD,CHR,CHR,CHR,BAD,BAD,1, 3, CHR,1, CHR,CHR,CHR,CHR},/* 2 handle macro */
{CHR,PAR,CHR,CHR,NAM,NAM,PAR,CHR,CHR,NAM,4, CHR,CHR,CHR,CHR},/* 3 do macro name */
{CHR,PAR,CHR,CHR,5, PAR,PAR,CHR,CHR,1, 4, CHR,CHR,CHR,CHR},/* 4 do mac (name) */
{6, 6, SEQ,6, 6, 6, PAR,6, 6, EQU,6, 6, 6, 6 ,6}, /* 5 found : do sub*/
{6, 6, 7, 6, 6, 6, SEQ,6, 6, SEQ,6, 6, 6, 6 ,6}, /* 6 read until = */
{7, 7, 7, 7, 7, 7, SEQ,7, 7, 1, 7, 7, 7, 7 ,7}, /* 7 read until ) */
{8, OK, 8, 8, 8, OK, OK, 9, 8, 8, 8, 8, 1, 8 ,8}, /* 8 do path list */
{CHR,BAD,CHR,CHR,CHR,BAD,BAD,8, 10, CHR,8, CHR,CHR,CHR,CHR},/* 9 do macro in {}*/
{CHR,PAR,CHR,CHR,NAM,10, PAR,CHR,CHR,NAM,11, CHR,CHR,CHR,CHR},/*10 do macro name */
{CHR,PAR,CHR,CHR,12, PAR,PAR,CHR,CHR,8, 11, CHR,CHR,CHR,CHR},/*11 do mac (name) */
{13, 13, SEQ,13, 13, 13, PAR,13, 13, EQU,13, 13, 13, 13 ,13}, /*12 found : do sub*/
{13, 13, 14, 13, 13, 13, SEQ,13, 13, SEQ,13, 13, 13, 13 ,13}, /*13 read until = */
{14, 14, 14, 14, 14, 14, SEQ,14, 14, 8, 14, 14, 14, 14 ,14}, /*14 read until ) */
{1, OK, OK, OK, OK, OK, OK, 2, 1, 1, 1, 8, 1, 1 ,1}, /*15 \ found so ...*/
{16, 16, 16, 16, 16, 16, NOQ,2, 16, 16, 16, 8, 16, BKS,17}, /*16 quoted name */
{OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK ,OK}};/*17 quoted name */
/*****
manis :- changed state[8][7]'s value from 10 to 9
changed state[9][10]'s value from 1 to 8.....(25th jan 88)
this is to allow macros inside path portions of rules, e.g.
{$(abc)}.c{$(def)}.obj: .......
or foo : {$a;$(bcd);efg\hijk\}lmn.opq .......
****/