ld lexer tidy, possibly break the world
authorAlan Modra <amodra@gmail.com>
Fri, 13 Aug 2021 07:50:10 +0000 (17:20 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 13 Aug 2021 13:16:54 +0000 (22:46 +0930)
This tidies the states in which ld lexer rules are enabled.
This change will quite likely trip over issues similar to those
mentioned in the new ldlex.l comments, so please test it out.

* ldgram.y (wildcard_name): Remove now unnecessary components.
* ldlex.l: Restrict many rules' states.  Remove -l expression
state rule.  Comment on lookahead state madness and need for
/DISCARD/ in expression state.

ld/ldgram.y
ld/ldlex.l

index 24979deebbea9e7425361bc0d24cd9d860588db0..1f6c44a073ca69692bca164f81c459579fb6a113 100644 (file)
@@ -421,21 +421,11 @@ statement_anywhere:
                  lang_add_assignment (exp_assert ($4, $6)); }
        ;
 
-/* The '*' and '?' cases are there because the lexer returns them as
-   separate tokens rather than as NAME.  */
 wildcard_name:
                NAME
                        {
                          $$ = $1;
                        }
-       |       '*'
-                       {
-                         $$ = "*";
-                       }
-       |       '?'
-                       {
-                         $$ = "?";
-                       }
        ;
 
 wildcard_maybe_exclude:
index b0861d78e49f89d20a5ed7e0334d9e729d75fc37..6aeba6de6567fe5cb22a5bbda8416d02561cc53d 100644 (file)
@@ -192,132 +192,155 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
                                    }
                                  return INT;
                                }
-<SCRIPT,EXPRESSION,MRI,WILD>"]"                { RTOKEN(']');}
-<SCRIPT,EXPRESSION,MRI,WILD>"["                { RTOKEN('[');}
-<SCRIPT,EXPRESSION,MRI,WILD>"<<="      { RTOKEN(LSHIFTEQ);}
-<SCRIPT,EXPRESSION,MRI,WILD>">>="      { RTOKEN(RSHIFTEQ);}
-<SCRIPT,EXPRESSION,MRI>"||"            { RTOKEN(OROR);}
-<SCRIPT,EXPRESSION,MRI>"=="            { RTOKEN(EQ);}
-<SCRIPT,EXPRESSION,MRI>"!="            { RTOKEN(NE);}
-<SCRIPT,EXPRESSION,MRI>">="            { RTOKEN(GE);}
-<SCRIPT,EXPRESSION,MRI>"<="            { RTOKEN(LE);}
-<SCRIPT,EXPRESSION,MRI>"<<"            { RTOKEN(LSHIFT);}
-<SCRIPT,EXPRESSION,MRI>">>"            { RTOKEN(RSHIFT);}
-<SCRIPT,EXPRESSION,MRI,WILD>"+="       { RTOKEN(PLUSEQ);}
-<SCRIPT,EXPRESSION,MRI,WILD>"-="       { RTOKEN(MINUSEQ);}
-<SCRIPT,EXPRESSION,MRI,WILD>"*="       { RTOKEN(MULTEQ);}
-<SCRIPT,EXPRESSION,MRI,WILD>"/="       { RTOKEN(DIVEQ);}
-<SCRIPT,EXPRESSION,MRI,WILD>"&="       { RTOKEN(ANDEQ);}
-<SCRIPT,EXPRESSION,MRI,WILD>"|="       { RTOKEN(OREQ);}
-<SCRIPT,EXPRESSION,MRI>"&&"            { RTOKEN(ANDAND);}
-<SCRIPT,EXPRESSION,MRI>">"             { RTOKEN('>');}
-<SCRIPT,EXPRESSION,MRI,INPUTLIST>","   { RTOKEN(',');}
-<SCRIPT,EXPRESSION,MRI,WILD>"&"                { RTOKEN('&');}
-<SCRIPT,EXPRESSION,MRI>"|"             { RTOKEN('|');}
-<SCRIPT,EXPRESSION,MRI>"~"             { RTOKEN('~');}
-<SCRIPT,EXPRESSION,MRI>"!"             { RTOKEN('!');}
-<SCRIPT,EXPRESSION,MRI>"?"             { RTOKEN('?');}
-<SCRIPT,EXPRESSION,MRI>"*"             { RTOKEN('*');}
-<SCRIPT,EXPRESSION,MRI>"+"             { RTOKEN('+');}
-<SCRIPT,EXPRESSION,MRI>"-"             { RTOKEN('-');}
-<SCRIPT,EXPRESSION,MRI>"/"             { RTOKEN('/');}
-<SCRIPT,EXPRESSION,MRI>"%"             { RTOKEN('%');}
-<SCRIPT,EXPRESSION,MRI>"<"             { RTOKEN('<');}
-<SCRIPT,EXPRESSION,MRI,WILD>"="                { RTOKEN('=');}
+
+  /* Some tokens that only appear in expressions must be enabled for
+     states other than EXPRESSION, since parser lookahead means they
+     must be recognised before the parser switches the lexer out of
+     SCRIPT or WILD state into EXPRESSION state.
+
+     This sort of thing happens for example with NAME in ldgram.y
+     "section" rule, which is immediately followed by ldlex_expression.
+     However, if you follow the grammar from "sec_or_group_p1" you see
+     "assignment" appearing in "statement_anywhere".  Now,
+     "assignment" also has NAME as its first token, just like
+     "section".  So the parser can't know whether it is in the
+     "section" or the "assignment" rule until it has scanned the next
+     token to find an assignment operator.  Thus the next token after
+     NAME in the "section" rule may be lexed before the lexer is
+     switched to EXPRESSION state, and there are quite a number of
+     optional components.  The first token in all those components
+     must be able to be lexed in SCRIPT state, as well as the
+     assignment operators.  In fact, due to "opt_exp_with_type",
+     anything that can appear on the left hand side of "exp" might
+     need to be lexed in SCRIPT state.
+
+     MRI mode tends to cover everything in MRI scripts.
+  */
+<MRI,WILD>"]"                          { RTOKEN(']'); }
+<MRI,WILD>"["                          { RTOKEN('['); }
+<SCRIPT,EXPRESSION,MRI,WILD>"<<="      { RTOKEN(LSHIFTEQ); }
+<SCRIPT,EXPRESSION,MRI,WILD>">>="      { RTOKEN(RSHIFTEQ); }
+<EXPRESSION,MRI>"||"                   { RTOKEN(OROR); }
+<EXPRESSION,MRI>"=="                   { RTOKEN(EQ); }
+<EXPRESSION,MRI>"!="                   { RTOKEN(NE); }
+<EXPRESSION,MRI>">="                   { RTOKEN(GE); }
+<EXPRESSION,MRI>"<="                   { RTOKEN(LE); }
+<EXPRESSION,MRI>"<<"                   { RTOKEN(LSHIFT); }
+<EXPRESSION,MRI>">>"                   { RTOKEN(RSHIFT); }
+<SCRIPT,EXPRESSION,MRI,WILD>"+="       { RTOKEN(PLUSEQ); }
+<SCRIPT,EXPRESSION,MRI,WILD>"-="       { RTOKEN(MINUSEQ); }
+<SCRIPT,EXPRESSION,MRI,WILD>"*="       { RTOKEN(MULTEQ); }
+<SCRIPT,EXPRESSION,MRI,WILD>"/="       { RTOKEN(DIVEQ); }
+<SCRIPT,EXPRESSION,MRI,WILD>"&="       { RTOKEN(ANDEQ); }
+<SCRIPT,EXPRESSION,MRI,WILD>"|="       { RTOKEN(OREQ); }
+<EXPRESSION,MRI>"&&"                   { RTOKEN(ANDAND); }
+<SCRIPT,EXPRESSION,MRI>">"             { RTOKEN('>'); }
+<SCRIPT,EXPRESSION,MRI,INPUTLIST>","   { RTOKEN(','); }
+<EXPRESSION,MRI,WILD>"&"               { RTOKEN('&'); }
+<EXPRESSION,MRI>"|"                    { RTOKEN('|'); }
+<SCRIPT,EXPRESSION,MRI>"~"             { RTOKEN('~'); }
+<SCRIPT,EXPRESSION,MRI>"!"             { RTOKEN('!'); }
+<EXPRESSION,MRI>"?"                    { RTOKEN('?'); }
+<EXPRESSION,MRI>"*"                    { RTOKEN('*'); }
+<SCRIPT,EXPRESSION,MRI>"+"             { RTOKEN('+'); }
+<SCRIPT,EXPRESSION,MRI>"-"             { RTOKEN('-'); }
+<EXPRESSION,MRI>"/"                    { RTOKEN('/'); }
+<EXPRESSION,MRI>"%"                    { RTOKEN('%'); }
+<EXPRESSION,MRI>"<"                    { RTOKEN('<'); }
+<SCRIPT,EXPRESSION,MRI,WILD>"="                { RTOKEN('='); }
 <SCRIPT,EXPRESSION,MRI,WILD>"}"                { RTOKEN('}'); }
 <SCRIPT,EXPRESSION,MRI,WILD>"{"                { RTOKEN('{'); }
-<SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>")" { RTOKEN(')');}
-<SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>"(" { RTOKEN('(');}
+<SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>")" { RTOKEN(')'); }
+<SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>"(" { RTOKEN('('); }
 <SCRIPT,EXPRESSION,MRI>":"             { RTOKEN(':'); }
-<SCRIPT,EXPRESSION,MRI,WILD>";"                { RTOKEN(';');}
-<SCRIPT>"MEMORY"                       { RTOKEN(MEMORY);}
-<SCRIPT>"REGION_ALIAS"                 { RTOKEN(REGION_ALIAS);}
-<SCRIPT>"LD_FEATURE"                   { RTOKEN(LD_FEATURE);}
-<SCRIPT,EXPRESSION>"ORIGIN"            { RTOKEN(ORIGIN);}
-<SCRIPT>"VERSION"                      { RTOKEN(VERSIONK);}
-<SCRIPT,EXPRESSION>"BLOCK"             { RTOKEN(BLOCK);}
-<SCRIPT,EXPRESSION>"BIND"              { RTOKEN(BIND);}
-<SCRIPT,EXPRESSION>"LENGTH"            { RTOKEN(LENGTH);}
-<SCRIPT,EXPRESSION>"ALIGN"             { RTOKEN(ALIGN_K);}
-<SCRIPT,EXPRESSION>"DATA_SEGMENT_ALIGN"        { RTOKEN(DATA_SEGMENT_ALIGN);}
-<SCRIPT,EXPRESSION>"DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END);}
-<SCRIPT,EXPRESSION>"DATA_SEGMENT_END"  { RTOKEN(DATA_SEGMENT_END);}
-<SCRIPT,EXPRESSION>"ADDR"              { RTOKEN(ADDR);}
-<SCRIPT,EXPRESSION>"LOADADDR"          { RTOKEN(LOADADDR);}
+<SCRIPT,EXPRESSION,MRI,WILD>";"                { RTOKEN(';'); }
+<SCRIPT>"MEMORY"                       { RTOKEN(MEMORY); }
+<SCRIPT>"REGION_ALIAS"                 { RTOKEN(REGION_ALIAS); }
+<SCRIPT>"LD_FEATURE"                   { RTOKEN(LD_FEATURE); }
+<SCRIPT,EXPRESSION>"ORIGIN"            { RTOKEN(ORIGIN); }
+<SCRIPT>"VERSION"                      { RTOKEN(VERSIONK); }
+<SCRIPT,EXPRESSION>"BLOCK"             { RTOKEN(BLOCK); }
+<SCRIPT,EXPRESSION>"BIND"              { RTOKEN(BIND); }
+<SCRIPT,EXPRESSION>"LENGTH"            { RTOKEN(LENGTH); }
+<SCRIPT,EXPRESSION>"ALIGN"             { RTOKEN(ALIGN_K); }
+<SCRIPT,EXPRESSION>"DATA_SEGMENT_ALIGN"        { RTOKEN(DATA_SEGMENT_ALIGN); }
+<SCRIPT,EXPRESSION>"DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END); }
+<SCRIPT,EXPRESSION>"DATA_SEGMENT_END"  { RTOKEN(DATA_SEGMENT_END); }
+<SCRIPT,EXPRESSION>"ADDR"              { RTOKEN(ADDR); }
+<SCRIPT,EXPRESSION>"LOADADDR"          { RTOKEN(LOADADDR); }
 <SCRIPT,EXPRESSION>"ALIGNOF"           { RTOKEN(ALIGNOF); }
 <SCRIPT,EXPRESSION>"ABSOLUTE"          { RTOKEN(ABSOLUTE); }
-<EXPRESSION>"MAX"                      { RTOKEN(MAX_K); }
-<EXPRESSION>"MIN"                      { RTOKEN(MIN_K); }
-<EXPRESSION>"LOG2CEIL"                 { RTOKEN(LOG2CEIL); }
+<SCRIPT,EXPRESSION>"MAX"               { RTOKEN(MAX_K); }
+<SCRIPT,EXPRESSION>"MIN"               { RTOKEN(MIN_K); }
+<SCRIPT,EXPRESSION>"LOG2CEIL"          { RTOKEN(LOG2CEIL); }
 <SCRIPT,EXPRESSION,WILD>"ASSERT"       { RTOKEN(ASSERT_K); }
-<SCRIPT,WILD>"ENTRY"                   { RTOKEN(ENTRY);}
-<SCRIPT,MRI>"EXTERN"                   { RTOKEN(EXTERN);}
-<SCRIPT,EXPRESSION>"NEXT"              { RTOKEN(NEXT);}
-<SCRIPT,EXPRESSION>"SIZEOF_HEADERS"    { RTOKEN(SIZEOF_HEADERS);}
-<SCRIPT,EXPRESSION>"SEGMENT_START"     { RTOKEN(SEGMENT_START);}
-<SCRIPT>"MAP"                          { RTOKEN(MAP);}
-<SCRIPT,EXPRESSION>"SIZEOF"            { RTOKEN(SIZEOF);}
-<SCRIPT>"TARGET"                       { RTOKEN(TARGET_K);}
-<SCRIPT>"SEARCH_DIR"                   { RTOKEN(SEARCH_DIR);}
-<SCRIPT>"OUTPUT"                       { RTOKEN(OUTPUT);}
-<SCRIPT>"INPUT"                                { RTOKEN(INPUT);}
-<SCRIPT,EXPRESSION,WILD>"GROUP"                { RTOKEN(GROUP);}
-<SCRIPT,EXPRESSION,INPUTLIST>"AS_NEEDED" { RTOKEN(AS_NEEDED);}
-<SCRIPT,EXPRESSION>"DEFINED"           { RTOKEN(DEFINED);}
-<SCRIPT,WILD>"CREATE_OBJECT_SYMBOLS"   { RTOKEN(CREATE_OBJECT_SYMBOLS);}
-<SCRIPT,WILD>"CONSTRUCTORS"            { RTOKEN(CONSTRUCTORS);}
-<SCRIPT>"FORCE_COMMON_ALLOCATION"      { RTOKEN(FORCE_COMMON_ALLOCATION);}
-<SCRIPT>"FORCE_GROUP_ALLOCATION"       { RTOKEN(FORCE_GROUP_ALLOCATION);}
-<SCRIPT>"INHIBIT_COMMON_ALLOCATION"    { RTOKEN(INHIBIT_COMMON_ALLOCATION);}
-<SCRIPT>"SECTIONS"                     { RTOKEN(SECTIONS);}
-<SCRIPT>"INSERT"                       { RTOKEN(INSERT_K);}
-<SCRIPT>"AFTER"                                { RTOKEN(AFTER);}
-<SCRIPT>"BEFORE"                       { RTOKEN(BEFORE);}
-<SCRIPT,WILD>"FILL"                    { RTOKEN(FILL);}
-<SCRIPT>"STARTUP"                      { RTOKEN(STARTUP);}
-<SCRIPT>"OUTPUT_FORMAT"                        { RTOKEN(OUTPUT_FORMAT);}
-<SCRIPT>"OUTPUT_ARCH"                  { RTOKEN(OUTPUT_ARCH);}
-<SCRIPT>"HLL"                          { RTOKEN(HLL);}
-<SCRIPT>"SYSLIB"                       { RTOKEN(SYSLIB);}
-<SCRIPT>"FLOAT"                                { RTOKEN(FLOAT);}
-<SCRIPT,WILD>"QUAD"                    { RTOKEN( QUAD);}
-<SCRIPT,WILD>"SQUAD"                   { RTOKEN( SQUAD);}
-<SCRIPT,WILD>"LONG"                    { RTOKEN( LONG);}
-<SCRIPT,WILD>"SHORT"                   { RTOKEN( SHORT);}
-<SCRIPT,WILD>"BYTE"                    { RTOKEN( BYTE);}
-<SCRIPT>"NOFLOAT"                      { RTOKEN(NOFLOAT);}
-<SCRIPT,EXPRESSION>"NOCROSSREFS"       { RTOKEN(NOCROSSREFS);}
-<SCRIPT,EXPRESSION>"NOCROSSREFS_TO"    { RTOKEN(NOCROSSREFS_TO);}
-<SCRIPT>"OVERLAY"                      { RTOKEN(OVERLAY); }
-<SCRIPT,WILD>"SORT_BY_NAME"            { RTOKEN(SORT_BY_NAME); }
-<SCRIPT,WILD>"SORT_BY_ALIGNMENT"       { RTOKEN(SORT_BY_ALIGNMENT); }
-<SCRIPT,WILD>"SORT"                    { RTOKEN(SORT_BY_NAME); }
-<SCRIPT,WILD>"SORT_BY_INIT_PRIORITY"   { RTOKEN(SORT_BY_INIT_PRIORITY); }
-<SCRIPT,WILD>"SORT_NONE"               { RTOKEN(SORT_NONE); }
-<SCRIPT,EXPRESSION>"NOLOAD"            { RTOKEN(NOLOAD);}
-<SCRIPT,EXPRESSION>"READONLY"          { RTOKEN(READONLY);}
-<SCRIPT,EXPRESSION>"DSECT"             { RTOKEN(DSECT);}
-<SCRIPT,EXPRESSION>"COPY"              { RTOKEN(COPY);}
-<SCRIPT,EXPRESSION>"INFO"              { RTOKEN(INFO);}
-<SCRIPT,EXPRESSION>"OVERLAY"           { RTOKEN(OVERLAY);}
-<EXPRESSION>"ONLY_IF_RO"               { RTOKEN(ONLY_IF_RO); }
-<EXPRESSION>"ONLY_IF_RW"               { RTOKEN(ONLY_IF_RW); }
-<EXPRESSION>"SPECIAL"                  { RTOKEN(SPECIAL); }
-<SCRIPT>"o"                            { RTOKEN(ORIGIN);}
-<SCRIPT>"org"                          { RTOKEN(ORIGIN);}
-<SCRIPT>"l"                            { RTOKEN( LENGTH);}
-<SCRIPT>"len"                          { RTOKEN( LENGTH);}
-<SCRIPT,EXPRESSION,WILD>"INPUT_SECTION_FLAGS" { RTOKEN(INPUT_SECTION_FLAGS); }
-<SCRIPT,EXPRESSION,WILD>"INCLUDE"      { RTOKEN(INCLUDE);}
-<SCRIPT>"PHDRS"                                { RTOKEN (PHDRS); }
+<SCRIPT>"ENTRY"                                { RTOKEN(ENTRY); }
+<SCRIPT,MRI>"EXTERN"                   { RTOKEN(EXTERN); }
+<SCRIPT,EXPRESSION>"NEXT"              { RTOKEN(NEXT); }
+<SCRIPT,EXPRESSION>"SIZEOF_HEADERS"    { RTOKEN(SIZEOF_HEADERS); }
+<SCRIPT,EXPRESSION>"SEGMENT_START"     { RTOKEN(SEGMENT_START); }
+<SCRIPT>"MAP"                          { RTOKEN(MAP); }
+<SCRIPT,EXPRESSION>"SIZEOF"            { RTOKEN(SIZEOF); }
+<SCRIPT>"TARGET"                       { RTOKEN(TARGET_K); }
+<SCRIPT>"SEARCH_DIR"                   { RTOKEN(SEARCH_DIR); }
+<SCRIPT>"OUTPUT"                       { RTOKEN(OUTPUT); }
+<SCRIPT>"INPUT"                                { RTOKEN(INPUT); }
+<SCRIPT>"GROUP"                                { RTOKEN(GROUP); }
+<INPUTLIST>"AS_NEEDED"                 { RTOKEN(AS_NEEDED); }
+<SCRIPT,EXPRESSION>"DEFINED"           { RTOKEN(DEFINED); }
+<WILD>"CREATE_OBJECT_SYMBOLS"          { RTOKEN(CREATE_OBJECT_SYMBOLS); }
+<WILD>"CONSTRUCTORS"                   { RTOKEN(CONSTRUCTORS); }
+<SCRIPT>"FORCE_COMMON_ALLOCATION"      { RTOKEN(FORCE_COMMON_ALLOCATION); }
+<SCRIPT>"FORCE_GROUP_ALLOCATION"       { RTOKEN(FORCE_GROUP_ALLOCATION); }
+<SCRIPT>"INHIBIT_COMMON_ALLOCATION"    { RTOKEN(INHIBIT_COMMON_ALLOCATION); }
+<SCRIPT>"SECTIONS"                     { RTOKEN(SECTIONS); }
+<SCRIPT>"INSERT"                       { RTOKEN(INSERT_K); }
+<SCRIPT>"AFTER"                                { RTOKEN(AFTER); }
+<SCRIPT>"BEFORE"                       { RTOKEN(BEFORE); }
+<WILD>"FILL"                           { RTOKEN(FILL); }
+<SCRIPT>"STARTUP"                      { RTOKEN(STARTUP); }
+<SCRIPT>"OUTPUT_FORMAT"                        { RTOKEN(OUTPUT_FORMAT); }
+<SCRIPT>"OUTPUT_ARCH"                  { RTOKEN(OUTPUT_ARCH); }
+<SCRIPT>"HLL"                          { RTOKEN(HLL); }
+<SCRIPT>"SYSLIB"                       { RTOKEN(SYSLIB); }
+<SCRIPT>"FLOAT"                                { RTOKEN(FLOAT); }
+<WILD>"QUAD"                           { RTOKEN(QUAD); }
+<WILD>"SQUAD"                          { RTOKEN(SQUAD); }
+<WILD>"LONG"                           { RTOKEN(LONG); }
+<WILD>"SHORT"                          { RTOKEN(SHORT); }
+<WILD>"BYTE"                           { RTOKEN(BYTE); }
+<SCRIPT>"NOFLOAT"                      { RTOKEN(NOFLOAT); }
+<SCRIPT,EXPRESSION>"NOCROSSREFS"       { RTOKEN(NOCROSSREFS); }
+<SCRIPT,EXPRESSION>"NOCROSSREFS_TO"    { RTOKEN(NOCROSSREFS_TO); }
+<SCRIPT,EXPRESSION>"OVERLAY"           { RTOKEN(OVERLAY); }
+<WILD>"SORT_BY_NAME"                   { RTOKEN(SORT_BY_NAME); }
+<WILD>"SORT_BY_ALIGNMENT"              { RTOKEN(SORT_BY_ALIGNMENT); }
+<WILD>"SORT"                           { RTOKEN(SORT_BY_NAME); }
+<WILD>"SORT_BY_INIT_PRIORITY"          { RTOKEN(SORT_BY_INIT_PRIORITY); }
+<WILD>"SORT_NONE"                      { RTOKEN(SORT_NONE); }
+<EXPRESSION>"NOLOAD"                   { RTOKEN(NOLOAD); }
+<EXPRESSION>"READONLY"                 { RTOKEN(READONLY); }
+<EXPRESSION>"DSECT"                    { RTOKEN(DSECT); }
+<EXPRESSION>"COPY"                     { RTOKEN(COPY); }
+<EXPRESSION>"INFO"                     { RTOKEN(INFO); }
+<SCRIPT,EXPRESSION>"ONLY_IF_RO"                { RTOKEN(ONLY_IF_RO); }
+<SCRIPT,EXPRESSION>"ONLY_IF_RW"                { RTOKEN(ONLY_IF_RW); }
+<SCRIPT,EXPRESSION>"SPECIAL"           { RTOKEN(SPECIAL); }
+<SCRIPT>"o"                            { RTOKEN(ORIGIN); }
+<SCRIPT>"org"                          { RTOKEN(ORIGIN); }
+<SCRIPT>"l"                            { RTOKEN(LENGTH); }
+<SCRIPT>"len"                          { RTOKEN(LENGTH); }
+<WILD>"INPUT_SECTION_FLAGS"            { RTOKEN(INPUT_SECTION_FLAGS); }
+<SCRIPT,EXPRESSION,WILD,MRI>"INCLUDE"  { RTOKEN(INCLUDE);}
+<SCRIPT>"PHDRS"                                { RTOKEN(PHDRS); }
 <SCRIPT,EXPRESSION,WILD>"AT"           { RTOKEN(AT);}
 <SCRIPT,EXPRESSION>"ALIGN_WITH_INPUT"  { RTOKEN(ALIGN_WITH_INPUT);}
 <SCRIPT,EXPRESSION>"SUBALIGN"          { RTOKEN(SUBALIGN);}
 <SCRIPT,EXPRESSION,WILD>"HIDDEN"       { RTOKEN(HIDDEN); }
 <SCRIPT,EXPRESSION,WILD>"PROVIDE"      { RTOKEN(PROVIDE); }
 <SCRIPT,EXPRESSION,WILD>"PROVIDE_HIDDEN" { RTOKEN(PROVIDE_HIDDEN); }
-<SCRIPT,EXPRESSION,WILD>"KEEP"         { RTOKEN(KEEP); }
-<SCRIPT,EXPRESSION,WILD>"EXCLUDE_FILE" { RTOKEN(EXCLUDE_FILE); }
+<WILD>"KEEP"                           { RTOKEN(KEEP); }
+<WILD>"EXCLUDE_FILE"                   { RTOKEN(EXCLUDE_FILE); }
 <SCRIPT,EXPRESSION>"CONSTANT"          { RTOKEN(CONSTANT);}
 
 <MRI>"#".*\n?                  { ++ lineno; }
@@ -384,14 +407,12 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
                                  yylval.name = xstrdup (yytext);
                                  return NAME;
                                }
+  /* The following rule is to prevent a fill expression on the output
+     section before /DISCARD/ interpreting the '/' as a divide.  */
 <EXPRESSION>"/DISCARD/"                {
                                  yylval.name = xstrdup (yytext);
                                  return NAME;
                                }
-<EXPRESSION>"-l"{NOCFILENAMECHAR}+ {
-                                 yylval.name = xstrdup (yytext + 2);
-                                 return LNAME;
-                               }
 <WILD>{WILDCHAR}* {
                /* Annoyingly, this pattern can match comments, and we have
                   longest match issues to consider.  So if the first two
@@ -473,7 +494,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
   return END;
 }
 
-<SCRIPT,MRI,VERS_START,VERS_SCRIPT,VERS_NODE>. lex_warn_invalid (" in script", yytext);
+<SCRIPT,WILD,MRI,VERS_START,VERS_SCRIPT,VERS_NODE>.    lex_warn_invalid (" in script", yytext);
 <EXPRESSION>.  lex_warn_invalid (" in expression", yytext);
 
 %%