2 -- m
2-h
.bnf grammar and associated actions for pass h
.
4 -- Copyright
(C
) 2001-
2022 Free Software Foundation, Inc
.
5 -- Contributed by Gaius Mulley <gaius
.mulley@southwales
.ac
.uk>
.
7 -- This file is part of GNU Modula-
2.
9 -- GNU Modula-
2 is free software; you can redistribute it and/or modify
10 -- it under the terms of the GNU General Public License as published by
11 -- the Free Software Foundation; either version
3, or
(at your option
)
14 -- GNU Modula-
2 is distributed in the hope that it will be useful, but
15 -- WITHOUT ANY WARRANTY; without even the implied warranty of
16 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
. See the GNU
17 -- General Public License for more details
.
19 -- You should have received a copy of the GNU General Public License
20 -- along with GNU Modula-
2; see the file COPYING
3. If not see
21 -- <http
://www.gnu.org/licenses/>.
22 % module PHBuild begin
23 (* output from m
2-h
.bnf, automatically generated do not edit if these
24 are the top two lines in the file
.
26 Copyright
(C
) 2001-
2022 Free Software Foundation, Inc
.
27 Contributed by Gaius Mulley <gaius
.mulley@southwales
.ac
.uk>
.
29 This file is part of GNU Modula-
2.
31 GNU Modula-
2 is free software; you can redistribute it and/or modify
32 it under the terms of the GNU General Public License as published by
33 the Free Software Foundation; either version
3, or
(at your option
)
36 GNU Modula-
2 is distributed in the hope that it will be useful, but
37 WITHOUT ANY WARRANTY; without even the implied warranty of
38 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
. See the GNU
39 General Public License for more details
.
41 You should have received a copy of the GNU General Public License
42 along with GNU Modula-
2; see the file COPYING
. If not,
43 see <https
://www.gnu.org/licenses/>. *)
45 IMPLEMENTATION MODULE PHBuild ;
47 FROM M
2LexBuf IMPORT currentstring, currenttoken, GetToken, InsertToken, InsertTokenAndRewind, GetTokenNo ;
48 FROM M
2Error IMPORT ErrorStringAt ;
49 FROM NameKey IMPORT NulName, Name, makekey ;
50 FROM M
2Reserved IMPORT NulTok, ByTok, PeriodPeriodTok, tokToTok, toktype ;
51 FROM DynamicStrings IMPORT String, InitString, KillString, Mark, ConCat, ConCatChar ;
52 FROM M
2Printf IMPORT printf
0 ;
53 FROM M
2Debug IMPORT Assert ;
54 FROM P
2SymBuild IMPORT BuildString, BuildNumber ;
56 FROM M
2Quads IMPORT PushT, PopT, PushTF, PopTF, PopNothing, PushTFtok, PopTFtok, PopTtok,
57 StartBuildDefFile, StartBuildModFile,
64 BuildAssignment, BuildAssignConstant,
65 BuildFunctionCall, BuildConstFunctionCall,
66 BuildBinaryOp, BuildUnaryOp, BuildRelOp, BuildNot,
67 BuildEmptySet, BuildInclRange, BuildInclBit,
68 BuildSetStart, BuildSetEnd,
70 BuildRepeat, BuildUntil,
71 BuildWhile, BuildDoWhile, BuildEndWhile,
72 BuildLoop, BuildExit, BuildEndLoop,
73 BuildThenIf, BuildElse, BuildEndIf,
74 BuildForToByDo, BuildPseudoBy, BuildEndFor,
75 BuildElsif
1, BuildElsif
2,
76 BuildProcedureCall, BuildReturn, BuildNulExpression,
77 StartBuildWith, EndBuildWith,
83 BuildCaseStartStatementSequence,
84 BuildCaseEndStatementSequence,
86 BuildCaseRange, BuildCaseEquality,
87 BuildConstructorStart,
89 SilentBuildConstructorStart,
90 BuildComponentValue, BuildTypeForConstructor,
91 BuildBooleanVariable, BuildAlignment,
94 BuildDesignatorRecord,
96 BuildDesignatorPointer,
97 BeginVarient, EndVarient, ElseVarient,
98 BeginVarientList, EndVarientList,
99 AddVarientRange, AddVarientEquality,
101 IsAutoPushOn, PushAutoOff, PushAutoOn, PopAuto ;
103 FROM P
3SymBuild IMPORT P
3StartBuildProgModule,
104 P
3EndBuildProgModule,
106 P
3StartBuildDefModule,
109 P
3StartBuildImpModule,
112 StartBuildInnerModule,
116 BuildProcedureHeading,
122 FROM SymbolTable IMPORT MakeGnuAsm, PutGnuAsmVolatile, PutGnuAsm, PutGnuAsmInput,
123 PutGnuAsmOutput, PutGnuAsmTrash, PutGnuAsmVolatile,
125 PutRegInterface, GetRegInterface,
128 StartScope, EndScope,
130 IsVarParam, IsProcedure, IsDefImp, IsModule,
133 GetSym, GetLocalSym ;
135 FROM M
2Batch IMPORT IsModuleKnown ;
137 FROM M
2CaseList IMPORT BeginCaseList, EndCaseList, ElseCase ;
139 FROM M
2Reserved IMPORT NulTok, ImportTok, ExportTok, QualifiedTok, UnQualifiedTok,
140 EqualTok, HashTok, LessGreaterTok, LessTok, LessEqualTok,
141 GreaterTok, GreaterEqualTok, InTok, PlusTok, MinusTok,
142 OrTok, TimesTok, DivTok, DivideTok, ModTok, RemTok, AndTok, AmbersandTok ;
149 Pass
1 = FALSE ;
(* permanently disabled for the time being *
)
150 Pass
2 = FALSE ;
(* permanently disabled for the time being *
)
154 WasNoError: BOOLEAN ;
157 PROCEDURE ErrorString
(s
: String
) ;
159 ErrorStringAt
(s, GetTokenNo
()) ;
164 PROCEDURE ErrorArray
(a
: ARRAY OF CHAR
) ;
166 ErrorString
(InitString
(a
))
170 % declaration PHBuild begin
174 SyntaxError - after a syntax error we skip all tokens up until we reach
178 PROCEDURE SyntaxError
(stopset
0: SetOfStop
0; stopset
1: SetOfStop
1; stopset
2: SetOfStop
2) ;
183 printf
0('
\nskipping token *** '
)
185 (* --fixme-- this assumes a
32 bit word size
. *
)
186 WHILE NOT
(((ORD
(currenttoken
)<
32) AND
(currenttoken IN stopset
0)) OR
187 ((ORD
(currenttoken
)>
=32) AND
(ORD
(currenttoken
)<
64) AND
(currenttoken IN stopset
1)) OR
188 ((ORD
(currenttoken
)>
=64) AND
(currenttoken IN stopset
2)))
203 PROCEDURE SyntaxCheck
(stopset
0: SetOfStop
0; stopset
1: SetOfStop
1; stopset
2: SetOfStop
2) ;
205 (* --fixme-- this assumes a
32 bit word size
. *
)
206 IF NOT
(((ORD
(currenttoken
)<
32) AND
(currenttoken IN stopset
0)) OR
207 ((ORD
(currenttoken
)>
=32) AND
(ORD
(currenttoken
)<
64) AND
(currenttoken IN stopset
1)) OR
208 ((ORD
(currenttoken
)>
=64) AND
(currenttoken IN stopset
2)))
210 SyntaxError
(stopset
0, stopset
1, stopset
2)
216 WarnMissingToken - generates a warning message about a missing token, t
.
219 PROCEDURE WarnMissingToken
(t
: toktype
) ;
238 str := DescribeStop
(s
0, s
1, s
2) ;
240 str := ConCat
(InitString
('syntax error,'
), Mark
(str
)) ;
241 ErrorStringAt
(str, GetTokenNo
())
242 END WarnMissingToken ;
246 MissingToken - generates a warning message about a missing token, t
.
249 PROCEDURE MissingToken
(t
: toktype
) ;
251 WarnMissingToken
(t
) ;
252 IF
(t#identtok
) AND
(t#integertok
) AND
(t#realtok
) AND
(t#stringtok
)
256 printf
0('inserting token
\n'
)
267 PROCEDURE CheckAndInsert
(t
: toktype; stopset
0: SetOfStop
0; stopset
1: SetOfStop
1; stopset
2: SetOfStop
2) : BOOLEAN ;
269 IF
((ORD
(t
)<
32) AND
(t IN stopset
0)) OR
270 ((ORD
(t
)>
=32) AND
(ORD
(t
)<
64) AND
(t IN stopset
1)) OR
271 ((ORD
(t
)>
=64) AND
(t IN stopset
2))
273 WarnMissingToken
(t
) ;
274 InsertTokenAndRewind
(t
) ;
286 PROCEDURE InStopSet
(t
: toktype; stopset
0: SetOfStop
0; stopset
1: SetOfStop
1; stopset
2: SetOfStop
2) : BOOLEAN ;
288 IF
((ORD
(t
)<
32) AND
(t IN stopset
0)) OR
289 ((ORD
(t
)>
=32) AND
(ORD
(t
)<
64) AND
(t IN stopset
1)) OR
290 ((ORD
(t
)>
=64) AND
(t IN stopset
2))
300 PeepToken - peep token checks to see whether the stopset is satisfied by currenttoken
301 If it is not then it will insert a token providing the token
302 is one of ;
] ) } . OF END ,
304 if the stopset contains <identtok> then we do not insert a token
307 PROCEDURE PeepToken
(stopset
0: SetOfStop
0; stopset
1: SetOfStop
1; stopset
2: SetOfStop
2) ;
309 (* and again
(see above re
: ORD
)
311 IF
(NOT
(((ORD
(currenttoken
)<
32) AND
(currenttoken IN stopset
0)) OR
312 ((ORD
(currenttoken
)>
=32) AND
(ORD
(currenttoken
)<
64) AND
(currenttoken IN stopset
1)) OR
313 ((ORD
(currenttoken
)>
=64) AND
(currenttoken IN stopset
2)))) AND
314 (NOT InStopSet
(identtok, stopset
0, stopset
1, stopset
2))
316 (* SyntaxCheck would fail since currentoken is not part of the stopset
317 we check to see whether any of currenttoken might be a commonly omitted token *
)
318 IF CheckAndInsert
(semicolontok, stopset
0, stopset
1, stopset
2) OR
319 CheckAndInsert
(rsbratok, stopset
0, stopset
1, stopset
2) OR
320 CheckAndInsert
(rparatok, stopset
0, stopset
1, stopset
2) OR
321 CheckAndInsert
(rcbratok, stopset
0, stopset
1, stopset
2) OR
322 CheckAndInsert
(periodtok, stopset
0, stopset
1, stopset
2) OR
323 CheckAndInsert
(oftok, stopset
0, stopset
1, stopset
2) OR
324 CheckAndInsert
(endtok, stopset
0, stopset
1, stopset
2) OR
325 CheckAndInsert
(commatok, stopset
0, stopset
1, stopset
2)
336 PROCEDURE Expect
(t
: toktype; stopset
0: SetOfStop
0; stopset
1: SetOfStop
1; stopset
2: SetOfStop
2) ;
343 PeepToken
(stopset
0, stopset
1, stopset
2)
348 SyntaxCheck
(stopset
0, stopset
1, stopset
2)
353 CompilationUnit - returns TRUE if the input was correct enough to parse
357 PROCEDURE CompilationUnit
() : BOOLEAN ;
360 FileUnit
(SetOfStop
0{eoftok
}, SetOfStop
1{}, SetOfStop
2{}) ;
362 END CompilationUnit ;
366 Ident - error checking varient of Ident
369 PROCEDURE Ident
(stopset
0: SetOfStop
0; stopset
1: SetOfStop
1; stopset
2: SetOfStop
2) ;
373 PushTF
(makekey
(currentstring
), identtok
)
375 Expect
(identtok, stopset
0, stopset
1, stopset
2)
383 PROCEDURE string
(stopset
0: SetOfStop
0; stopset
1: SetOfStop
1; stopset
2: SetOfStop
2) ;
387 PushTF
(makekey
(currentstring
), stringtok
) ;
390 Expect
(stringtok, stopset
0, stopset
1, stopset
2)
398 PROCEDURE Integer
(stopset
0: SetOfStop
0; stopset
1: SetOfStop
1; stopset
2: SetOfStop
2) ;
402 PushTFtok
(makekey
(currentstring
), integertok, GetTokenNo
()) ;
405 Expect
(integertok, stopset
0, stopset
1, stopset
2)
413 PROCEDURE Real
(stopset
0: SetOfStop
0; stopset
1: SetOfStop
1; stopset
2: SetOfStop
2) ;
417 PushTFtok
(makekey
(currentstring
), realtok, GetTokenNo
()) ;
420 Expect
(realtok, stopset
0, stopset
1, stopset
2)
426 error 'ErrorArray' 'ErrorString'
427 tokenfunc 'currenttoken'
429 token '' eoftok -- internal token
434 token '
:=' becomestok
435 token '&' ambersandtok
438 token
";" semicolontok
441 token '
[' lsbratok -- left square brackets
442 token '
]' rsbratok -- right square brackets
443 token '
{' lcbratok -- left curly brackets
444 token '
}' rcbratok -- right curly brackets
446 token
"'" singlequotetok
451 token '<>' lessgreatertok
452 token '<
=' lessequaltok
453 token '>
=' greaterequaltok
454 token '<*' ldirectivetok
455 token '*>' rdirectivetok
456 token '
..' periodperiodtok
458 token '
"' doublequotestok
461 token 'ARRAY' arraytok
462 token 'BEGIN' begintok
465 token 'CONST' consttok
466 token 'DEFINITION' definitiontok
470 token 'ELSIF' elsiftok
472 token 'EXCEPT' excepttok
474 token 'EXPORT' exporttok
475 token 'FINALLY' finallytok
479 token 'IMPLEMENTATION' implementationtok
480 token 'IMPORT' importtok
484 token 'MODULE' moduletok
488 token 'PACKEDSET' packedsettok
489 token 'POINTER' pointertok
490 token 'PROCEDURE' proceduretok
491 token 'QUALIFIED' qualifiedtok
492 token 'UNQUALIFIED' unqualifiedtok
493 token 'RECORD' recordtok
495 token 'REPEAT' repeattok
496 token 'RETRY' retrytok
497 token 'RETURN' returntok
502 token 'UNTIL' untiltok
504 token 'WHILE' whiletok
507 token 'VOLATILE' volatiletok
508 token '...' periodperiodperiodtok
509 token '__DATE__' datetok
510 token '__LINE__' linetok
511 token '__FILE__' filetok
512 token '__ATTRIBUTE__' attributetok
513 token '__BUILTIN__' builtintok
514 token '__INLINE__' inlinetok
515 token 'integer number' integertok
516 token 'identifier' identtok
517 token 'real number' realtok
518 token 'string' stringtok
520 special Ident first { < identtok > } follow { }
521 special Integer first { < integertok > } follow { }
522 special Real first { < realtok > } follow { }
523 special string first { < stringtok > } follow { }
527 -- the following are provided by the module m2flex and also handbuild procedures below
528 -- Ident := Letter { ( Letter | Digit ) } =:
529 -- Integer := Digit { Digit } | OctalDigit { OctalDigit } ( " B
" | " C
" ) |
530 -- Digit { HexDigit } " H
" =:
531 -- Real := Digit { Digit } " . " { Digit } [ ScaleFactor ] =:
532 -- ScaleFactor := " E
" [ ( " +
" | " -
" ) ] Digit { Digit } =:
533 -- HexDigit := Digit | " A
" | " B
" | " C
" | " D
" | " E
" | " F
" =:
534 -- Digit := OctalDigit | " 8 " | " 9 " =:
535 -- OctalDigit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" =:
538 FileUnit := % PushAutoOff %
540 ImplementationOrProgramModule ) % PopAuto %
543 ProgramModule := % VAR begint, endt: CARDINAL ; %
544 % begint := GetTokenNo () %
545 "MODULE
" % M2Error.DefaultProgramModule %
547 Ident % P3StartBuildProgModule %
548 % BuildModuleStart (begint) %
554 } % begint := GetTokenNo () %
555 % StartBuildInit (begint) %
557 % endt := GetTokenNo () -1 %
558 Ident % EndBuildFile (endt) %
559 % P3EndBuildProgModule %
561 EndBuildInit (endt) ;
565 ImplementationModule := % VAR begint, endt: CARDINAL ; %
566 % begint := GetTokenNo () %
567 "IMPLEMENTATION
" % M2Error.DefaultImplementationModule %
568 "MODULE
" % PushAutoOn %
569 Ident % StartBuildModFile (begint) %
570 % P3StartBuildImpModule %
571 % BuildModuleStart (begint) %
576 } % begint := GetTokenNo () %
577 % StartBuildInit (begint) %
579 % endt := GetTokenNo () -1 %
580 Ident % EndBuildFile (endt) %
581 % P3EndBuildImpModule %
583 EndBuildInit (endt) ;
588 ImplementationOrProgramModule := % PushAutoOff %
589 ( ImplementationModule | ProgramModule ) % PopAuto %
592 Number := Integer | Real =:
594 Qualident := % VAR name: Name ;
595 Type, Sym, tok: CARDINAL ; %
600 Sym := RequestSym (tok, name) ;
601 IF IsDefImp(Sym) OR IsModule(Sym)
603 Expect(periodtok, stopset0, stopset1, stopset2 + SetOfStop2{identtok}) ;
605 Qualident(stopset0, stopset1, stopset2) ;
606 (* should we test for lack of ident? *)
607 PopTFtok(Sym, Type, tok) ;
608 PushTFtok(Sym, Type, tok) ;
612 PushTFtok(Sym, GetType(Sym), tok) ;
614 ELSE (* just parse qualident *) %
615 { "." Ident } % END %
618 ConstantDeclaration := % PushAutoOn %
619 % VAR tokno: CARDINAL ; %
620 ( Ident "=" % tokno := GetTokenNo () %
622 ConstExpression ) % BuildAssignConstant (tokno) %
626 ConstExpression := % VAR tokpos: CARDINAL ; %
628 SimpleConstExpr [ Relation % tokpos := GetTokenNo ()-1 %
629 SimpleConstExpr % BuildRelOp (tokpos) %
633 Relation := "=" % PushT(EqualTok) %
634 | "#
" % PushT(HashTok) %
635 | "<>
" % PushT(LessGreaterTok) %
636 | "<
" % PushT(LessTok) %
637 | "<
=" % PushT(LessEqualTok) %
638 | ">
" % PushT(GreaterTok) %
639 | ">
=" % PushT(GreaterEqualTok) %
640 | "IN
" % PushT(InTok) %
643 SimpleConstExpr := UnaryOrConstTerm { AddOperator ConstTerm % BuildBinaryOp %
646 UnaryOrConstTerm := "+
" % PushT(PlusTok) %
647 ConstTerm % BuildUnaryOp %
649 "-
" % PushT(MinusTok) %
650 ConstTerm % BuildUnaryOp %
654 AddOperator := "+
" % PushT(PlusTok) ;
656 | "-
" % PushT(MinusTok) ;
658 | "OR
" % PushT(OrTok) ;
662 ConstTerm := ConstFactor { MulOperator ConstFactor % BuildBinaryOp %
665 MulOperator := "*
" % PushT(TimesTok) ;
667 | "/
" % PushT(DivideTok) ;
669 | "DIV
" % PushT(DivTok) ;
671 | "MOD
" % PushT(ModTok) ;
673 | "REM
" % PushT(RemTok) ;
675 | "AND
" % PushT(AndTok) ;
677 | "&
" % PushT(AmbersandTok) ;
681 ConstFactor := Number | ConstString | ConstSetOrQualidentOrFunction |
682 "(" ConstExpression ")" | "NOT
" ConstFactor % BuildNot %
685 -- to help satisfy LL1
687 ConstString := string =:
689 ComponentElement := ConstExpression ( ".." ConstExpression % PushT(PeriodPeriodTok) %
694 ComponentValue := ComponentElement ( 'BY' ConstExpression % PushT(ByTok) %
700 ArraySetRecordValue := ComponentValue % BuildComponentValue %
701 { ',' ComponentValue % BuildComponentValue %
705 Constructor := '{' % BuildConstructorStart (GetTokenNo() -1) %
706 [ ArraySetRecordValue ] % BuildConstructorEnd (GetTokenNo()) %
709 ConstSetOrQualidentOrFunction := Qualident
710 [ Constructor | ConstActualParameters % BuildConstFunctionCall %
712 | % BuildTypeForConstructor %
715 ConstAttribute := "__ATTRIBUTE__
" "__BUILTIN__
" "(" "(" ConstAttributeExpression ")" ")" =:
717 ConstAttributeExpression := Ident | "<
" Qualident ',' Ident ">
" =:
719 ByteAlignment := '<*' % PushAutoOn %
720 AttributeExpression % BuildAlignment %
724 -- OptAlignmentExpression := [ AlignmentExpression ] =:
726 -- AlignmentExpression := "(" ConstExpression ")" =:
728 Alignment := [ ByteAlignment ] =:
730 TypeDeclaration := Ident "=" Type Alignment
735 ( SimpleType | ArrayType
739 | ProcedureType ) % PopAuto %
742 SimpleType := Qualident [ SubrangeType ] | Enumeration | SubrangeType =:
750 IdentList := Ident % VAR
753 % on := IsAutoPushOn() ;
768 SubrangeType := "[" ConstExpression ".." ConstExpression "]" % BuildSubrange ; %
780 RecordType := "RECORD
" [ DefaultRecordAttributes ] FieldListSequence "END
" =:
782 DefaultRecordAttributes := '<*' AttributeExpression '*>' =:
784 RecordFieldPragma := [ '<*' FieldPragmaExpression
785 { ',' FieldPragmaExpression } '*>' ] =:
787 FieldPragmaExpression := % PushAutoOff %
788 Ident [ '(' ConstExpression ')' ] % PopAuto %
791 AttributeExpression := % PushAutoOff %
792 Ident '(' ConstExpression ')' % PopAuto %
795 FieldListSequence := FieldListStatement { ";
" FieldListStatement } =:
797 -- at present FieldListStatement is as follows:
798 FieldListStatement := [ FieldList ] =:
799 -- later replace it with FieldList to comply with PIM2
801 -- sadly the PIM rules are not LL1 as Ident and Qualident have the same first
802 -- symbols. We rewrite FieldList to inline qualident
804 -- FieldList := IdentList ":" % BuildNulName %
806 -- "CASE
" [ Ident ] [ ":" Qualident ] "OF
" Varient { "|
" Varient }
807 -- [ "ELSE
" FieldListSequence ] "END
" =:
809 FieldList := IdentList ":"
810 Type RecordFieldPragma
812 "CASE
" % BeginVarient %
814 Varient { "|
" Varient }
815 [ "ELSE
" % ElseVarient %
817 ] "END
" % EndVarient %
820 TagIdent := [ Ident ] =:
822 CaseTag := TagIdent [":" Qualident ] =:
824 Varient := [ % BeginVarientList %
825 VarientCaseLabelList ":" FieldListSequence % EndVarientList %
828 VarientCaseLabelList := VarientCaseLabels { ",
" VarientCaseLabels } =:
830 VarientCaseLabels := ConstExpression ( ".." ConstExpression % AddVarientRange %
831 | % AddVarientEquality ; (* epsilon *) %
835 SilentCaseLabelList := SilentCaseLabels { ",
" SilentCaseLabels } =:
837 SilentCaseLabels := SilentConstExpression [ ".." SilentConstExpression ] =:
840 -- the following rules are a copy of the ConstExpression ebnf rules but without
841 -- any actions all prefixed with Silent.
844 SilentConstExpression := % PushAutoOff %
845 SilentSimpleConstExpr
846 [ SilentRelation SilentSimpleConstExpr ] % PopAuto %
849 SilentRelation := "=" | "#
" | "<>
" | "<
" | "<
=" | ">
" | ">
=" | "IN
" =:
851 SilentSimpleConstExpr := SilentUnaryOrConstTerm { SilentAddOperator SilentConstTerm } =:
853 SilentUnaryOrConstTerm := "+
" SilentConstTerm | "-
" SilentConstTerm | SilentConstTerm =:
855 SilentAddOperator := "+
" | "-
" | "OR
" =:
857 SilentConstTerm := SilentConstFactor { SilentMulOperator SilentConstFactor } =:
859 SilentMulOperator := "*
" | "/
" | "DIV
" | "MOD
" | "REM
" | "AND
" | "&
" =:
861 SilentConstFactor := Number | SilentConstString | SilentConstSetOrQualidentOrFunction |
862 "(" SilentConstExpression ")" | "NOT
" SilentConstFactor
863 | SilentConstAttribute =:
865 SilentConstString := string =:
867 SilentConstAttribute := "__ATTRIBUTE__
" "__BUILTIN__
" "(" "(" SilentConstAttributeExpression ")" ")" =:
869 SilentConstAttributeExpression := Ident | "<
" Ident ',' SilentConstString ">
" =:
871 SilentConstSetOrQualidentOrFunction := Qualident [ SilentConstructor | SilentActualParameters ] |
874 SilentSetOrDesignatorOrFunction := ( Qualident
875 [ SilentConstructor |
876 SilentSimpleDes [ SilentActualParameters ]
877 ] | SilentConstructor )
880 SilentSimpleDes := { SilentSubDesignator } =:
882 SilentConstructor := "{" % SilentBuildConstructorStart %
883 [ SilentElement { ",
" SilentElement } ] "}" =:
885 SilentElement := SilentConstExpression [ ".." SilentConstExpression ] =:
887 SilentActualParameters := "(" [ SilentExpList ] ")" =:
889 SilentSubDesignator := "." Ident | "[" SilentExpList "]" | "^
"
892 SilentExpList := SilentExpression { ",
" SilentExpression } =:
894 SilentDesignator := Qualident { SilentSubDesignator } =:
897 SilentSimpleExpression
899 SilentSimpleExpression ]
902 SilentSimpleExpression := SilentUnaryOrTerm { SilentAddOperator SilentTerm } =:
904 SilentUnaryOrTerm := "+
"
910 SilentTerm := SilentFactor { SilentMulOperator SilentFactor
913 SilentFactor := Number | string | SilentSetOrDesignatorOrFunction |
914 "(" SilentExpression ")" | "NOT
" SilentFactor | ConstAttribute =:
916 -- end of the Silent constant rules
918 SetType := ( "SET
" | "PACKEDSET
" ) "OF
" SimpleType =:
920 PointerType := "POINTER
" "TO
" Type
923 ProcedureType := "PROCEDURE
"
924 [ FormalTypeList ] =:
926 FormalTypeList := "(" ( ")" FormalReturn |
927 ProcedureParameters ")" FormalReturn ) =:
929 FormalReturn := [ ":" OptReturnType ] =:
931 OptReturnType := "[" Qualident "]" | Qualident =:
933 ProcedureParameters := ProcedureParameter
934 { ",
" ProcedureParameter } =:
936 ProcedureParameter := "..." | "VAR
" FormalType | FormalType =:
938 VarIdent := % VAR Sym, Type: CARDINAL ; %
939 Ident [ "[" ConstExpression % PopTF(Sym, Type) %
943 VarIdentList := VarIdent % VAR
946 % on := IsAutoPushOn() ;
951 { ",
" VarIdent % IF on
961 VariableDeclaration := VarIdentList ":" Type Alignment
964 Designator := Qualident
983 SimpleExpression [ SilentRelation SimpleExpression
987 SimpleExpression := UnaryOrTerm { SilentAddOperator Term
996 Term := Factor { SilentMulOperator Factor
999 Factor := Number | string | SetOrDesignatorOrFunction |
1000 "(" Expression ")" | "NOT
" Factor | ConstAttribute =:
1002 -- again Set | Designator causes problems as both has a first symbol, ident or Qualident
1004 SetOrDesignatorOrFunction := ( Qualident [ Constructor |
1005 SimpleDes [ ActualParameters ]
1010 -- SimpleDes := { "." Ident | "[" ExpList "]" | "^
" } =:
1011 SimpleDes := { SubDesignator } =:
1013 ActualParameters := "("
1014 ( ExpList | % (* epsilon *) %
1017 ConstActualParameters := "(" % BuildSizeCheckStart %
1018 ( ConstExpList | % BuildNulParam %
1021 ConstExpList := % VAR n: CARDINAL ; %
1022 ConstExpression % BuildBooleanVariable %
1025 ConstExpression % BuildBooleanVariable %
1032 [ AssignmentOrProcedureCall | IfStatement | CaseStatement |
1033 WhileStatement | RepeatStatement | LoopStatement |
1034 ForStatement | WithStatement | AsmStatement |
1037 ( Expression | % (* in epsilon *) %
1042 RetryStatement := "RETRY
" =:
1044 AssignmentOrProcedureCall := Designator ( ":=" SilentExpression |
1045 SilentActualParameters | % (* in epsilon *) %
1048 -- these two break LL1 as both start with a Designator
1049 -- ProcedureCall := Designator [ ActualParameters ] =:
1050 -- Assignment := Designator ":=" Expression =:
1052 StatementSequence :=
1060 SilentExpression "THEN
"
1067 StatementSequence ] "END
"
1070 CaseStatement := "CASE
"
1072 "OF
" Case { "|
" Case }
1074 StatementSequence ] "END
"
1077 Case := [ SilentCaseLabelList ":" StatementSequence ] =:
1079 WhileStatement := "WHILE
"
1086 RepeatStatement := "REPEAT
"
1092 ForStatement := "FOR
"
1093 Ident ":=" SilentExpression "TO
" SilentExpression
1094 ( "BY
" SilentConstExpression | % (* epsilon *) %
1096 StatementSequence "END
"
1099 LoopStatement := "LOOP
"
1104 WithStatement := "WITH
"
1105 SilentDesignator "DO
"
1110 ProcedureDeclaration := ProcedureHeading ";
" ( ProcedureBlock % PushAutoOn %
1111 Ident ) % EndBuildProcedure %
1115 DefineBuiltinProcedure := [ "__ATTRIBUTE__
" "__BUILTIN__
" "(" "(" Ident ")" ")" |
1119 ProcedureHeading := "PROCEDURE
" % M2Error.DefaultProcedure %
1120 DefineBuiltinProcedure % PushAutoOn %
1121 ( Ident % StartBuildProcedure %
1123 [ FormalParameters ] AttributeNoReturn
1128 Builtin := [ "__BUILTIN__
" | "__INLINE__
" ] =:
1130 DefProcedureHeading := "PROCEDURE
" % M2Error.DefaultProcedure %
1133 [ DefFormalParameters ] AttributeNoReturn
1134 ) % M2Error.LeaveErrorScope %
1137 AttributeNoReturn := [ "<*
" Ident "*>
" ] =:
1139 AttributeUnused := [ "<*
" Ident "*>
" ] =:
1141 -- introduced procedure block so we can produce more informative
1144 ProcedureBlock := { Declaration } [ "BEGIN
" BlockBody ] "END
"
1147 Block := { Declaration } InitialBlock FinalBlock "END
" =:
1149 InitialBlock := [ "BEGIN
" BlockBody ] =:
1151 FinalBlock := [ "FINALLY
" BlockBody ] =:
1153 BlockBody := NormalPart [ "EXCEPT
" ExceptionalPart ] =:
1155 NormalPart := StatementSequence =:
1157 ExceptionalPart := StatementSequence =:
1159 Declaration := "CONST
" { ConstantDeclaration ";
" } |
1160 "TYPE
" { TypeDeclaration ";
" } |
1161 "VAR
" { VariableDeclaration ";
" } |
1162 ProcedureDeclaration ";
" |
1163 ModuleDeclaration ";
" =:
1165 DefFormalParameters := "(" [ DefMultiFPSection ] ")" FormalReturn =:
1167 DefMultiFPSection := DefExtendedFP |
1168 FPSection [ ";
" DefMultiFPSection ] =:
1170 FormalParameters := "(" [ MultiFPSection ] ")" FormalReturn =:
1172 MultiFPSection := ExtendedFP |
1173 FPSection [ ";
" MultiFPSection ] =:
1175 FPSection := NonVarFPSection | VarFPSection =:
1177 DefExtendedFP := DefOptArg | "..." =:
1179 ExtendedFP := OptArg | "..." =:
1181 VarFPSection := "VAR
" IdentList ":" FormalType [ AttributeUnused ] =:
1183 NonVarFPSection := IdentList ":" FormalType [ AttributeUnused ] =:
1185 OptArg := "[" Ident ":" FormalType [ "=" SilentConstExpression ] "]" =:
1187 DefOptArg := "[" Ident ":" FormalType "=" SilentConstExpression "]" =:
1189 FormalType := { "ARRAY
" "OF
" } Qualident =:
1191 ModuleDeclaration := % VAR begint: CARDINAL ; %
1192 % begint := GetTokenNo () %
1193 "MODULE
" % M2Error.DefaultInnerModule %
1195 Ident % StartBuildInnerModule ;
1196 BuildModuleStart (begint) ;
1203 Block % PushAutoOn %
1204 Ident % EndBuildInnerModule %
1205 % PopAuto ; PopAuto ; PopAuto %
1208 Priority := "[" SilentConstExpression "]" =:
1210 Export := "EXPORT
" ( "QUALIFIED
"
1216 Import := "FROM
" Ident "IMPORT
" IdentList ";
" |
1220 DefinitionModule := % VAR begint, endt: CARDINAL ; %
1221 % begint := GetTokenNo () %
1222 "DEFINITION
" % M2Error.DefaultDefinitionModule %
1223 "MODULE
" % PushAutoOn %
1225 Ident % StartBuildDefFile (begint) ;
1226 P3StartBuildDefModule ;
1232 { Definition } % endt := GetTokenNo () %
1233 "END
" % PushAutoOn %
1234 Ident % EndBuildFile (endt) ;
1235 P3EndBuildDefModule %
1236 "." % PopAuto ; PopAuto ; PopAuto %
1239 Definition := "CONST
" { ConstantDeclaration ";
" } |
1242 | "=" Type Alignment ";
" )
1245 "VAR
" { VariableDeclaration ";
" } |
1246 DefProcedureHeading ";
" =:
1248 AsmStatement := 'ASM' [ 'VOLATILE' ] '(' AsmOperands ')' =:
1250 NamedOperand := '[' Ident ']' =:
1252 AsmOperandName := [ NamedOperand ] =:
1254 AsmOperands := AsmOperandName string [ ':' AsmList [ ':' AsmList [ ':' TrashList ] ] ]
1257 AsmList := [ AsmElement ] { ',' AsmElement } =:
1259 AsmElement := string '(' Expression ')'
1262 TrashList := [ string ] { ',' string } =: