aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2018-11-29 19:00:35 +0100
committerTristan Gingold <tgingold@free.fr>2018-11-29 20:55:17 +0100
commit00e936db3909875d17512543d2573c635bc2a38a (patch)
treee28436ef139d44f9214d12eb2ad25c836b1b8e90 /src
parent787b286207964eb4880ed868f39814732d891482 (diff)
downloadghdl-00e936db3909875d17512543d2573c635bc2a38a.tar.gz
ghdl-00e936db3909875d17512543d2573c635bc2a38a.tar.bz2
ghdl-00e936db3909875d17512543d2573c635bc2a38a.zip
parse: strenghten, skip semi-colon in declarations.
Diffstat (limited to 'src')
-rw-r--r--src/vhdl/parse.adb243
1 files changed, 140 insertions, 103 deletions
diff --git a/src/vhdl/parse.adb b/src/vhdl/parse.adb
index 989885209..3acd4a731 100644
--- a/src/vhdl/parse.adb
+++ b/src/vhdl/parse.adb
@@ -189,6 +189,20 @@ package body Parse is
end loop;
end Eat_Tokens_Until_Semi_Colon;
+ procedure Resync_To_End_Of_Statement is
+ begin
+ loop
+ case Current_Token is
+ when Tok_Eof
+ | Tok_Semi_Colon
+ | Tok_End =>
+ exit;
+ when others =>
+ Scan;
+ end case;
+ end loop;
+ end Resync_To_End_Of_Statement;
+
-- Expect and scan ';' emit an error message using MSG if not present.
procedure Scan_Semi_Colon (Msg : String) is
begin
@@ -831,7 +845,7 @@ package body Parse is
when others =>
Error_Msg_Parse
- ("identifier or all is expected after '.'");
+ ("identifier or ""all"" is expected after '.'");
Res := Prefix;
end case;
@@ -1301,13 +1315,13 @@ package body Parse is
Last := Inter;
end loop;
- Expect (Tok_Colon, "':' must follow the interface element identifier");
-
- -- Skip ':'
if Flag_Elocations then
Set_Colon_Location (First, Get_Token_Location);
end if;
- Scan;
+
+ -- Skip ':'
+ Expect_Scan (Tok_Colon,
+ "':' must follow the interface element identifier");
-- Parse mode.
case Current_Token is
@@ -2449,8 +2463,9 @@ package body Parse is
Scan;
if Current_Token = Tok_Semi_Colon then
- -- If there is a ';', this is an imcomplete type declaration.
- Invalidate_Current_Token;
+ -- If there is a ';', this is an incomplete type declaration.
+ Scan;
+
Decl := Create_Iir (Iir_Kind_Type_Declaration);
Set_Identifier (Decl, Ident);
Set_Location (Decl, Loc);
@@ -2571,8 +2586,7 @@ package body Parse is
Set_Location (Decl, Loc);
-- ';' is expected after end of type declaration
- Expect (Tok_Semi_Colon);
- Invalidate_Current_Token;
+ Expect_Scan (Tok_Semi_Colon);
if Flag_Elocations then
Create_Elocations (Decl);
@@ -2842,7 +2856,7 @@ package body Parse is
end Parse_Subtype_Indication;
-- precond : SUBTYPE
- -- postcond: ';'
+ -- postcond: next token
--
-- [ LRM93 4.2 ]
-- subtype_declaration ::= SUBTYPE identifier IS subtype_indication ;
@@ -2854,25 +2868,30 @@ package body Parse is
Start_Loc : Location_Type;
begin
Decl := Create_Iir (Iir_Kind_Subtype_Declaration);
+ Set_Parent (Decl, Parent);
+ Set_Location (Decl);
Start_Loc := Get_Token_Location;
-- Eat 'subtype'.
- Scan_Expect (Tok_Identifier);
+ Scan;
- Set_Identifier (Decl, Current_Identifier);
- Set_Parent (Decl, Parent);
- Set_Location (Decl);
+ if Current_Token = Tok_Identifier then
+ Set_Identifier (Decl, Current_Identifier);
- -- Skip identifier.
- Scan_Expect (Tok_Is);
+ -- Skip identifier.
+ Scan;
+ else
+ Error_Msg_Parse ("identifier expected after 'type'");
+ end if;
-- Skip 'is'.
- Scan;
+ Expect_Scan (Tok_Is);
Def := Parse_Subtype_Indication;
Set_Subtype_Indication (Decl, Def);
- Expect (Tok_Semi_Colon);
+ -- Skip 'end'.
+ Expect_Scan (Tok_Semi_Colon);
if Flag_Elocations then
Create_Elocations (Decl);
@@ -2916,13 +2935,8 @@ package body Parse is
Scan;
- if Current_Token /= Tok_Is then
- Error_Msg_Parse ("'is' expected here");
- -- Act as if IS token was forgotten.
- else
- -- Skip 'is'.
- Scan;
- end if;
+ -- Skip 'is'.
+ Expect_Scan (Tok_Is);
case Current_Token is
when Tok_Array =>
@@ -2977,8 +2991,8 @@ package body Parse is
Set_Location (Decl, Loc);
-- ';' is expected after end of type declaration
- Expect (Tok_Semi_Colon);
- Invalidate_Current_Token;
+ Expect_Scan (Tok_Semi_Colon);
+
return Decl;
end Parse_Nature_Declaration;
@@ -3018,7 +3032,7 @@ package body Parse is
end Parse_Subnature_Indication;
-- precond : TERMINAL
- -- postcond: ;
+ -- postcond: next token.
--
-- [ 4.3.1.5 Terminal declarations ]
-- terminal_declaration ::=
@@ -3066,12 +3080,12 @@ package body Parse is
end if;
Terminal := Get_Chain (Terminal);
end loop;
- Expect (Tok_Semi_Colon);
+ Expect_Scan (Tok_Semi_Colon);
return First;
end Parse_Terminal_Declaration;
-- precond : QUANTITY
- -- postcond: ;
+ -- postcond: next token.
--
-- [ 4.3.1.6 Quantity declarations ]
-- quantity_declaration ::=
@@ -3271,12 +3285,12 @@ package body Parse is
Eat_Tokens_Until_Semi_Colon;
return Null_Iir;
end case;
- Expect (Tok_Semi_Colon);
+ Expect_Scan (Tok_Semi_Colon);
return First;
end Parse_Quantity_Declaration;
-- precond : token (CONSTANT, SIGNAL, VARIABLE, FILE)
- -- postcond: ;
+ -- postcond: next token.
--
-- KIND can be iir_kind_constant_declaration, iir_kind_file_declaration
-- or iir_kind_variable_declaration
@@ -3400,7 +3414,7 @@ package body Parse is
end loop;
-- Skip ':'.
- Scan;
+ Expect_Scan (Tok_Colon);
Object_Type := Parse_Subtype_Indication;
@@ -3492,14 +3506,14 @@ package body Parse is
Object := Get_Chain (Object);
end loop;
- -- ';' is not eaten.
- Expect (Tok_Semi_Colon);
+ -- Skip ';'.
+ Expect_Scan (Tok_Semi_Colon);
return First;
end Parse_Object_Declaration;
-- precond : COMPONENT
- -- postcond: ';'
+ -- postcond: next token.
--
-- [ LRM93 4.5 ]
-- component_declaration ::=
@@ -3543,6 +3557,10 @@ package body Parse is
end if;
Check_End_Name (Tok_Component, Component);
+
+ -- Skip ';'.
+ Scan;
+
return Component;
end Parse_Component_Declaration;
@@ -3591,7 +3609,7 @@ package body Parse is
end Parse_Signature;
-- precond : ALIAS
- -- postcond: a token
+ -- postcond: next token
--
-- [ LRM93 4.3.3 ]
-- alias_declaration ::=
@@ -3639,8 +3657,7 @@ package body Parse is
end if;
-- FIXME: nice message if token is ':=' ?
- Expect (Tok_Is);
- Scan;
+ Expect_Scan (Tok_Is);
Set_Name (Res, Parse_Signature_Name);
if Flag_Elocations then
@@ -3648,11 +3665,14 @@ package body Parse is
Set_Start_Location (Res, Start_Loc);
end if;
+ -- Skip ';'.
+ Expect_Scan (Tok_Semi_Colon);
+
return Res;
end Parse_Alias_Declaration;
-- precond : FOR
- -- postcond: ';'
+ -- postcond: next token.
--
-- [ LRM93 5.2 ]
-- configuration_specification ::=
@@ -3666,12 +3686,14 @@ package body Parse is
Set_Location (Res);
-- Eat 'for'.
- Expect (Tok_For);
- Scan;
+ Expect_Scan (Tok_For);
Parse_Component_Specification (Res);
Set_Binding_Indication (Res, Parse_Binding_Indication);
- Expect (Tok_Semi_Colon);
+
+ -- Skip ';'.
+ Expect_Scan (Tok_Semi_Colon);
+
return Res;
end Parse_Configuration_Specification;
@@ -3805,7 +3827,7 @@ package body Parse is
end Parse_Entity_Name_List;
-- precond : ATTRIBUTE
- -- postcond: ';'
+ -- postcond: next token
--
-- [ 4.4 ]
-- attribute_declaration ::= ATTRIBUTE identifier : type_mark ;
@@ -3846,7 +3868,7 @@ package body Parse is
Scan;
Set_Type_Mark (Res, Parse_Type_Mark (Check_Paren => True));
- Expect (Tok_Semi_Colon);
+ Expect_Scan (Tok_Semi_Colon);
when Tok_Of =>
Res := Create_Iir (Iir_Kind_Attribute_Specification);
@@ -3860,13 +3882,12 @@ package body Parse is
Scan;
Parse_Entity_Name_List (Res);
- Expect (Tok_Is);
-- Skip 'is'.
- Scan;
+ Expect_Scan (Tok_Is);
Set_Expression (Res, Parse_Expression);
- Expect (Tok_Semi_Colon);
+ Expect_Scan (Tok_Semi_Colon);
when others =>
Error_Msg_Parse ("':' or 'of' expected after identifier");
@@ -3891,7 +3912,8 @@ package body Parse is
-- entity_class_entry_list ::= entity_class_entry { , entity_class_entry }
--
-- entity_class_entry ::= entity_class [ <> ]
- function Parse_Group return Iir is
+ function Parse_Group return Iir
+ is
Loc : Location_Type;
Ident : Name_Id;
begin
@@ -3899,7 +3921,10 @@ package body Parse is
Scan_Expect (Tok_Identifier);
Loc := Get_Token_Location;
Ident := Current_Identifier;
+
+ -- Skip 'group'.
Scan;
+
case Current_Token is
when Tok_Is =>
declare
@@ -3944,7 +3969,7 @@ package body Parse is
-- Skip ')' ';'
Expect_Scan (Tok_Right_Paren);
- Expect (Tok_Semi_Colon);
+ Expect_Scan (Tok_Semi_Colon);
return Res;
end;
when Tok_Colon =>
@@ -3976,7 +4001,7 @@ package body Parse is
-- Skip ')' ';'.
Expect_Scan (Tok_Right_Paren);
- Expect (Tok_Semi_Colon);
+ Expect_Scan (Tok_Semi_Colon);
Set_Group_Constituent_List (Res, List_To_Flist (List));
return Res;
@@ -4026,7 +4051,7 @@ package body Parse is
end Parse_Signal_List;
-- precond : DISCONNECT
- -- postcond: ';'
+ -- postcond: next token.
--
-- [ LRM93 5.4 ]
-- disconnection_specification ::=
@@ -4036,26 +4061,29 @@ package body Parse is
is
Res : Iir_Disconnection_Specification;
begin
+ pragma Assert (Current_Token = Tok_Disconnect);
+
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;
+ Expect_Scan (Tok_Colon);
Set_Type_Mark (Res, Parse_Type_Mark (Check_Paren => True));
-- Skip 'after'
- Expect (Tok_After);
- Scan;
+ Expect_Scan (Tok_After);
Set_Expression (Res, Parse_Expression);
+
+ -- Skip ';'.
+ Expect_Scan (Tok_Semi_Colon);
+
return Res;
end Parse_Disconnection_Specification;
@@ -4620,6 +4648,11 @@ package body Parse is
(+Decl, "package body not allowed in a package");
end if;
end if;
+
+ if Current_Token = Tok_Semi_Colon then
+ -- Skip ';'.
+ Scan;
+ end if;
when Tok_Identifier =>
if Vhdl_Std >= Vhdl_08
and then Current_Identifier = Name_Default
@@ -4647,6 +4680,11 @@ package body Parse is
Error_Kind ("parse_declarative_part", Parent);
end case;
Decl := Parse_Psl_Default_Clock;
+
+ if Current_Token = Tok_Semi_Colon then
+ -- Skip ';' (scan without PSL keywords).
+ Scan;
+ end if;
else
Error_Msg_Parse
("object class keyword such as 'variable' is expected");
@@ -4661,15 +4699,11 @@ package body Parse is
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: ';'
+ -- postcond: ';'.
--
-- [ LRM93 1.1 ]
-- entity_declaration ::=
@@ -4705,10 +4739,10 @@ package body Parse is
"an identifier is expected after ""entity""");
Set_Identifier (Res, Current_Identifier);
Set_Location (Res);
-
- Scan_Expect (Tok_Is, "missing ""is"" after identifier");
Scan;
+ Expect_Scan (Tok_Is);
+
Parse_Generic_Port_Clauses (Res);
Parse_Declarative_Part (Res);
@@ -4726,11 +4760,8 @@ package body Parse is
end if;
-- end keyword is expected to finish an entity declaration
- Expect (Tok_End);
End_Loc := Get_Token_Location;
-
- -- Skip 'end'.
- Scan;
+ Expect_Scan (Tok_End);
if Current_Token = Tok_Entity then
if Flags.Vhdl_Std = Vhdl_87 then
@@ -4741,7 +4772,7 @@ package body Parse is
end if;
Check_End_Name (Res);
Expect (Tok_Semi_Colon);
- Invalidate_Current_Token;
+
Set_Library_Unit (Unit, Res);
if Flag_Elocations then
@@ -5321,6 +5352,7 @@ package body Parse is
when Tok_Comma
| Tok_Semi_Colon
+ | Tok_Right_Paren
| Tok_Eof
| Tok_End =>
-- Token not to be skipped
@@ -6039,7 +6071,11 @@ package body Parse is
begin
Res := Create_Iir (Iir_Kind_Wait_Statement);
Set_Location (Res);
+
+ -- Skip 'wait'.
Scan;
+
+ -- Sensitivity clause.
case Current_Token is
when Tok_On =>
List := Create_Iir_List;
@@ -6054,13 +6090,15 @@ package body Parse is
return Res;
when others =>
Error_Msg_Parse ("'on', 'until', 'for' or ';' expected");
- Eat_Tokens_Until_Semi_Colon;
+ Resync_To_End_Of_Statement;
return Res;
end case;
+
+ -- Condition clause.
case Current_Token is
when Tok_On =>
Error_Msg_Parse ("only one sensitivity is allowed");
- -- FIXME: sync
+ Resync_To_End_Of_Statement;
return Res;
when Tok_Until =>
Scan;
@@ -6071,17 +6109,19 @@ package body Parse is
return Res;
when others =>
Error_Msg_Parse ("'until', 'for' or ';' expected");
- Eat_Tokens_Until_Semi_Colon;
+ Resync_To_End_Of_Statement;
return Res;
end case;
+
+ -- Timeout clause.
case Current_Token is
when Tok_On =>
Error_Msg_Parse ("only one sensitivity clause is allowed");
- -- FIXME: sync
+ Resync_To_End_Of_Statement;
return Res;
when Tok_Until =>
Error_Msg_Parse ("only one condition clause is allowed");
- -- FIXME: sync
+ Resync_To_End_Of_Statement;
return Res;
when Tok_For =>
Scan;
@@ -6091,7 +6131,7 @@ package body Parse is
return Res;
when others =>
Error_Msg_Parse ("'for' or ';' expected");
- Eat_Tokens_Until_Semi_Colon;
+ Resync_To_End_Of_Statement;
return Res;
end case;
end Parse_Wait_Statement;
@@ -6421,7 +6461,7 @@ package body Parse is
Set_Prefix (Call, Target);
Set_Procedure_Call (Stmt, Call);
Set_Location (Call);
- Eat_Tokens_Until_Semi_Colon;
+ Resync_To_End_Of_Statement;
return Stmt;
end if;
end Parse_Sequential_Assignment_Statement;
@@ -6824,7 +6864,7 @@ package body Parse is
end Parse_Sequential_Statements;
-- precond : PROCEDURE, FUNCTION, PURE or IMPURE.
- -- postcond: ';'
+ -- postcond: next token.
--
-- [ LRM93 2.1 ]
-- subprogram_declaration ::= subprogram_specification ;
@@ -6912,6 +6952,9 @@ package body Parse is
end if;
if Current_Token = Tok_Semi_Colon then
+ -- Skip ';'.
+ Scan;
+
return Subprg;
end if;
@@ -7000,7 +7043,7 @@ package body Parse is
when others =>
null;
end case;
- Expect (Tok_Semi_Colon);
+ Expect_Scan (Tok_Semi_Colon);
return Subprg;
end Parse_Subprogram_Declaration;
@@ -8453,7 +8496,7 @@ package body Parse is
end Parse_Library_Clause;
-- precond : USE
- -- postcond: ;
+ -- postcond: next token (after ';').
--
-- [ LRM93 10.4 ]
-- use_clause ::= USE selected_name { , selected_name }
@@ -8494,13 +8537,13 @@ package body Parse is
Scan;
end loop;
- Expect (Tok_Semi_Colon, "';' expected at end of use clause");
+ Expect_Scan (Tok_Semi_Colon, "';' expected at end of use clause");
return First;
end Parse_Use_Clause;
-- precond : ARCHITECTURE
- -- postcond: ';'
+ -- postcond: ';'.
--
-- [ LRM93 1.2 ]
-- architecture_body ::=
@@ -8543,22 +8586,24 @@ package body Parse is
Parse_Declarative_Part (Res);
-- Skip 'begin'.
- Expect (Tok_Begin);
Begin_Loc := Get_Token_Location;
- Scan;
+ Expect_Scan (Tok_Begin);
Parse_Concurrent_Statements (Res);
-- end was scanned.
End_Loc := Get_Token_Location;
-- Skip 'end'.
- Scan;
+ Expect_Scan (Tok_End);
+
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);
+
+ -- Skip 'architecture'.
Scan;
end if;
Check_End_Name (Res);
@@ -8823,8 +8868,6 @@ package body Parse is
while Current_Token = Tok_Use loop
Append_Subchain (Last, Res, Parse_Use_Clause);
- -- Eat ';'.
- Scan;
end loop;
end;
end if;
@@ -8978,12 +9021,11 @@ package body Parse is
when others =>
exit;
end case;
- Scan;
end loop;
end Parse_Configuration_Declarative_Part;
-- precond : CONFIGURATION
- -- postcond: ';'
+ -- postcond: ';'.
--
-- [ LRM93 1.3 ]
-- configuration_declaration ::=
@@ -9010,16 +9052,15 @@ package body Parse is
Set_Location (Res);
-- Skip identifier.
- Scan_Expect (Tok_Of);
+ Scan;
-- Skip 'of'.
- Scan;
+ Expect_Scan (Tok_Of);
Set_Entity_Name (Res, Parse_Name (False));
-- Skip 'is'.
- Expect (Tok_Is);
- Scan;
+ Expect_Scan (Tok_Is);
Parse_Configuration_Declarative_Part (Res);
@@ -9079,7 +9120,7 @@ package body Parse is
end Parse_Package_Header;
-- precond : token (after 'IS')
- -- postcond: ';'
+ -- postcond: ';'.
--
-- [ LRM93 2.5, LRM08 4.7 ]
-- package_declaration ::=
@@ -9107,11 +9148,10 @@ package body Parse is
Parse_Declarative_Part (Res);
- Expect (Tok_End);
End_Loc := Get_Token_Location;
-- Skip 'end'
- Scan;
+ Expect_Scan (Tok_End);
if Current_Token = Tok_Package then
if Flags.Vhdl_Std = Vhdl_87 then
@@ -9135,7 +9175,7 @@ package body Parse is
end Parse_Package_Declaration;
-- precond : BODY
- -- postcond: ';'
+ -- postcond: ';'.
--
-- [ LRM93 2.6, LRM08 4.8 ]
-- package_body ::=
@@ -9194,7 +9234,7 @@ package body Parse is
end Parse_Package_Body;
-- precond : NEW
- -- postcond: ';'
+ -- postcond: ';'.
--
-- [ LRM08 4.9 ]
-- package_instantiation_declaration ::=
@@ -9223,13 +9263,13 @@ package body Parse is
(Res, Parse_Association_List_In_Parenthesis);
end if;
- Expect (Tok_Semi_Colon);
-
if Flag_Elocations then
Create_Elocations (Res);
Set_End_Location (Res, Get_Token_Location);
end if;
+ Expect (Tok_Semi_Colon);
+
return Res;
end Parse_Package_Instantiation_Declaration;
@@ -9264,8 +9304,7 @@ package body Parse is
Scan;
-- Skip 'is'.
- Expect (Tok_Is);
- Scan;
+ Expect_Scan (Tok_Is);
if Current_Token = Tok_New then
Res := Parse_Package_Instantiation_Declaration (Parent, Id, Loc);
@@ -9306,7 +9345,6 @@ package body Parse is
Els := Parse_Library_Clause;
when Tok_Use =>
Els := Parse_Use_Clause;
- Scan;
when Tok_Context =>
Parse_Context_Declaration_Or_Reference (Unit, Els);
if Els = Null_Iir then
@@ -9332,7 +9370,6 @@ package body Parse is
Error_Msg_Parse ("'with' not allowed in context clause "
& "(try 'use' or 'library')");
Els := Parse_Use_Clause;
- Scan;
when others =>
exit;
end case;