summaryrefslogtreecommitdiff
path: root/src/parse.adb
diff options
context:
space:
mode:
authorTristan Gingold2014-11-04 20:21:00 +0100
committerTristan Gingold2014-11-04 20:21:00 +0100
commit0a088b311ed2fcebc542f8a2e42d09e2e3c9311c (patch)
tree8ec898f38ddff616e459a0df57b3f4112bd96ffc /src/parse.adb
parent9c195bf5d86d67ea5eb419ccf6e48dc153e57c68 (diff)
downloadghdl-0a088b311ed2fcebc542f8a2e42d09e2e3c9311c.tar.gz
ghdl-0a088b311ed2fcebc542f8a2e42d09e2e3c9311c.tar.bz2
ghdl-0a088b311ed2fcebc542f8a2e42d09e2e3c9311c.zip
Create src/vhdl subdirectory.
Diffstat (limited to 'src/parse.adb')
-rw-r--r--src/parse.adb7143
1 files changed, 0 insertions, 7143 deletions
diff --git a/src/parse.adb b/src/parse.adb
deleted file mode 100644
index 97ff876..0000000
--- a/src/parse.adb
+++ /dev/null
@@ -1,7143 +0,0 @@
--- VHDL parser.
--- Copyright (C) 2002, 2003, 2004, 2005 Tristan Gingold
---
--- GHDL is free software; you can redistribute it and/or modify it under
--- the terms of the GNU General Public License as published by the Free
--- Software Foundation; either version 2, or (at your option) any later
--- version.
---
--- GHDL is distributed in the hope that it will be useful, but WITHOUT ANY
--- WARRANTY; without even the implied warranty of MERCHANTABILITY or
--- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
--- for more details.
---
--- You should have received a copy of the GNU General Public License
--- along with GHDL; see the file COPYING. If not, write to the Free
--- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
--- 02111-1307, USA.
-with Iir_Chains; use Iir_Chains;
-with Ada.Text_IO; use Ada.Text_IO;
-with Types; use Types;
-with Tokens; use Tokens;
-with Scanner; use Scanner;
-with Iirs_Utils; use Iirs_Utils;
-with Errorout; use Errorout;
-with Std_Names; use Std_Names;
-with Flags; use Flags;
-with Parse_Psl;
-with Name_Table;
-with Str_Table;
-with Xrefs;
-
--- Recursive descendant parser.
--- Each subprogram (should) parse one production rules.
--- Rules are written in a comment just before the subprogram.
--- terminals are written in upper case.
--- non-terminal are written in lower case.
--- syntaxic category of a non-terminal are written in upper case.
--- eg: next_statement ::= [ label : ] NEXT [ LOOP_label ] [ WHEN condition ] ;
--- Or (|) must be aligned by the previous or, or with the '=' character.
--- Indentation is 4.
---
--- To document what is expected for input and what is left as an output
--- concerning token stream, a precond and a postcond comment shoud be
--- added before the above rules.
--- a token (such as IF or ';') means the current token is this token.
--- 'a token' means the current token was analysed.
--- 'next token' means the current token is to be analysed.
-
-
-package body Parse is
-
- -- current_token must be valid.
- -- Leaves a token.
- function Parse_Simple_Expression (Primary : Iir := Null_Iir)
- return Iir_Expression;
- function Parse_Primary return Iir_Expression;
- function Parse_Use_Clause return Iir_Use_Clause;
-
- function Parse_Association_List return Iir;
- function Parse_Association_List_In_Parenthesis return Iir;
-
- function Parse_Sequential_Statements (Parent : Iir) return Iir;
- function Parse_Configuration_Item return Iir;
- function Parse_Block_Configuration return Iir_Block_Configuration;
- procedure Parse_Concurrent_Statements (Parent : Iir);
- function Parse_Subprogram_Declaration (Parent : Iir) return Iir;
- function Parse_Subtype_Indication (Name : Iir := Null_Iir) return Iir;
- procedure Parse_Component_Specification (Res : Iir);
- function Parse_Binding_Indication return Iir_Binding_Indication;
- function Parse_Aggregate return Iir;
- function Parse_Signature return Iir_Signature;
- procedure Parse_Declarative_Part (Parent : Iir);
- function Parse_Tolerance_Aspect_Opt return Iir;
-
- Expect_Error: exception;
-
- -- Copy the current location into an iir.
- procedure Set_Location (Node : Iir) is
- begin
- Set_Location (Node, Get_Token_Location);
- end Set_Location;
-
- procedure Set_End_Location (Node : Iir) is
- begin
- Set_End_Location (Node, Get_Token_Location);
- end Set_End_Location;
-
- procedure Unexpected (Where: String) is
- begin
- Error_Msg_Parse
- ("unexpected token '" & Image (Current_Token) & "' in a " & Where);
- end Unexpected;
-
--- procedure Unexpected_Eof is
--- begin
--- Error_Msg_Parse ("unexpected end of file");
--- end Unexpected_Eof;
-
- -- Emit an error if the current_token if different from TOKEN.
- -- Otherwise, accept the current_token (ie set it to tok_invalid, unless
- -- TOKEN is Tok_Identifier).
- procedure Expect (Token: Token_Type; Msg: String := "") is
- begin
- if Current_Token /= Token then
- if Msg'Length > 0 then
- Error_Msg_Parse (Msg);
- Error_Msg_Parse ("(found: " & Image (Current_Token) & ")");
- else
- Error_Msg_Parse
- (''' & Image(Token) & "' is expected instead of '"
- & Image (Current_Token) & ''');
- end if;
- raise Expect_Error;
- end if;
-
- -- Accept the current_token.
- if Current_Token /= Tok_Identifier then
- Invalidate_Current_Token;
- end if;
- exception
- when Parse_Error =>
- Put_Line ("found " & Token_Type'Image (Current_Token));
- if Current_Token = Tok_Identifier then
- Put_Line ("identifier: " & Name_Table.Image (Current_Identifier));
- end if;
- raise;
- end Expect;
-
- -- Scan a token and expect it.
- procedure Scan_Expect (Token: Token_Type; Msg: String := "") is
- begin
- Scan;
- Expect (Token, Msg);
- end Scan_Expect;
-
- -- If the current_token is an identifier, it must be equal to name.
- -- In this case, a token is eaten.
- -- If the current_token is not an identifier, this is a noop.
- procedure Check_End_Name (Name : Name_Id; Decl : Iir) is
- begin
- if Current_Token /= Tok_Identifier then
- return;
- end if;
- if Name = Null_Identifier then
- Error_Msg_Parse
- ("end label for an unlabeled declaration or statement");
- else
- if Current_Identifier /= Name then
- Error_Msg_Parse
- ("mispelling, """ & Name_Table.Image (Name) & """ expected");
- else
- Set_End_Has_Identifier (Decl, True);
- Xrefs.Xref_End (Get_Token_Location, Decl);
- end if;
- end if;
- Scan;
- end Check_End_Name;
-
- procedure Check_End_Name (Decl : Iir) is
- begin
- Check_End_Name (Get_Identifier (Decl), Decl);
- end Check_End_Name;
-
-
- -- Expect ' END tok [ name ] ; '
- procedure Check_End_Name (Tok : Token_Type; Decl : Iir) is
- begin
- if Current_Token /= Tok_End then
- Error_Msg_Parse ("""end " & Image (Tok) & ";"" expected");
- else
- Scan;
- if Current_Token /= Tok then
- Error_Msg_Parse
- ("""end"" must be followed by """ & Image (Tok) & """");
- else
- Set_End_Has_Reserved_Id (Decl, True);
- Scan;
- end if;
- Check_End_Name (Decl);
- Expect (Tok_Semi_Colon);
- end if;
- end Check_End_Name;
-
- procedure Eat_Tokens_Until_Semi_Colon is
- begin
- loop
- case Current_Token is
- when Tok_Semi_Colon
- | Tok_Eof =>
- exit;
- when others =>
- Scan;
- end case;
- end loop;
- end Eat_Tokens_Until_Semi_Colon;
-
- -- Expect and scan ';' emit an error message using MSG if not present.
- procedure Scan_Semi_Colon (Msg : String) is
- begin
- if Current_Token /= Tok_Semi_Colon then
- Error_Msg_Parse ("missing "";"" at end of " & Msg);
- else
- Scan;
- end if;
- end Scan_Semi_Colon;
-
- -- precond : next token
- -- postcond: next token.
- --
- -- [§ 4.3.2 ]
- -- mode ::= IN | OUT | INOUT | BUFFER | LINKAGE
- --
- -- If there is no mode, DEFAULT is returned.
- function Parse_Mode (Default: Iir_Mode) return Iir_Mode is
- begin
- case Current_Token is
- when Tok_Identifier =>
- return Default;
- when Tok_In =>
- Scan;
- if Current_Token = Tok_Out then
- -- Nice message for Ada users...
- Error_Msg_Parse ("typo error, in out must be 'inout' in vhdl");
- Scan;
- return Iir_Inout_Mode;
- end if;
- return Iir_In_Mode;
- when Tok_Out =>
- Scan;
- return Iir_Out_Mode;
- when Tok_Inout =>
- Scan;
- return Iir_Inout_Mode;
- when Tok_Linkage =>
- Scan;
- return Iir_Linkage_Mode;
- when Tok_Buffer =>
- Scan;
- return Iir_Buffer_Mode;
- when others =>
- Error_Msg_Parse
- ("mode is 'in', 'out', 'inout', 'buffer' or 'linkage'");
- return Iir_In_Mode;
- end case;
- end Parse_Mode;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §4.3.1.2 ]
- -- signal_kind ::= REGISTER | BUS
- --
- -- If there is no signal_kind, then no_signal_kind is returned.
- function Parse_Signal_Kind return Iir_Signal_Kind is
- begin
- if Current_Token = Tok_Bus then
- Scan;
- return Iir_Bus_Kind;
- elsif Current_Token = Tok_Register then
- Scan;
- return Iir_Register_Kind;
- else
- return Iir_No_Signal_Kind;
- end if;
- end Parse_Signal_Kind;
-
- -- precond : next token
- -- postcond: next token
- --
- -- Parse a range.
- -- If LEFT is not null_iir, then it must be an expression corresponding to
- -- the left limit of the range, and the current_token must be either
- -- tok_to or tok_downto.
- -- If left is null_iir, the current token is used to create the left limit
- -- expression.
- --
- -- [3.1]
- -- range ::= RANGE_attribute_name
- -- | simple_expression direction simple_expression
- function Parse_Range_Expression (Left: Iir; Discrete: Boolean := False)
- return Iir
- is
- Res : Iir;
- Left1: Iir;
- begin
- if Left /= Null_Iir then
- Left1 := Left;
- else
- Left1 := Parse_Simple_Expression;
- end if;
-
- case Current_Token is
- when Tok_To =>
- Res := Create_Iir (Iir_Kind_Range_Expression);
- Set_Direction (Res, Iir_To);
- when Tok_Downto =>
- Res := Create_Iir (Iir_Kind_Range_Expression);
- Set_Direction (Res, Iir_Downto);
- when Tok_Range =>
- if not Discrete then
- Unexpected ("range definition");
- end if;
- Scan;
- if Current_Token = Tok_Box then
- Unexpected ("range expression expected");
- Scan;
- return Null_Iir;
- end if;
- Res := Parse_Range_Expression (Null_Iir, False);
- if Res /= Null_Iir then
- Set_Type (Res, Left1);
- end if;
- return Res;
- when others =>
- if Left1 = Null_Iir then
- return Null_Iir;
- end if;
- if Is_Range_Attribute_Name (Left1) then
- return Left1;
- end if;
- if Discrete
- and then Get_Kind (Left1) in Iir_Kinds_Denoting_Name
- then
- return Left1;
- end if;
- Error_Msg_Parse ("'to' or 'downto' expected");
- return Null_Iir;
- end case;
- Set_Left_Limit (Res, Left1);
- Location_Copy (Res, Left1);
-
- Scan;
- Set_Right_Limit (Res, Parse_Simple_Expression);
- return Res;
- end Parse_Range_Expression;
-
- -- [ 3.1 ]
- -- range_constraint ::= RANGE range
- --
- -- [ 3.1 ]
- -- range ::= range_attribute_name
- -- | simple_expression direction simple_expression
- --
- -- [ 3.1 ]
- -- direction ::= TO | DOWNTO
-
- -- precond: TO or DOWNTO
- -- postcond: next token
- function Parse_Range_Right (Left : Iir) return Iir
- is
- Res : Iir;
- begin
- Res := Create_Iir (Iir_Kind_Range_Expression);
- Set_Location (Res);
- Set_Left_Limit (Res, Left);
-
- case Current_Token is
- when Tok_To =>
- Set_Direction (Res, Iir_To);
- when Tok_Downto =>
- Set_Direction (Res, Iir_Downto);
- when others =>
- raise Internal_Error;
- end case;
-
- Scan;
- Set_Right_Limit (Res, Parse_Simple_Expression);
- return Res;
- end Parse_Range_Right;
-
- -- precond: next token
- -- postcond: next token
- function Parse_Range return Iir
- is
- Left: Iir;
- begin
- Left := Parse_Simple_Expression;
-
- case Current_Token is
- when Tok_To
- | Tok_Downto =>
- return Parse_Range_Right (Left);
- when others =>
- if Left /= Null_Iir then
- if Is_Range_Attribute_Name (Left) then
- return Left;
- end if;
- Error_Msg_Parse ("'to' or 'downto' expected");
- end if;
- return Null_Iir;
- end case;
- end Parse_Range;
-
- -- precond: next token (after RANGE)
- -- postcond: next token
- function Parse_Range_Constraint return Iir is
- begin
- if Current_Token = Tok_Box then
- Error_Msg_Parse ("range constraint required");
- Scan;
- return Null_Iir;
- end if;
-
- return Parse_Range;
- end Parse_Range_Constraint;
-
- -- precond: next token (after RANGE)
- -- postcond: next token
- function Parse_Range_Constraint_Of_Subtype_Indication
- (Type_Mark : Iir;
- Resolution_Indication : Iir := Null_Iir)
- return Iir
- is
- Def : Iir;
- begin
- Def := Create_Iir (Iir_Kind_Subtype_Definition);
- Location_Copy (Def, Type_Mark);
- Set_Subtype_Type_Mark (Def, Type_Mark);
- Set_Range_Constraint (Def, Parse_Range_Constraint);
- Set_Resolution_Indication (Def, Resolution_Indication);
- Set_Tolerance (Def, Parse_Tolerance_Aspect_Opt);
-
- return Def;
- end Parse_Range_Constraint_Of_Subtype_Indication;
-
- -- precond: next token
- -- postcond: next token
- --
- -- [ 3.2.1 ]
- -- discrete_range ::= discrete_subtype_indication | range
- function Parse_Discrete_Range return Iir
- is
- Left: Iir;
- begin
- Left := Parse_Simple_Expression;
-
- case Current_Token is
- when Tok_To
- | Tok_Downto =>
- return Parse_Range_Right (Left);
- when Tok_Range =>
- return Parse_Subtype_Indication (Left);
- when others =>
- -- Either a /range/_attribute_name or a type_mark.
- return Left;
- end case;
- end Parse_Discrete_Range;
-
- -- Convert the STR (0 .. LEN - 1) into a operator symbol identifier.
- -- Emit an error message if the name is not an operator name.
- function Str_To_Operator_Name (Str : String_Fat_Acc;
- Len : Nat32;
- Loc : Location_Type) return Name_Id
- is
- -- LRM93 2.1
- -- Extra spaces are not allowed in an operator symbol, and the
- -- case of letters is not signifiant.
-
- -- LRM93 2.1
- -- The sequence of characters represented by an operator symbol
- -- must be an operator belonging to one of classes of operators
- -- defined in section 7.2.
-
- procedure Bad_Operator_Symbol is
- begin
- Error_Msg_Parse ("""" & String (Str (1 .. Len))
- & """ is not an operator symbol", Loc);
- end Bad_Operator_Symbol;
-
- procedure Check_Vhdl93 is
- begin
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("""" & String (Str (1 .. Len))
- & """ is not a vhdl87 operator symbol", Loc);
- end if;
- end Check_Vhdl93;
-
- Id : Name_Id;
- C1, C2, C3, C4 : Character;
- begin
- C1 := Str (1);
- case Len is
- when 1 =>
- -- =, <, >, +, -, *, /, &
- case C1 is
- when '=' =>
- Id := Name_Op_Equality;
- when '>' =>
- Id := Name_Op_Greater;
- when '<' =>
- Id := Name_Op_Less;
- when '+' =>
- Id := Name_Op_Plus;
- when '-' =>
- Id := Name_Op_Minus;
- when '*' =>
- Id := Name_Op_Mul;
- when '/' =>
- Id := Name_Op_Div;
- when '&' =>
- Id := Name_Op_Concatenation;
- when others =>
- Bad_Operator_Symbol;
- Id := Name_Op_Plus;
- end case;
- when 2 =>
- -- or, /=, <=, >=, **
- C2 := Str (2);
- case C1 is
- when 'o' | 'O' =>
- Id := Name_Or;
- if C2 /= 'r' and C2 /= 'R' then
- Bad_Operator_Symbol;
- end if;
- when '/' =>
- Id := Name_Op_Inequality;
- if C2 /= '=' then
- Bad_Operator_Symbol;
- end if;
- when '<' =>
- Id := Name_Op_Less_Equal;
- if C2 /= '=' then
- Bad_Operator_Symbol;
- end if;
- when '>' =>
- Id := Name_Op_Greater_Equal;
- if C2 /= '=' then
- Bad_Operator_Symbol;
- end if;
- when '*' =>
- Id := Name_Op_Exp;
- if C2 /= '*' then
- Bad_Operator_Symbol;
- end if;
- when '?' =>
- if Vhdl_Std < Vhdl_08 then
- Bad_Operator_Symbol;
- Id := Name_Op_Condition;
- elsif C2 = '?' then
- Id := Name_Op_Condition;
- elsif C2 = '=' then
- Id := Name_Op_Match_Equality;
- elsif C2 = '<' then
- Id := Name_Op_Match_Less;
- elsif C2 = '>' then
- Id := Name_Op_Match_Greater;
- else
- Bad_Operator_Symbol;
- Id := Name_Op_Condition;
- end if;
- when others =>
- Bad_Operator_Symbol;
- Id := Name_Op_Equality;
- end case;
- when 3 =>
- -- mod, rem, and, xor, nor, abs, not, sll, sla, sra, srl, rol
- -- ror
- C2 := Str (2);
- C3 := Str (3);
- case C1 is
- when 'm' | 'M' =>
- Id := Name_Mod;
- if (C2 /= 'o' and C2 /= 'O') or (C3 /= 'd' and C3 /= 'D')
- then
- Bad_Operator_Symbol;
- end if;
- when 'a' | 'A' =>
- if (C2 = 'n' or C2 = 'N') and (C3 = 'd' or C3 = 'D') then
- Id := Name_And;
- elsif (C2 = 'b' or C2 = 'B') and (C3 = 's' or C3 = 'S') then
- Id := Name_Abs;
- else
- Id := Name_And;
- Bad_Operator_Symbol;
- end if;
- when 'x' | 'X' =>
- Id := Name_Xor;
- if (C2 /= 'o' and C2 /= 'O') or (C3 /= 'r' and C3 /= 'R')
- then
- Bad_Operator_Symbol;
- end if;
- when 'n' | 'N' =>
- if C2 = 'o' or C2 = 'O' then
- if C3 = 'r' or C3 = 'R' then
- Id := Name_Nor;
- elsif C3 = 't' or C3 = 'T' then
- Id := Name_Not;
- else
- Id := Name_Not;
- Bad_Operator_Symbol;
- end if;
- else
- Id := Name_Not;
- Bad_Operator_Symbol;
- end if;
- when 's' | 'S' =>
- if C2 = 'l' or C2 = 'L' then
- if C3 = 'l' or C3 = 'L' then
- Check_Vhdl93;
- Id := Name_Sll;
- elsif C3 = 'a' or C3 = 'A' then
- Check_Vhdl93;
- Id := Name_Sla;
- else
- Id := Name_Sll;
- Bad_Operator_Symbol;
- end if;
- elsif C2 = 'r' or C2 = 'R' then
- if C3 = 'l' or C3 = 'L' then
- Check_Vhdl93;
- Id := Name_Srl;
- elsif C3 = 'a' or C3 = 'A' then
- Check_Vhdl93;
- Id := Name_Sra;
- else
- Id := Name_Srl;
- Bad_Operator_Symbol;
- end if;
- else
- Id := Name_Sll;
- Bad_Operator_Symbol;
- end if;
- when 'r' | 'R' =>
- if C2 = 'e' or C2 = 'E' then
- if C3 = 'm' or C3 = 'M' then
- Id := Name_Rem;
- else
- Id := Name_Rem;
- Bad_Operator_Symbol;
- end if;
- elsif C2 = 'o' or C2 = 'O' then
- if C3 = 'l' or C3 = 'L' then
- Check_Vhdl93;
- Id := Name_Rol;
- elsif C3 = 'r' or C3 = 'R' then
- Check_Vhdl93;
- Id := Name_Ror;
- else
- Id := Name_Rol;
- Bad_Operator_Symbol;
- end if;
- else
- Id := Name_Rem;
- Bad_Operator_Symbol;
- end if;
- when '?' =>
- if Vhdl_Std < Vhdl_08 then
- Bad_Operator_Symbol;
- Id := Name_Op_Match_Less_Equal;
- else
- if C2 = '<' and C3 = '=' then
- Id := Name_Op_Match_Less_Equal;
- elsif C2 = '>' and C3 = '=' then
- Id := Name_Op_Match_Greater_Equal;
- elsif C2 = '/' and C3 = '=' then
- Id := Name_Op_Match_Inequality;
- else
- Bad_Operator_Symbol;
- Id := Name_Op_Match_Less_Equal;
- end if;
- end if;
- when others =>
- Id := Name_And;
- Bad_Operator_Symbol;
- end case;
- when 4 =>
- -- nand, xnor
- C2 := Str (2);
- C3 := Str (3);
- C4 := Str (4);
- if (C1 = 'n' or C1 = 'N')
- and (C2 = 'a' or C2 = 'A')
- and (C3 = 'n' or C3 = 'N')
- and (C4 = 'd' or C4 = 'D')
- then
- Id := Name_Nand;
- elsif (C1 = 'x' or C1 = 'X')
- and (C2 = 'n' or C2 = 'N')
- and (C3 = 'o' or C3 = 'O')
- and (C4 = 'r' or C4 = 'R')
- then
- Check_Vhdl93;
- Id := Name_Xnor;
- else
- Id := Name_Nand;
- Bad_Operator_Symbol;
- end if;
- when others =>
- Id := Name_Op_Plus;
- Bad_Operator_Symbol;
- end case;
- return Id;
- end Str_To_Operator_Name;
-
- function Scan_To_Operator_Name (Loc : Location_Type) return Name_Id is
- begin
- return Str_To_Operator_Name
- (Str_Table.Get_String_Fat_Acc (Current_String_Id),
- Current_String_Length,
- Loc);
- end Scan_To_Operator_Name;
- pragma Inline (Scan_To_Operator_Name);
-
- -- Convert string literal STR to an operator symbol.
- -- Emit an error message if the string is not an operator name.
- function String_To_Operator_Symbol (Str : Iir_String_Literal)
- return Iir
- is
- Id : Name_Id;
- Res : Iir;
- begin
- Id := Str_To_Operator_Name
- (Str_Table.Get_String_Fat_Acc (Get_String_Id (Str)),
- Get_String_Length (Str),
- Get_Location (Str));
- Res := Create_Iir (Iir_Kind_Operator_Symbol);
- Location_Copy (Res, Str);
- Set_Identifier (Res, Id);
- Free_Iir (Str);
- return Res;
- end String_To_Operator_Symbol;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §6.1 ]
- -- name ::= simple_name
- -- | operator_symbol
- -- | selected_name
- -- | indexed_name
- -- | slice_name
- -- | attribute_name
- --
- -- [ §6.2 ]
- -- simple_name ::= identifier
- --
- -- [ §6.5 ]
- -- slice_name ::= prefix ( discrete_range )
- --
- -- [ §6.3 ]
- -- selected_name ::= prefix . suffix
- --
- -- [ §6.1 ]
- -- prefix ::= name
- -- | function_call
- --
- -- [ §6.3 ]
- -- suffix ::= simple_name
- -- | character_literal
- -- | operator_symbol
- -- | ALL
- --
- -- [ §3.2.1 ]
- -- discrete_range ::= DISCRETE_subtype_indication | range
- --
- -- [ §3.1 ]
- -- range ::= RANGE_attribute_name
- -- | simple_expression direction simple_expression
- --
- -- [ §3.1 ]
- -- direction ::= TO | DOWNTO
- --
- -- [ §6.6 ]
- -- attribute_name ::=
- -- prefix [ signature ] ' attribute_designator [ ( expression ) ]
- --
- -- [ §6.6 ]
- -- attribute_designator ::= ATTRIBUTE_simple_name
- --
- -- Note: in order to simplify the parsing, this function may return a
- -- signature without attribute designator. Signatures may appear at 3
- -- places:
- -- - in attribute name
- -- - in alias declaration
- -- - in entity designator
- function Parse_Name_Suffix (Pfx : Iir; Allow_Indexes: Boolean := True)
- return Iir
- is
- Res: Iir;
- Prefix: Iir;
- begin
- Res := Pfx;
- loop
- Prefix := Res;
-
- case Current_Token is
- when Tok_Left_Bracket =>
- if Get_Kind (Prefix) = Iir_Kind_String_Literal then
- Prefix := String_To_Operator_Symbol (Prefix);
- end if;
-
- -- There is a signature. They are normally followed by an
- -- attribute.
- Res := Parse_Signature;
- Set_Signature_Prefix (Res, Prefix);
-
- when Tok_Tick =>
- -- There is an attribute.
- if Get_Kind (Prefix) = Iir_Kind_String_Literal then
- Prefix := String_To_Operator_Symbol (Prefix);
- end if;
-
- Scan;
- if Current_Token = Tok_Left_Paren then
- -- A qualified expression.
- Res := Create_Iir (Iir_Kind_Qualified_Expression);
- Set_Type_Mark (Res, Prefix);
- Location_Copy (Res, Prefix);
- Set_Expression (Res, Parse_Aggregate);
- return Res;
- elsif Current_Token /= Tok_Range
- and then Current_Token /= Tok_Identifier
- then
- Expect (Tok_Identifier, "required for an attribute name");
- return Null_Iir;
- end if;
- Res := Create_Iir (Iir_Kind_Attribute_Name);
- Set_Identifier (Res, Current_Identifier);
- Set_Location (Res);
- if Get_Kind (Prefix) = Iir_Kind_Signature then
- Set_Attribute_Signature (Res, Prefix);
- Set_Prefix (Res, Get_Signature_Prefix (Prefix));
- else
- Set_Prefix (Res, Prefix);
- end if;
-
- -- accept the identifier.
- Scan;
-
- when Tok_Left_Paren =>
- if not Allow_Indexes then
- return Res;
- end if;
-
- if Get_Kind (Prefix) = Iir_Kind_String_Literal then
- Prefix := String_To_Operator_Symbol (Prefix);
- end if;
-
- Res := Create_Iir (Iir_Kind_Parenthesis_Name);
- Set_Location (Res);
- Set_Prefix (Res, Prefix);
- Set_Association_Chain
- (Res, Parse_Association_List_In_Parenthesis);
-
- when Tok_Dot =>
- if Get_Kind (Prefix) = Iir_Kind_String_Literal then
- Prefix := String_To_Operator_Symbol (Prefix);
- end if;
-
- Scan;
- case Current_Token is
- when Tok_All =>
- Res := Create_Iir (Iir_Kind_Selected_By_All_Name);
- Set_Location (Res);
- Set_Prefix (Res, Prefix);
- when Tok_Identifier
- | Tok_Character =>
- Res := Create_Iir (Iir_Kind_Selected_Name);
- Set_Location (Res);
- Set_Prefix (Res, Prefix);
- Set_Identifier (Res, Current_Identifier);
- when Tok_String =>
- Res := Create_Iir (Iir_Kind_Selected_Name);
- Set_Location (Res);
- Set_Prefix (Res, Prefix);
- Set_Identifier
- (Res, Scan_To_Operator_Name (Get_Token_Location));
- when others =>
- Error_Msg_Parse ("an identifier or all is expected");
- end case;
- Scan;
- when others =>
- return Res;
- end case;
- end loop;
- end Parse_Name_Suffix;
-
- function Parse_Name (Allow_Indexes: Boolean := True) return Iir
- is
- Res: Iir;
- begin
- case Current_Token is
- when Tok_Identifier =>
- Res := Create_Iir (Iir_Kind_Simple_Name);
- Set_Identifier (Res, Current_Identifier);
- Set_Location (Res);
- when Tok_String =>
- Res := Create_Iir (Iir_Kind_String_Literal);
- Set_String_Id (Res, Current_String_Id);
- Set_String_Length (Res, Current_String_Length);
- Set_Location (Res);
- when others =>
- Error_Msg_Parse ("identifier expected here");
- raise Parse_Error;
- end case;
-
- Scan;
-
- return Parse_Name_Suffix (Res, Allow_Indexes);
- end Parse_Name;
-
- -- Emit an error message if MARK doesn't have the form of a type mark.
- procedure Check_Type_Mark (Mark : Iir) is
- begin
- case Get_Kind (Mark) is
- when Iir_Kind_Simple_Name
- | Iir_Kind_Selected_Name =>
- null;
- when others =>
- Error_Msg_Parse ("type mark must be a name of a type", Mark);
- end case;
- end Check_Type_Mark;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ 4.2 ]
- -- type_mark ::= type_name
- -- | subtype_name
- function Parse_Type_Mark (Check_Paren : Boolean := False) return Iir
- is
- Res : Iir;
- Old : Iir;
- pragma Unreferenced (Old);
- begin
- Res := Parse_Name (Allow_Indexes => False);
- Check_Type_Mark (Res);
- if Check_Paren and then Current_Token = Tok_Left_Paren then
- Error_Msg_Parse ("index constraint not allowed here");
- Old := Parse_Name_Suffix (Res, True);
- end if;
- return Res;
- end Parse_Type_Mark;
-
- -- precond : CONSTANT, SIGNAL, VARIABLE. FILE or identifier
- -- postcond: next token (';' or ')')
- --
- -- [ LRM93 4.3.2 ] [ LRM08 6.5.2 ]
- -- interface_declaration ::= interface_constant_declaration
- -- | interface_signal_declaration
- -- | interface_variable_declaration
- -- | interface_file_declaration
- --
- --
- -- [ LRM93 3.2.2 ]
- -- identifier_list ::= identifier { , identifier }
- --
- -- [ LRM93 4.3.2 ]
- -- interface_constant_declaration ::=
- -- [ CONSTANT ] identifier_list : [ IN ] subtype_indication
- -- [ := STATIC_expression ]
- --
- -- [ LRM93 4.3.2 ]
- -- interface_file_declaration ::= FILE identifier_list : subtype_indication
- --
- -- [ LRM93 4.3.2 ]
- -- interface_signal_declaration ::=
- -- [ SIGNAL ] identifier_list : [ mode ] subtype_indication [ BUS ]
- -- [ := STATIC_expression ]
- --
- -- [ LRM93 4.3.2 ]
- -- interface_variable_declaration ::=
- -- [ VARIABLE ] identifier_list : [ mode ] subtype_indication
- -- [ := STATIC_expression ]
- --
- -- The default kind of interface declaration is DEFAULT.
- function Parse_Interface_Object_Declaration (Ctxt : Interface_Kind_Type)
- return Iir
- is
- Kind : Iir_Kind;
- Res, Last : Iir;
- First, Prev_First : Iir;
- Inter: Iir;
- Is_Default : Boolean;
- Interface_Mode: Iir_Mode;
- Interface_Type: Iir;
- Signal_Kind: Iir_Signal_Kind;
- Default_Value: Iir;
- Lexical_Layout : Iir_Lexical_Layout_Type;
- begin
- Res := Null_Iir;
- Last := Null_Iir;
-
- -- LRM08 6.5.2 Interface object declarations
- -- Interface obejcts include interface constants that appear as
- -- generics of a design entity, a component, a block, a package or
- -- a subprogram, or as constant parameter of subprograms; interface
- -- signals that appear as ports of a design entity, component or
- -- block, or as signal parameters of subprograms; interface variables
- -- that appear as variable parameter subprograms; interface files
- -- that appear as file parameters of subrograms.
- case Current_Token is
- when Tok_Identifier =>
- -- The class of the object is unknown. Select default
- -- according to the above rule, assuming the mode is IN. If
- -- the mode is not IN, Parse_Interface_Object_Declaration will
- -- change the class.
- case Ctxt is
- when Generic_Interface_List
- | Parameter_Interface_List =>
- Kind := Iir_Kind_Interface_Constant_Declaration;
- when Port_Interface_List =>
- Kind := Iir_Kind_Interface_Signal_Declaration;
- end case;
- when Tok_Constant =>
- Kind := Iir_Kind_Interface_Constant_Declaration;
- when Tok_Signal =>
- if Ctxt = Generic_Interface_List then
- Error_Msg_Parse
- ("signal interface not allowed in generic clause");
- end if;
- Kind := Iir_Kind_Interface_Signal_Declaration;
- when Tok_Variable =>
- if Ctxt not in Parameter_Interface_List then
- Error_Msg_Parse
- ("variable interface not allowed in generic or port clause");
- end if;
- Kind := Iir_Kind_Interface_Variable_Declaration;
- when Tok_File =>
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("file interface not allowed in vhdl 87");
- end if;
- if Ctxt not in Parameter_Interface_List then
- Error_Msg_Parse
- ("variable interface not allowed in generic or port clause");
- end if;
- Kind := Iir_Kind_Interface_File_Declaration;
- when others =>
- -- Fall back in case of parse error.
- Kind := Iir_Kind_Interface_Variable_Declaration;
- end case;
-
- Inter := Create_Iir (Kind);
-
- if Current_Token = Tok_Identifier then
- Is_Default := True;
- Lexical_Layout := 0;
- else
- Is_Default := False;
- Lexical_Layout := Iir_Lexical_Has_Class;
-
- -- Skip 'signal', 'variable', 'constant' or 'file'.
- Scan;
- end if;
-
- Prev_First := Last;
- First := Inter;
- loop
- if Current_Token /= Tok_Identifier then
- Expect (Tok_Identifier);
- end if;
- Set_Identifier (Inter, Current_Identifier);
- Set_Location (Inter);
-
- if Res = Null_Iir then
- Res := Inter;
- else
- Set_Chain (Last, Inter);
- end if;
- Last := Inter;
-
- -- Skip identifier
- Scan;
-
- exit when Current_Token = Tok_Colon;
- Expect (Tok_Comma, "',' or ':' expected after identifier");
-
- -- Skip ','
- Scan;
-
- Inter := Create_Iir (Kind);
- end loop;
-
- Expect (Tok_Colon, "':' must follow the interface element identifier");
-
- -- Skip ':'
- Scan;
-
- -- LRM93 2.1.1 LRM08 4.2.2.1
- -- If the mode is INOUT or OUT, and no object class is explicitly
- -- specified, variable is assumed.
- if Is_Default
- and then Ctxt in Parameter_Interface_List
- and then (Current_Token = Tok_Inout or else Current_Token = Tok_Out)
- then
- -- Convert into variable.
- declare
- O_Interface : Iir_Interface_Constant_Declaration;
- N_Interface : Iir_Interface_Variable_Declaration;
- begin
- O_Interface := First;
- while O_Interface /= Null_Iir loop
- N_Interface :=
- Create_Iir (Iir_Kind_Interface_Variable_Declaration);
- Location_Copy (N_Interface, O_Interface);
- Set_Identifier (N_Interface,
- Get_Identifier (O_Interface));
- if Prev_First = Null_Iir then
- Res := N_Interface;
- else
- Set_Chain (Prev_First, N_Interface);
- end if;
- Prev_First := N_Interface;
- if O_Interface = First then
- First := N_Interface;
- end if;
- Last := N_Interface;
- Inter := Get_Chain (O_Interface);
- Free_Iir (O_Interface);
- O_Interface := Inter;
- end loop;
- Inter := First;
- end;
- end if;
-
- -- Update lexical layout if mode is present.
- case Current_Token is
- when Tok_In
- | Tok_Out
- | Tok_Inout
- | Tok_Linkage
- | Tok_Buffer =>
- Lexical_Layout := Lexical_Layout or Iir_Lexical_Has_Mode;
- when others =>
- null;
- end case;
-
- -- Parse mode (and handle default mode).
- case Get_Kind (Inter) is
- when Iir_Kind_Interface_File_Declaration =>
- if Parse_Mode (Iir_Unknown_Mode) /= Iir_Unknown_Mode then
- Error_Msg_Parse
- ("mode can't be specified for a file interface");
- end if;
- Interface_Mode := Iir_Inout_Mode;
- when Iir_Kind_Interface_Signal_Declaration
- | Iir_Kind_Interface_Variable_Declaration =>
- -- LRM93 4.3.2
- -- If no mode is explicitly given in an interface declaration
- -- other than an interface file declaration, mode IN is
- -- assumed.
- Interface_Mode := Parse_Mode (Iir_In_Mode);
- when Iir_Kind_Interface_Constant_Declaration =>
- Interface_Mode := Parse_Mode (Iir_In_Mode);
- if Interface_Mode /= Iir_In_Mode then
- Error_Msg_Parse ("mode must be 'in' for a constant");
- end if;
- when others =>
- raise Internal_Error;
- end case;
-
- Interface_Type := Parse_Subtype_Indication;
-
- -- Signal kind (but only for signal).
- if Get_Kind (Inter) = Iir_Kind_Interface_Signal_Declaration then
- Signal_Kind := Parse_Signal_Kind;
- else
- Signal_Kind := Iir_No_Signal_Kind;
- end if;
-
- if Current_Token = Tok_Assign then
- if Get_Kind (Inter) = Iir_Kind_Interface_File_Declaration then
- Error_Msg_Parse
- ("default expression not allowed for an interface file");
- end if;
-
- -- Skip ':='
- Scan;
-
- Default_Value := Parse_Expression;
- else
- Default_Value := Null_Iir;
- end if;
-
- -- Subtype_Indication and Default_Value are set only on the first
- -- interface.
- Set_Subtype_Indication (First, Interface_Type);
- if Get_Kind (First) /= Iir_Kind_Interface_File_Declaration then
- Set_Default_Value (First, Default_Value);
- end if;
-
- Inter := First;
- while Inter /= Null_Iir loop
- Set_Mode (Inter, Interface_Mode);
- Set_Is_Ref (Inter, Inter /= First);
- if Inter = Last then
- Set_Lexical_Layout (Inter,
- Lexical_Layout or Iir_Lexical_Has_Type);
- else
- Set_Lexical_Layout (Inter, Lexical_Layout);
- end if;
- if Get_Kind (Inter) = Iir_Kind_Interface_Signal_Declaration then
- Set_Signal_Kind (Inter, Signal_Kind);
- end if;
- Inter := Get_Chain (Inter);
- end loop;
-
- return Res;
- end Parse_Interface_Object_Declaration;
-
- -- Precond : 'package'
- -- Postcond: next token
- --
- -- LRM08 6.5.5 Interface package declarations
- -- interface_package_declaration ::=
- -- PACKAGE identifier IS NEW uninstantiated_package name
- -- interface_package_generic_map_aspect
- --
- -- interface_package_generic_map_aspect ::=
- -- generic_map_aspect
- -- | GENERIC MAP ( <> )
- -- | GENERIC MAP ( DEFAULT )
- function Parse_Interface_Package_Declaration return Iir
- is
- Inter : Iir;
- Map : Iir;
- begin
- Inter := Create_Iir (Iir_Kind_Interface_Package_Declaration);
-
- -- Skip 'package'
- Scan_Expect (Tok_Identifier,
- "an identifier is expected after ""package""");
- Set_Identifier (Inter, Current_Identifier);
- Set_Location (Inter);
-
- -- Skip identifier
- Scan_Expect (Tok_Is);
-
- -- Skip 'is'
- Scan_Expect (Tok_New);
-
- -- Skip 'new'
- Scan;
-
- Set_Uninstantiated_Package_Name (Inter, Parse_Name (False));
-
- Expect (Tok_Generic);
-
- -- Skip 'generic'
- Scan_Expect (Tok_Map);
-
- -- Skip 'map'
- Scan_Expect (Tok_Left_Paren);
-
- -- Skip '('
- Scan;
-
- case Current_Token is
- when Tok_Box =>
- Map := Null_Iir;
- -- Skip '<>'
- Scan;
- when others =>
- Map := Parse_Association_List;
- end case;
- Set_Generic_Map_Aspect_Chain (Inter, Map);
-
- Expect (Tok_Right_Paren);
-
- -- Skip ')'
- Scan;
-
- return Inter;
- end Parse_Interface_Package_Declaration;
-
- -- Precond : '('
- -- Postcond: next token
- --
- -- LRM08 6.5.6 Interface lists
- -- interface_list ::= interface_element { ';' interface_element }
- --
- -- interface_element ::= interface_declaration
- function Parse_Interface_List (Ctxt : Interface_Kind_Type; Parent : Iir)
- return Iir
- is
- Res, Last : Iir;
- Inters : Iir;
- Next : Iir;
- Prev_Loc : Location_Type;
- begin
- Expect (Tok_Left_Paren);
-
- Res := Null_Iir;
- Last := Null_Iir;
- loop
- Prev_Loc := Get_Token_Location;
-
- -- Skip '(' or ';'
- Scan;
-
- case Current_Token is
- when Tok_Identifier
- | Tok_Signal
- | Tok_Variable
- | Tok_Constant
- | Tok_File =>
- -- An inteface object.
- Inters := Parse_Interface_Object_Declaration (Ctxt);
- when Tok_Package =>
- if Ctxt /= Generic_Interface_List then
- Error_Msg_Parse
- ("package interface only allowed in generic interface");
- elsif Flags.Vhdl_Std < Vhdl_08 then
- Error_Msg_Parse
- ("package interface not allowed before vhdl 08");
- end if;
- Inters := Parse_Interface_Package_Declaration;
- when Tok_Right_Paren =>
- if Res = Null_Iir then
- Error_Msg_Parse
- ("empty interface list not allowed", Prev_Loc);
- else
- Error_Msg_Parse
- ("extra ';' at end of interface list", Prev_Loc);
- end if;
- exit;
- when others =>
- Error_Msg_Parse
- ("'signal', 'constant', 'variable', 'file' "
- & "or identifier expected");
- -- Use a variable interface as a fall-back.
- Inters := Parse_Interface_Object_Declaration (Ctxt);
- end case;
-
- -- Chain
- if Last = Null_Iir then
- Res := Inters;
- else
- Set_Chain (Last, Inters);
- end if;
-
- -- Set parent and set Last to the last interface.
- Last := Inters;
- loop
- Set_Parent (Last, Parent);
- Next := Get_Chain (Last);
- exit when Next = Null_Iir;
- Last := Next;
- end loop;
-
- exit when Current_Token /= Tok_Semi_Colon;
- end loop;
-
- if Current_Token /= Tok_Right_Paren then
- Error_Msg_Parse ("')' expected at end of interface list");
- end if;
-
- -- Skip ')'
- Scan;
-
- return Res;
- end Parse_Interface_List;
-
- -- precond : PORT
- -- postcond: next token
- --
- -- [ §1.1.1 ]
- -- port_clause ::= PORT ( port_list ) ;
- --
- -- [ §1.1.1.2 ]
- -- port_list ::= PORT_interface_list
- procedure Parse_Port_Clause (Parent : Iir)
- is
- Res: Iir;
- El : Iir;
- begin
- -- Skip 'port'
- pragma Assert (Current_Token = Tok_Port);
- Scan;
-
- Res := Parse_Interface_List (Port_Interface_List, Parent);
-
- -- Check the interface are signal interfaces.
- El := Res;
- while El /= Null_Iir loop
- if Get_Kind (El) /= Iir_Kind_Interface_Signal_Declaration then
- Error_Msg_Parse ("port must be a signal", El);
- end if;
- El := Get_Chain (El);
- end loop;
-
- Scan_Semi_Colon ("port clause");
- Set_Port_Chain (Parent, Res);
- end Parse_Port_Clause;
-
- -- precond : GENERIC
- -- postcond: next token
- --
- -- [ LRM93 1.1.1, LRM08 6.5.6.2 ]
- -- generic_clause ::= GENERIC ( generic_list ) ;
- --
- -- [ LRM93 1.1.1.1, LRM08 6.5.6.2]
- -- generic_list ::= GENERIC_interface_list
- procedure Parse_Generic_Clause (Parent : Iir)
- is
- Res: Iir;
- begin
- -- Skip 'generic'
- pragma Assert (Current_Token = Tok_Generic);
- Scan;
-
- Res := Parse_Interface_List (Generic_Interface_List, Parent);
- Set_Generic_Chain (Parent, Res);
-
- Scan_Semi_Colon ("generic clause");
- end Parse_Generic_Clause;
-
- -- precond : a token.
- -- postcond: next token
- --
- -- [ §1.1.1 ]
- -- entity_header ::=
- -- [ FORMAL_generic_clause ]
- -- [ FORMAL_port_clause ]
- --
- -- [ §4.5 ]
- -- [ LOCAL_generic_clause ]
- -- [ LOCAL_port_clause ]
- procedure Parse_Generic_Port_Clauses (Parent : Iir)
- is
- Has_Port, Has_Generic : Boolean;
- begin
- Has_Port := False;
- Has_Generic := False;
- loop
- if Current_Token = Tok_Generic then
- if Has_Generic then
- Error_Msg_Parse ("at most one generic clause is allowed");
- end if;
- if Has_Port then
- Error_Msg_Parse ("generic clause must precede port clause");
- end if;
- Has_Generic := True;
- Parse_Generic_Clause (Parent);
- elsif Current_Token = Tok_Port then
- if Has_Port then
- Error_Msg_Parse ("at most one port clause is allowed");
- end if;
- Has_Port := True;
- Parse_Port_Clause (Parent);
- else
- exit;
- end if;
- end loop;
- end Parse_Generic_Port_Clauses;
-
- -- precond : a token
- -- postcond: next token
- --
- -- [ §3.1.1 ]
- -- enumeration_type_definition ::=
- -- ( enumeration_literal { , enumeration_literal } )
- --
- -- [ §3.1.1 ]
- -- enumeration_literal ::= identifier | character_literal
- function Parse_Enumeration_Type_Definition
- return Iir_Enumeration_Type_Definition
- is
- Pos: Iir_Int32;
- Enum_Lit: Iir_Enumeration_Literal;
- Enum_Type: Iir_Enumeration_Type_Definition;
- Enum_List : Iir_List;
- begin
- -- This is an enumeration.
- Enum_Type := Create_Iir (Iir_Kind_Enumeration_Type_Definition);
- Set_Location (Enum_Type);
- Enum_List := Create_Iir_List;
- Set_Enumeration_Literal_List (Enum_Type, Enum_List);
-
- -- LRM93 3.1.1
- -- The position number of the first listed enumeration literal is zero.
- Pos := 0;
- -- scan every literal.
- Scan;
- if Current_Token = Tok_Right_Paren then
- Error_Msg_Parse ("at least one literal must be declared");
- Scan;
- return Enum_Type;
- end if;
- loop
- if Current_Token /= Tok_Identifier
- and then Current_Token /= Tok_Character
- then
- if Current_Token = Tok_Eof then
- Error_Msg_Parse ("unexpected end of file");
- return Enum_Type;
- end if;
- Error_Msg_Parse ("identifier or character expected");
- end if;
- Enum_Lit := Create_Iir (Iir_Kind_Enumeration_Literal);
- Set_Identifier (Enum_Lit, Current_Identifier);
- Set_Location (Enum_Lit);
- Set_Enum_Pos (Enum_Lit, Pos);
-
- -- LRM93 3.1.1
- -- the position number for each additional enumeration literal is
- -- one more than that if its predecessor in the list.
- Pos := Pos + 1;
-
- Append_Element (Enum_List, Enum_Lit);
-
- -- next token.
- Scan;
- exit when Current_Token = Tok_Right_Paren;
- if Current_Token /= Tok_Comma then
- Error_Msg_Parse ("')' or ',' is expected after an enum literal");
- end if;
-
- -- scan a literal.
- Scan;
- if Current_Token = Tok_Right_Paren then
- Error_Msg_Parse ("extra ',' ignored");
- exit;
- end if;
- end loop;
- Scan;
- return Enum_Type;
- end Parse_Enumeration_Type_Definition;
-
- -- precond : ARRAY
- -- postcond: ??
- --
- -- [ LRM93 3.2.1 ]
- -- array_type_definition ::= unconstrained_array_definition
- -- | constrained_array_definition
- --
- -- unconstrained_array_definition ::=
- -- ARRAY ( index_subtype_definition { , index_subtype_definition } )
- -- OF element_subtype_indication
- --
- -- constrained_array_definition ::=
- -- ARRAY index_constraint OF element_subtype_indication
- --
- -- index_subtype_definition ::= type_mark RANGE <>
- --
- -- index_constraint ::= ( discrete_range { , discrete_range } )
- --
- -- discrete_range ::= discrete_subtype_indication | range
- --
- -- [ LRM08 5.3.2.1 ]
- -- array_type_definition ::= unbounded_array_definition
- -- | constrained_array_definition
- --
- -- unbounded_array_definition ::=
- -- ARRAY ( index_subtype_definition { , index_subtype_definition } )
- -- OF element_subtype_indication
- function Parse_Array_Definition return Iir
- is
- Index_Constrained : Boolean;
- Array_Constrained : Boolean;
- First : Boolean;
- Res_Type: Iir;
- Index_List : Iir_List;
-
- Loc : Location_Type;
- Def : Iir;
- Type_Mark : Iir;
- Element_Subtype : Iir;
- begin
- Loc := Get_Token_Location;
-
- -- Skip 'array', scan '('
- Scan_Expect (Tok_Left_Paren);
- Scan;
-
- First := True;
- Index_List := Create_Iir_List;
-
- loop
- -- The accepted syntax can be one of:
- -- * index_subtype_definition, which is:
- -- * type_mark RANGE <>
- -- * discrete_range, which is either:
- -- * /discrete/_subtype_indication
- -- * [ resolution_indication ] type_mark [ range_constraint ]
- -- * range_constraint ::= RANGE range
- -- * range
- -- * /range/_attribute_name
- -- * simple_expression direction simple_expression
-
- -- Parse a simple expression (for the range), which can also parse a
- -- name.
- Type_Mark := Parse_Simple_Expression;
-
- case Current_Token is
- when Tok_Range =>
- -- Skip 'range'
- Scan;
-
- if Current_Token = Tok_Box then
- -- Parsed 'RANGE <>': this is an index_subtype_definition.
- Index_Constrained := False;
- Scan;
- Def := Type_Mark;
- else
- -- This is a /discrete/_subtype_indication
- Index_Constrained := True;
- Def :=
- Parse_Range_Constraint_Of_Subtype_Indication (Type_Mark);
- end if;
- when Tok_To
- | Tok_Downto =>
- -- A range
- Index_Constrained := True;
- Def := Parse_Range_Right (Type_Mark);
- when others =>
- -- For a /range/_attribute_name
- Index_Constrained := True;
- Def := Type_Mark;
- end case;
-
- Append_Element (Index_List, Def);
-
- if First then
- Array_Constrained := Index_Constrained;
- First := False;
- else
- if Array_Constrained /= Index_Constrained then
- Error_Msg_Parse
- ("cannot mix constrained and unconstrained index");
- end if;
- end if;
- exit when Current_Token /= Tok_Comma;
- Scan;
- end loop;
-
- -- Skip ')' and 'of'
- Expect (Tok_Right_Paren);
- Scan_Expect (Tok_Of);
- Scan;
-
- Element_Subtype := Parse_Subtype_Indication;
-
- if Array_Constrained then
- -- Sem_Type will create the array type.
- Res_Type := Create_Iir (Iir_Kind_Array_Subtype_Definition);
- Set_Element_Subtype (Res_Type, Element_Subtype);
- Set_Index_Constraint_List (Res_Type, Index_List);
- else
- Res_Type := Create_Iir (Iir_Kind_Array_Type_Definition);
- Set_Element_Subtype_Indication (Res_Type, Element_Subtype);
- Set_Index_Subtype_Definition_List (Res_Type, Index_List);
- end if;
- Set_Location (Res_Type, Loc);
-
- return Res_Type;
- end Parse_Array_Definition;
-
- -- precond : UNITS
- -- postcond: next token
- --
- -- [ LRM93 3.1.3 ]
- -- physical_type_definition ::=
- -- range_constraint
- -- UNITS
- -- base_unit_declaration
- -- { secondary_unit_declaration }
- -- END UNITS [ PHYSICAL_TYPE_simple_name ]
- --
- -- [ LRM93 3.1.3 ]
- -- base_unit_declaration ::= identifier ;
- --
- -- [ LRM93 3.1.3 ]
- -- secondary_unit_declaration ::= identifier = physical_literal ;
- function Parse_Physical_Type_Definition (Parent : Iir)
- return Iir_Physical_Type_Definition
- is
- use Iir_Chains.Unit_Chain_Handling;
- Res: Iir_Physical_Type_Definition;
- Unit: Iir_Unit_Declaration;
- Last : Iir_Unit_Declaration;
- Multiplier : Iir;
- begin
- Res := Create_Iir (Iir_Kind_Physical_Type_Definition);
- Set_Location (Res);
-
- -- Skip 'units'
- Expect (Tok_Units);
- Scan;
-
- -- Parse primary unit.
- Expect (Tok_Identifier);
- Unit := Create_Iir (Iir_Kind_Unit_Declaration);
- Set_Location (Unit);
- Set_Parent (Unit, Parent);
- Set_Identifier (Unit, Current_Identifier);
-
- -- Skip identifier
- Scan;
-
- Scan_Semi_Colon ("primary unit");
-
- Build_Init (Last);
- Append (Last, Res, Unit);
-
- -- Parse secondary units.
- while Current_Token /= Tok_End loop
- Unit := Create_Iir (Iir_Kind_Unit_Declaration);
- Set_Location (Unit);
- Set_Identifier (Unit, Current_Identifier);
-
- -- Skip identifier.
- Scan_Expect (Tok_Equal);
-
- -- Skip '='.
- Scan;
-
- Multiplier := Parse_Primary;
- Set_Physical_Literal (Unit, Multiplier);
- case Get_Kind (Multiplier) is
- when Iir_Kind_Simple_Name
- | Iir_Kind_Selected_Name
- | Iir_Kind_Physical_Int_Literal =>
- null;
- when Iir_Kind_Physical_Fp_Literal =>
- Error_Msg_Parse
- ("secondary units may only be defined with integer literals");
- when others =>
- Error_Msg_Parse ("a physical literal is expected here");
- end case;
- Append (Last, Res, Unit);
- Scan_Semi_Colon ("secondary unit");
- end loop;
-
- -- Skip 'end'.
- Scan;
-
- Expect (Tok_Units);
- Set_End_Has_Reserved_Id (Res, True);
-
- -- Skip 'units'.
- Scan;
- return Res;
- end Parse_Physical_Type_Definition;
-
- -- precond : RECORD
- -- postcond: next token
- --
- -- [ LRM93 3.2.2 ]
- -- record_type_definition ::=
- -- RECORD
- -- element_declaration
- -- { element_declaration }
- -- END RECORD [ RECORD_TYPE_simple_name ]
- --
- -- element_declaration ::=
- -- identifier_list : element_subtype_definition
- --
- -- element_subtype_definition ::= subtype_indication
- function Parse_Record_Type_Definition return Iir_Record_Type_Definition
- is
- Res: Iir_Record_Type_Definition;
- El_List : Iir_List;
- El: Iir_Element_Declaration;
- First : Iir;
- Pos: Iir_Index32;
- Subtype_Indication: Iir;
- begin
- Res := Create_Iir (Iir_Kind_Record_Type_Definition);
- Set_Location (Res);
- El_List := Create_Iir_List;
- Set_Elements_Declaration_List (Res, El_List);
-
- -- Skip 'record'
- Scan;
-
- Pos := 0;
- First := Null_Iir;
- loop
- pragma Assert (First = Null_Iir);
- -- Parse identifier_list
- loop
- El := Create_Iir (Iir_Kind_Element_Declaration);
- Set_Location (El);
- if First = Null_Iir then
- First := El;
- end if;
- Expect (Tok_Identifier);
- Set_Identifier (El, Current_Identifier);
- Append_Element (El_List, El);
- Set_Element_Position (El, Pos);
- Pos := Pos + 1;
- if First = Null_Iir then
- First := El;
- end if;
-
- -- Skip identifier
- Scan;
-
- exit when Current_Token /= Tok_Comma;
-
- Set_Has_Identifier_List (El, True);
-
- -- Skip ','
- Scan;
- end loop;
-
- -- Scan ':'.
- Expect (Tok_Colon);
- Scan;
-
- -- Parse element subtype indication.
- Subtype_Indication := Parse_Subtype_Indication;
- Set_Subtype_Indication (First, Subtype_Indication);
-
- First := Null_Iir;
- Scan_Semi_Colon ("element declaration");
- exit when Current_Token = Tok_End;
- end loop;
-
- -- Skip 'end'
- Scan_Expect (Tok_Record);
- Set_End_Has_Reserved_Id (Res, True);
-
- -- Skip 'record'
- Scan;
-
- return Res;
- end Parse_Record_Type_Definition;
-
- -- precond : ACCESS
- -- postcond: ?
- --
- -- [ LRM93 3.3]
- -- access_type_definition ::= ACCESS subtype_indication.
- function Parse_Access_Type_Definition return Iir_Access_Type_Definition
- is
- Res : Iir_Access_Type_Definition;
- begin
- Res := Create_Iir (Iir_Kind_Access_Type_Definition);
- Set_Location (Res);
-
- -- Skip 'access'
- Expect (Tok_Access);
- Scan;
-
- Set_Designated_Subtype_Indication (Res, Parse_Subtype_Indication);
-
- return Res;
- end Parse_Access_Type_Definition;
-
- -- precond : FILE
- -- postcond: next token
- --
- -- [ LRM93 3.4 ]
- -- file_type_definition ::= FILE OF type_mark
- function Parse_File_Type_Definition return Iir_File_Type_Definition
- is
- Res : Iir_File_Type_Definition;
- Type_Mark: Iir;
- begin
- Res := Create_Iir (Iir_Kind_File_Type_Definition);
- Set_Location (Res);
- -- Accept token 'file'.
- Scan_Expect (Tok_Of);
- Scan;
- Type_Mark := Parse_Type_Mark (Check_Paren => True);
- if Get_Kind (Type_Mark) not in Iir_Kinds_Denoting_Name then
- Error_Msg_Parse ("type mark expected");
- else
- Set_File_Type_Mark (Res, Type_Mark);
- end if;
- return Res;
- end Parse_File_Type_Definition;
-
- -- precond : PROTECTED
- -- postcond: ';'
- --
- -- [ 3.5 ]
- -- protected_type_definition ::= protected_type_declaration
- -- | protected_type_body
- --
- -- [ 3.5.1 ]
- -- protected_type_declaration ::= PROTECTED
- -- protected_type_declarative_part
- -- END PROTECTED [ simple_name ]
- --
- -- protected_type_declarative_part ::=
- -- { protected_type_declarative_item }
- --
- -- protected_type_declarative_item ::=
- -- subprogram_declaration
- -- | attribute_specification
- -- | use_clause
- --
- -- [ 3.5.2 ]
- -- protected_type_body ::= PROTECTED BODY
- -- protected_type_body_declarative_part
- -- END PROTECTED BODY [ simple_name ]
- --
- -- protected_type_body_declarative_part ::=
- -- { protected_type_body_declarative_item }
- --
- -- protected_type_body_declarative_item ::=
- -- subprogram_declaration
- -- | subprogram_body
- -- | type_declaration
- -- | subtype_declaration
- -- | constant_declaration
- -- | variable_declaration
- -- | file_declaration
- -- | alias_declaration
- -- | attribute_declaration
- -- | attribute_specification
- -- | use_clause
- -- | group_template_declaration
- -- | group_declaration
- function Parse_Protected_Type_Definition
- (Ident : Name_Id; Loc : Location_Type) return Iir
- is
- Res : Iir;
- Decl : Iir;
- begin
- Scan;
- if Current_Token = Tok_Body then
- Res := Create_Iir (Iir_Kind_Protected_Type_Body);
- Scan;
- Decl := Res;
- else
- Decl := Create_Iir (Iir_Kind_Type_Declaration);
- Res := Create_Iir (Iir_Kind_Protected_Type_Declaration);
- Set_Location (Res, Loc);
- Set_Type_Definition (Decl, Res);
- end if;
- Set_Identifier (Decl, Ident);
- Set_Location (Decl, Loc);
-
- Parse_Declarative_Part (Res);
-
- Expect (Tok_End);
- Scan_Expect (Tok_Protected);
- Set_End_Has_Reserved_Id (Res, True);
- if Get_Kind (Res) = Iir_Kind_Protected_Type_Body then
- Scan_Expect (Tok_Body);
- end if;
- Scan;
- Check_End_Name (Ident, Res);
- return Decl;
- end Parse_Protected_Type_Definition;
-
- -- precond : TYPE
- -- postcond: a token
- --
- -- [ LRM93 4.1 ]
- -- type_definition ::= scalar_type_definition
- -- | composite_type_definition
- -- | access_type_definition
- -- | file_type_definition
- -- | protected_type_definition
- --
- -- [ LRM93 3.1 ]
- -- scalar_type_definition ::= enumeration_type_definition
- -- | integer_type_definition
- -- | floating_type_definition
- -- | physical_type_definition
- --
- -- [ LRM93 3.2 ]
- -- composite_type_definition ::= array_type_definition
- -- | record_type_definition
- --
- -- [ LRM93 3.1.2 ]
- -- integer_type_definition ::= range_constraint
- --
- -- [ LRM93 3.1.4 ]
- -- floating_type_definition ::= range_constraint
- function Parse_Type_Declaration (Parent : Iir) return Iir
- is
- Def : Iir;
- Loc : Location_Type;
- Ident : Name_Id;
- Decl : Iir;
- begin
- -- The current token must be type.
- pragma Assert (Current_Token = Tok_Type);
-
- -- Get the identifier
- Scan_Expect (Tok_Identifier,
- "an identifier is expected after 'type' keyword");
- Loc := Get_Token_Location;
- Ident := Current_Identifier;
-
- -- Skip identifier
- Scan;
-
- if Current_Token = Tok_Semi_Colon then
- -- If there is a ';', this is an imcomplete type declaration.
- Invalidate_Current_Token;
- Decl := Create_Iir (Iir_Kind_Type_Declaration);
- Set_Identifier (Decl, Ident);
- Set_Location (Decl, Loc);
- return Decl;
- end if;
-
- if Current_Token /= Tok_Is then
- Error_Msg_Parse ("'is' expected here");
- -- Act as if IS token was forgotten.
- else
- -- Eat IS token.
- Scan;
- end if;
-
- case Current_Token is
- when Tok_Left_Paren =>
- -- This is an enumeration.
- Def := Parse_Enumeration_Type_Definition;
- Decl := Null_Iir;
-
- when Tok_Range =>
- -- This is a range definition.
- Decl := Create_Iir (Iir_Kind_Anonymous_Type_Declaration);
- Set_Identifier (Decl, Ident);
- Set_Location (Decl, Loc);
-
- -- Skip 'range'
- Scan;
-
- Def := Parse_Range_Constraint;
- Set_Type_Definition (Decl, Def);
-
- if Current_Token = Tok_Units then
- -- A physical type definition.
- declare
- Unit_Def : Iir;
- begin
- Unit_Def := Parse_Physical_Type_Definition (Parent);
- if Current_Token = Tok_Identifier then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse
- ("simple_name not allowed here in vhdl87");
- end if;
- Check_End_Name (Get_Identifier (Decl), Unit_Def);
- end if;
- if Def /= Null_Iir then
- Set_Type (Def, Unit_Def);
- end if;
- end;
- end if;
-
- when Tok_Array =>
- Def := Parse_Array_Definition;
- Decl := Null_Iir;
-
- when Tok_Record =>
- Decl := Create_Iir (Iir_Kind_Type_Declaration);
- Set_Identifier (Decl, Ident);
- Set_Location (Decl, Loc);
- Def := Parse_Record_Type_Definition;
- Set_Type_Definition (Decl, Def);
- if Current_Token = Tok_Identifier then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("simple_name not allowed here in vhdl87");
- end if;
- Check_End_Name (Get_Identifier (Decl), Def);
- end if;
-
- when Tok_Access =>
- Def := Parse_Access_Type_Definition;
- Decl := Null_Iir;
-
- when Tok_File =>
- Def := Parse_File_Type_Definition;
- Decl := Null_Iir;
-
- when Tok_Identifier =>
- if Current_Identifier = Name_Protected then
- Error_Msg_Parse ("protected type not allowed in vhdl87/93");
- Decl := Parse_Protected_Type_Definition (Ident, Loc);
- else
- Error_Msg_Parse ("type '" & Name_Table.Image (Ident) &
- "' cannot be defined from another type");
- Error_Msg_Parse ("(you should declare a subtype)");
- Decl := Create_Iir (Iir_Kind_Type_Declaration);
- Eat_Tokens_Until_Semi_Colon;
- end if;
-
- when Tok_Protected =>
- if Flags.Vhdl_Std < Vhdl_00 then
- Error_Msg_Parse ("protected type not allowed in vhdl87/93");
- end if;
- Decl := Parse_Protected_Type_Definition (Ident, Loc);
-
- when others =>
- Error_Msg_Parse
- ("type definition starting with a keyword such as RANGE, ARRAY");
- Error_Msg_Parse
- (" FILE, RECORD or '(' is expected here");
- Eat_Tokens_Until_Semi_Colon;
- Decl := Create_Iir (Iir_Kind_Type_Declaration);
- end case;
-
- if Decl = Null_Iir then
- case Get_Kind (Def) is
- when Iir_Kind_Enumeration_Type_Definition
- | Iir_Kind_Access_Type_Definition
- | Iir_Kind_Array_Type_Definition
- | Iir_Kind_File_Type_Definition =>
- Decl := Create_Iir (Iir_Kind_Type_Declaration);
- when Iir_Kind_Array_Subtype_Definition =>
- Decl := Create_Iir (Iir_Kind_Anonymous_Type_Declaration);
- when others =>
- Error_Kind ("parse_type_declaration", Def);
- end case;
- Set_Type_Definition (Decl, Def);
- end if;
- Set_Identifier (Decl, Ident);
- Set_Location (Decl, Loc);
-
- -- ';' is expected after end of type declaration
- Expect (Tok_Semi_Colon);
- Invalidate_Current_Token;
- return Decl;
- end Parse_Type_Declaration;
-
- -- precond: '(' or identifier
- -- postcond: next token
- --
- -- [ LRM08 6.3 ]
- --
- -- resolution_indication ::=
- -- resolution_function_name | ( element_resolution )
- --
- -- element_resolution ::=
- -- array_element_resolution | record_resolution
- --
- -- array_element_resolution ::= resolution_indication
- --
- -- record_resolution ::=
- -- record_element_resolution { , record_element_resolution }
- --
- -- record_element_resolution ::=
- -- record_element_simple_name resolution_indication
- function Parse_Resolution_Indication return Iir
- is
- Ind : Iir;
- Def : Iir;
- Loc : Location_Type;
- begin
- if Current_Token = Tok_Identifier then
- -- Resolution function name.
- return Parse_Name (Allow_Indexes => False);
- elsif Current_Token = Tok_Left_Paren then
- -- Element resolution.
- Loc := Get_Token_Location;
-
- -- Eat '('
- Scan;
-
- Ind := Parse_Resolution_Indication;
- if Current_Token = Tok_Identifier
- or else Current_Token = Tok_Left_Paren
- then
- declare
- Id : Name_Id;
- El : Iir;
- First, Last : Iir;
- begin
- -- This was in fact a record_resolution.
- if Get_Kind (Ind) = Iir_Kind_Simple_Name then
- Id := Get_Identifier (Ind);
- else
- Error_Msg_Parse ("element name expected", Ind);
- Id := Null_Identifier;
- end if;
- Free_Iir (Ind);
-
- Def := Create_Iir (Iir_Kind_Record_Resolution);
- Set_Location (Def, Loc);
- Sub_Chain_Init (First, Last);
- loop
- El := Create_Iir (Iir_Kind_Record_Element_Resolution);
- Set_Location (El, Loc);
- Set_Identifier (El, Id);
- Set_Resolution_Indication (El, Parse_Resolution_Indication);
- Sub_Chain_Append (First, Last, El);
- exit when Current_Token = Tok_Right_Paren;
-
- -- Eat ','
- Expect (Tok_Comma);
- Scan;
-
- if Current_Token /= Tok_Identifier then
- Error_Msg_Parse ("record element identifier expected");
- exit;
- end if;
- Id := Current_Identifier;
- Loc := Get_Token_Location;
-
- -- Eat identifier
- Scan;
- end loop;
- Set_Record_Element_Resolution_Chain (Def, First);
- end;
- else
- Def := Create_Iir (Iir_Kind_Array_Element_Resolution);
- Set_Location (Def, Loc);
- Set_Resolution_Indication (Def, Ind);
- end if;
-
- -- Eat ')'
- Expect (Tok_Right_Paren);
- Scan;
-
- return Def;
- else
- Error_Msg_Parse ("resolution indication expected");
- raise Parse_Error;
- end if;
- end Parse_Resolution_Indication;
-
- -- precond : '('
- -- postcond: next token
- --
- -- [ LRM08 6.3 Subtype declarations ]
- -- element_constraint ::=
- -- array_constraint | record_constraint
- --
- -- [ LRM08 5.3.2.1 Array types ]
- -- array_constraint ::=
- -- index_constraint [ array_element_constraint ]
- -- | ( open ) [ array_element_constraint ]
- --
- -- array_element_constraint ::= element_constraint
- --
- -- RES is the resolution_indication of the subtype indication.
- function Parse_Element_Constraint return Iir
- is
- Def : Iir;
- El : Iir;
- Index_List : Iir_List;
- begin
- -- Index_constraint.
- Def := Create_Iir (Iir_Kind_Array_Subtype_Definition);
- Set_Location (Def);
-
- -- Eat '('.
- Scan;
-
- if Current_Token = Tok_Open then
- -- Eat 'open'.
- Scan;
- else
- Index_List := Create_Iir_List;
- Set_Index_Constraint_List (Def, Index_List);
- -- index_constraint ::= (discrete_range {, discrete_range} )
- loop
- El := Parse_Discrete_Range;
- Append_Element (Index_List, El);
-
- exit when Current_Token = Tok_Right_Paren;
-
- -- Eat ','
- Expect (Tok_Comma);
- Scan;
- end loop;
- end if;
-
- -- Eat ')'
- Expect (Tok_Right_Paren);
- Scan;
-
- if Current_Token = Tok_Left_Paren then
- Set_Element_Subtype (Def, Parse_Element_Constraint);
- end if;
- return Def;
- end Parse_Element_Constraint;
-
- -- precond : tolerance
- -- postcond: next token
- --
- -- [ LRM93 4.2 ]
- -- tolerance_aspect ::= TOLERANCE string_expression
- function Parse_Tolerance_Aspect_Opt return Iir is
- begin
- if AMS_Vhdl
- and then Current_Token = Tok_Tolerance
- then
- Scan;
- return Parse_Expression;
- else
- return Null_Iir;
- end if;
- end Parse_Tolerance_Aspect_Opt;
-
- -- precond : identifier or '('
- -- postcond: next token
- --
- -- [ LRM93 4.2 ]
- -- subtype_indication ::=
- -- [ RESOLUTION_FUNCTION_name ] type_mark [ constraint ]
- --
- -- constraint ::= range_constraint | index_constraint
- --
- -- [ LRM08 6.3 ]
- -- subtype_indication ::=
- -- [ resolution_indication ] type_mark [ constraint ]
- --
- -- constraint ::=
- -- range_constraint | array_constraint | record_constraint
- --
- -- NAME is the type_mark when already parsed (in range expression or
- -- allocator by type).
- function Parse_Subtype_Indication (Name : Iir := Null_Iir)
- return Iir
- is
- Type_Mark : Iir;
- Def: Iir;
- Resolution_Indication: Iir;
- Tolerance : Iir;
- begin
- -- FIXME: location.
- Resolution_Indication := Null_Iir;
- Def := Null_Iir;
-
- if Name /= Null_Iir then
- -- The type_mark was already parsed.
- Type_Mark := Name;
- Check_Type_Mark (Name);
- else
- if Current_Token = Tok_Left_Paren then
- if Vhdl_Std < Vhdl_08 then
- Error_Msg_Parse
- ("resolution_indication not allowed before vhdl08");
- end if;
- Resolution_Indication := Parse_Resolution_Indication;
- end if;
- if Current_Token /= Tok_Identifier then
- Error_Msg_Parse ("type mark expected in a subtype indication");
- raise Parse_Error;
- end if;
- Type_Mark := Parse_Type_Mark (Check_Paren => False);
- end if;
-
- if Current_Token = Tok_Identifier then
- if Resolution_Indication /= Null_Iir then
- Error_Msg_Parse ("resolution function already indicated");
- end if;
- Resolution_Indication := Type_Mark;
- Type_Mark := Parse_Type_Mark (Check_Paren => False);
- end if;
-
- case Current_Token is
- when Tok_Left_Paren =>
- -- element_constraint.
- Def := Parse_Element_Constraint;
- Set_Subtype_Type_Mark (Def, Type_Mark);
- Set_Resolution_Indication (Def, Resolution_Indication);
- Set_Tolerance (Def, Parse_Tolerance_Aspect_Opt);
-
- when Tok_Range =>
- -- range_constraint.
- -- Skip 'range'
- Scan;
-
- Def := Parse_Range_Constraint_Of_Subtype_Indication
- (Type_Mark, Resolution_Indication);
-
- when others =>
- Tolerance := Parse_Tolerance_Aspect_Opt;
- if Resolution_Indication /= Null_Iir
- or else Tolerance /= Null_Iir
- then
- -- A subtype needs to be created.
- Def := Create_Iir (Iir_Kind_Subtype_Definition);
- Location_Copy (Def, Type_Mark);
- Set_Subtype_Type_Mark (Def, Type_Mark);
- Set_Resolution_Indication (Def, Resolution_Indication);
- Set_Tolerance (Def, Tolerance);
- else
- -- This is just an alias.
- Def := Type_Mark;
- end if;
- end case;
- return Def;
- end Parse_Subtype_Indication;
-
- -- precond : SUBTYPE
- -- postcond: ';'
- --
- -- [ §4.2 ]
- -- subtype_declaration ::= SUBTYPE identifier IS subtype_indication ;
- function Parse_Subtype_Declaration return Iir_Subtype_Declaration
- is
- Decl: Iir_Subtype_Declaration;
- Def: Iir;
- begin
- Decl := Create_Iir (Iir_Kind_Subtype_Declaration);
-
- Scan_Expect (Tok_Identifier);
- Set_Identifier (Decl, Current_Identifier);
- Set_Location (Decl);
-
- Scan_Expect (Tok_Is);
- Scan;
- Def := Parse_Subtype_Indication;
- Set_Subtype_Indication (Decl, Def);
-
- Expect (Tok_Semi_Colon);
- return Decl;
- end Parse_Subtype_Declaration;
-
- -- precond : NATURE
- -- postcond: a token
- --
- -- [ §4.8 ]
- -- nature_definition ::= scalar_nature_definition
- -- | composite_nature_definition
- --
- -- [ §3.5.1 ]
- -- scalar_nature_definition ::= type_mark ACROSS
- -- type_mark THROUGH
- -- identifier REFERENCE
- --
- -- [ §3.5.2 ]
- -- composite_nature_definition ::= array_nature_definition
- -- | record_nature_definition
- function Parse_Nature_Declaration return Iir
- is
- Def : Iir;
- Ref : Iir;
- Loc : Location_Type;
- Ident : Name_Id;
- Decl : Iir;
- begin
- -- The current token must be type.
- if Current_Token /= Tok_Nature then
- raise Program_Error;
- end if;
-
- -- Get the identifier
- Scan_Expect (Tok_Identifier,
- "an identifier is expected after 'nature'");
- Loc := Get_Token_Location;
- Ident := Current_Identifier;
-
- Scan;
-
- if Current_Token /= Tok_Is then
- Error_Msg_Parse ("'is' expected here");
- -- Act as if IS token was forgotten.
- else
- -- Eat IS token.
- Scan;
- end if;
-
- case Current_Token is
- when Tok_Array =>
- -- TODO
- Error_Msg_Parse ("array nature definition not supported");
- Def := Null_Iir;
- Eat_Tokens_Until_Semi_Colon;
- when Tok_Record =>
- -- TODO
- Error_Msg_Parse ("record nature definition not supported");
- Def := Null_Iir;
- Eat_Tokens_Until_Semi_Colon;
- when Tok_Identifier =>
- Def := Create_Iir (Iir_Kind_Scalar_Nature_Definition);
- Set_Location (Def, Loc);
- Set_Across_Type (Def, Parse_Type_Mark);
- if Current_Token = Tok_Across then
- Scan;
- else
- Expect (Tok_Across, "'across' expected after type mark");
- end if;
- Set_Through_Type (Def, Parse_Type_Mark);
- if Current_Token = Tok_Through then
- Scan;
- else
- Expect (Tok_Across, "'through' expected after type mark");
- end if;
- if Current_Token = Tok_Identifier then
- Ref := Create_Iir (Iir_Kind_Terminal_Declaration);
- Set_Identifier (Ref, Current_Identifier);
- Set_Location (Ref);
- Set_Reference (Def, Ref);
- Scan;
- if Current_Token = Tok_Reference then
- Scan;
- else
- Expect (Tok_Reference, "'reference' expected");
- Eat_Tokens_Until_Semi_Colon;
- end if;
- else
- Error_Msg_Parse ("reference identifier expected");
- Eat_Tokens_Until_Semi_Colon;
- end if;
- when others =>
- Error_Msg_Parse ("nature definition expected here");
- Eat_Tokens_Until_Semi_Colon;
- end case;
-
- Decl := Create_Iir (Iir_Kind_Nature_Declaration);
- Set_Nature (Decl, Def);
- Set_Identifier (Decl, Ident);
- Set_Location (Decl, Loc);
-
- -- ';' is expected after end of type declaration
- Expect (Tok_Semi_Colon);
- Invalidate_Current_Token;
- return Decl;
- end Parse_Nature_Declaration;
-
- -- precond : identifier
- -- postcond: next token
- --
- -- LRM 4.8 Nature declaration
- --
- -- subnature_indication ::=
- -- nature_mark [ index_constraint ]
- -- [ TOLERANCE string_expression ACROSS string_expression THROUGH ]
- --
- -- nature_mark ::=
- -- nature_name | subnature_name
- function Parse_Subnature_Indication return Iir is
- Nature_Mark : Iir;
- begin
- if Current_Token /= Tok_Identifier then
- Error_Msg_Parse ("nature mark expected in a subnature indication");
- raise Parse_Error;
- end if;
- Nature_Mark := Parse_Name (Allow_Indexes => False);
-
- if Current_Token = Tok_Left_Paren then
- -- TODO
- Error_Msg_Parse
- ("index constraint not supported for subnature indication");
- raise Parse_Error;
- end if;
-
- if Current_Token = Tok_Tolerance then
- Error_Msg_Parse
- ("tolerance not supported for subnature indication");
- raise Parse_Error;
- end if;
- return Nature_Mark;
- end Parse_Subnature_Indication;
-
- -- precond : TERMINAL
- -- postcond: ;
- --
- -- [ 4.3.1.5 Terminal declarations ]
- -- terminal_declaration ::=
- -- TERMINAL identifier_list : subnature_indication
- function Parse_Terminal_Declaration (Parent : Iir) return Iir
- is
- -- First and last element of the chain to be returned.
- First, Last : Iir;
- Terminal : Iir;
- Subnature : Iir;
- begin
- Sub_Chain_Init (First, Last);
-
- loop
- -- 'terminal' or "," was just scanned.
- Terminal := Create_Iir (Iir_Kind_Terminal_Declaration);
- Scan_Expect (Tok_Identifier);
- Set_Identifier (Terminal, Current_Identifier);
- Set_Location (Terminal);
- Set_Parent (Terminal, Parent);
-
- Sub_Chain_Append (First, Last, Terminal);
-
- Scan;
- exit when Current_Token = Tok_Colon;
- if Current_Token /= Tok_Comma then
- Error_Msg_Parse
- ("',' or ':' is expected after "
- & "identifier in terminal declaration");
- raise Expect_Error;
- end if;
- end loop;
-
- -- The colon was parsed.
- Scan;
- Subnature := Parse_Subnature_Indication;
-
- Terminal := First;
- while Terminal /= Null_Iir loop
- -- Type definitions are factorized. This is OK, but not done by
- -- sem.
- if Terminal = First then
- Set_Nature (Terminal, Subnature);
- else
- Set_Nature (Terminal, Null_Iir);
- end if;
- Terminal := Get_Chain (Terminal);
- end loop;
- Expect (Tok_Semi_Colon);
- return First;
- end Parse_Terminal_Declaration;
-
- -- precond : QUANTITY
- -- postcond: ;
- --
- -- [ 4.3.1.6 Quantity declarations ]
- -- quantity_declaration ::=
- -- free_quantity_declaration
- -- | branch_quantity_declaration
- -- | source_quantity_declaration
- --
- -- free_quantity_declaration ::=
- -- QUANTITY identifier_list : subtype_indication [ := expression ] ;
- --
- -- branch_quantity_declaration ::=
- -- QUANTITY [ across_aspect ] [ through_aspect ] terminal_aspect ;
- --
- -- source_quantity_declaration ::=
- -- QUANTITY identifier_list : subtype_indication source_aspect ;
- --
- -- across_aspect ::=
- -- identifier_list [ tolerance_aspect ] [ := expression ] ACROSS
- --
- -- through_aspect ::=
- -- identifier_list [ tolerance_aspect ] [ := expression ] THROUGH
- --
- -- terminal_aspect ::=
- -- plus_terminal_name [ TO minus_terminal_name ]
- function Parse_Quantity_Declaration (Parent : Iir) return Iir
- is
- -- First and last element of the chain to be returned.
- First, Last : Iir;
- Object : Iir;
- New_Object : Iir;
- Tolerance : Iir;
- Default_Value : Iir;
- Kind : Iir_Kind;
- Plus_Terminal : Iir;
- begin
- Sub_Chain_Init (First, Last);
-
- -- Eat 'quantity'
- Scan;
-
- loop
- -- Quantity or "," was just scanned. We assume a free quantity
- -- declaration and will change to branch or source quantity if
- -- necessary.
- Object := Create_Iir (Iir_Kind_Free_Quantity_Declaration);
- Expect (Tok_Identifier);
- Set_Identifier (Object, Current_Identifier);
- Set_Location (Object);
- Set_Parent (Object, Parent);
-
- Sub_Chain_Append (First, Last, Object);
-
- -- Eat identifier
- Scan;
- exit when Current_Token /= Tok_Comma;
-
- -- Eat ','
- Scan;
- end loop;
-
- case Current_Token is
- when Tok_Colon =>
- -- Either a free quantity (or a source quantity)
- -- TODO
- raise Program_Error;
- when Tok_Tolerance
- | Tok_Assign
- | Tok_Across
- | Tok_Through =>
- -- A branch quantity
-
- -- Parse tolerance aspect
- Tolerance := Parse_Tolerance_Aspect_Opt;
-
- -- Parse default value
- if Current_Token = Tok_Assign then
- Scan;
- Default_Value := Parse_Expression;
- else
- Default_Value := Null_Iir;
- end if;
-
- case Current_Token is
- when Tok_Across =>
- Kind := Iir_Kind_Across_Quantity_Declaration;
- when Tok_Through =>
- Kind := Iir_Kind_Through_Quantity_Declaration;
- when others =>
- Error_Msg_Parse ("'across' or 'through' expected here");
- Eat_Tokens_Until_Semi_Colon;
- raise Expect_Error;
- end case;
-
- -- Eat across/through
- Scan;
-
- -- Change declarations
- Object := First;
- Sub_Chain_Init (First, Last);
- while Object /= Null_Iir loop
- New_Object := Create_Iir (Kind);
- Location_Copy (New_Object, Object);
- Set_Identifier (New_Object, Get_Identifier (Object));
- Set_Parent (New_Object, Parent);
- Set_Tolerance (New_Object, Tolerance);
- Set_Default_Value (New_Object, Default_Value);
-
- Sub_Chain_Append (First, Last, New_Object);
-
- if Object /= First then
- Set_Plus_Terminal (New_Object, Null_Iir);
- end if;
- New_Object := Get_Chain (Object);
- Free_Iir (Object);
- Object := New_Object;
- end loop;
-
- -- Parse terminal (or first identifier of through declarations)
- Plus_Terminal := Parse_Name;
-
- case Current_Token is
- when Tok_Comma
- | Tok_Tolerance
- | Tok_Assign
- | Tok_Through
- | Tok_Across =>
- -- Through quantity declaration. Convert the Plus_Terminal
- -- to a declaration.
- Object := Create_Iir (Iir_Kind_Through_Quantity_Declaration);
- New_Object := Object;
- Location_Copy (Object, Plus_Terminal);
- if Get_Kind (Plus_Terminal) /= Iir_Kind_Simple_Name then
- Error_Msg_Parse
- ("identifier for quantity declaration expected");
- else
- Set_Identifier (Object, Get_Identifier (Plus_Terminal));
- end if;
- Set_Plus_Terminal (Object, Null_Iir);
- Free_Iir (Plus_Terminal);
-
- loop
- Set_Parent (Object, Parent);
- Sub_Chain_Append (First, Last, Object);
- exit when Current_Token /= Tok_Comma;
- Scan;
-
- Object := Create_Iir
- (Iir_Kind_Through_Quantity_Declaration);
- Set_Location (Object);
- if Current_Token /= Tok_Identifier then
- Error_Msg_Parse
- ("identifier for quantity declaration expected");
- else
- Set_Identifier (Object, Current_Identifier);
- Scan;
- end if;
- Set_Plus_Terminal (Object, Null_Iir);
-
- end loop;
-
- -- Parse tolerance aspect
- Set_Tolerance (Object, Parse_Tolerance_Aspect_Opt);
-
- -- Parse default value
- if Current_Token = Tok_Assign then
- Scan;
- Set_Default_Value (Object, Parse_Expression);
- end if;
-
- -- Scan 'through'
- if Current_Token = Tok_Through then
- Scan;
- elsif Current_Token = Tok_Across then
- Error_Msg_Parse ("across quantity declaration must appear"
- & " before though declaration");
- Scan;
- else
- Error_Msg_Parse ("'through' expected");
- end if;
-
- -- Parse plus terminal
- Plus_Terminal := Parse_Name;
- when others =>
- null;
- end case;
-
- Set_Plus_Terminal (First, Plus_Terminal);
-
- -- Parse minus terminal (if present)
- if Current_Token = Tok_To then
- Scan;
- Set_Minus_Terminal (First, Parse_Name);
- end if;
- when others =>
- Error_Msg_Parse ("missign type or across/throught aspect "
- & "in quantity declaration");
- Eat_Tokens_Until_Semi_Colon;
- raise Expect_Error;
- end case;
- Expect (Tok_Semi_Colon);
- return First;
- end Parse_Quantity_Declaration;
-
- -- precond : token (CONSTANT, SIGNAL, VARIABLE, FILE)
- -- postcond: ;
- --
- -- KIND can be iir_kind_constant_declaration, iir_kind_file_declaration
- -- or iir_kind_variable_declaration
- --
- -- [ LRM93 4.3.1 ]
- -- object_declaration ::= constant_declaration
- -- | signal_declaration
- -- | variable_declaration
- -- | file_declaration
- --
- -- [ LRM93 4.3.1.1 ]
- -- constant_declaration ::=
- -- CONSTANT identifier_list : subtype_indication [ := expression ]
- --
- -- [ LRM87 4.3.2 ]
- -- file_declaration ::=
- -- FILE identifier : subtype_indication IS [ mode ] file_logical_name
- --
- -- [ LRM93 4.3.1.4 ]
- -- file_declaration ::=
- -- FILE identifier_list : subtype_indication [ file_open_information ]
- --
- -- [ LRM93 4.3.1.4 ]
- -- file_open_information ::=
- -- [ OPEN FILE_OPEN_KIND_expression ] IS file_logical_name
- --
- -- [ LRM93 4.3.1.4 ]
- -- file_logical_name ::= STRING_expression
- --
- -- [ LRM93 4.3.1.3 ]
- -- variable_declaration ::=
- -- [ SHARED ] VARIABLE identifier_list : subtype_indication
- -- [ := expression ]
- --
- -- [ LRM93 4.3.1.2 ]
- -- signal_declaration ::=
- -- SIGNAL identifier_list : subtype_information [ signal_kind ]
- -- [ := expression ]
- --
- -- [ LRM93 4.3.1.2 ]
- -- signal_kind ::= REGISTER | BUS
- --
- -- FIXME: file_open_information.
- function Parse_Object_Declaration (Parent : Iir) return Iir
- is
- -- First and last element of the chain to be returned.
- First, Last : Iir;
- Object: Iir;
- Object_Type: Iir;
- Default_Value : Iir;
- Mode: Iir_Mode;
- Signal_Kind : Iir_Signal_Kind;
- Open_Kind : Iir;
- Logical_Name : Iir;
- Kind: Iir_Kind;
- Shared : Boolean;
- Has_Mode : Boolean;
- begin
- Sub_Chain_Init (First, Last);
-
- -- object keyword was just scanned.
- case Current_Token is
- when Tok_Signal =>
- Kind := Iir_Kind_Signal_Declaration;
- when Tok_Constant =>
- Kind := Iir_Kind_Constant_Declaration;
- when Tok_File =>
- Kind := Iir_Kind_File_Declaration;
- when Tok_Variable =>
- Kind := Iir_Kind_Variable_Declaration;
- Shared := False;
- when Tok_Shared =>
- Kind := Iir_Kind_Variable_Declaration;
- Shared := True;
- Scan_Expect (Tok_Variable);
- when others =>
- raise Internal_Error;
- end case;
-
- loop
- -- object or "," was just scanned.
- Object := Create_Iir (Kind);
- if Kind = Iir_Kind_Variable_Declaration then
- Set_Shared_Flag (Object, Shared);
- end if;
- Scan_Expect (Tok_Identifier);
- Set_Identifier (Object, Current_Identifier);
- Set_Location (Object);
- Set_Parent (Object, Parent);
-
- Sub_Chain_Append (First, Last, Object);
-
- Scan;
- exit when Current_Token = Tok_Colon;
- if Current_Token /= Tok_Comma then
- case Current_Token is
- when Tok_Assign =>
- Error_Msg_Parse ("missign type in " & Disp_Name (Kind));
- exit;
- when others =>
- Error_Msg_Parse
- ("',' or ':' is expected after identifier in "
- & Disp_Name (Kind));
- raise Expect_Error;
- end case;
- end if;
- Set_Has_Identifier_List (Object, True);
- end loop;
-
- -- Eat ':'
- Scan;
-
- Object_Type := Parse_Subtype_Indication;
-
- if Kind = Iir_Kind_Signal_Declaration then
- Signal_Kind := Parse_Signal_Kind;
- end if;
-
- if Current_Token = Tok_Assign then
- if Kind = Iir_Kind_File_Declaration then
- Error_Msg_Parse
- ("default expression not allowed for a file declaration");
- end if;
-
- -- Skip ':='.
- Scan;
-
- Default_Value := Parse_Expression;
- else
- Default_Value := Null_Iir;
- end if;
-
- if Kind = Iir_Kind_File_Declaration then
- if Current_Token = Tok_Open then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse
- ("'open' and open kind expression not allowed in vhdl 87");
- end if;
- Scan;
- Open_Kind := Parse_Expression;
- else
- Open_Kind := Null_Iir;
- end if;
-
- -- LRM 4.3.1.4
- -- The default mode is IN, if no mode is specified.
- Mode := Iir_In_Mode;
-
- Logical_Name := Null_Iir;
- Has_Mode := False;
- if Current_Token = Tok_Is then
- -- Skip 'is'.
- Scan;
-
- case Current_Token is
- when Tok_In | Tok_Out | Tok_Inout =>
- if Flags.Vhdl_Std >= Vhdl_93 then
- Error_Msg_Parse ("mode allowed only in vhdl 87");
- end if;
- Mode := Parse_Mode (Iir_In_Mode);
- if Mode = Iir_Inout_Mode then
- Error_Msg_Parse ("inout mode not allowed for file");
- end if;
- Has_Mode := True;
- when others =>
- null;
- end case;
- Logical_Name := Parse_Expression;
- elsif Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("file name expected (vhdl 87)");
- end if;
- end if;
-
- Set_Subtype_Indication (First, Object_Type);
- if Kind /= Iir_Kind_File_Declaration then
- Set_Default_Value (First, Default_Value);
- end if;
-
- Object := First;
- while Object /= Null_Iir loop
- case Kind is
- when Iir_Kind_File_Declaration =>
- Set_Mode (Object, Mode);
- Set_File_Open_Kind (Object, Open_Kind);
- Set_File_Logical_Name (Object, Logical_Name);
- Set_Has_Mode (Object, Has_Mode);
- when Iir_Kind_Signal_Declaration =>
- Set_Signal_Kind (Object, Signal_Kind);
- when others =>
- null;
- end case;
- Set_Is_Ref (Object, Object /= First);
- Object := Get_Chain (Object);
- end loop;
-
- -- ';' is not eaten.
- Expect (Tok_Semi_Colon);
-
- return First;
- end Parse_Object_Declaration;
-
- -- precond : COMPONENT
- -- postcond: ';'
- --
- -- [ §4.5 ]
- -- component_declaration ::=
- -- COMPONENT identifier [ IS ]
- -- [ LOCAL_generic_clause ]
- -- [ LOCAL_port_clause ]
- -- END COMPONENT [ COMPONENT_simple_name ] ;
- function Parse_Component_Declaration
- return Iir_Component_Declaration
- is
- Component: Iir_Component_Declaration;
- begin
- Component := Create_Iir (Iir_Kind_Component_Declaration);
- Scan_Expect (Tok_Identifier,
- "an identifier is expected after 'component'");
- Set_Identifier (Component, Current_Identifier);
- Set_Location (Component);
- Scan;
- if Current_Token = Tok_Is then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("""is"" keyword is not allowed here by vhdl 87");
- end if;
- Set_Has_Is (Component, True);
- Scan;
- end if;
- Parse_Generic_Port_Clauses (Component);
- Check_End_Name (Tok_Component, Component);
- return Component;
- end Parse_Component_Declaration;
-
- -- precond : '['
- -- postcond: next token after ']'
- --
- -- [ 2.3.2 ]
- -- signature ::= [ [ type_mark { , type_mark } ] [ RETURN type_mark ] ]
- function Parse_Signature return Iir_Signature
- is
- Res : Iir_Signature;
- List : Iir_List;
- begin
- Expect (Tok_Left_Bracket);
- Res := Create_Iir (Iir_Kind_Signature);
- Set_Location (Res);
-
- -- Skip '['
- Scan;
-
- -- List of type_marks.
- if Current_Token = Tok_Identifier then
- List := Create_Iir_List;
- Set_Type_Marks_List (Res, List);
- loop
- Append_Element (List, Parse_Type_Mark (Check_Paren => True));
- exit when Current_Token /= Tok_Comma;
- Scan;
- end loop;
- end if;
-
- if Current_Token = Tok_Return then
- -- Skip 'return'
- Scan;
-
- Set_Return_Type_Mark (Res, Parse_Name);
- end if;
-
- -- Skip ']'
- Expect (Tok_Right_Bracket);
- Scan;
-
- return Res;
- end Parse_Signature;
-
- -- precond : ALIAS
- -- postcond: a token
- --
- -- [ LRM93 4.3.3 ]
- -- alias_declaration ::=
- -- ALIAS alias_designator [ : subtype_indication ]
- -- IS name [ signature ] ;
- --
- -- [ LRM93 4.3.3 ]
- -- alias_designator ::= identifier | character_literal | operator_symbol
- --
- -- FIXME: signature is not part of the node.
- function Parse_Alias_Declaration return Iir
- is
- Res: Iir;
- Ident : Name_Id;
- begin
- -- Eat 'alias'.
- Scan;
-
- Res := Create_Iir (Iir_Kind_Object_Alias_Declaration);
- Set_Location (Res);
-
- case Current_Token is
- when Tok_Identifier =>
- Ident := Current_Identifier;
- when Tok_Character =>
- Ident := Current_Identifier;
- when Tok_String =>
- Ident := Scan_To_Operator_Name (Get_Token_Location);
- -- FIXME: vhdl87
- -- FIXME: operator symbol.
- when others =>
- Error_Msg_Parse ("alias designator expected");
- end case;
-
- -- Eat identifier.
- Set_Identifier (Res, Ident);
- Scan;
-
- if Current_Token = Tok_Colon then
- Scan;
- Set_Subtype_Indication (Res, Parse_Subtype_Indication);
- end if;
-
- -- FIXME: nice message if token is ':=' ?
- Expect (Tok_Is);
- Scan;
- Set_Name (Res, Parse_Name);
-
- return Res;
- end Parse_Alias_Declaration;
-
- -- precond : FOR
- -- postcond: ';'
- --
- -- [ §5.2 ]
- -- configuration_specification ::=
- -- FOR component_specification binding_indication ;
- function Parse_Configuration_Specification
- return Iir_Configuration_Specification
- is
- Res : Iir_Configuration_Specification;
- begin
- Res := Create_Iir (Iir_Kind_Configuration_Specification);
- Set_Location (Res);
- Expect (Tok_For);
- Scan;
- Parse_Component_Specification (Res);
- Set_Binding_Indication (Res, Parse_Binding_Indication);
- Expect (Tok_Semi_Colon);
- return Res;
- end Parse_Configuration_Specification;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ § 5.2 ]
- -- entity_class := ENTITY | ARCHITECTURE | CONFIGURATION | PROCEDURE
- -- | FUNCTION | PACKAGE | TYPE | SUBTYPE | CONSTANT
- -- | SIGNAL | VARIABLE | COMPONENT | LABEL | LITERAL
- -- | UNITS | GROUP | FILE
- function Parse_Entity_Class return Token_Type
- is
- Res : Token_Type;
- begin
- case Current_Token is
- when Tok_Entity
- | Tok_Architecture
- | Tok_Configuration
- | Tok_Procedure
- | Tok_Function
- | Tok_Package
- | Tok_Type
- | Tok_Subtype
- | Tok_Constant
- | Tok_Signal
- | Tok_Variable
- | Tok_Component
- | Tok_Label =>
- null;
- when Tok_Literal
- | Tok_Units
- | Tok_Group
- | Tok_File =>
- null;
- when others =>
- Error_Msg_Parse
- (''' & Tokens.Image (Current_Token) & "' is not a entity class");
- end case;
- Res := Current_Token;
- Scan;
- return Res;
- end Parse_Entity_Class;
-
- function Parse_Entity_Class_Entry return Iir_Entity_Class
- is
- Res : Iir_Entity_Class;
- begin
- Res := Create_Iir (Iir_Kind_Entity_Class);
- Set_Location (Res);
- Set_Entity_Class (Res, Parse_Entity_Class);
- return Res;
- end Parse_Entity_Class_Entry;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §5.1 ]
- -- entity_designator ::= entity_tag [ signature ]
- --
- -- entity_tag ::= simple_name | character_literal | operator_symbol
- function Parse_Entity_Designator return Iir
- is
- Res : Iir;
- Name : Iir;
- begin
- case Current_Token is
- when Tok_Identifier =>
- Res := Create_Iir (Iir_Kind_Simple_Name);
- Set_Location (Res);
- Set_Identifier (Res, Current_Identifier);
- when Tok_Character =>
- Res := Create_Iir (Iir_Kind_Character_Literal);
- Set_Location (Res);
- Set_Identifier (Res, Current_Identifier);
- when Tok_String =>
- Res := Create_Iir (Iir_Kind_Operator_Symbol);
- Set_Location (Res);
- Set_Identifier (Res, Scan_To_Operator_Name (Get_Token_Location));
- when others =>
- Error_Msg_Parse ("identifier, character or string expected");
- raise Expect_Error;
- end case;
- Scan;
- if Current_Token = Tok_Left_Bracket then
- Name := Res;
- Res := Parse_Signature;
- Set_Signature_Prefix (Res, Name);
- end if;
- return Res;
- end Parse_Entity_Designator;
-
- -- precond : next token
- -- postcond: IS
- --
- -- [ §5.1 ]
- -- entity_name_list ::= entity_designator { , entity_designator }
- -- | OTHERS
- -- | ALL
- procedure Parse_Entity_Name_List
- (Attribute : Iir_Attribute_Specification)
- is
- List : Iir_List;
- El : Iir;
- begin
- case Current_Token is
- when Tok_All =>
- List := Iir_List_All;
- Scan;
- when Tok_Others =>
- List := Iir_List_Others;
- Scan;
- when others =>
- List := Create_Iir_List;
- loop
- El := Parse_Entity_Designator;
- Append_Element (List, El);
- exit when Current_Token /= Tok_Comma;
- Scan;
- end loop;
- end case;
- Set_Entity_Name_List (Attribute, List);
- if Current_Token = Tok_Colon then
- Scan;
- Set_Entity_Class (Attribute, Parse_Entity_Class);
- else
- Error_Msg_Parse
- ("missing ':' and entity kind in attribute specification");
- end if;
- end Parse_Entity_Name_List;
-
- -- precond : ATTRIBUTE
- -- postcond: ';'
- --
- -- [ 4.4 ]
- -- attribute_declaration ::= ATTRIBUTE identifier : type_mark ;
- --
- -- [ 5.1 ]
- -- attribute_specification ::=
- -- ATTRIBUTE attribute_designator OF entity_specification
- -- IS expression ;
- function Parse_Attribute return Iir
- is
- Loc : Location_Type;
- Ident : Name_Id;
- begin
- Expect (Tok_Attribute);
- Scan_Expect (Tok_Identifier);
- Loc := Get_Token_Location;
- Ident := Current_Identifier;
- Scan;
- case Current_Token is
- when Tok_Colon =>
- declare
- Res : Iir_Attribute_Declaration;
- begin
- Res := Create_Iir (Iir_Kind_Attribute_Declaration);
- Set_Location (Res, Loc);
- Set_Identifier (Res, Ident);
- Scan;
- Set_Type_Mark (Res, Parse_Type_Mark (Check_Paren => True));
- Expect (Tok_Semi_Colon);
- return Res;
- end;
- when Tok_Of =>
- declare
- Res : Iir_Attribute_Specification;
- Designator : Iir_Simple_Name;
- begin
- Res := Create_Iir (Iir_Kind_Attribute_Specification);
- Set_Location (Res, Loc);
- Designator := Create_Iir (Iir_Kind_Simple_Name);
- Set_Location (Designator, Loc);
- Set_Identifier (Designator, Ident);
- Set_Attribute_Designator (Res, Designator);
- Scan;
- Parse_Entity_Name_List (Res);
- Expect (Tok_Is);
- Scan;
- Set_Expression (Res, Parse_Expression);
- Expect (Tok_Semi_Colon);
- return Res;
- end;
- when others =>
- Error_Msg_Parse ("':' or 'of' expected after identifier");
- return Null_Iir;
- end case;
- end Parse_Attribute;
-
- -- precond : GROUP
- -- postcond: ';'
- --
- -- [ §4.6 ]
- -- group_template_declaration ::=
- -- GROUP identifier IS (entity_class_entry_list) ;
- --
- -- entity_class_entry_list ::= entity_class_entry { , entity_class_entry }
- --
- -- entity_class_entry ::= entity_class [ <> ]
- function Parse_Group return Iir is
- Loc : Location_Type;
- Ident : Name_Id;
- begin
- Expect (Tok_Group);
- Scan_Expect (Tok_Identifier);
- Loc := Get_Token_Location;
- Ident := Current_Identifier;
- Scan;
- case Current_Token is
- when Tok_Is =>
- declare
- use Iir_Chains.Entity_Class_Entry_Chain_Handling;
- Res : Iir_Group_Template_Declaration;
- El : Iir_Entity_Class;
- Last : Iir_Entity_Class;
- begin
- Res := Create_Iir (Iir_Kind_Group_Template_Declaration);
- Set_Location (Res, Loc);
- Set_Identifier (Res, Ident);
- Scan_Expect (Tok_Left_Paren);
- Scan;
- Build_Init (Last);
- loop
- Append (Last, Res, Parse_Entity_Class_Entry);
- if Current_Token = Tok_Box then
- El := Create_Iir (Iir_Kind_Entity_Class);
- Set_Location (El);
- Set_Entity_Class (El, Tok_Box);
- Append (Last, Res, El);
- Scan;
- if Current_Token = Tok_Comma then
- Error_Msg_Parse
- ("'<>' is allowed only for the last "
- & "entity class entry");
- end if;
- end if;
- exit when Current_Token = Tok_Right_Paren;
- Expect (Tok_Comma);
- Scan;
- end loop;
- Scan_Expect (Tok_Semi_Colon);
- return Res;
- end;
- when Tok_Colon =>
- declare
- Res : Iir_Group_Declaration;
- List : Iir_Group_Constituent_List;
- begin
- Res := Create_Iir (Iir_Kind_Group_Declaration);
- Set_Location (Res, Loc);
- Set_Identifier (Res, Ident);
- Scan;
- Set_Group_Template_Name
- (Res, Parse_Name (Allow_Indexes => False));
- Expect (Tok_Left_Paren);
- Scan;
- List := Create_Iir_List;
- Set_Group_Constituent_List (Res, List);
- loop
- Append_Element (List, Parse_Name (Allow_Indexes => False));
- exit when Current_Token = Tok_Right_Paren;
- Expect (Tok_Comma);
- Scan;
- end loop;
- Scan_Expect (Tok_Semi_Colon);
- return Res;
- end;
- when others =>
- Error_Msg_Parse ("':' or 'is' expected here");
- return Null_Iir;
- end case;
- end Parse_Group;
-
- -- precond : next token
- -- postcond: ':'
- --
- -- [ §5.4 ]
- -- signal_list ::= signal_name { , signal_name }
- -- | OTHERS
- -- | ALL
- function Parse_Signal_List return Iir_List
- is
- Res : Iir_List;
- begin
- case Current_Token is
- when Tok_Others =>
- Scan;
- return Iir_List_Others;
- when Tok_All =>
- Scan;
- return Iir_List_All;
- when others =>
- Res := Create_Iir_List;
- loop
- Append_Element (Res, Parse_Name);
- exit when Current_Token = Tok_Colon;
- Expect (Tok_Comma);
- Scan;
- end loop;
- return Res;
- end case;
- end Parse_Signal_List;
-
- -- precond : DISCONNECT
- -- postcond: ';'
- --
- -- [ §5.4 ]
- -- disconnection_specification ::=
- -- DISCONNECT guarded_signal_specification AFTER time_expression ;
- function Parse_Disconnection_Specification
- return Iir_Disconnection_Specification
- is
- Res : Iir_Disconnection_Specification;
- begin
- Res := Create_Iir (Iir_Kind_Disconnection_Specification);
- Set_Location (Res);
-
- -- Skip 'disconnect'
- Expect (Tok_Disconnect);
- Scan;
-
- Set_Signal_List (Res, Parse_Signal_List);
-
- -- Skip ':'
- Expect (Tok_Colon);
- Scan;
-
- Set_Type_Mark (Res, Parse_Type_Mark (Check_Paren => True));
-
- -- Skip 'after'
- Expect (Tok_After);
- Scan;
-
- Set_Expression (Res, Parse_Expression);
- return Res;
- end Parse_Disconnection_Specification;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ LRM93 4 ]
- -- declaration ::= type_declaration
- -- | subtype_declaration
- -- | object_declaration
- -- | interface_declaration
- -- | alias_declaration
- -- | attribute_declaration
- -- | component_declaration
- -- | group_template_declaration
- -- | group_declaration
- -- | entity_declaration
- -- | configuration_declaration
- -- | subprogram_declaration
- -- | package_declaration
- procedure Parse_Declarative_Part (Parent : Iir)
- is
- use Declaration_Chain_Handling;
- Last_Decl : Iir;
- Decl : Iir;
- begin
- Build_Init (Last_Decl);
- loop
- Decl := Null_Iir;
- case Current_Token is
- when Tok_Invalid =>
- raise Internal_Error;
- when Tok_Type =>
- Decl := Parse_Type_Declaration (Parent);
-
- -- LRM 2.5 Package declarations
- -- If a package declarative item is a type declaration that is
- -- a full type declaration whose type definition is a
- -- protected_type definition, then that protected type
- -- definition must not be a protected type body.
- if Decl /= Null_Iir
- and then Get_Kind (Decl) = Iir_Kind_Protected_Type_Body
- then
- case Get_Kind (Parent) is
- when Iir_Kind_Package_Declaration =>
- Error_Msg_Parse ("protected type body not allowed "
- & "in package declaration", Decl);
- when others =>
- null;
- end case;
- end if;
- when Tok_Subtype =>
- Decl := Parse_Subtype_Declaration;
- when Tok_Nature =>
- Decl := Parse_Nature_Declaration;
- when Tok_Terminal =>
- Decl := Parse_Terminal_Declaration (Parent);
- when Tok_Quantity =>
- Decl := Parse_Quantity_Declaration (Parent);
- when Tok_Signal =>
- case Get_Kind (Parent) is
- when Iir_Kind_Function_Body
- | Iir_Kind_Procedure_Body =>
- Error_Msg_Parse
- ("signal declaration not allowed in subprogram body");
- when Iir_Kinds_Process_Statement =>
- Error_Msg_Parse
- ("signal declaration not allowed in process");
- when others =>
- null;
- end case;
- Decl := Parse_Object_Declaration (Parent);
- when Tok_Constant =>
- Decl := Parse_Object_Declaration (Parent);
- when Tok_Variable =>
- -- FIXME: remove this message (already checked during sem).
- case Get_Kind (Parent) is
- when Iir_Kind_Entity_Declaration
- | Iir_Kind_Architecture_Body
- | Iir_Kind_Block_Statement
- | Iir_Kind_Package_Declaration
- | Iir_Kind_Package_Body =>
- -- FIXME: replace HERE with the kind of declaration
- -- ie: "not allowed in a package" rather than "here".
- Error_Msg_Parse ("variable declaration not allowed here");
- when others =>
- null;
- end case;
- Decl := Parse_Object_Declaration (Parent);
- when Tok_Shared =>
- if Flags.Vhdl_Std <= Vhdl_87 then
- Error_Msg_Parse ("shared variable not allowed in vhdl 87");
- end if;
- Decl := Parse_Object_Declaration (Parent);
- when Tok_File =>
- Decl := Parse_Object_Declaration (Parent);
- when Tok_Function
- | Tok_Procedure
- | Tok_Pure
- | Tok_Impure =>
- Decl := Parse_Subprogram_Declaration (Parent);
- when Tok_Alias =>
- Decl := Parse_Alias_Declaration;
- when Tok_Component =>
- case Get_Kind (Parent) is
- when Iir_Kind_Entity_Declaration
- | Iir_Kind_Procedure_Body
- | Iir_Kind_Function_Body
- | Iir_Kinds_Process_Statement =>
- Error_Msg_Parse
- ("component declaration are not allowed here");
- when others =>
- null;
- end case;
- Decl := Parse_Component_Declaration;
- when Tok_For =>
- case Get_Kind (Parent) is
- when Iir_Kind_Entity_Declaration
- | Iir_Kind_Function_Body
- | Iir_Kind_Procedure_Body
- | Iir_Kinds_Process_Statement =>
- Error_Msg_Parse
- ("configuration specification not allowed here");
- when others =>
- null;
- end case;
- Decl := Parse_Configuration_Specification;
- when Tok_Attribute =>
- Decl := Parse_Attribute;
- when Tok_Disconnect =>
- case Get_Kind (Parent) is
- when Iir_Kind_Function_Body
- | Iir_Kind_Procedure_Body
- | Iir_Kinds_Process_Statement =>
- Error_Msg_Parse
- ("disconnect specification not allowed here");
- when others =>
- null;
- end case;
- Decl := Parse_Disconnection_Specification;
- when Tok_Use =>
- Decl := Parse_Use_Clause;
- when Tok_Group =>
- Decl := Parse_Group;
-
- when Tok_Identifier =>
- Error_Msg_Parse
- ("object class keyword such as 'variable' is expected");
- Eat_Tokens_Until_Semi_Colon;
- when Tok_Semi_Colon =>
- Error_Msg_Parse ("';' (semi colon) not allowed alone");
- Scan;
- when others =>
- exit;
- end case;
- if Decl /= Null_Iir then
- Append_Subchain (Last_Decl, Parent, Decl);
- end if;
-
- if Current_Token = Tok_Semi_Colon or Current_Token = Tok_Invalid then
- Scan;
- end if;
- end loop;
- end Parse_Declarative_Part;
-
- -- precond : ENTITY
- -- postcond: ';'
- --
- -- [ §1.1 ]
- -- entity_declaration ::=
- -- ENTITY identifier IS
- -- entiy_header
- -- entity_declarative_part
- -- [ BEGIN
- -- entity_statement_part ]
- -- END [ ENTITY ] [ ENTITY_simple_name ]
- --
- -- [ §1.1.1 ]
- -- entity_header ::=
- -- [ FORMAL_generic_clause ]
- -- [ FORMAL_port_clause ]
- procedure Parse_Entity_Declaration (Unit : Iir_Design_Unit)
- is
- Res: Iir_Entity_Declaration;
- begin
- Expect (Tok_Entity);
- Res := Create_Iir (Iir_Kind_Entity_Declaration);
-
- -- Get identifier.
- Scan_Expect (Tok_Identifier,
- "an identifier is expected after ""entity""");
- Set_Identifier (Res, Current_Identifier);
- Set_Location (Res);
-
- Scan_Expect (Tok_Is, "missing ""is"" after identifier");
- Scan;
-
- Parse_Generic_Port_Clauses (Res);
-
- Parse_Declarative_Part (Res);
-
- if Current_Token = Tok_Begin then
- Set_Has_Begin (Res, True);
- Scan;
- Parse_Concurrent_Statements (Res);
- end if;
-
- -- end keyword is expected to finish an entity declaration
- Expect (Tok_End);
- Set_End_Location (Unit);
-
- Scan;
- if Current_Token = Tok_Entity then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("""entity"" keyword not allowed here by vhdl 87");
- end if;
- Set_End_Has_Reserved_Id (Res, True);
- Scan;
- end if;
- Check_End_Name (Res);
- Expect (Tok_Semi_Colon);
- Invalidate_Current_Token;
- Set_Library_Unit (Unit, Res);
- end Parse_Entity_Declaration;
-
- -- [ LRM93 7.3.2 ]
- -- choice ::= simple_expression
- -- | discrete_range
- -- | ELEMENT_simple_name
- -- | OTHERS
- function Parse_A_Choice (Expr: Iir) return Iir
- is
- A_Choice: Iir;
- Expr1: Iir;
- begin
- if Expr = Null_Iir then
- if Current_Token = Tok_Others then
- A_Choice := Create_Iir (Iir_Kind_Choice_By_Others);
- Set_Location (A_Choice);
-
- -- Skip 'others'
- Scan;
-
- return A_Choice;
- else
- Expr1 := Parse_Expression;
-
- if Expr1 = Null_Iir then
- -- Handle parse error now.
- -- FIXME: skip until '=>'.
- A_Choice := Create_Iir (Iir_Kind_Choice_By_Expression);
- Set_Location (A_Choice);
- return A_Choice;
- end if;
- end if;
- else
- Expr1 := Expr;
- end if;
- if Is_Range_Attribute_Name (Expr1) then
- A_Choice := Create_Iir (Iir_Kind_Choice_By_Range);
- Location_Copy (A_Choice, Expr1);
- Set_Choice_Range (A_Choice, Expr1);
- return A_Choice;
- elsif Current_Token = Tok_To or else Current_Token = Tok_Downto then
- A_Choice := Create_Iir (Iir_Kind_Choice_By_Range);
- Location_Copy (A_Choice, Expr1);
- Set_Choice_Range (A_Choice, Parse_Range_Right (Expr1));
- return A_Choice;
- else
- A_Choice := Create_Iir (Iir_Kind_Choice_By_Expression);
- Location_Copy (A_Choice, Expr1);
- Set_Choice_Expression (A_Choice, Expr1);
- return A_Choice;
- end if;
- end Parse_A_Choice;
-
- -- [ LRM93 7.3.2 ]
- -- choices ::= choice { | choice }
- --
- -- Leave tok_double_arrow as current token.
- function Parse_Choices (Expr: Iir) return Iir
- is
- First, Last : Iir;
- A_Choice: Iir;
- Expr1 : Iir;
- begin
- Sub_Chain_Init (First, Last);
- Expr1 := Expr;
- loop
- A_Choice := Parse_A_Choice (Expr1);
- if First /= Null_Iir then
- Set_Same_Alternative_Flag (A_Choice, True);
- if Get_Kind (A_Choice) = Iir_Kind_Choice_By_Others then
- Error_Msg_Parse ("'others' choice must be alone");
- end if;
- end if;
- Sub_Chain_Append (First, Last, A_Choice);
- if Current_Token /= Tok_Bar then
- return First;
- end if;
- Scan;
- Expr1 := Null_Iir;
- end loop;
- end Parse_Choices;
-
- -- precond : '('
- -- postcond: next token
- --
- -- This can be an expression or an aggregate.
- --
- -- [ LRM93 7.3.2 ]
- -- aggregate ::= ( element_association { , element_association } )
- --
- -- [ LRM93 7.3.2 ]
- -- element_association ::= [ choices => ] expression
- function Parse_Aggregate return Iir
- is
- use Iir_Chains.Association_Choices_Chain_Handling;
- Expr: Iir;
- Res: Iir;
- Last : Iir;
- Assoc: Iir;
- Loc : Location_Type;
- begin
- Loc := Get_Token_Location;
-
- -- Skip '('
- Scan;
-
- if Current_Token /= Tok_Others then
- Expr := Parse_Expression;
- case Current_Token is
- when Tok_Comma
- | Tok_Double_Arrow
- | Tok_Bar =>
- -- This is really an aggregate
- null;
- when Tok_Right_Paren =>
- -- This was just a braced expression.
-
- -- Eat ')'.
- Scan;
-
- if Get_Kind (Expr) = Iir_Kind_Aggregate then
- -- Parenthesis around aggregate is useless and change the
- -- context for array aggregate.
- Warning_Msg_Sem
- ("suspicious parenthesis around aggregate", Expr);
- elsif not Flag_Parse_Parenthesis then
- return Expr;
- end if;
-
- -- Create a node for the parenthesis.
- Res := Create_Iir (Iir_Kind_Parenthesis_Expression);
- Set_Location (Res, Loc);
- Set_Expression (Res, Expr);
- return Res;
-
- when Tok_Semi_Colon =>
- -- Surely a missing parenthesis.
- -- FIXME: in case of multiple missing parenthesises, several
- -- messages will be displayed
- Error_Msg_Parse ("missing ')' for opening parenthesis at "
- & Get_Location_Str (Loc, Filename => False));
- return Expr;
- when others =>
- -- Surely a parse error...
- null;
- end case;
- else
- Expr := Null_Iir;
- end if;
- Res := Create_Iir (Iir_Kind_Aggregate);
- Set_Location (Res, Loc);
- Build_Init (Last);
- loop
- if Current_Token = Tok_Others then
- Assoc := Parse_A_Choice (Null_Iir);
- Expect (Tok_Double_Arrow);
- Scan;
- Expr := Parse_Expression;
- else
- if Expr = Null_Iir then
- Expr := Parse_Expression;
- end if;
- if Expr = Null_Iir then
- return Null_Iir;
- end if;
- case Current_Token is
- when Tok_Comma
- | Tok_Right_Paren =>
- Assoc := Create_Iir (Iir_Kind_Choice_By_None);
- Location_Copy (Assoc, Expr);
- when others =>
- Assoc := Parse_Choices (Expr);
- Expect (Tok_Double_Arrow);
- Scan;
- Expr := Parse_Expression;
- end case;
- end if;
- Set_Associated_Expr (Assoc, Expr);
- Append_Subchain (Last, Res, Assoc);
- exit when Current_Token = Tok_Right_Paren;
- Expect (Tok_Comma);
- Scan;
- Expr := Null_Iir;
- end loop;
- Scan;
- return Res;
- end Parse_Aggregate;
-
- -- precond : NEW
- -- postcond: next token
- --
- -- [LRM93 7.3.6]
- -- allocator ::= NEW subtype_indication
- -- | NEW qualified_expression
- function Parse_Allocator return Iir
- is
- Loc: Location_Type;
- Res : Iir;
- Expr: Iir;
- begin
- Loc := Get_Token_Location;
-
- -- Accept 'new'.
- Scan;
- Expr := Parse_Name (Allow_Indexes => False);
- if Get_Kind (Expr) /= Iir_Kind_Qualified_Expression then
- -- This is a subtype_indication.
- Res := Create_Iir (Iir_Kind_Allocator_By_Subtype);
- Expr := Parse_Subtype_Indication (Expr);
- Set_Subtype_Indication (Res, Expr);
- else
- Res := Create_Iir (Iir_Kind_Allocator_By_Expression);
- Set_Expression (Res, Expr);
- end if;
-
- Set_Location (Res, Loc);
- return Res;
- end Parse_Allocator;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §7.1 ]
- -- primary ::= name
- -- | literal
- -- | aggregate
- -- | function_call
- -- | qualified_expression
- -- | type_conversion
- -- | allocator
- -- | ( expression )
- --
- -- [ §7.3.1 ]
- -- literal ::= numeric_literal
- -- | enumeration_literal
- -- | string_literal
- -- | bit_string_literal
- -- | NULL
- --
- -- [ §7.3.1 ]
- -- numeric_literal ::= abstract_literal
- -- | physical_literal
- --
- -- [ §13.4 ]
- -- abstract_literal ::= decimal_literal | based_literal
- --
- -- [ §3.1.3 ]
- -- physical_literal ::= [ abstract_literal ] UNIT_name
- function Parse_Primary return Iir_Expression
- is
- Res: Iir_Expression;
- Int: Iir_Int64;
- Fp: Iir_Fp64;
- Loc: Location_Type;
- begin
- case Current_Token is
- when Tok_Integer =>
- Int := Current_Iir_Int64;
- Loc := Get_Token_Location;
-
- -- Skip integer
- Scan;
-
- if Current_Token = Tok_Identifier then
- -- physical literal
- Res := Create_Iir (Iir_Kind_Physical_Int_Literal);
- Set_Unit_Name (Res, Parse_Name (Allow_Indexes => False));
- else
- -- integer literal
- Res := Create_Iir (Iir_Kind_Integer_Literal);
- end if;
- Set_Location (Res, Loc);
- Set_Value (Res, Int);
- return Res;
-
- when Tok_Real =>
- Fp := Current_Iir_Fp64;
- Loc := Get_Token_Location;
-
- -- Skip real
- Scan;
-
- if Current_Token = Tok_Identifier then
- -- physical literal
- Res := Create_Iir (Iir_Kind_Physical_Fp_Literal);
- Set_Unit_Name (Res, Parse_Name (Allow_Indexes => False));
- else
- -- real literal
- Res := Create_Iir (Iir_Kind_Floating_Point_Literal);
- end if;
- Set_Location (Res, Loc);
- Set_Fp_Value (Res, Fp);
- return Res;
-
- when Tok_Identifier =>
- return Parse_Name (Allow_Indexes => True);
- when Tok_Character =>
- Res := Current_Text;
- Scan;
- if Current_Token = Tok_Tick then
- Error_Msg_Parse
- ("prefix of an attribute can't be a character literal");
- -- skip tick.
- Scan;
- -- skip attribute designator
- Scan;
- end if;
- return Res;
- when Tok_Left_Paren =>
- return Parse_Aggregate;
- when Tok_String =>
- return Parse_Name;
- when Tok_Null =>
- Res := Create_Iir (Iir_Kind_Null_Literal);
- Set_Location (Res);
- Scan;
- return Res;
- when Tok_New =>
- return Parse_Allocator;
- when Tok_Bit_String =>
- Res := Create_Iir (Iir_Kind_Bit_String_Literal);
- Set_Location (Res);
- Set_String_Id (Res, Current_String_Id);
- Set_String_Length (Res, Current_String_Length);
- case Current_Iir_Int64 is
- when 1 =>
- Set_Bit_String_Base (Res, Base_2);
- when 3 =>
- Set_Bit_String_Base (Res, Base_8);
- when 4 =>
- Set_Bit_String_Base (Res, Base_16);
- when others =>
- raise Internal_Error;
- end case;
- Scan;
- return Res;
- when Tok_Minus
- | Tok_Plus =>
- Error_Msg_Parse
- ("'-' and '+' are not allowed in primary, use parenthesis");
- return Parse_Simple_Expression;
- when Tok_Comma
- | Tok_Semi_Colon
- | Tok_Eof
- | Tok_End =>
- -- Token not to be skipped
- Unexpected ("primary");
- return Null_Iir;
- when others =>
- Unexpected ("primary");
- Scan;
- return Null_Iir;
- end case;
- end Parse_Primary;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §7.1 ]
- -- factor ::= primary [ ** primary ]
- -- | ABS primary
- -- | NOT primary
- -- | logical_operator primary [ VHDL08 9.1 ]
- function Build_Unary_Factor (Primary : Iir; Op : Iir_Kind) return Iir is
- Res : Iir;
- begin
- if Primary /= Null_Iir then
- return Primary;
- end if;
- Res := Create_Iir (Op);
- Set_Location (Res);
- Scan;
- Set_Operand (Res, Parse_Primary);
- return Res;
- end Build_Unary_Factor;
-
- function Build_Unary_Factor_08 (Primary : Iir; Op : Iir_Kind) return Iir is
- begin
- if Primary /= Null_Iir then
- return Primary;
- end if;
- if Flags.Vhdl_Std < Vhdl_08 then
- Error_Msg_Parse ("missing left operand of logical expression");
- -- Skip operator
- Scan;
- return Parse_Primary;
- else
- return Build_Unary_Factor (Primary, Op);
- end if;
- end Build_Unary_Factor_08;
-
- function Parse_Factor (Primary : Iir := Null_Iir) return Iir_Expression is
- Res, Left: Iir_Expression;
- begin
- case Current_Token is
- when Tok_Abs =>
- return Build_Unary_Factor (Primary, Iir_Kind_Absolute_Operator);
- when Tok_Not =>
- return Build_Unary_Factor (Primary, Iir_Kind_Not_Operator);
-
- when Tok_And =>
- return Build_Unary_Factor_08
- (Primary, Iir_Kind_Reduction_And_Operator);
- when Tok_Or =>
- return Build_Unary_Factor_08
- (Primary, Iir_Kind_Reduction_Or_Operator);
- when Tok_Nand =>
- return Build_Unary_Factor_08
- (Primary, Iir_Kind_Reduction_Nand_Operator);
- when Tok_Nor =>
- return Build_Unary_Factor_08
- (Primary, Iir_Kind_Reduction_Nor_Operator);
- when Tok_Xor =>
- return Build_Unary_Factor_08
- (Primary, Iir_Kind_Reduction_Xor_Operator);
- when Tok_Xnor =>
- return Build_Unary_Factor_08
- (Primary, Iir_Kind_Reduction_Xnor_Operator);
-
- when others =>
- if Primary /= Null_Iir then
- Left := Primary;
- else
- Left := Parse_Primary;
- end if;
- if Current_Token = Tok_Double_Star then
- Res := Create_Iir (Iir_Kind_Exponentiation_Operator);
- Set_Location (Res);
- Scan;
- Set_Left (Res, Left);
- Set_Right (Res, Parse_Primary);
- return Res;
- else
- return Left;
- end if;
- end case;
- end Parse_Factor;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §7.1 ]
- -- term ::= factor { multiplying_operator factor }
- --
- -- [ §7.2 ]
- -- multiplying_operator ::= * | / | MOD | REM
- function Parse_Term (Primary : Iir) return Iir_Expression is
- Res, Tmp: Iir_Expression;
- begin
- Res := Parse_Factor (Primary);
- while Current_Token in Token_Multiplying_Operator_Type loop
- case Current_Token is
- when Tok_Star =>
- Tmp := Create_Iir (Iir_Kind_Multiplication_Operator);
- when Tok_Slash =>
- Tmp := Create_Iir (Iir_Kind_Division_Operator);
- when Tok_Mod =>
- Tmp := Create_Iir (Iir_Kind_Modulus_Operator);
- when Tok_Rem =>
- Tmp := Create_Iir (Iir_Kind_Remainder_Operator);
- when others =>
- raise Program_Error;
- end case;
- Set_Location (Tmp);
- Set_Left (Tmp, Res);
- Scan;
- Set_Right (Tmp, Parse_Factor);
- Res := Tmp;
- end loop;
- return Res;
- end Parse_Term;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §7.1 ]
- -- simple_expression ::= [ sign ] term { adding_operator term }
- --
- -- [ §7.2 ]
- -- sign ::= + | -
- --
- -- [ §7.2 ]
- -- adding_operator ::= + | - | &
- function Parse_Simple_Expression (Primary : Iir := Null_Iir)
- return Iir_Expression
- is
- Res, Tmp: Iir_Expression;
- begin
- if Current_Token in Token_Sign_Type
- and then Primary = Null_Iir
- then
- case Current_Token is
- when Tok_Plus =>
- Res := Create_Iir (Iir_Kind_Identity_Operator);
- when Tok_Minus =>
- Res := Create_Iir (Iir_Kind_Negation_Operator);
- when others =>
- raise Program_Error;
- end case;
- Set_Location (Res);
- Scan;
- Set_Operand (Res, Parse_Term (Null_Iir));
- else
- Res := Parse_Term (Primary);
- end if;
- while Current_Token in Token_Adding_Operator_Type loop
- case Current_Token is
- when Tok_Plus =>
- Tmp := Create_Iir (Iir_Kind_Addition_Operator);
- when Tok_Minus =>
- Tmp := Create_Iir (Iir_Kind_Substraction_Operator);
- when Tok_Ampersand =>
- Tmp := Create_Iir (Iir_Kind_Concatenation_Operator);
- when others =>
- raise Program_Error;
- end case;
- Set_Location (Tmp);
- Scan;
- Set_Left (Tmp, Res);
- Set_Right (Tmp, Parse_Term (Null_Iir));
- Res := Tmp;
- end loop;
- return Res;
- end Parse_Simple_Expression;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §7.1 ]
- -- shift_expression ::=
- -- simple_expression [ shift_operator simple_expression ]
- --
- -- [ §7.2 ]
- -- shift_operator ::= SLL | SRL | SLA | SRA | ROL | ROR
- function Parse_Shift_Expression return Iir_Expression is
- Res, Tmp: Iir_Expression;
- begin
- Tmp := Parse_Simple_Expression;
- if Current_Token not in Token_Shift_Operator_Type then
- return Tmp;
- elsif Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("shift operators not allowed in vhdl 87");
- end if;
- case Current_Token is
- when Tok_Sll =>
- Res := Create_Iir (Iir_Kind_Sll_Operator);
- when Tok_Sla =>
- Res := Create_Iir (Iir_Kind_Sla_Operator);
- when Tok_Srl =>
- Res := Create_Iir (Iir_Kind_Srl_Operator);
- when Tok_Sra =>
- Res := Create_Iir (Iir_Kind_Sra_Operator);
- when Tok_Rol =>
- Res := Create_Iir (Iir_Kind_Rol_Operator);
- when Tok_Ror =>
- Res := Create_Iir (Iir_Kind_Ror_Operator);
- when others =>
- raise Program_Error;
- end case;
- Set_Location (Res);
- Scan;
- Set_Left (Res, Tmp);
- Set_Right (Res, Parse_Simple_Expression);
- return Res;
- end Parse_Shift_Expression;
-
- -- precond : next token (relational_operator)
- -- postcond: next token
- --
- -- [ §7.1 ]
- -- relational_operator shift_expression
- function Parse_Relation_Rhs (Left : Iir) return Iir
- is
- Res, Tmp: Iir_Expression;
- begin
- Tmp := Left;
-
- -- This loop is just to handle errors such as a = b = c.
- loop
- case Current_Token is
- when Tok_Equal =>
- Res := Create_Iir (Iir_Kind_Equality_Operator);
- when Tok_Not_Equal =>
- Res := Create_Iir (Iir_Kind_Inequality_Operator);
- when Tok_Less =>
- Res := Create_Iir (Iir_Kind_Less_Than_Operator);
- when Tok_Less_Equal =>
- Res := Create_Iir (Iir_Kind_Less_Than_Or_Equal_Operator);
- when Tok_Greater =>
- Res := Create_Iir (Iir_Kind_Greater_Than_Operator);
- when Tok_Greater_Equal =>
- Res := Create_Iir (Iir_Kind_Greater_Than_Or_Equal_Operator);
- when Tok_Match_Equal =>
- Res := Create_Iir (Iir_Kind_Match_Equality_Operator);
- when Tok_Match_Not_Equal =>
- Res := Create_Iir (Iir_Kind_Match_Inequality_Operator);
- when Tok_Match_Less =>
- Res := Create_Iir (Iir_Kind_Match_Less_Than_Operator);
- when Tok_Match_Less_Equal =>
- Res := Create_Iir (Iir_Kind_Match_Less_Than_Or_Equal_Operator);
- when Tok_Match_Greater =>
- Res := Create_Iir (Iir_Kind_Match_Greater_Than_Operator);
- when Tok_Match_Greater_Equal =>
- Res := Create_Iir
- (Iir_Kind_Match_Greater_Than_Or_Equal_Operator);
- when others =>
- raise Program_Error;
- end case;
- Set_Location (Res);
- Scan;
- Set_Left (Res, Tmp);
- Set_Right (Res, Parse_Shift_Expression);
- exit when Current_Token not in Token_Relational_Operator_Type;
- Error_Msg_Parse
- ("use parenthesis for consecutive relational expressions");
- Tmp := Res;
- end loop;
- return Res;
- end Parse_Relation_Rhs;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §7.1 ]
- -- relation ::= shift_expression [ relational_operator shift_expression ]
- --
- -- [ §7.2 ]
- -- relational_operator ::= = | /= | < | <= | > | >=
- -- | ?= | ?/= | ?< | ?<= | ?> | ?>=
- function Parse_Relation return Iir
- is
- Tmp: Iir;
- begin
- Tmp := Parse_Shift_Expression;
- if Current_Token not in Token_Relational_Operator_Type then
- return Tmp;
- end if;
-
- return Parse_Relation_Rhs (Tmp);
- end Parse_Relation;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §7.1 ]
- -- expression ::= relation { AND relation }
- -- | relation { OR relation }
- -- | relation { XOR relation }
- -- | relation [ NAND relation }
- -- | relation [ NOR relation }
- -- | relation { XNOR relation }
- function Parse_Expression_Rhs (Left : Iir) return Iir
- is
- Res, Tmp: Iir;
-
- -- OP_TOKEN contains the operator combinaison.
- Op_Token: Token_Type;
- begin
- Tmp := Left;
- Op_Token := Tok_Invalid;
- loop
- case Current_Token is
- when Tok_And =>
- Res := Create_Iir (Iir_Kind_And_Operator);
- when Tok_Or =>
- Res := Create_Iir (Iir_Kind_Or_Operator);
- when Tok_Xor =>
- Res := Create_Iir (Iir_Kind_Xor_Operator);
- when Tok_Nand =>
- Res := Create_Iir (Iir_Kind_Nand_Operator);
- when Tok_Nor =>
- Res := Create_Iir (Iir_Kind_Nor_Operator);
- when Tok_Xnor =>
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("'xnor' keyword not allowed in vhdl 87");
- end if;
- Res := Create_Iir (Iir_Kind_Xnor_Operator);
- when others =>
- return Tmp;
- end case;
-
- if Op_Token = Tok_Invalid then
- Op_Token := Current_Token;
- else
- -- Check after the case, since current_token may not be an
- -- operator...
- -- TODO: avoid repetition of this message ?
- if Op_Token = Tok_Nand or Op_Token = Tok_Nor then
- Error_Msg_Parse ("sequence of 'nor' or 'nand' not allowed");
- Error_Msg_Parse ("('nor' and 'nand' are not associative)");
- end if;
- if Op_Token /= Current_Token then
- -- Expression is a sequence of relations, with the same
- -- operator.
- Error_Msg_Parse ("only one type of logical operators may be "
- & "used to combine relation");
- end if;
- end if;
-
- Set_Location (Res);
- Scan;
-
- -- Catch errors for Ada programmers.
- if Current_Token = Tok_Then or Current_Token = Tok_Else then
- Error_Msg_Parse ("""or else"" and ""and then"" sequences "
- & "are not allowed in vhdl");
- Error_Msg_Parse ("""and"" and ""or"" are short-circuit "
- & "operators for BIT and BOOLEAN types");
- Scan;
- end if;
-
- Set_Left (Res, Tmp);
- Set_Right (Res, Parse_Relation);
- Tmp := Res;
- end loop;
- end Parse_Expression_Rhs;
-
- -- precond : next token
- -- postcond: next token
- --
- -- LRM08 9.1 General
- -- expression ::= condition_operator primary
- -- | logical_expression
- function Parse_Expression return Iir_Expression
- is
- Res : Iir;
- begin
- if Current_Token = Tok_Condition then
- Res := Create_Iir (Iir_Kind_Condition_Operator);
- Set_Location (Res);
-
- -- Skip '??'
- Scan;
-
- Set_Operand (Res, Parse_Primary);
- else
- Res := Parse_Expression_Rhs (Parse_Relation);
- end if;
-
- return Res;
- end Parse_Expression;
-
- -- precond : next token
- -- postcond: next token.
- --
- -- [ §8.4 ]
- -- waveform ::= waveform_element { , waveform_element }
- -- | UNAFFECTED
- --
- -- [ §8.4.1 ]
- -- waveform_element ::= VALUE_expression [ AFTER TIME_expression ]
- -- | NULL [ AFTER TIME_expression ]
- function Parse_Waveform return Iir_Waveform_Element
- is
- Res: Iir_Waveform_Element;
- We, Last_We : Iir_Waveform_Element;
- begin
- if Current_Token = Tok_Unaffected then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("'unaffected' is not allowed in vhdl87");
- end if;
- Scan;
- return Null_Iir;
- else
- Sub_Chain_Init (Res, Last_We);
- loop
- We := Create_Iir (Iir_Kind_Waveform_Element);
- Sub_Chain_Append (Res, Last_We, We);
- Set_Location (We);
- -- Note: NULL is handled as a null_literal.
- Set_We_Value (We, Parse_Expression);
- if Current_Token = Tok_After then
- Scan;
- Set_Time (We, Parse_Expression);
- end if;
- exit when Current_Token /= Tok_Comma;
- Scan;
- end loop;
- return Res;
- end if;
- end Parse_Waveform;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §8.4 ]
- -- delay_mechanism ::= TRANSPORT
- -- | [ REJECT TIME_expression ] INERTIAL
- procedure Parse_Delay_Mechanism (Assign: Iir) is
- begin
- if Current_Token = Tok_Transport then
- Set_Delay_Mechanism (Assign, Iir_Transport_Delay);
- Scan;
- else
- Set_Delay_Mechanism (Assign, Iir_Inertial_Delay);
- if Current_Token = Tok_Reject then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse
- ("'reject' delay mechanism not allowed in vhdl 87");
- end if;
- Scan;
- Set_Reject_Time_Expression (Assign, Parse_Expression);
- Expect (Tok_Inertial);
- Scan;
- elsif Current_Token = Tok_Inertial then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse
- ("'inertial' keyword not allowed in vhdl 87");
- end if;
- Scan;
- end if;
- end if;
- end Parse_Delay_Mechanism;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §9.5 ]
- -- options ::= [ GUARDED ] [ delay_mechanism ]
- procedure Parse_Options (Stmt : Iir) is
- begin
- if Current_Token = Tok_Guarded then
- Set_Guard (Stmt, Stmt);
- Scan;
- end if;
- Parse_Delay_Mechanism (Stmt);
- end Parse_Options;
-
- -- precond : next tkoen
- -- postcond: ';'
- --
- -- [ §9.5.1 ]
- -- conditional_signal_assignment ::=
- -- target <= options conditional_waveforms ;
- --
- -- [ §9.5.1 ]
- -- conditional_waveforms ::=
- -- { waveform WHEN condition ELSE }
- -- waveform [ WHEN condition ]
- function Parse_Conditional_Signal_Assignment (Target: Iir) return Iir
- is
- use Iir_Chains.Conditional_Waveform_Chain_Handling;
- Res: Iir;
- Cond_Wf, Last_Cond_Wf : Iir_Conditional_Waveform;
- begin
- Res := Create_Iir (Iir_Kind_Concurrent_Conditional_Signal_Assignment);
- Set_Target (Res, Target);
- Location_Copy (Res, Get_Target (Res));
-
- case Current_Token is
- when Tok_Less_Equal =>
- null;
- when Tok_Assign =>
- Error_Msg_Parse ("':=' not allowed in concurrent statement, "
- & "replaced by '<='");
- when others =>
- Expect (Tok_Less_Equal);
- end case;
- Scan;
-
- Parse_Options (Res);
-
- Build_Init (Last_Cond_Wf);
- loop
- Cond_Wf := Create_Iir (Iir_Kind_Conditional_Waveform);
- Append (Last_Cond_Wf, Res, Cond_Wf);
- Set_Location (Cond_Wf);
- Set_Waveform_Chain (Cond_Wf, Parse_Waveform);
- exit when Current_Token /= Tok_When;
- Scan;
- Set_Condition (Cond_Wf, Parse_Expression);
- if Current_Token /= Tok_Else then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("else missing in vhdl 87");
- end if;
- exit;
- end if;
- Scan;
- end loop;
- Expect (Tok_Semi_Colon);
- return Res;
- end Parse_Conditional_Signal_Assignment;
-
- -- precond : WITH
- -- postcond: ';'
- --
- -- [ §9.5.2 ]
- -- selected_signal_assignment ::=
- -- WITH expresion SELECT
- -- target <= options selected_waveforms ;
- --
- -- [ §9.5.2 ]
- -- selected_waveforms ::=
- -- { waveform WHEN choices , }
- -- waveform WHEN choices
- function Parse_Selected_Signal_Assignment return Iir
- is
- use Iir_Chains.Selected_Waveform_Chain_Handling;
- Res: Iir;
- Assoc: Iir;
- Wf_Chain : Iir_Waveform_Element;
- Target : Iir;
- Last : Iir;
- begin
- Scan; -- accept 'with' token.
- Res := Create_Iir (Iir_Kind_Concurrent_Selected_Signal_Assignment);
- Set_Location (Res);
- Set_Expression (Res, Parse_Expression);
-
- Expect (Tok_Select, "'select' expected after expression");
- Scan;
- if Current_Token = Tok_Left_Paren then
- Target := Parse_Aggregate;
- else
- Target := Parse_Name (Allow_Indexes => True);
- end if;
- Set_Target (Res, Target);
- Expect (Tok_Less_Equal);
- Scan;
-
- Parse_Options (Res);
-
- Build_Init (Last);
- loop
- Wf_Chain := Parse_Waveform;
- Expect (Tok_When, "'when' expected after waveform");
- Scan;
- Assoc := Parse_Choices (Null_Iir);
- Set_Associated_Chain (Assoc, Wf_Chain);
- Append_Subchain (Last, Res, Assoc);
- exit when Current_Token = Tok_Semi_Colon;
- Expect (Tok_Comma, "',' (comma) expected after choice");
- Scan;
- end loop;
- return Res;
- end Parse_Selected_Signal_Assignment;
-
- -- precond : next token
- -- postcond: next token.
- --
- -- [ §8.1 ]
- -- sensitivity_list ::= SIGNAL_name { , SIGNAL_name }
- procedure Parse_Sensitivity_List (List: Iir_Designator_List)
- is
- El : Iir;
- begin
- loop
- El := Parse_Name (Allow_Indexes => True);
- case Get_Kind (El) is
- when Iir_Kind_Simple_Name
- | Iir_Kind_Parenthesis_Name
- | Iir_Kind_Selected_Name
- | Iir_Kind_Slice_Name
- | Iir_Kind_Attribute_Name
- | Iir_Kind_Selected_By_All_Name
- | Iir_Kind_Indexed_Name =>
- null;
- when others =>
- Error_Msg_Parse
- ("only names are allowed in a sensitivity list");
- end case;
- Append_Element (List, El);
- exit when Current_Token /= Tok_Comma;
- Scan;
- end loop;
- end Parse_Sensitivity_List;
-
- -- precond : ASSERT
- -- postcond: next token
- -- Note: this fill an sequential or a concurrent statement.
- --
- -- [ §8.2 ]
- -- assertion ::= ASSERT condition
- -- [ REPORT expression ] [ SEVERITY expression ]
- procedure Parse_Assertion (Stmt: Iir) is
- begin
- Set_Location (Stmt);
- Scan;
- Set_Assertion_Condition (Stmt, Parse_Expression);
- if Current_Token = Tok_Report then
- Scan;
- Set_Report_Expression (Stmt, Parse_Expression);
- end if;
- if Current_Token = Tok_Severity then
- Scan;
- Set_Severity_Expression (Stmt, Parse_Expression);
- if Current_Token = Tok_Report then
- -- Nice message in case of inversion.
- Error_Msg_Parse
- ("report expression must precede severity expression");
- Scan;
- Set_Report_Expression (Stmt, Parse_Expression);
- end if;
- end if;
- end Parse_Assertion;
-
- -- precond : REPORT
- -- postcond: next token
- --
- -- [ 8.3 ]
- -- report_statement ::= REPORT expression [ SEVERITY expression ]
- function Parse_Report_Statement return Iir_Report_Statement
- is
- Res : Iir_Report_Statement;
- begin
- Res := Create_Iir (Iir_Kind_Report_Statement);
- Set_Location (Res);
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("report statement not allowed in vhdl87");
- end if;
- Scan;
- Set_Report_Expression (Res, Parse_Expression);
- if Current_Token = Tok_Severity then
- Scan;
- Set_Severity_Expression (Res, Parse_Expression);
- end if;
- return Res;
- end Parse_Report_Statement;
-
- -- precond : WAIT
- -- postcond: ';'
- --
- -- [ §8.1 ]
- -- wait_statement ::=
- -- [ label : ] WAIT [ sensitivity_clause ] [ condition_clause ]
- -- [ timeout_clause ] ;
- --
- -- [ §8.1 ]
- -- sensitivity_clause ::= ON sensitivity_list
- --
- -- [ §8.1 ]
- -- condition_clause ::= UNTIL conditiion
- --
- -- [ §8.1 ]
- -- timeout_clause ::= FOR TIME_expression
- function Parse_Wait_Statement return Iir_Wait_Statement
- is
- Res: Iir_Wait_Statement;
- List: Iir_List;
- begin
- Res := Create_Iir (Iir_Kind_Wait_Statement);
- Set_Location (Res);
- Scan;
- case Current_Token is
- when Tok_On =>
- List := Create_Iir_List;
- Set_Sensitivity_List (Res, List);
- Scan;
- Parse_Sensitivity_List (List);
- when Tok_Until =>
- null;
- when Tok_For =>
- null;
- when Tok_Semi_Colon =>
- return Res;
- when others =>
- Error_Msg_Parse ("'on', 'until', 'for' or ';' expected");
- Eat_Tokens_Until_Semi_Colon;
- return Res;
- end case;
- case Current_Token is
- when Tok_On =>
- Error_Msg_Parse ("only one sensitivity is allowed");
- -- FIXME: sync
- return Res;
- when Tok_Until =>
- Scan;
- Set_Condition_Clause (Res, Parse_Expression);
- when Tok_For =>
- null;
- when Tok_Semi_Colon =>
- return Res;
- when others =>
- Error_Msg_Parse ("'until', 'for' or ';' expected");
- Eat_Tokens_Until_Semi_Colon;
- return Res;
- end case;
- case Current_Token is
- when Tok_On =>
- Error_Msg_Parse ("only one sensitivity clause is allowed");
- -- FIXME: sync
- return Res;
- when Tok_Until =>
- Error_Msg_Parse ("only one condition clause is allowed");
- -- FIXME: sync
- return Res;
- when Tok_For =>
- Scan;
- Set_Timeout_Clause (Res, Parse_Expression);
- return Res;
- when Tok_Semi_Colon =>
- return Res;
- when others =>
- Error_Msg_Parse ("'for' or ';' expected");
- Eat_Tokens_Until_Semi_Colon;
- return Res;
- end case;
- end Parse_Wait_Statement;
-
- -- precond : IF
- -- postcond: next token.
- --
- -- [ §8.7 ]
- -- if_statement ::=
- -- [ IF_label : ]
- -- IF condition THEN
- -- sequence_of_statements
- -- { ELSIF condition THEN
- -- sequence_of_statements }
- -- [ ELSE
- -- sequence_of_statements ]
- -- END IF [ IF_label ] ;
- --
- -- FIXME: end label.
- function Parse_If_Statement (Parent : Iir) return Iir_If_Statement
- is
- Res: Iir_If_Statement;
- Clause: Iir;
- N_Clause: Iir;
- begin
- Res := Create_Iir (Iir_Kind_If_Statement);
- Set_Location (Res);
- Set_Parent (Res, Parent);
- Scan;
- Clause := Res;
- loop
- Set_Condition (Clause, Parse_Expression);
- Expect (Tok_Then, "'then' is expected here");
- Scan;
- Set_Sequential_Statement_Chain
- (Clause, Parse_Sequential_Statements (Res));
- exit when Current_Token = Tok_End;
- N_Clause := Create_Iir (Iir_Kind_Elsif);
- Set_Location (N_Clause);
- Set_Else_Clause (Clause, N_Clause);
- Clause := N_Clause;
- if Current_Token = Tok_Else then
- Scan;
- Set_Sequential_Statement_Chain
- (Clause, Parse_Sequential_Statements (Res));
- exit;
- elsif Current_Token = Tok_Elsif then
- Scan;
- else
- Error_Msg_Parse ("'else' or 'elsif' expected");
- end if;
- end loop;
- Expect (Tok_End);
- Scan_Expect (Tok_If);
- Scan;
- return Res;
- end Parse_If_Statement;
-
- function Parenthesis_Name_To_Procedure_Call (Name: Iir; Kind : Iir_Kind)
- return Iir
- is
- Res: Iir;
- Call : Iir_Procedure_Call;
- begin
- Res := Create_Iir (Kind);
- Location_Copy (Res, Name);
- Call := Create_Iir (Iir_Kind_Procedure_Call);
- Location_Copy (Call, Name);
- Set_Procedure_Call (Res, Call);
- case Get_Kind (Name) is
- when Iir_Kind_Parenthesis_Name =>
- Set_Prefix (Call, Get_Prefix (Name));
- Set_Parameter_Association_Chain
- (Call, Get_Association_Chain (Name));
- Free_Iir (Name);
- when Iir_Kind_Simple_Name
- | Iir_Kind_Selected_Name =>
- Set_Prefix (Call, Name);
- when Iir_Kind_Attribute_Name =>
- Error_Msg_Parse ("attribute cannot be used as procedure call");
- when others =>
- Error_Kind ("parenthesis_name_to_procedure_call", Name);
- end case;
- return Res;
- end Parenthesis_Name_To_Procedure_Call;
-
- -- precond : identifier
- -- postcond: next token
- --
- -- [ LRM93 8.9 ]
- -- parameter_specification ::= identifier IN discrete_range
- function Parse_Parameter_Specification (Parent : Iir)
- return Iir_Iterator_Declaration
- is
- Decl : Iir_Iterator_Declaration;
- begin
- Decl := Create_Iir (Iir_Kind_Iterator_Declaration);
- Set_Location (Decl);
- Set_Parent (Decl, Parent);
-
- Expect (Tok_Identifier);
- Set_Identifier (Decl, Current_Identifier);
-
- -- Skip identifier
- Scan_Expect (Tok_In);
-
- -- Skip 'in'
- Scan;
-
- Set_Discrete_Range (Decl, Parse_Discrete_Range);
- return Decl;
- end Parse_Parameter_Specification;
-
- -- precond: '<='
- -- postcond: next token
- --
- -- [ §8.4 ]
- -- signal_assignment_statement ::=
- -- [ label : ] target <= [ delay_mechanism ] waveform ;
- function Parse_Signal_Assignment_Statement (Target : Iir) return Iir
- is
- Stmt : Iir;
- Wave_Chain : Iir_Waveform_Element;
- begin
- Stmt := Create_Iir (Iir_Kind_Signal_Assignment_Statement);
- Location_Copy (Stmt, Target);
- Set_Target (Stmt, Target);
- Scan;
- Parse_Delay_Mechanism (Stmt);
- Wave_Chain := Parse_Waveform;
- -- LRM 8.4 Signal assignment statement
- -- It is an error is the reserved word UNAFFECTED appears as a
- -- waveform in a (sequential) signa assignment statement.
- if Wave_Chain = Null_Iir then
- Error_Msg_Parse
- ("'unaffected' is not allowed in a sequential statement");
- end if;
- Set_Waveform_Chain (Stmt, Wave_Chain);
- return Stmt;
- end Parse_Signal_Assignment_Statement;
-
- -- precond: ':='
- -- postcond: next token
- --
- -- [ §8.5 ]
- -- variable_assignment_statement ::=
- -- [ label : ] target := expression ;
- function Parse_Variable_Assignment_Statement (Target : Iir) return Iir
- is
- Stmt : Iir;
- begin
- Stmt := Create_Iir (Iir_Kind_Variable_Assignment_Statement);
- Location_Copy (Stmt, Target);
- Set_Target (Stmt, Target);
- Scan;
- Set_Expression (Stmt, Parse_Expression);
- return Stmt;
- end Parse_Variable_Assignment_Statement;
-
- -- precond: next token
- -- postcond: next token
- --
- -- [ 8 ]
- -- sequence_of_statement ::= { sequential_statement }
- --
- -- [ 8 ]
- -- sequential_statement ::= wait_statement
- -- | assertion_statement
- -- | report_statement
- -- | signal_assignment_statement
- -- | variable_assignment_statement
- -- | procedure_call_statement
- -- | if_statement
- -- | case_statement
- -- | loop_statement
- -- | next_statement
- -- | exit_statement
- -- | return_statement
- -- | null_statement
- --
- -- [ 8.13 ]
- -- null_statement ::= [ label : ] NULL ;
- --
- -- [ 8.12 ]
- -- return_statement ::= [ label : ] RETURN [ expression ]
- --
- -- [ 8.10 ]
- -- next_statement ::= [ label : ] NEXT [ LOOP_label ] [ WHEN condition ] ;
- --
- -- [ 8.11 ]
- -- exit_statement ::= [ label : ] EXIT [ LOOP_label ] [ WHEN condition ] ;
- --
- -- [ 8.9 ]
- -- loop_statement ::=
- -- [ LOOP_label : ]
- -- [ iteration_scheme ] LOOP
- -- sequence_of_statements
- -- END LOOP [ LOOP_label ] ;
- --
- -- [ 8.9 ]
- -- iteration_scheme ::= WHILE condition
- -- | FOR LOOP_parameter_specification
- --
- -- [ 8.8 ]
- -- case_statement ::=
- -- [ CASE_label : ]
- -- CASE expression IS
- -- case_statement_alternative
- -- { case_statement_alternative }
- -- END CASE [ CASE_label ] ;
- --
- -- [ 8.8 ]
- -- case_statement_alternative ::= WHEN choices => sequence_of_statements
- --
- -- [ 8.2 ]
- -- assertion_statement ::= [ label : ] assertion ;
- --
- -- [ 8.3 ]
- -- report_statement ::= [ label : ] REPORT expression SEVERITY expression ;
- function Parse_Sequential_Assignment_Statement (Target : Iir) return Iir
- is
- Stmt : Iir;
- Call : Iir;
- begin
- if Current_Token = Tok_Less_Equal then
- return Parse_Signal_Assignment_Statement (Target);
- elsif Current_Token = Tok_Assign then
- return Parse_Variable_Assignment_Statement (Target);
- elsif Current_Token = Tok_Semi_Colon then
- return Parenthesis_Name_To_Procedure_Call
- (Target, Iir_Kind_Procedure_Call_Statement);
- else
- Error_Msg_Parse ("""<="" or "":="" expected instead of "
- & Image (Current_Token));
- Stmt := Create_Iir (Iir_Kind_Procedure_Call_Statement);
- Call := Create_Iir (Iir_Kind_Procedure_Call);
- Set_Prefix (Call, Target);
- Set_Procedure_Call (Stmt, Call);
- Set_Location (Call);
- Eat_Tokens_Until_Semi_Colon;
- return Stmt;
- end if;
- end Parse_Sequential_Assignment_Statement;
-
- function Parse_Sequential_Statements (Parent : Iir)
- return Iir
- is
- First_Stmt : Iir;
- Last_Stmt : Iir;
- Stmt: Iir;
- Label: Name_Id;
- Loc : Location_Type;
- Target : Iir;
- begin
- First_Stmt := Null_Iir;
- Last_Stmt := Null_Iir;
- -- Expect a current_token.
- loop
- Loc := Get_Token_Location;
- if Current_Token = Tok_Identifier then
- Label := Current_Identifier;
- Scan;
- if Current_Token = Tok_Colon then
- Scan;
- else
- Target := Create_Iir (Iir_Kind_Simple_Name);
- Set_Identifier (Target, Label);
- Set_Location (Target, Loc);
- Label := Null_Identifier;
- Target := Parse_Name_Suffix (Target, True);
- Stmt := Parse_Sequential_Assignment_Statement (Target);
- goto Has_Stmt;
- end if;
- else
- Label := Null_Identifier;
- end if;
-
- case Current_Token is
- when Tok_Null =>
- Stmt := Create_Iir (Iir_Kind_Null_Statement);
- Scan;
- when Tok_Assert =>
- Stmt := Create_Iir (Iir_Kind_Assertion_Statement);
- Parse_Assertion (Stmt);
- when Tok_Report =>
- Stmt := Parse_Report_Statement;
- when Tok_If =>
- Stmt := Parse_If_Statement (Parent);
- Set_Label (Stmt, Label);
- Set_Location (Stmt, Loc);
- if Flags.Vhdl_Std >= Vhdl_93c then
- Check_End_Name (Stmt);
- end if;
- when Tok_Identifier
- | Tok_String =>
- -- String for an expanded name with operator_symbol prefix.
- Stmt := Parse_Sequential_Assignment_Statement (Parse_Name);
- when Tok_Left_Paren =>
- declare
- Target : Iir;
- begin
- Target := Parse_Aggregate;
- if Current_Token = Tok_Less_Equal then
- Stmt := Parse_Signal_Assignment_Statement (Target);
- elsif Current_Token = Tok_Assign then
- Stmt := Parse_Variable_Assignment_Statement (Target);
- else
- Error_Msg_Parse ("'<=' or ':=' expected");
- return First_Stmt;
- end if;
- end;
-
- when Tok_Return =>
- Stmt := Create_Iir (Iir_Kind_Return_Statement);
- Scan;
- if Current_Token /= Tok_Semi_Colon then
- Set_Expression (Stmt, Parse_Expression);
- end if;
-
- when Tok_For =>
- Stmt := Create_Iir (Iir_Kind_For_Loop_Statement);
- Set_Location (Stmt, Loc);
- Set_Label (Stmt, Label);
-
- -- Skip 'for'
- Scan;
-
- Set_Parameter_Specification
- (Stmt, Parse_Parameter_Specification (Stmt));
-
- -- Skip 'loop'
- Expect (Tok_Loop);
- Scan;
-
- Set_Sequential_Statement_Chain
- (Stmt, Parse_Sequential_Statements (Stmt));
-
- -- Skip 'end'
- Expect (Tok_End);
- Scan_Expect (Tok_Loop);
-
- -- Skip 'loop'
- Scan;
-
- Check_End_Name (Stmt);
- -- A loop statement can have a label, even in vhdl87.
- Label := Null_Identifier;
-
- when Tok_While
- | Tok_Loop =>
- Stmt := Create_Iir (Iir_Kind_While_Loop_Statement);
- Set_Location (Stmt);
- Set_Label (Stmt, Label);
- if Current_Token = Tok_While then
- Scan;
- Set_Condition (Stmt, Parse_Expression);
- Expect (Tok_Loop);
- end if;
- Scan;
- Set_Sequential_Statement_Chain
- (Stmt, Parse_Sequential_Statements (Stmt));
- Expect (Tok_End);
- Scan_Expect (Tok_Loop);
- Scan;
- Check_End_Name (Stmt);
- -- A loop statement can have a label, even in vhdl87.
- Label := Null_Identifier;
-
- when Tok_Next
- | Tok_Exit =>
- if Current_Token = Tok_Next then
- Stmt := Create_Iir (Iir_Kind_Next_Statement);
- else
- Stmt := Create_Iir (Iir_Kind_Exit_Statement);
- end if;
-
- -- Skip 'next' or 'exit'.
- Scan;
-
- if Current_Token = Tok_Identifier then
- Set_Loop_Label (Stmt, Parse_Name (Allow_Indexes => False));
- end if;
-
- if Current_Token = Tok_When then
- -- Skip 'when'.
- Scan;
-
- Set_Condition (Stmt, Parse_Expression);
- end if;
-
- when Tok_Case =>
- declare
- use Iir_Chains.Case_Statement_Alternative_Chain_Handling;
- Assoc: Iir;
- Last_Assoc : Iir;
- begin
- Stmt := Create_Iir (Iir_Kind_Case_Statement);
- Set_Location (Stmt);
- Set_Label (Stmt, Label);
- Scan;
- Set_Expression (Stmt, Parse_Expression);
- Expect (Tok_Is);
- Scan;
- if Current_Token = Tok_End then
- Error_Msg_Parse ("missing alternative in case statement");
- end if;
- Build_Init (Last_Assoc);
- while Current_Token /= Tok_End loop
- -- Eat 'when'
- Expect (Tok_When);
- Scan;
-
- if Current_Token = Tok_Double_Arrow then
- Error_Msg_Parse ("missing expression in alternative");
- Assoc := Create_Iir (Iir_Kind_Choice_By_Expression);
- Set_Location (Assoc);
- else
- Assoc := Parse_Choices (Null_Iir);
- end if;
-
- -- Eat '=>'
- Expect (Tok_Double_Arrow);
- Scan;
-
- Set_Associated_Chain
- (Assoc, Parse_Sequential_Statements (Stmt));
- Append_Subchain (Last_Assoc, Stmt, Assoc);
- end loop;
-
- -- Eat 'end', 'case'
- Scan_Expect (Tok_Case);
- Scan;
-
- if Flags.Vhdl_Std >= Vhdl_93c then
- Check_End_Name (Stmt);
- end if;
- end;
- when Tok_Wait =>
- Stmt := Parse_Wait_Statement;
- when others =>
- return First_Stmt;
- end case;
- << Has_Stmt >> null;
- Set_Parent (Stmt, Parent);
- Set_Location (Stmt, Loc);
- if Label /= Null_Identifier then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Sem
- ("this statement can't have a label in vhdl 87", Stmt);
- else
- Set_Label (Stmt, Label);
- end if;
- end if;
- Scan_Semi_Colon ("statement");
-
- -- Append it to the chain.
- if First_Stmt = Null_Iir then
- First_Stmt := Stmt;
- else
- Set_Chain (Last_Stmt, Stmt);
- end if;
- Last_Stmt := Stmt;
- end loop;
- end Parse_Sequential_Statements;
-
- -- precond : PROCEDURE, FUNCTION, PURE or IMPURE.
- -- postcond: ';'
- --
- -- [ §2.1 ]
- -- subprogram_declaration ::= subprogram_specification ;
- --
- -- [ §2.1 ]
- -- subprogram_specification ::=
- -- PROCEDURE designator [ ( formal_parameter_list ) ]
- -- | [ PURE | IMPURE ] FUNCTION designator [ ( formal_parameter_list ) ]
- -- RETURN type_mark
- --
- -- [ §2.2 ]
- -- subprogram_body ::=
- -- subprogram_specification IS
- -- subprogram_declarative_part
- -- BEGIN
- -- subprogram_statement_part
- -- END [ subprogram_kind ] [ designator ] ;
- --
- -- [ §2.1 ]
- -- designator ::= identifier | operator_symbol
- --
- -- [ §2.1 ]
- -- operator_symbol ::= string_literal
- function Parse_Subprogram_Declaration (Parent : Iir) return Iir
- is
- Kind : Iir_Kind;
- Inters : Iir;
- Subprg: Iir;
- Subprg_Body : Iir;
- Old : Iir;
- pragma Unreferenced (Old);
- begin
- -- Create the node.
- case Current_Token is
- when Tok_Procedure =>
- Kind := Iir_Kind_Procedure_Declaration;
- when Tok_Function
- | Tok_Pure
- | Tok_Impure =>
- Kind := Iir_Kind_Function_Declaration;
- when others =>
- raise Internal_Error;
- end case;
- Subprg := Create_Iir (Kind);
- Set_Location (Subprg);
-
- case Current_Token is
- when Tok_Procedure =>
- null;
- when Tok_Function =>
- -- LRM93 2.1
- -- A function is impure if its specification contains the
- -- reserved word IMPURE; otherwise it is said to be pure.
- Set_Pure_Flag (Subprg, True);
- when Tok_Pure
- | Tok_Impure =>
- Set_Pure_Flag (Subprg, Current_Token = Tok_Pure);
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse
- ("'pure' and 'impure' are not allowed in vhdl 87");
- end if;
- Set_Has_Pure (Subprg, True);
- -- FIXME: what to do in case of error ??
- -- Eat PURE or IMPURE.
- Scan;
- Expect (Tok_Function, "'function' must follow 'pure' or 'impure'");
- when others =>
- raise Internal_Error;
- end case;
-
- -- Eat PROCEDURE or FUNCTION.
- Scan;
-
- if Current_Token = Tok_Identifier then
- Set_Identifier (Subprg, Current_Identifier);
- Set_Location (Subprg);
- elsif Current_Token = Tok_String then
- if Kind = Iir_Kind_Procedure_Declaration then
- -- LRM93 2.1
- -- A procedure designator is always an identifier.
- Error_Msg_Parse ("a procedure name must be an identifier");
- end if;
- -- LRM93 2.1
- -- A function designator is either an identifier or an operator
- -- symbol.
- Set_Identifier (Subprg, Scan_To_Operator_Name (Get_Token_Location));
- Set_Location (Subprg);
- else
- -- Just to display a parse error.
- Expect (Tok_Identifier);
- end if;
-
- Scan;
- if Current_Token = Tok_Left_Paren then
- -- Parse the interface declaration.
- if Kind = Iir_Kind_Function_Declaration then
- Inters := Parse_Interface_List
- (Function_Parameter_Interface_List, Subprg);
- else
- Inters := Parse_Interface_List
- (Procedure_Parameter_Interface_List, Subprg);
- end if;
- Set_Interface_Declaration_Chain (Subprg, Inters);
- end if;
-
- if Current_Token = Tok_Return then
- if Kind = Iir_Kind_Procedure_Declaration then
- Error_Msg_Parse ("'return' not allowed for a procedure");
- Error_Msg_Parse ("(remove return part or define a function)");
-
- -- Skip 'return'
- Scan;
-
- Old := Parse_Type_Mark;
- else
- -- Skip 'return'
- Scan;
-
- Set_Return_Type_Mark
- (Subprg, Parse_Type_Mark (Check_Paren => True));
- end if;
- else
- if Kind = Iir_Kind_Function_Declaration then
- Error_Msg_Parse ("'return' expected");
- end if;
- end if;
-
- if Current_Token = Tok_Semi_Colon then
- return Subprg;
- end if;
-
- -- The body.
- Set_Has_Body (Subprg, True);
- if Kind = Iir_Kind_Function_Declaration then
- Subprg_Body := Create_Iir (Iir_Kind_Function_Body);
- else
- Subprg_Body := Create_Iir (Iir_Kind_Procedure_Body);
- end if;
- Location_Copy (Subprg_Body, Subprg);
-
- Set_Subprogram_Body (Subprg, Subprg_Body);
- Set_Subprogram_Specification (Subprg_Body, Subprg);
- Set_Chain (Subprg, Subprg_Body);
-
- if Get_Kind (Parent) = Iir_Kind_Package_Declaration then
- Error_Msg_Parse ("subprogram body not allowed in package spec");
- end if;
- Expect (Tok_Is);
- Scan;
- Parse_Declarative_Part (Subprg_Body);
- Expect (Tok_Begin);
- Scan;
- Set_Sequential_Statement_Chain
- (Subprg_Body, Parse_Sequential_Statements (Subprg_Body));
- Expect (Tok_End);
- Scan;
-
- case Current_Token is
- when Tok_Function =>
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("'function' not allowed here by vhdl 87");
- end if;
- if Kind = Iir_Kind_Procedure_Declaration then
- Error_Msg_Parse ("'procedure' expected instead of 'function'");
- end if;
- Set_End_Has_Reserved_Id (Subprg_Body, True);
- Scan;
- when Tok_Procedure =>
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("'procedure' not allowed here by vhdl 87");
- end if;
- if Kind = Iir_Kind_Function_Declaration then
- Error_Msg_Parse ("'function' expected instead of 'procedure'");
- end if;
- Set_End_Has_Reserved_Id (Subprg_Body, True);
- Scan;
- when others =>
- null;
- end case;
- case Current_Token is
- when Tok_Identifier =>
- Check_End_Name (Get_Identifier (Subprg), Subprg_Body);
- when Tok_String =>
- if Scan_To_Operator_Name (Get_Token_Location)
- /= Get_Identifier (Subprg)
- then
- Error_Msg_Parse
- ("mispelling, 'end """ & Image_Identifier (Subprg)
- & """;' expected");
- end if;
- Set_End_Has_Identifier (Subprg_Body, True);
- Scan;
- when others =>
- null;
- end case;
- Expect (Tok_Semi_Colon);
- return Subprg;
- end Parse_Subprogram_Declaration;
-
- -- precond: PROCESS
- -- postcond: null
- --
- -- [ LRM87 9.2 / LRM08 11.3 ]
- -- process_statement ::=
- -- [ PROCESS_label : ]
- -- [ POSTPONED ] PROCESS [ ( process_sensitivity_list ) ] [ IS ]
- -- process_declarative_part
- -- BEGIN
- -- process_statement_part
- -- END [ POSTPONED ] PROCESS [ PROCESS_label ] ;
- --
- -- process_sensitivity_list ::= ALL | sensitivity_list
- function Parse_Process_Statement
- (Label: Name_Id; Loc : Location_Type; Is_Postponed : Boolean)
- return Iir
- is
- Res: Iir;
- Sensitivity_List : Iir_List;
- begin
- -- The PROCESS keyword was just scaned.
- Scan;
-
- if Current_Token = Tok_Left_Paren then
- Res := Create_Iir (Iir_Kind_Sensitized_Process_Statement);
- Scan;
- if Current_Token = Tok_All then
- if Vhdl_Std < Vhdl_08 then
- Error_Msg_Parse
- ("all sensitized process allowed only in vhdl 08");
- end if;
- Sensitivity_List := Iir_List_All;
- Scan;
- else
- Sensitivity_List := Create_Iir_List;
- Parse_Sensitivity_List (Sensitivity_List);
- end if;
- Set_Sensitivity_List (Res, Sensitivity_List);
- Expect (Tok_Right_Paren);
- Scan;
- else
- Res := Create_Iir (Iir_Kind_Process_Statement);
- end if;
-
- Set_Location (Res, Loc);
- Set_Label (Res, Label);
-
- if Current_Token = Tok_Is then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("""is"" not allowed here by vhdl 87");
- end if;
- Set_Has_Is (Res, True);
- Scan;
- end if;
-
- -- declarative part.
- Parse_Declarative_Part (Res);
-
- -- Skip 'begin'.
- Expect (Tok_Begin);
- Scan;
-
- Set_Sequential_Statement_Chain (Res, Parse_Sequential_Statements (Res));
-
- -- Skip 'end'.
- Expect (Tok_End);
- Scan;
-
- if Current_Token = Tok_Postponed then
- if not Is_Postponed then
- -- LRM93 9.2
- -- If the reserved word POSTPONED appears at the end of a process
- -- statement, the process must be a postponed process.
- Error_Msg_Parse ("process is not a postponed process");
- end if;
-
- Set_End_Has_Postponed (Res, True);
-
- -- Skip 'postponed',
- Scan;
- end if;
-
- if Current_Token = Tok_Semi_Colon then
- Error_Msg_Parse ("""end"" must be followed by ""process""");
- else
- Expect (Tok_Process);
- Scan;
- Set_End_Has_Reserved_Id (Res, True);
- Check_End_Name (Res);
- Expect (Tok_Semi_Colon);
- end if;
- return Res;
- end Parse_Process_Statement;
-
- -- precond : NEXT_TOKEN
- -- postcond: NEXT_TOKEN
- --
- -- [ LRM93 4.3.2.2 ]
- -- association_list ::= association_element { , association_element }
- --
- -- [ LRM93 4.3.2.2 ]
- -- association_element ::= [ formal_part => ] actual_part
- --
- -- [ LRM93 4.3.2.2 ]
- -- actual_part ::= actual_designator
- -- | FUNCTION_name ( actual_designator )
- -- | type_mark ( actual_designator )
- --
- -- [ LRM93 4.3.2.2 ]
- -- actual_designator ::= expression
- -- | SIGNAL_name
- -- | VARIABLE_name
- -- | FILE_name
- -- | OPEN
- --
- -- [ LRM93 4.3.2.2 ]
- -- formal_part ::= formal_designator
- -- | FUNCTION_name ( formal_designator )
- -- | type_mark ( formal_designator )
- --
- -- [ LRM93 4.3.2.2 ]
- -- formal_designator ::= GENERIC_name
- -- | PORT_name
- -- | PARAMETER_name
- --
- -- Note: an actual part is parsed as an expression.
- function Parse_Association_List return Iir
- is
- Res, Last: Iir;
- El: Iir;
- Formal: Iir;
- Actual: Iir;
- Nbr_Assocs : Natural;
- Loc : Location_Type;
- begin
- Sub_Chain_Init (Res, Last);
-
- if Current_Token = Tok_Right_Paren then
- Error_Msg_Parse ("empty association list is not allowed");
- return Res;
- end if;
-
- Nbr_Assocs := 1;
- loop
- -- Parse formal and actual.
- Loc := Get_Token_Location;
- Formal := Null_Iir;
-
- if Current_Token /= Tok_Open then
- Actual := Parse_Expression;
- case Current_Token is
- when Tok_To
- | Tok_Downto =>
- -- To/downto can appear in slice name (which are parsed as
- -- function call).
-
- if Actual = Null_Iir then
- -- Left expression is missing ie: (downto x).
- Scan;
- Actual := Parse_Expression;
- else
- Actual := Parse_Range_Expression (Actual);
- end if;
- if Nbr_Assocs /= 1 then
- Error_Msg_Parse ("multi-dimensional slice is forbidden");
- end if;
-
- when Tok_Double_Arrow =>
- Formal := Actual;
-
- -- Skip '=>'
- Scan;
- Loc := Get_Token_Location;
-
- if Current_Token /= Tok_Open then
- Actual := Parse_Expression;
- end if;
-
- when others =>
- null;
- end case;
- end if;
-
- if Current_Token = Tok_Open then
- El := Create_Iir (Iir_Kind_Association_Element_Open);
- Set_Location (El);
-
- -- Skip 'open'
- Scan;
- else
- El := Create_Iir (Iir_Kind_Association_Element_By_Expression);
- Set_Location (El, Loc);
- Set_Actual (El, Actual);
- end if;
- Set_Formal (El, Formal);
-
- Sub_Chain_Append (Res, Last, El);
- exit when Current_Token = Tok_Right_Paren;
- Expect (Tok_Comma);
- Scan;
- Nbr_Assocs := Nbr_Assocs + 1;
- end loop;
-
- return Res;
- end Parse_Association_List;
-
- -- precond : NEXT_TOKEN
- -- postcond: NEXT_TOKEN
- --
- -- Parse: '(' association_list ')'
- function Parse_Association_List_In_Parenthesis return Iir
- is
- Res : Iir;
- begin
- -- Skip '('
- Expect (Tok_Left_Paren);
- Scan;
-
- Res := Parse_Association_List;
-
- -- Skip ')'
- Scan;
-
- return Res;
- end Parse_Association_List_In_Parenthesis;
-
- -- precond : GENERIC
- -- postcond: next token
- --
- -- [ LRM93 5.2.1.2, LRM08 6.5.7.2 ]
- -- generic_map_aspect ::= GENERIC MAP ( GENERIC_association_list )
- function Parse_Generic_Map_Aspect return Iir is
- begin
- Expect (Tok_Generic);
- Scan_Expect (Tok_Map);
- Scan;
- return Parse_Association_List_In_Parenthesis;
- end Parse_Generic_Map_Aspect;
-
- -- precond : PORT
- -- postcond: next token
- --
- -- [ §5.2.1.2 ]
- -- port_map_aspect ::= PORT MAP ( PORT_association_list )
- function Parse_Port_Map_Aspect return Iir is
- begin
- Expect (Tok_Port);
- Scan_Expect (Tok_Map);
- Scan;
- return Parse_Association_List_In_Parenthesis;
- end Parse_Port_Map_Aspect;
-
- -- precond : COMPONENT | ENTIY | CONFIGURATION
- -- postcond : next_token
- --
- -- instantiated_unit ::=
- -- [ COMPONENT ] component_name
- -- ENTITY entity_name [ ( architecture_identifier ) ]
- -- CONFIGURATION configuration_name
- function Parse_Instantiated_Unit return Iir
- is
- Res : Iir;
- begin
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse
- ("component instantiation using keyword 'component', 'entity',");
- Error_Msg_Parse (" or 'configuration' is not allowed in vhdl87");
- end if;
-
- case Current_Token is
- when Tok_Component =>
- Scan;
- return Parse_Name (False);
- when Tok_Entity =>
- Res := Create_Iir (Iir_Kind_Entity_Aspect_Entity);
- Set_Location (Res);
- Scan;
- Set_Entity_Name (Res, Parse_Name (False));
- if Current_Token = Tok_Left_Paren then
- Scan_Expect (Tok_Identifier);
- Set_Architecture (Res, Current_Text);
- Scan_Expect (Tok_Right_Paren);
- Scan;
- end if;
- return Res;
- when Tok_Configuration =>
- Res := Create_Iir (Iir_Kind_Entity_Aspect_Configuration);
- Set_Location (Res);
- Scan_Expect (Tok_Identifier);
- Set_Configuration_Name (Res, Parse_Name (False));
- return Res;
- when others =>
- raise Internal_Error;
- end case;
- end Parse_Instantiated_Unit;
-
- -- precond : next token
- -- postcond: ';'
- --
- -- component_instantiation_statement ::=
- -- INSTANTIATION_label :
- -- instantiated_unit [ generic_map_aspect ] [ port_map_aspect ] ;
- function Parse_Component_Instantiation (Name: Iir)
- return Iir_Component_Instantiation_Statement is
- Res: Iir_Component_Instantiation_Statement;
- begin
- Res := Create_Iir (Iir_Kind_Component_Instantiation_Statement);
- Set_Location (Res);
-
- Set_Instantiated_Unit (Res, Name);
-
- if Current_Token = Tok_Generic then
- Set_Generic_Map_Aspect_Chain (Res, Parse_Generic_Map_Aspect);
- end if;
- if Current_Token = Tok_Port then
- Set_Port_Map_Aspect_Chain (Res, Parse_Port_Map_Aspect);
- end if;
- Expect (Tok_Semi_Colon);
- return Res;
- end Parse_Component_Instantiation;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §9.1 ]
- -- block_header ::= [ generic_clause [ generic_map_aspect ; ] ]
- -- [ port_clause [ port_map_aspect ; ] ]
- function Parse_Block_Header return Iir_Block_Header is
- Res : Iir_Block_Header;
- begin
- Res := Create_Iir (Iir_Kind_Block_Header);
- Set_Location (Res);
- if Current_Token = Tok_Generic then
- Parse_Generic_Clause (Res);
- if Current_Token = Tok_Generic then
- Set_Generic_Map_Aspect_Chain (Res, Parse_Generic_Map_Aspect);
- Scan_Semi_Colon ("generic map aspect");
- end if;
- end if;
- if Current_Token = Tok_Port then
- Parse_Port_Clause (Res);
- if Current_Token = Tok_Port then
- Set_Port_Map_Aspect_Chain (Res, Parse_Port_Map_Aspect);
- Scan_Semi_Colon ("port map aspect");
- end if;
- end if;
- return Res;
- end Parse_Block_Header;
-
- -- precond : BLOCK
- -- postcond: ';'
- --
- -- [ §9.1 ]
- -- block_statement ::=
- -- BLOCK_label :
- -- BLOCK [ ( GUARD_expression ) ] [ IS ]
- -- block_header
- -- block_declarative_part
- -- BEGIN
- -- block_statement_part
- -- END BLOCK [ BLOCK_label ] ;
- --
- -- [ §9.1 ]
- -- block_declarative_part ::= { block_declarative_item }
- --
- -- [ §9.1 ]
- -- block_statement_part ::= { concurrent_statement }
- function Parse_Block_Statement (Label: Name_Id; Loc : Location_Type)
- return Iir_Block_Statement
- is
- Res : Iir_Block_Statement;
- Guard : Iir_Guard_Signal_Declaration;
- begin
- if Label = Null_Identifier then
- Error_Msg_Parse ("a block statement must have a label");
- end if;
-
- -- block was just parsed.
- Res := Create_Iir (Iir_Kind_Block_Statement);
- Set_Location (Res, Loc);
- Set_Label (Res, Label);
- Scan;
- if Current_Token = Tok_Left_Paren then
- Guard := Create_Iir (Iir_Kind_Guard_Signal_Declaration);
- Set_Location (Guard);
- Set_Guard_Decl (Res, Guard);
- Scan;
- Set_Guard_Expression (Guard, Parse_Expression);
- Expect (Tok_Right_Paren, "a ')' is expected after guard expression");
- Scan;
- end if;
- if Current_Token = Tok_Is then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("'is' not allowed here in vhdl87");
- end if;
- Scan;
- end if;
- if Current_Token = Tok_Generic or Current_Token = Tok_Port then
- Set_Block_Header (Res, Parse_Block_Header);
- end if;
- if Current_Token /= Tok_Begin then
- Parse_Declarative_Part (Res);
- end if;
- Expect (Tok_Begin);
- Scan;
- Parse_Concurrent_Statements (Res);
- Check_End_Name (Tok_Block, Res);
- return Res;
- end Parse_Block_Statement;
-
- -- precond : IF or FOR
- -- postcond: ';'
- --
- -- [ LRM93 9.7 ]
- -- generate_statement ::=
- -- GENERATE_label : generation_scheme GENERATE
- -- [ { block_declarative_item }
- -- BEGIN ]
- -- { concurrent_statement }
- -- END GENERATE [ GENERATE_label ] ;
- --
- -- [ LRM93 9.7 ]
- -- generation_scheme ::=
- -- FOR GENERATE_parameter_specification
- -- | IF condition
- --
- -- FIXME: block_declarative item.
- function Parse_Generate_Statement (Label : Name_Id; Loc : Location_Type)
- return Iir_Generate_Statement
- is
- Res : Iir_Generate_Statement;
- begin
- if Label = Null_Identifier then
- Error_Msg_Parse ("a generate statement must have a label");
- end if;
- Res := Create_Iir (Iir_Kind_Generate_Statement);
- Set_Location (Res, Loc);
- Set_Label (Res, Label);
- case Current_Token is
- when Tok_For =>
- Scan;
- Set_Generation_Scheme (Res, Parse_Parameter_Specification (Res));
- when Tok_If =>
- Scan;
- Set_Generation_Scheme (Res, Parse_Expression);
- when others =>
- raise Internal_Error;
- end case;
- Expect (Tok_Generate);
-
- Scan;
- -- Check for a block declarative item.
- case Current_Token is
- when
- -- subprogram_declaration
- -- subprogram_body
- Tok_Procedure
- | Tok_Function
- | Tok_Pure
- | Tok_Impure
- -- type_declaration
- | Tok_Type
- -- subtype_declaration
- | Tok_Subtype
- -- constant_declaration
- | Tok_Constant
- -- signal_declaration
- | Tok_Signal
- -- shared_variable_declaration
- | Tok_Shared
- | Tok_Variable
- -- file_declaration
- | Tok_File
- -- alias_declaration
- | Tok_Alias
- -- component_declaration
- | Tok_Component
- -- attribute_declaration
- -- attribute_specification
- | Tok_Attribute
- -- configuration_specification
- | Tok_For
- -- disconnection_specification
- | Tok_Disconnect
- -- use_clause
- | Tok_Use
- -- group_template_declaration
- -- group_declaration
- | Tok_Group
- | Tok_Begin =>
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse
- ("declarations not allowed in a generate in vhdl87");
- end if;
- Parse_Declarative_Part (Res);
- Expect (Tok_Begin);
- Set_Has_Begin (Res, True);
- Scan;
- when others =>
- null;
- end case;
-
- Parse_Concurrent_Statements (Res);
-
- Expect (Tok_End);
-
- -- Skip 'end'
- Scan_Expect (Tok_Generate);
- Set_End_Has_Reserved_Id (Res, True);
-
- -- Skip 'generate'
- Scan;
-
- -- LRM93 9.7
- -- If a label appears at the end of a generate statement, it must repeat
- -- the generate label.
- Check_End_Name (Res);
- Expect (Tok_Semi_Colon);
- return Res;
- end Parse_Generate_Statement;
-
- -- precond : first token
- -- postcond: END
- --
- -- [ §9 ]
- -- concurrent_statement ::= block_statement
- -- | process_statement
- -- | concurrent_procedure_call_statement
- -- | concurrent_assertion_statement
- -- | concurrent_signal_assignment_statement
- -- | component_instantiation_statement
- -- | generate_statement
- --
- -- [ §9.4 ]
- -- concurrent_assertion_statement ::=
- -- [ label : ] [ POSTPONED ] assertion ;
- --
- -- [ §9.3 ]
- -- concurrent_procedure_call_statement ::=
- -- [ label : ] [ POSTPONED ] procedure_call ;
- --
- -- [ §9.5 ]
- -- concurrent_signal_assignment_statement ::=
- -- [ label : ] [ POSTPONED ] conditional_signal_assignment
- -- | [ label : ] [ POSTPONED ] selected_signal_assignment
- function Parse_Concurrent_Assignment (Target : Iir) return Iir
- is
- Res : Iir;
- begin
- case Current_Token is
- when Tok_Less_Equal
- | Tok_Assign =>
- -- This is a conditional signal assignment.
- -- Error for ':=' is handled by the subprogram.
- return Parse_Conditional_Signal_Assignment (Target);
- when Tok_Semi_Colon =>
- -- a procedure call or a component instantiation.
- -- Parse it as a procedure call, may be revert to a
- -- component instantiation during sem.
- Expect (Tok_Semi_Colon);
- return Parenthesis_Name_To_Procedure_Call
- (Target, Iir_Kind_Concurrent_Procedure_Call_Statement);
- when Tok_Generic | Tok_Port =>
- -- or a component instantiation.
- return Parse_Component_Instantiation (Target);
- when others =>
- -- or a simple simultaneous statement
- if AMS_Vhdl then
- Res := Create_Iir (Iir_Kind_Simple_Simultaneous_Statement);
- Set_Simultaneous_Left (Res, Parse_Simple_Expression (Target));
- if Current_Token /= Tok_Equal_Equal then
- Error_Msg_Parse ("'==' expected after expression");
- else
- Set_Location (Res);
- Scan;
- end if;
- Set_Simultaneous_Right (Res, Parse_Simple_Expression);
- Set_Tolerance (Res, Parse_Tolerance_Aspect_Opt);
- Expect (Tok_Semi_Colon);
- return Res;
- else
- return Parse_Conditional_Signal_Assignment
- (Parse_Simple_Expression (Target));
- end if;
- end case;
- end Parse_Concurrent_Assignment;
-
- function Parse_Psl_Default_Clock return Iir
- is
- Res : Iir;
- begin
- Res := Create_Iir (Iir_Kind_Psl_Default_Clock);
- Scanner.Flag_Psl := True;
- Scan_Expect (Tok_Psl_Clock);
- Scan_Expect (Tok_Is);
- Scan;
- Set_Psl_Boolean (Res, Parse_Psl.Parse_Psl_Boolean);
- Expect (Tok_Semi_Colon);
- Scanner.Flag_Scan_In_Comment := False;
- Scanner.Flag_Psl := False;
- return Res;
- end Parse_Psl_Default_Clock;
-
- function Parse_Psl_Declaration return Iir
- is
- Tok : constant Token_Type := Current_Token;
- Res : Iir;
- begin
- Res := Create_Iir (Iir_Kind_Psl_Declaration);
- Scan;
- if Current_Token /= Tok_Identifier then
- Error_Msg_Parse ("property name expected here");
- else
- Set_Identifier (Res, Current_Identifier);
- end if;
- Scanner.Flag_Psl := True;
- Set_Psl_Declaration (Res, Parse_Psl.Parse_Psl_Declaration (Tok));
- Expect (Tok_Semi_Colon);
- Scanner.Flag_Scan_In_Comment := False;
- Scanner.Flag_Psl := False;
- return Res;
- end Parse_Psl_Declaration;
-
- function Parse_Psl_Assert_Statement return Iir
- is
- Res : Iir;
- begin
- case Current_Token is
- when Tok_Psl_Assert =>
- Res := Create_Iir (Iir_Kind_Psl_Assert_Statement);
- when Tok_Psl_Cover =>
- Res := Create_Iir (Iir_Kind_Psl_Cover_Statement);
- when others =>
- raise Internal_Error;
- end case;
-
- -- Scan extended PSL tokens.
- Scanner.Flag_Psl := True;
-
- -- Skip 'assert'
- Scan;
-
- Set_Psl_Property (Res, Parse_Psl.Parse_Psl_Property);
-
- -- No more PSL tokens after the property.
- Scanner.Flag_Psl := False;
-
- if Current_Token = Tok_Report then
- -- Skip 'report'
- Scan;
-
- Set_Report_Expression (Res, Parse_Expression);
- end if;
-
- if Current_Token = Tok_Severity then
- -- Skip 'severity'
- Scan;
-
- Set_Severity_Expression (Res, Parse_Expression);
- end if;
-
- Expect (Tok_Semi_Colon);
- Scanner.Flag_Scan_In_Comment := False;
- return Res;
- end Parse_Psl_Assert_Statement;
-
- procedure Parse_Concurrent_Statements (Parent : Iir)
- is
- Last_Stmt : Iir;
- Stmt: Iir;
- Label: Name_Id;
- Id: Iir;
- Postponed : Boolean;
- Loc : Location_Type;
- Target : Iir;
-
- procedure Postponed_Not_Allowed is
- begin
- if Postponed then
- Error_Msg_Parse ("'postponed' not allowed here");
- Postponed := False;
- end if;
- end Postponed_Not_Allowed;
- begin
- -- begin was just parsed.
- Last_Stmt := Null_Iir;
- loop
- Stmt := Null_Iir;
- Label := Null_Identifier;
- Postponed := False;
- Loc := Get_Token_Location;
-
- -- Try to find a label.
- if Current_Token = Tok_Identifier then
- Label := Current_Identifier;
- Scan;
- if Current_Token = Tok_Colon then
- -- The identifier is really a label.
- Scan;
- else
- -- This is not a label.
- Target := Create_Iir (Iir_Kind_Simple_Name);
- Set_Location (Target, Loc);
- Set_Identifier (Target, Label);
- Label := Null_Identifier;
- Target := Parse_Name_Suffix (Target);
- Stmt := Parse_Concurrent_Assignment (Target);
- goto Has_Stmt;
- end if;
- end if;
-
- if Current_Token = Tok_Postponed then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("'postponed' is not allowed in vhdl 87");
- else
- Postponed := True;
- end if;
- Scan;
- end if;
-
- case Current_Token is
- when Tok_End =>
- Postponed_Not_Allowed;
- if Label /= Null_Identifier then
- Error_Msg_Parse
- ("no label is allowed before the 'end' keyword");
- end if;
- return;
- when Tok_Identifier =>
- Target := Parse_Name (Allow_Indexes => True);
- Stmt := Parse_Concurrent_Assignment (Target);
- if Get_Kind (Stmt) = Iir_Kind_Component_Instantiation_Statement
- and then Postponed
- then
- Error_Msg_Parse ("'postponed' not allowed for " &
- "an instantiation statement");
- Postponed := False;
- end if;
- when Tok_Left_Paren =>
- Id := Parse_Aggregate;
- if Current_Token = Tok_Less_Equal then
- -- This is a conditional signal assignment.
- Stmt := Parse_Conditional_Signal_Assignment (Id);
- else
- Error_Msg_Parse ("'<=' expected after aggregate");
- Eat_Tokens_Until_Semi_Colon;
- end if;
- when Tok_Process =>
- Stmt := Parse_Process_Statement (Label, Loc, Postponed);
- when Tok_Assert =>
- Stmt := Create_Iir (Iir_Kind_Concurrent_Assertion_Statement);
- Parse_Assertion (Stmt);
- Expect (Tok_Semi_Colon);
- when Tok_With =>
- Stmt := Parse_Selected_Signal_Assignment;
- when Tok_Block =>
- Postponed_Not_Allowed;
- Stmt := Parse_Block_Statement (Label, Loc);
- when Tok_If
- | Tok_For =>
- if Postponed then
- Error_Msg_Parse
- ("'postponed' not allowed before a generate statement");
- Postponed := False;
- end if;
- Stmt := Parse_Generate_Statement (Label, Loc);
- when Tok_Eof =>
- Error_Msg_Parse ("unexpected end of file, 'END;' expected");
- return;
- when Tok_Component
- | Tok_Entity
- | Tok_Configuration =>
- Postponed_Not_Allowed;
- declare
- Unit : Iir;
- begin
- Unit := Parse_Instantiated_Unit;
- Stmt := Parse_Component_Instantiation (Unit);
- end;
- when Tok_Psl_Default =>
- Postponed_Not_Allowed;
- Stmt := Parse_Psl_Default_Clock;
- when Tok_Psl_Property
- | Tok_Psl_Sequence
- | Tok_Psl_Endpoint =>
- Postponed_Not_Allowed;
- Stmt := Parse_Psl_Declaration;
- when Tok_Psl_Assert
- | Tok_Psl_Cover =>
- Postponed_Not_Allowed;
- Stmt := Parse_Psl_Assert_Statement;
- when others =>
- -- FIXME: improve message:
- -- instead of 'unexpected token 'signal' in conc stmt list'
- -- report: 'signal declarations are not allowed in conc stmt'
- Unexpected ("concurrent statement list");
- Eat_Tokens_Until_Semi_Colon;
- end case;
-
- << Has_Stmt >> null;
-
- -- stmt can be null in case of error.
- if Stmt /= Null_Iir then
- Set_Location (Stmt, Loc);
- if Label /= Null_Identifier then
- Set_Label (Stmt, Label);
- end if;
- Set_Parent (Stmt, Parent);
- if Postponed then
- Set_Postponed_Flag (Stmt, True);
- end if;
- -- Append it to the chain.
- if Last_Stmt = Null_Iir then
- Set_Concurrent_Statement_Chain (Parent, Stmt);
- else
- Set_Chain (Last_Stmt, Stmt);
- end if;
- Last_Stmt := Stmt;
- end if;
-
- Scan;
- end loop;
- end Parse_Concurrent_Statements;
-
- -- precond : LIBRARY
- -- postcond: ;
- --
- -- [ LRM93 11.2 ]
- -- library_clause ::= LIBRARY logical_name_list
- function Parse_Library_Clause return Iir
- is
- First, Last : Iir;
- Library: Iir_Library_Clause;
- begin
- Sub_Chain_Init (First, Last);
- Expect (Tok_Library);
- loop
- Library := Create_Iir (Iir_Kind_Library_Clause);
-
- -- Skip 'library' or ','.
- Scan_Expect (Tok_Identifier);
-
- Set_Identifier (Library, Current_Identifier);
- Set_Location (Library);
- Sub_Chain_Append (First, Last, Library);
-
- -- Skip identifier.
- Scan;
-
- exit when Current_Token = Tok_Semi_Colon;
- Expect (Tok_Comma);
-
- Set_Has_Identifier_List (Library, True);
- end loop;
-
- -- Skip ';'.
- Scan;
- return First;
- end Parse_Library_Clause;
-
- -- precond : USE
- -- postcond: ;
- --
- -- [ §10.4 ]
- -- use_clause ::= USE selected_name { , selected_name }
- --
- -- FIXME: should be a list.
- function Parse_Use_Clause return Iir_Use_Clause
- is
- Use_Clause: Iir_Use_Clause;
- First, Last : Iir;
- begin
- First := Null_Iir;
- Last := Null_Iir;
- Scan;
- loop
- Use_Clause := Create_Iir (Iir_Kind_Use_Clause);
- Set_Location (Use_Clause);
- Expect (Tok_Identifier);
- Set_Selected_Name (Use_Clause, Parse_Name);
-
- -- Chain use clauses.
- if First = Null_Iir then
- First := Use_Clause;
- else
- Set_Use_Clause_Chain (Last, Use_Clause);
- end if;
- Last := Use_Clause;
-
- exit when Current_Token = Tok_Semi_Colon;
- Expect (Tok_Comma);
- Scan;
- end loop;
- return First;
- end Parse_Use_Clause;
-
- -- precond : ARCHITECTURE
- -- postcond: ';'
- --
- -- [ §1.2 ]
- -- architecture_body ::=
- -- ARCHITECTURE identifier OF ENTITY_name IS
- -- architecture_declarative_part
- -- BEGIN
- -- architecture_statement_part
- -- END [ ARCHITECTURE ] [ ARCHITECTURE_simple_name ] ;
- procedure Parse_Architecture_Body (Unit : Iir_Design_Unit)
- is
- Res: Iir_Architecture_Body;
- begin
- Expect (Tok_Architecture);
- Res := Create_Iir (Iir_Kind_Architecture_Body);
-
- -- Get identifier.
- Scan_Expect (Tok_Identifier);
- Set_Identifier (Res, Current_Identifier);
- Set_Location (Res);
- Scan;
- if Current_Token = Tok_Is then
- Error_Msg_Parse ("architecture identifier is missing");
- else
- Expect (Tok_Of);
- Scan;
- Set_Entity_Name (Res, Parse_Name (False));
- Expect (Tok_Is);
- end if;
-
- Scan;
- Parse_Declarative_Part (Res);
-
- Expect (Tok_Begin);
- Scan;
- Parse_Concurrent_Statements (Res);
- -- end was scanned.
- Set_End_Location (Unit);
- Scan;
- if Current_Token = Tok_Architecture then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse
- ("'architecture' keyword not allowed here by vhdl 87");
- end if;
- Set_End_Has_Reserved_Id (Res, True);
- Scan;
- end if;
- Check_End_Name (Res);
- Expect (Tok_Semi_Colon);
- Set_Library_Unit (Unit, Res);
- end Parse_Architecture_Body;
-
- -- precond : next token
- -- postcond: a token
- --
- -- [ §5.2 ]
- -- instantiation_list ::= INSTANTIATION_label { , INSTANTIATION_label }
- -- | OTHERS
- -- | ALL
- function Parse_Instantiation_List return Iir_List
- is
- Res : Iir_List;
- begin
- case Current_Token is
- when Tok_All =>
- Scan;
- return Iir_List_All;
- when Tok_Others =>
- Scan;
- return Iir_List_Others;
- when Tok_Identifier =>
- Res := Create_Iir_List;
- loop
- Append_Element (Res, Current_Text);
- Scan;
- exit when Current_Token /= Tok_Comma;
- Expect (Tok_Comma);
- Scan;
- end loop;
- return Res;
- when others =>
- Error_Msg_Parse ("instantiation list expected");
- return Null_Iir_List;
- end case;
- end Parse_Instantiation_List;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §5.2 ]
- -- component_specification ::= instantiation_list : COMPONENT_name
- procedure Parse_Component_Specification (Res : Iir)
- is
- List : Iir_List;
- begin
- List := Parse_Instantiation_List;
- Set_Instantiation_List (Res, List);
- Expect (Tok_Colon);
- Scan_Expect (Tok_Identifier);
- Set_Component_Name (Res, Parse_Name);
- end Parse_Component_Specification;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §5.2.1.1 ]
- -- entity_aspect ::= ENTITY ENTITY_name [ ( ARCHITECTURE_identifier ) ]
- -- | CONFIGURATION CONFIGURATION_name
- -- | OPEN
- function Parse_Entity_Aspect return Iir
- is
- Res : Iir;
- begin
- case Current_Token is
- when Tok_Entity =>
- Res := Create_Iir (Iir_Kind_Entity_Aspect_Entity);
- Set_Location (Res);
- Scan_Expect (Tok_Identifier);
- Set_Entity_Name (Res, Parse_Name (False));
- if Current_Token = Tok_Left_Paren then
- Scan_Expect (Tok_Identifier);
- Set_Architecture (Res, Current_Text);
- Scan_Expect (Tok_Right_Paren);
- Scan;
- end if;
- when Tok_Configuration =>
- Res := Create_Iir (Iir_Kind_Entity_Aspect_Configuration);
- Set_Location (Res);
- Scan_Expect (Tok_Identifier);
- Set_Configuration_Name (Res, Parse_Name (False));
- when Tok_Open =>
- Res := Create_Iir (Iir_Kind_Entity_Aspect_Open);
- Set_Location (Res);
- Scan;
- when others =>
- -- FIXME: if the token is an identifier, try as if the 'entity'
- -- keyword is missing.
- Error_Msg_Parse
- ("'entity', 'configuration' or 'open' keyword expected");
- end case;
- return Res;
- end Parse_Entity_Aspect;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [ §5.2.1 ]
- -- binding_indication ::=
- -- [ USE entity_aspect ]
- -- [ generic_map_aspect ]
- -- [ port_map_aspect ]
- function Parse_Binding_Indication return Iir_Binding_Indication
- is
- Res : Iir_Binding_Indication;
- begin
- case Current_Token is
- when Tok_Use
- | Tok_Generic
- | Tok_Port =>
- null;
- when others =>
- return Null_Iir;
- end case;
- Res := Create_Iir (Iir_Kind_Binding_Indication);
- Set_Location (Res);
- if Current_Token = Tok_Use then
- Scan;
- Set_Entity_Aspect (Res, Parse_Entity_Aspect);
- end if;
- if Current_Token = Tok_Generic then
- Set_Generic_Map_Aspect_Chain (Res, Parse_Generic_Map_Aspect);
- end if;
- if Current_Token = Tok_Port then
- Set_Port_Map_Aspect_Chain (Res, Parse_Port_Map_Aspect);
- end if;
- return Res;
- end Parse_Binding_Indication;
-
- -- precond : ':' after instantiation_list.
- -- postcond: ';'
- --
- -- [ §1.3.2 ]
- -- component_configuration ::=
- -- FOR component_specification
- -- [ binding_indication ; ]
- -- [ block_configuration ]
- -- END FOR ;
- function Parse_Component_Configuration (Loc : Location_Type;
- Inst_List : Iir_List)
- return Iir_Component_Configuration
- is
- Res : Iir_Component_Configuration;
- begin
- Res := Create_Iir (Iir_Kind_Component_Configuration);
- Set_Location (Res, Loc);
-
- -- Component specification.
- Set_Instantiation_List (Res, Inst_List);
- Expect (Tok_Colon);
- Scan_Expect (Tok_Identifier);
- Set_Component_Name (Res, Parse_Name);
-
- case Current_Token is
- when Tok_Use
- | Tok_Generic
- | Tok_Port =>
- Set_Binding_Indication (Res, Parse_Binding_Indication);
- Scan_Semi_Colon ("binding indication");
- when others =>
- null;
- end case;
- if Current_Token = Tok_For then
- Set_Block_Configuration (Res, Parse_Block_Configuration);
- -- Eat ';'.
- Scan;
- end if;
- Expect (Tok_End);
- Scan_Expect (Tok_For);
- Scan_Expect (Tok_Semi_Colon);
- return Res;
- end Parse_Component_Configuration;
-
- -- precond : FOR
- -- postcond: ';'
- --
- -- [ §1.3.1 ]
- -- block_configuration ::=
- -- FOR block_specification
- -- { use_clause }
- -- { configuration_item }
- -- END FOR ;
- --
- -- [ §1.3.1 ]
- -- block_specification ::=
- -- ARCHITECTURE_name
- -- | BLOCK_STATEMENT_label
- -- | GENERATE_STATEMENT_label [ ( index_specification ) ]
- function Parse_Block_Configuration_Suffix (Loc : Location_Type;
- Block_Spec : Iir)
- return Iir
- is
- Res : Iir_Block_Configuration;
- begin
- Res := Create_Iir (Iir_Kind_Block_Configuration);
- Set_Location (Res, Loc);
-
- Set_Block_Specification (Res, Block_Spec);
-
- -- Parse use clauses.
- if Current_Token = Tok_Use then
- declare
- Last : Iir;
- use Declaration_Chain_Handling;
- begin
- Build_Init (Last);
-
- while Current_Token = Tok_Use loop
- Append_Subchain (Last, Res, Parse_Use_Clause);
- -- Eat ';'.
- Scan;
- end loop;
- end;
- end if;
-
- -- Parse configuration item list
- declare
- use Iir_Chains.Configuration_Item_Chain_Handling;
- Last : Iir;
- begin
- Build_Init (Last);
- while Current_Token /= Tok_End loop
- Append (Last, Res, Parse_Configuration_Item);
- -- Eat ';'.
- Scan;
- end loop;
- end;
- Scan_Expect (Tok_For);
- Scan_Expect (Tok_Semi_Colon);
- return Res;
- end Parse_Block_Configuration_Suffix;
-
- function Parse_Block_Configuration return Iir_Block_Configuration
- is
- Loc : Location_Type;
- begin
- Loc := Get_Token_Location;
- Expect (Tok_For);
-
- -- Parse label.
- Scan;
- return Parse_Block_Configuration_Suffix (Loc, Parse_Name);
- end Parse_Block_Configuration;
-
- -- precond : FOR
- -- postcond: ';'
- --
- -- [ §1.3.1 ]
- -- configuration_item ::= block_configuration
- -- | component_configuration
- function Parse_Configuration_Item return Iir
- is
- Loc : Location_Type;
- List : Iir_List;
- El : Iir;
- begin
- Loc := Get_Token_Location;
- Expect (Tok_For);
- Scan;
-
- -- ALL and OTHERS are tokens from an instantiation list.
- -- Thus, the rule is a component_configuration.
- case Current_Token is
- when Tok_All =>
- Scan;
- return Parse_Component_Configuration (Loc, Iir_List_All);
- when Tok_Others =>
- Scan;
- return Parse_Component_Configuration (Loc, Iir_List_Others);
- when Tok_Identifier =>
- El := Current_Text;
- Scan;
- case Current_Token is
- when Tok_Colon =>
- -- The identifier was a label from an instantiation list.
- List := Create_Iir_List;
- Append_Element (List, El);
- return Parse_Component_Configuration (Loc, List);
- when Tok_Comma =>
- -- The identifier was a label from an instantiation list.
- List := Create_Iir_List;
- Append_Element (List, El);
- loop
- Scan_Expect (Tok_Identifier);
- Append_Element (List, Current_Text);
- Scan;
- exit when Current_Token /= Tok_Comma;
- end loop;
- return Parse_Component_Configuration (Loc, List);
- when Tok_Left_Paren =>
- El := Parse_Name_Suffix (El);
- return Parse_Block_Configuration_Suffix (Loc, El);
- when Tok_Use | Tok_For | Tok_End =>
- -- Possibilities for a block_configuration.
- -- FIXME: should use 'when others' ?
- return Parse_Block_Configuration_Suffix (Loc, El);
- when others =>
- Error_Msg_Parse
- ("block_configuration or component_configuration "
- & "expected");
- raise Parse_Error;
- end case;
- when others =>
- Error_Msg_Parse ("configuration item expected");
- raise Parse_Error;
- end case;
- end Parse_Configuration_Item;
-
- -- precond : next token
- -- postcond: next token
- --
- -- [§ 1.3]
- -- configuration_declarative_part ::= { configuration_declarative_item }
- --
- -- [§ 1.3]
- -- configuration_declarative_item ::= use_clause
- -- | attribute_specification
- -- | group_declaration
- -- FIXME: attribute_specification, group_declaration
- procedure Parse_Configuration_Declarative_Part (Parent : Iir)
- is
- use Declaration_Chain_Handling;
- Last : Iir;
- El : Iir;
- begin
- Build_Init (Last);
- loop
- case Current_Token is
- when Tok_Invalid =>
- raise Internal_Error;
- when Tok_Use =>
- Append_Subchain (Last, Parent, Parse_Use_Clause);
- when Tok_Attribute =>
- El := Parse_Attribute;
- if El /= Null_Iir then
- if Get_Kind (El) /= Iir_Kind_Attribute_Specification then
- Error_Msg_Parse
- ("attribute declaration not allowed here");
- end if;
- Append (Last, Parent, El);
- end if;
- when Tok_Group =>
- El := Parse_Group;
- if El /= Null_Iir then
- if Get_Kind (El) /= Iir_Kind_Group_Declaration then
- Error_Msg_Parse
- ("group template declaration not allowed here");
- end if;
- Append (Last, Parent, El);
- end if;
- when others =>
- exit;
- end case;
- Scan;
- end loop;
- end Parse_Configuration_Declarative_Part;
-
- -- precond : CONFIGURATION
- -- postcond: ';'
- --
- -- [ LRM93 1.3 ]
- -- configuration_declaration ::=
- -- CONFIGURATION identifier OF ENTITY_name IS
- -- configuration_declarative_part
- -- block_configuration
- -- END [ CONFIGURATION ] [ CONFIGURATION_simple_name ] ;
- --
- -- [ LRM93 1.3 ]
- -- configuration_declarative_part ::= { configuration_declarative_item }
- procedure Parse_Configuration_Declaration (Unit : Iir_Design_Unit)
- is
- Res : Iir_Configuration_Declaration;
- begin
- if Current_Token /= Tok_Configuration then
- raise Program_Error;
- end if;
- Res := Create_Iir (Iir_Kind_Configuration_Declaration);
-
- -- Get identifier.
- Scan_Expect (Tok_Identifier);
- Set_Identifier (Res, Current_Identifier);
- Set_Location (Res);
-
- -- Skip identifier.
- Scan_Expect (Tok_Of);
-
- -- Skip 'of'.
- Scan;
-
- Set_Entity_Name (Res, Parse_Name (False));
-
- -- Skip 'is'.
- Expect (Tok_Is);
- Scan;
-
- Parse_Configuration_Declarative_Part (Res);
-
- Set_Block_Configuration (Res, Parse_Block_Configuration);
-
- Scan_Expect (Tok_End);
- Set_End_Location (Unit);
-
- -- Skip 'end'.
- Scan;
-
- if Current_Token = Tok_Configuration then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse
- ("'configuration' keyword not allowed here by vhdl 87");
- end if;
- Set_End_Has_Reserved_Id (Res, True);
-
- -- Skip 'configuration'.
- Scan;
- end if;
-
- -- LRM93 1.3
- -- If a simple name appears at the end of a configuration declaration, it
- -- must repeat the identifier of the configuration declaration.
- Check_End_Name (Res);
- Expect (Tok_Semi_Colon);
- Set_Library_Unit (Unit, Res);
- end Parse_Configuration_Declaration;
-
- -- precond : generic
- -- postcond: next token
- --
- -- LRM08 4.7
- -- package_header ::=
- -- [ generic_clause -- LRM08 6.5.6.2
- -- [ generic_map aspect ; ] ]
- function Parse_Package_Header return Iir
- is
- Res : Iir;
- begin
- Res := Create_Iir (Iir_Kind_Package_Header);
- Parse_Generic_Clause (Res);
-
- if Current_Token = Tok_Generic then
- Set_Generic_Map_Aspect_Chain (Res, Parse_Generic_Map_Aspect);
- Scan_Semi_Colon ("generic map aspect");
- end if;
- return Res;
- end Parse_Package_Header;
-
- -- precond : token (after 'IS')
- -- postcond: ';'
- --
- -- [ LRM93 2.5, LRM08 4.7 ]
- -- package_declaration ::=
- -- PACKAGE identifier IS
- -- package_header -- LRM08
- -- package_declarative_part
- -- END [ PACKAGE ] [ PACKAGE_simple_name ] ;
- procedure Parse_Package_Declaration
- (Unit : Iir_Design_Unit; Id : Name_Id; Loc : Location_Type)
- is
- Res: Iir_Package_Declaration;
- begin
- Res := Create_Iir (Iir_Kind_Package_Declaration);
- Set_Location (Res, Loc);
- Set_Identifier (Res, Id);
-
- if Current_Token = Tok_Generic then
- if Vhdl_Std < Vhdl_08 then
- Error_Msg_Parse ("generic packages not allowed before vhdl 2008");
- end if;
- Set_Package_Header (Res, Parse_Package_Header);
- end if;
-
- Parse_Declarative_Part (Res);
-
- Expect (Tok_End);
- Set_End_Location (Unit);
-
- -- Skip 'end'
- Scan;
-
- if Current_Token = Tok_Package then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("'package' keyword not allowed here by vhdl 87");
- end if;
- Set_End_Has_Reserved_Id (Res, True);
-
- -- Skip 'package'.
- Scan;
- end if;
-
- Check_End_Name (Res);
- Expect (Tok_Semi_Colon);
- Set_Library_Unit (Unit, Res);
- end Parse_Package_Declaration;
-
- -- precond : BODY
- -- postcond: ';'
- --
- -- [ LRM93 2.6, LRM08 4.8 ]
- -- package_body ::=
- -- PACKAGE BODY PACKAGE_simple_name IS
- -- package_body_declarative_part
- -- END [ PACKAGE BODY ] [ PACKAGE_simple_name ] ;
- procedure Parse_Package_Body (Unit : Iir_Design_Unit)
- is
- Res: Iir;
- begin
- Res := Create_Iir (Iir_Kind_Package_Body);
- Set_Location (Res);
-
- -- Get identifier.
- Expect (Tok_Identifier);
- Set_Identifier (Res, Current_Identifier);
- Scan_Expect (Tok_Is);
- Scan;
-
- Parse_Declarative_Part (Res);
-
- Expect (Tok_End);
- Set_End_Location (Unit);
-
- -- Skip 'end'
- Scan;
-
- if Current_Token = Tok_Package then
- if Flags.Vhdl_Std = Vhdl_87 then
- Error_Msg_Parse ("'package' keyword not allowed here by vhdl 87");
- end if;
- Set_End_Has_Reserved_Id (Res, True);
-
- -- Skip 'package'
- Scan;
-
- if Current_Token /= Tok_Body then
- Error_Msg_Parse ("missing 'body' after 'package'");
- else
- -- Skip 'body'
- Scan;
- end if;
- end if;
-
- Check_End_Name (Res);
- Expect (Tok_Semi_Colon);
- Set_Library_Unit (Unit, Res);
- end Parse_Package_Body;
-
- -- precond : NEW
- -- postcond: ';'
- --
- -- [ LRM08 4.9 ]
- -- package_instantiation_declaration ::=
- -- PACKAGE identifier IS NEW uninstantiated_package_name
- -- [ generic_map_aspect ] ;
- function Parse_Package_Instantiation_Declaration
- (Id : Name_Id; Loc : Location_Type)
- return Iir
- is
- Res: Iir;
- begin
- Res := Create_Iir (Iir_Kind_Package_Instantiation_Declaration);
- Set_Location (Res, Loc);
- Set_Identifier (Res, Id);
-
- -- Skip 'new'
- Scan;
-
- Set_Uninstantiated_Package_Name (Res, Parse_Name (False));
-
- if Current_Token = Tok_Generic then
- Set_Generic_Map_Aspect_Chain (Res, Parse_Generic_Map_Aspect);
- end if;
-
- Expect (Tok_Semi_Colon);
-
- return Res;
- end Parse_Package_Instantiation_Declaration;
-
- -- precond : PACKAGE
- -- postcond: ';'
- --
- -- package_declaration
- -- | package_body
- -- | package_instantiation_declaration
- procedure Parse_Package (Unit : Iir_Design_Unit)
- is
- Loc : Location_Type;
- Id : Name_Id;
- begin
- -- Skip 'package'
- Scan;
-
- if Current_Token = Tok_Body then
- -- Skip 'body'
- Scan;
-
- Parse_Package_Body (Unit);
- else
- Expect (Tok_Identifier);
- Id := Current_Identifier;
- Loc := Get_Token_Location;
-
- -- Skip identifier.
- Scan;
-
- -- Skip 'is'.
- Expect (Tok_Is);
- Scan;
-
- if Current_Token = Tok_New then
- Set_Library_Unit
- (Unit,
- Parse_Package_Instantiation_Declaration (Id, Loc));
- -- Note: there is no 'end' in instantiation.
- Set_End_Location (Unit, Get_Token_Location);
- else
- Parse_Package_Declaration (Unit, Id, Loc);
- end if;
- end if;
- end Parse_Package;
-
- -- Parse a design_unit.
- -- The lexical scanner must have been initialized, but without a
- -- current_token.
- --
- -- [ §11.1 ]
- -- design_unit ::= context_clause library_unit
- --
- -- [ §11.3 ]
- -- context_clause ::= { context_item }
- --
- -- [ §11.3 ]
- -- context_item ::= library_clause | use_clause
- function Parse_Design_Unit return Iir_Design_Unit
- is
- Res: Iir_Design_Unit;
- Unit: Iir;
- begin
- -- Internal check: there must be no current_token.
- if Current_Token /= Tok_Invalid then
- raise Internal_Error;
- end if;
- Scan;
- if Current_Token = Tok_Eof then
- return Null_Iir;
- end if;
-
- -- Create the design unit node.
- Res := Create_Iir (Iir_Kind_Design_Unit);
- Set_Location (Res);
- Set_Date_State (Res, Date_Extern);
-
- -- Parse context clauses
- declare
- use Context_Items_Chain_Handling;
- Last : Iir;
- Els : Iir;
- begin
- Build_Init (Last);
-
- loop
- case Current_Token is
- when Tok_Library =>
- Els := Parse_Library_Clause;
- when Tok_Use =>
- Els := Parse_Use_Clause;
- Scan;
- when Tok_With =>
- -- Be Ada friendly.
- Error_Msg_Parse ("'with' not allowed in context clause "
- & "(try 'use' or 'library')");
- Els := Parse_Use_Clause;
- Scan;
- when others =>
- exit;
- end case;
- Append_Subchain (Last, Res, Els);
- end loop;
- end;
-
- -- Parse library unit
- case Current_Token is
- when Tok_Entity =>
- Parse_Entity_Declaration (Res);
- when Tok_Architecture =>
- Parse_Architecture_Body (Res);
- when Tok_Package =>
- Parse_Package (Res);
- when Tok_Configuration =>
- Parse_Configuration_Declaration (Res);
- when others =>
- Error_Msg_Parse ("entity, architecture, package or configuration "
- & "keyword expected");
- return Null_Iir;
- end case;
- Unit := Get_Library_Unit (Res);
- Set_Design_Unit (Unit, Res);
- Set_Identifier (Res, Get_Identifier (Unit));
- Set_Date (Res, Date_Parsed);
- Invalidate_Current_Token;
- return Res;
- exception
- when Expect_Error =>
- raise Compilation_Error;
- end Parse_Design_Unit;
-
- -- [ §11.1 ]
- -- design_file ::= design_unit { design_unit }
- function Parse_Design_File return Iir_Design_File
- is
- Res : Iir_Design_File;
- Design, Last_Design : Iir_Design_Unit;
- begin
- Res := Create_Iir (Iir_Kind_Design_File);
- Set_Location (Res);
-
- Last_Design := Null_Iir;
- loop
- Design := Parse.Parse_Design_Unit;
- exit when Design = Null_Iir;
- Set_Design_File (Design, Res);
- if Last_Design = Null_Iir then
- Set_First_Design_Unit (Res, Design);
- else
- Set_Chain (Last_Design, Design);
- end if;
- Last_Design := Design;
- Set_Last_Design_Unit (Res, Last_Design);
- end loop;
- if Last_Design = Null_Iir then
- Error_Msg_Parse ("design file is empty (no design unit found)");
- end if;
- return Res;
- exception
- when Parse_Error =>
- return Null_Iir;
- end Parse_Design_File;
-end Parse;