Re: Making Generated Scanners Faster.

Norman Culver <ndc@icanect.net>
9 Jul 1996 13:25:13 -0400

          From comp.compilers

Related articles
Making Generated Scanners Faster. stephen@dcs.rhbnc.ac.uk (Stephen P. Butler) (1996-06-30)
Re: Making Generated Scanners Faster. ndc@icanect.net (Norman Culver) (1996-07-09)
| List of all articles for this month |
From: Norman Culver <ndc@icanect.net>
Newsgroups: comp.compilers
Date: 9 Jul 1996 13:25:13 -0400
Organization: Oxbow Software
References: 96-06-155
Keywords: lex

This is a multi-part message in MIME format.


--------------646C87C2206
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit


I wrote an LR1 parser table generator `LRG' a few years ago which has
the properties your are discussing i.e. the lexical and phrase structure
information is in one file and actions can be attached to both. The
EBNF format was inspired by LALR by Paul Mann. Currently the
table generator just creates a second set of tables for the lexical
phase and the lexical scanner is a slightly faster copy of the
parser (no automatic AST generation). I've never gotten around to
making a faster set of tables for the lexer, since it is such a small
part of the total compilation time for any compiler that I have written.


Attached are two grammars, the grammar for the parser table generator
(compiler compiler) and the grammar for a C compiler. If you want
the code for LRG let me know.


--------------------------------------------------------
Norman David Culver ndc@icanect.net (954)463-4754
Oxbow Software 1323 SE 17th St. Ft. Lauderdale, FL 33316
--------------------------------------------------------


--------------646C87C2206
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="C.grm"


/*--- C grammar with extensions for oxcc multipass compiler ---*/
/*
Norman D. Culver
Oxbow Software
1323 S.E. 17th Street #662
Ft. Lauderdale, FL 33316
(305) 527-1663 Voice
(305) 760-7584 Fax
(305) 760-4679 Data
norman.culver@channel1.com
ndc@gcomm.com


Copyright 1994-1995 by Norman D. Culver, All Rights Reserved.
*/
/*
NOTE -- THE DEADWOOD IN THIS GRAMMAR IS THERE BECAUSE OF THE NEED TO
RUNTIME INTERPRET AND/OR REGENERATE SOURCE FROM THE AST TREE


NOTE -- PRODUCTIONS TERMINATED WITH $$; DO NOT MAKE AST NODES


NOTE -- THE COMPILER COMPILER DERIVES ANY UNFORCED TERMINALS
*/


/* Force a couple of terminal symbol values */
#1 {meta-name}
#2 {typedef-name}


/*--- Operator Precedence. ---*/


    !( '?' )
    !( '||' )
    !( '&&' )
    !( '|' )
    !( '^' )
    !( '&' )
    !( '==' '!=' )
    !( '<' '>' '<=' '>=' )
    !( '<<' '>>' )
    !( '+' '-' )
    !( '*' '/' '%' )


/*--- Phrase Structure Grammar ---*/


File
-> [Input]... <eof> ;


Input
-> OuterDecl $$;
-> FuncDef $$;
-> Directive $$;
-> OuterAnf $$;
-> SegStuff $$;


SegStuff
-> __segdef__ DeclID [SegList] ';' ;
-> __seguse__ DeclID ';' ;


SegList
-> ConstExp \','... $$;


FuncDef
-> [FrontSpec]
FuncDeclarator
[Attr]
[InnerDecl]...
FuncBody ;


NestedFuncDef
-> FrontSpec
FuncDeclarator
FuncBody ;


FuncDeclarator
-> Declarator ;


FuncBody
-> LB
[DeclOrFunc]...
[StmtC]...
BodyExit ;


BodyExit
-> RB ;


OuterDecl
-> [FrontSpec] [InitDeclarator \','...] ';'
=> classify (typedef 'InitDeclarator' 'TypeAgain' 'ParenDeclarator'
'DeclID' <identifier> {meta-name} {typedef-name}) ;


InnerDecl
-> FrontSpec [InitDeclarator \','...] ';'
=> classify (typedef 'InitDeclarator' 'TypeAgain' 'ParenDeclarator'
'DeclID' <identifier> {meta-name} {typedef-name}) ;


FrontSpec
-> TypeDefs $$;
-> DeclarationSpec... $$;


TypeDefs
-> TypeDef Esu... $$;
-> TypeDef TdQual... TypedefName $$;
-> TypeDef [TdQual...] Type... [TdQual...] $$;
-> TypeDef TypedefName [TdQual...] $$;
-> TypeDef TypeAgain \','... $$;


TypeDef
-> typedef ;


TdQual
-> Qualifier $$;
-> FuncTypeModifier $$;


TypeAgain
-> TypedefName InitRHS ; /* reuse of computed typedef in a new block */
-> Identifier InitRHS ;


DeclarationSpec
-> TypeSpec $$;
-> StorageClassSpec $$;
-> Qualifier $$;
-> FuncTypeModifier $$;


InitDeclarator
-> Declarator [Attr] ;
-> Declarator [Attr] InitRHS ;


Declarator
-> [Pointer] DirectDeclarator $$;


Pointer
-> '*' [PQualifier]... ;
-> '*' [PQualifier]... Pointer ;


DirectDeclarator
-> DeclID $$;
-> ParenDeclarator $$;
-> DirectDeclarator FuncParams $$;
-> DirectDeclarator ArrayDecl $$;


PQualifier
-> Qualifier $$;
-> FuncTypeModifier $$;


DeclID
-> <identifier> ;
-> {meta-name} ;


ParenDeclarator
-> '(' [PQualifier...] Declarator ')' ;


ArrayDecl
-> '[' [BinopC] ']' ;


FuncParams
-> '(' [ParamList] ')' ;


ParamList
-> Param \','... ;
-> Param \','... ',' '...' ;
-> '...' ;


Param
-> SpecQual... InitDeclarator ;
-> SpecQual... [NoNameDeclarator] ;
-> Identifier ;


NoNameDeclarator
-> Pointer ;
-> [Pointer] DirectNoNameDeclarator ;


DirectNoNameDeclarator
-> ParenNoNameDeclarator $$;
-> [DirectNoNameDeclarator] FuncParams $$;
-> [DirectNoNameDeclarator] ArrayDecl $$;


ParenNoNameDeclarator
-> '(' [PQualifier...] NoNameDeclarator ')' ;


InitRHS
-> '=' Init ;


TypeSpec
-> Specs $$;
-> DynType $$;


DynType
-> TypedefName $$;
-> TypeOf $$;


Specs
-> Type $$;
-> Esu $$;


Esu
-> EnumSpec $$;
-> StructSpec $$;
-> UnionSpec $$;


Type
-> void ;
-> char ;
-> short ;
-> int ;
-> long ;
-> float ;
-> double ;
-> signed ;
-> unsigned ;
-> _segment ;
-> __segment ;


FuncTypeModifier
-> inline ;
-> __inline__ ;
-> __inline ;
-> _cdecl ;
-> __cdecl ;
-> _pascal ;
-> __pascal ;
-> _fortran ;
-> __fortran ;
-> _interrupt ;
-> __interrupt ;
-> _ifunc ;
-> _loadds ;
-> __loadds ;
-> _export ;
-> __export ;
-> _fastcall ;
-> _saveregs ;
-> __saveregs ;
-> _syscall ;
-> __syscall ;
-> _stdcall ;
-> __stdcall ;


Qualifier
-> Based ;
-> const ;
-> volatile ;
-> __volatile__ ;
-> _far ;
-> __far ;
-> _near ;
-> __near ;
-> _huge ;
-> __huge ;
-> _seg16 ;
-> __seg16 ;
-> _far16 ;
-> __far16 ;
-> register ;


Based
-> _based '(' BaseExp ')' $$;
-> __based '(' BaseExp ')' $$;


BaseExp
-> CastExp ;
-> _self ;
-> __self ;


SpecQual
-> TypeSpec $$;
-> Qualifier $$;
-> FuncTypeModifier $$;


TypedefName
-> {meta-name} => require ({meta-name} {typedef-name}) ;


TypeOf
-> typeof '(' CastExp ')' ;


StorageClassSpec
-> extern ;
-> static ;
-> _ival ;
-> auto $$;


StructSpec
-> struct Tag ;
-> struct '{' StructMembers... '}' ;
-> struct Tag '{' StructMembers... '}' ;
-> _Packed struct '{' StructMembers... '}' ;
-> _Packed struct Tag '{' StructMembers... '}' ;


UnionSpec
-> union Tag ;
-> union '{' StructMembers... '}' ;
-> union Tag '{' StructMembers... '}' ;


StructMembers
-> SpecQual... Members ';'; /* Allow unnamed structs and unions etc. */


Members
-> SMember \','... $$;


SMember
-> Member $$;
-> Bitfield $$;


Member
-> MemberDeclarator [Attr] ;
-> [Attr] ;


Bitfield
-> FieldSize [Attr] ;
-> MemberDeclarator FieldSize [Attr] ;


FieldSize
-> ':' BinopC ;


MemberDeclarator
-> [Pointer] DirectDeclarator $$;


EnumSpec
-> enum Tag ;
-> enum '{' Enumerator \','... [','] '}' ;
-> enum Tag '{' Enumerator \','... [','] '}' ;


Tag
-> <identifier> ;
-> {meta-name} ;


Enumerator
-> EnumID ;
-> EnumID EnumInit ;


EnumID
-> <identifier> ;


EnumInit
-> '=' BinopC ;


Init
-> InitBlock $$;
-> InitExp $$;


InitBlock
-> '{' InitInner \','... [','] '}' ;


InitExp
-> AssignExp ;


InitInner
-> InitId InitBlock $$;
-> InitId InitExp $$;
-> InitBlock $$;
-> InitExp $$;


InitId
-> AryElem... '=' ;
-> '.' InitLabel '=' ;
-> InitLabel ':' ;


AryElem
-> '[' InitElem ']' $$;


InitElem
-> Constant ;


InitLabel
-> <identifier> ;
-> {meta-name} ;


Attr
-> Attr1 '(' Constant ')' ')' ')' ;
-> Attr1 ')' ')' ;
-> Attr1 '(' Identifier ')' ')' ')' ;
-> Attr1 '(' Identifier ',' Constant ',' Constant ')' ')' ')' ;


Attr1
-> __attribute__ '(' '(' AttrId $$;


AttrId
-> <identifier> ;
-> {meta-name} ;


/* Statements */


StmtC
-> ';' ; /*0*/
-> Exp ';' ; /*1*/
-> goto Identifier ';' ; /*2*/
-> continue ';' ; /*3*/
-> break ';' ; /*4*/
-> return [RetExp] ';' ; /*5*/
-> if '(' IfExp ')' IfStmtC ; /*6*/
-> if '(' IfExp ')' IfStmtC else ElseStmtC ; /*7*/
-> switch '(' SwExp ')' SwStmtC ; /*8*/
-> while '(' WhileExp ')' WhileStmtC ; /*9*/
-> do DoStmtC while '(' DoExp ')' ';' ; /*10*/
-> for '(' [ForInit] FS1 [ForCond] FS2 [ForPost] ')' ForStmtC ; /*11*/
-> BlockC ; /*12*/
-> Label ':' [StmtC] ; /*13*/
-> AsmStmt ; /*14*/
-> AnfBlock ; /*15*/


FS1
-> ';' ;
FS2
-> ';' ;


RetExp
-> Exp ;


IfExp
-> Exp ;


SwExp
-> Exp ;


WhileExp
-> Exp ;


DoExp
-> Exp ;


IfStmtC
-> StmtC ;


ElseStmtC
-> StmtC ;


DoStmtC
-> StmtC ;


WhileStmtC
-> StmtC ;


ForStmtC
-> StmtC ;


SwStmtC
-> StmtC ;


ForInit
-> Exp ;


ForCond
-> Exp ;


ForPost
-> Exp ;


BlockC
-> BlockEntry
[Local]...
[DeclOrFunc]...
[StmtC]...
BlockExit ;


BlockEntry
-> LB ;


BlockExit
-> RB ;


DeclOrFunc
-> InnerDecl $$;
-> NestedFuncDef $$;


Local
-> __label__ LocalID ':' $$;


LocalID
-> <identifier> ;
-> {meta-name} ;


Label
-> <identifier> ;
-> {meta-name} ;
-> default ;
-> case ConstExp ;
-> case ConstExp '...' ConstExp ;


OuterAnf
-> AnfBlock [';'] ;


AsmStmt
-> GccAsmStmt $$;
-> MscAsmStmt $$;


GccAsmStmt
-> asm '(' [AsmString]... [GccIOspec] ')' ';' ;


AsmString
-> String ;


GccIOspec
-> CO [GccOutputList] CO [GccInputList] [ClobbersList] $$;


GccOutputList
-> GccOutput \','... $$;


GccInputList
-> GccInput \','... $$;


ClobbersList
-> CO Clobbers \','... $$;


GccOutput
-> String GccfixExp ;


GccInput
-> String GccfixExp ;


Clobbers
-> String ;


GccfixExp
-> PostfixExp ;


MscAsmStmt
-> _asm [AsmElem]... ;
-> _asm '{' [AsmAll]... '}' ;
-> _asm '(' AsmEmit... ')' ;


AsmAll
-> AsmElem $$;
-> AsmUnixOp $$;


AsmElem
-> AsmOp $$;
-> AsmId $$;
-> Constant $$;
-> Type $$;
-> AsmEmit $$;


AsmOp
-> '+' ;
-> '-' ;
-> '*' ;
-> '/' ;
-> '.' ;
-> '[' ;
-> ']' ;
-> ',' ;
-> ':' ;


AsmUnixOp
-> '%' ;
-> '$' ;
-> '(' ;
-> ')' ;


AsmId
-> <identifier> ;
-> {meta-name} ;


AsmEmit
-> _emit Constant ;
-> _emit '(' Constant \','... ')' ;


CO
-> ':' ;


AnfBlock
-> __anf__ '{' [AnfStmt]... '}' ;


AnfStmt
-> AnfOp [AnfTarget] ';' ;
-> Label ':' [AnfStmt] ;


AnfTarget
-> AssignExp \','... $$;


AnfOp
-> DeclID ;


/* Expressions */


Exp
-> AssignExp ;
-> Exp ',' CommaExp ;


CommaExp
-> AssignExp ; /* needed for regen source */


ConstExp
->BinopC ;


AssignExp
-> BinopC $$;
-> AssignLHS '+=' AssignExp ; /* 1 */
-> AssignLHS '-=' AssignExp ; /* 2 */
-> AssignLHS '*=' AssignExp ; /* 3 */
-> AssignLHS '/=' AssignExp ; /* 4 */
-> AssignLHS '<<=' AssignExp ; /* 5 */
-> AssignLHS '>>=' AssignExp ; /* 6 */
-> AssignLHS '%=' AssignExp ; /* 7 */
-> AssignLHS '|=' AssignExp ; /* 8 */
-> AssignLHS '^=' AssignExp ; /* 9 */
-> AssignLHS '&=' AssignExp ; /* 10 */
-> AssignLHS '=' AssignExp ; /* 11 */


AssignLHS
-> CastExp ;


BinopC
-> BaseOrCast $$;
-> BinopC '+' BinopC ; /* 1 */
-> BinopC '-' BinopC ; /* 2 */
-> BinopC '*' BinopC ; /* 3 */
-> BinopC '/' BinopC ; /* 4 */
-> BinopC '<<' BinopC ; /* 5 */
-> BinopC '>>' BinopC ; /* 6 */
-> BinopC '%' BinopC ; /* 7 */
-> BinopC '|' BinopC ; /* 8 */
-> BinopC '^' BinopC ; /* 9 */
-> BinopC '&' BinopC ; /* 10 */
-> BinopC '==' BinopC ; /* 11 */
-> BinopC '!=' BinopC ; /* 12 */
-> BinopC '<' BinopC ; /* 13 */
-> BinopC '>' BinopC ; /* 14 */
-> BinopC '<=' BinopC ; /* 15 */
-> BinopC '>=' BinopC ; /* 16 */
-> BinopC '||' BinopC ; /* 17 */
-> BinopC '&&' BinopC ; /* 18 */
-> BinopC '?' BinopC ':' BinopC ; /* 19 */
-> BinopC '?' ':' BinopC ; /* 20 */


BaseOrCast
-> BasedPtr $$;
-> CastExp $$;


BasedPtr
-> PostfixExp ':>' PostfixExp ;


CastExp
-> UnaryExp ;
-> '(' Cast ')' CastExp ;


Cast
-> SpecQual... [NoNameDeclarator] ;


UnaryExp
-> PostfixExp $$;
-> PreIncrement $$;
-> UnOpC CastExp $$;
-> SizeOf $$;
-> AlignOf $$;
-> SegName $$;


UnOpC
-> '&' ;
-> '*' ;
-> '-' ;
-> '~' ;
-> '!' ;


PreIncrement
-> '++' UnaryExp ;
-> '--' UnaryExp ;


PostIncrement
-> PostfixExp '++' ;
-> PostfixExp '--' ;


SizeOf
-> sizeof UnaryExp ;
-> sizeof '(' Cast ')' ;


AlignOf
-> __alignof__ UnaryExp ;
-> __alignof__ '(' Cast ')' ;


SegName
-> _segname '(' String ')' ;
-> __segname '(' String ')' ;


PostfixExp
-> PrimaryExp $$;
-> ArrayElement $$;
-> StructureElement $$;
-> PointerElement $$;
-> FunctionCall $$;
-> PostIncrement $$;


ArrayElement
-> ElemNameExp '[' ElemExp ']' ;


ElemNameExp
-> Identifier ;
-> ArrayElement ;
-> '(' Exp ')' ;
-> PointerElement ;
-> StructureElement ;
-> FunctionCall ;
-> String ;


ElemExp
-> Exp ;


StructureElement
-> PostfixExp '.' ElementName ;


PointerElement
-> PostfixExp '->' ElementName ;


ElementName
-> <identifier> ;
-> {meta-name} ;


FunctionCall
-> PostfixExp ArgList ;


ArgList
-> '(' [Args] ')' ;


Args
-> Arg \','... $$;


Arg
-> AssignExp ;
-> ArgId AssignExp ;


ArgId
-> ArgLabel ':' $$;


ArgLabel
-> <identifier> ;
-> {meta-name} ;


PrimaryExp
-> Constant $$;
-> Identifier $$;
-> '(' Exp ')' $$;
-> CompoundExp $$;
-> String... $$;


CompoundExp
-> '(' BlockC CompoundExit ;


CompoundExit
-> ')' ;


Identifier
-> <identifier> ;


Constant
-> <int> ; /*0*/
-> <long> ; /*1*/
-> <ll> ; /*2*/
-> <uint> ; /*3*/
-> <ulong> ; /*4*/
-> <ull> ; /*5*/


-> <hex> ; /*6*/
-> <lhex> ; /*7*/
-> <llhex> ; /*8*/
-> <uhex> ; /*9*/
-> <ulhex> ; /*10*/
-> <ullhex> ; /*11*/


-> <octal> ; /*12*/
-> <loctal> ; /*13*/
-> <lloctal> ; /*14*/
-> <uoctal> ; /*15*/
-> <uloctal> ; /*16*/
-> <ulloctal> ; /*17*/


-> <float> ; /*18*/
-> <double> ; /*19*/
-> <ldouble> ; /*20*/


-> <literal> ; /*21*/
-> <wliteral> ; /*22*/


String
-> <string> ;
-> <wstring> ;


LB -> '{' $$;
RB -> '}' $$;


Directive
-> <notline> ;
-> <linenum> ; /* this will never happen, linenum is expunged by doline */


/* Lexical grammar for c and c++ */


IGNORE := spaces ;
:= comment ;
:= comment2 ;


"eof" := (0 | 26 | 255) ;




"linenum" := line restofline => doline ;
line := '#line' ;


"notline" := notline restofline ;
notline := '#' ;


"identifier" := ident => dyntoken ;
ident := letter ;
:= ident letter ;
:= ident digit ;


"int" := digits ;


"long" := digits 'l' ;
:= digits 'L' ;


"uint" := digits 'U' ;
:= digits 'u' ;


"ulong" := digits 'LU' ;
:= digits 'UL' ;
:= digits 'ul' ;
:= digits 'lu' ;
:= digits 'lU' ;
:= digits 'Lu' ;
:= digits 'uL' ;
:= digits 'Ul' ;


"ll" := digits 'LL' ;
:= digits 'll' ;


"ull" := digits 'ull' ;
:= digits 'llu' ;
:= digits 'ULL' ;
:= digits 'LLU' ;


digits := digit ;
:= digits digit ;


"hex" := hexx ;


"lhex" := hexx 'l' ;
:= hexx 'L' ;


"uhex" := hexx 'U' ;
:= hexx 'u' ;


"ulhex" := hexx 'LU' ;
:= hexx 'UL' ;
:= hexx 'ul' ;
:= hexx 'lu' ;
:= hexx 'lU' ;
:= hexx 'Lu' ;
:= hexx 'uL' ;
:= hexx 'Ul' ;


"llhex" := hexx 'LL' ;
:= hexx 'll' ;


"ullhex" := hexx 'ull' ;
:= hexx 'llu' ;
:= hexx 'ULL' ;
:= hexx 'LLU' ;




hexx := '0x' hexdigit ;
:= '0X' hexdigit ;
:= hexx hexdigit ;


hexdigit := '0'/'9' ;
:= a/f ;
:= A/F ;


"octal" := oct ;


"loctal" := oct 'l' ;
:= oct 'L' ;


"uoctal" := oct 'U' ;
:= oct 'u' ;


"uloctal" := oct 'LU' ;
:= oct 'UL' ;
:= oct 'ul' ;
:= oct 'lu' ;
:= oct 'lU' ;
:= oct 'Lu' ;
:= oct 'uL' ;
:= oct 'Ul' ;


"lloctal" := oct 'LL' ;
:= oct 'll' ;


"ulloctal" := oct 'ull' ;
:= oct 'llu' ;
:= oct 'ULL' ;
:= oct 'LLU' ;


oct := '0' octdigit ;
:= oct octdigit ;
octdigit := '0'/'7' ;


"double" := flt ;
"float" := flt 'f' ;
:= flt 'F' ;
"ldouble" := flt 'l' ;
:= flt 'L' ;


flt := rational ;
:= digits exp ;
:= rational exp ;


rational := digits '.' ;
:= '.' digits ;
:= digits '.' digits ;
exp := 'e' digits ;
:= 'E' digits ;
:= 'e-' digits ;
:= 'E-' digits ;
:= 'e+' digits ;
:= 'E+' digits ;


"literal" := lit ;
"wliteral" := 'L' lit ;
lit := qt lchar... qt ;
lchar := ch ;
:= qt qt ;
:= '"' ;
:= '*' ;
:= '/' ;
:= escapes ;


"string" := str ;
"wstring" := 'L' str ;


str := '"' [schar...] '"' ;
schar := ch ;
:= qt ;
:= '*' ;
:= '/' ;
:= escapes ;


escapes := bs qt ;
:= bs ch ;
:= bs '"' ;
:= bs '*' ;
:= bs '/' ;
:= bs bs ;
:= bs lf ;


spaces := space... ;
space := ( 9 | 10 | 12 | 32 ) ;


comment := '/*' end '/' ;
end := endinstar ;
                     := end noslash endinstar ;
endinstar := stars ;
                     := notstar stars ;
stars := '*'... ;
notstar := nostar ;
                     := notstar nostar ;
noslash := (ch | notsl) ;
notsl := (10 | 12 | 39 | '"' | '*' | 92) ;
nostar := (ch | notst) ;
notst := (10 | 12 | 39 | '"' | '/' | 92) ;




comment2 := '//' restofline ;


restofline := [(ch | noteol)]... ;
noteol := (39 | '"' | '/' | '*' | 92) ;


ch := 1/254 ^(10 12 26 39 '"' '/' '*' 92) ;


letter := a/z ;
:= A/Z ;
:= '_' ;


digit := '0'/'9' ;


bs := 92 ;
qt := 39 ;
lf := 10 ;
/*--- End. ---*/




--------------646C87C2206
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="Lrg.grm"




/*
  Tokens of the phrase structure grammar. Specification of tokens is optional
  because unmentioned tokens are deduced by the complier compiler.
*/


#1 <metameta>
#2 <meta>
#3 <alpha>
#4 <literal>
#5 <number>
#6 <string>
#7 <EOF>
#8 '->'
#9 '|'
#10 '['
#11 ']'
#12 '('
#13 ')'
#14 '...'
#15 '\\'
#16 '<<'
#17 '>>'
#18 ','
#19 '#'
#20 '!'
#21 '@@'
#22 ';'
#23 ':='
#24 '/'
#25 '^'
#26 '$$'
#27 '=>'
#28 '-=>'


/* ------ Phrase Structure Grammar which appears in the AST --------------- */


      File -> Grammar <EOF> ;


      Grammar -> Term... Prec... Rule... ;
                                    -> Prec... Rule... ;
                                    -> Term... Rule... ;
                                    -> Rule... ;
       -> Term... Prec... Rule... LgrRule... ;
                                    -> Prec... Rule... LgrRule... ;
                                    -> Term... Rule... LgrRule... ;
                                    -> Rule... LgrRule... ;


      Term -> NumbSymb [Eol] ;


      Prec -> PrecBody [Assoc] [Eol] ;


      PrecBody -> '!' LP [Operator]... ')' ;


      Rule -> HeadSymb ('->' Prod)... ;


      Prod -> Tail... [RulePrec] [NoNode] [Action] [Eol] ;


      ActArgs -> '(' [TailSymb]... ')' ;


      ActName -> <alpha> ;


      Action -> '=>' ActName [ActArgs] ;
-> '-=>' ActName [ActArgs] ;


      NumbSymb -> SeqNumb TermSymb ;


      SeqNumb -> '#' <number> ;


      TermSymb -> <meta> ;
       -> <alpha> ;
       -> <literal> ;
-> <metameta> ;


      Operator -> <meta> ;
                                    -> <alpha> ;
                                    -> <literal> ;


      Assoc -> '<<' ;
-> '>>' ;
-> '@@' ;


      HeadSymb -> <alpha> ;
-> <string> ;


      Tail -> TailSymb ;
-> ComplexTail ;


      ComplexTail -> TailSymb '...' ;
                                    -> TailSymb MS ;
                                    -> LB List RB ;
                                    -> LB List RZ ;
                                    -> LB List RZS ;
                                    -> LP List RP ;
                                    -> LP List RP '...' ;
                                    -> LP List RP MS ;


      or -> '|' ;


      LgrRule -> HeadSymb (':=' LgrProd)... ;
      LgrProd -> LgrTail... [RulePrec] [Action] [Eol] ;


      LgrTail -> TailSymb ;
-> ComplexTail ;
-> Lelem ;


      Range -> TailSymb '/' TailSymb ;


      Except -> '^' TailSymb ;
-> '^' Range ;
-> '^' LP TailSymb... RP ;


      RulePrec -> '!' <number> ;


      SepSymb -> <meta> ;
                                    -> <alpha> ;
                                    -> <literal> ;
                                    -> <number> ;


      TailSymb -> <meta> ;
                                    -> <alpha> ;
                                    -> <literal> ;
                                    -> <number> ;
-> <string> ;
-> <metameta> ;


      NoNode -> '$$' ;


/* No Nodes in AST for these rules (because $$ is last token) */


      Eol -> ';' $$ ;


      List -> Tail... [or Tail...]... $$ ;


      LP -> '(' $$ ;
      RP -> ')' $$ ;
      LB -> '[' $$ ;
      RB -> ']' $$ ;
      RZ -> ']' '...' $$ ;
      RZS -> ']' MS $$ ;


      MS -> '\\' SepSymb '...' $$ ;


      Lelem -> Range $$ ;
-> Except $$ ;


/* ------------ Lexical Grammar ------------------------- */


IGNORE := spaces ;
                    := comment ;


spaces := space... ;
space := ( 9 | 10 | 12 | 32 ) ;


comment := '/*' end '/' ;
end := endinstar ;
                    := end noslash endinstar ;
endinstar := stars ;
                    := notstar stars ;
stars := '*'... ;
notstar := nostar ;
                    := notstar nostar ;
noslash := (ch | notsl) ;
notsl := (10 | 12 | 39 | '"' | '*' | 92) ;
nostar := (ch | notst) ;
notst := (10 | 12 | 39 | '"' | '/' | 92) ;


"meta" := '<' alpha '>' ;
"metameta" := '{' alpha '}' ;
"alpha" := alpha ;
alpha := letter ;
:= alpha alphanum ;
                    := alpha '-' alphanum ;
alphanum := letter ;
                    := digit ;
letter := a/z ;
:= A/Z ;
:= '_' ;


"literal" := qt lchar... qt ;
lchar := ch ;
:= bs bs ;
                    := bs qt ;
:= '"' ;
:= '*' ;
:= '/' ;


"number" := digit... ;
digit := '0'/'9' ;


"string" := '"' schar... '"' ;
schar := ch ;
:= bs bs ;
                    := bs '"' ;
:= '/' ;
:= '*' ;
:= qt ;


"EOF" := (255 | 26 | 0) ;


ch := 1/254 ^(10 12 26 39 '"' '/' '*' 92) ;


bs := 92 ;
qt := 39 ;




/* End of grammar. */




--------------646C87C2206--


--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.