diff --git a/tests/VHDL_TreeWidget/mainwindow.cpp b/tests/VHDL_TreeWidget/mainwindow.cpp --- a/tests/VHDL_TreeWidget/mainwindow.cpp +++ b/tests/VHDL_TreeWidget/mainwindow.cpp @@ -82,13 +82,13 @@ void MainWindow::parseFile(const QString void MainWindow::parseDirectory(const QString &dirName) { QDir dir(dirName); - dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); + dir.setFilter(QDir::Files | QDir::NoDotAndDotDot| QDir::Dirs | QDir::NoSymLinks); QFileInfoList list = dir.entryInfoList(); for (int i = 0; i < list.size(); ++i) { if(list.at(i).isDir()) { - parseDirectory(list.at(i).fileName()); + parseDirectory(list.at(i).absoluteFilePath()); } else { @@ -96,8 +96,11 @@ void MainWindow::parseDirectory(const QS { parseFile(list.at(i).absoluteFilePath(),false); VHDL_Tools::VHDL_AST_Node* parseTree = file->getParseTree(); - this->rootNode->childs.append(parseTree); - parseTree->parent = this->rootNode; + if(parseTree!=NULL) + { + this->rootNode->childs.append(parseTree); + parseTree->setParent(this->rootNode); + } } } } diff --git a/tests/VHDL_TreeWidget/mainwindow.h b/tests/VHDL_TreeWidget/mainwindow.h --- a/tests/VHDL_TreeWidget/mainwindow.h +++ b/tests/VHDL_TreeWidget/mainwindow.h @@ -28,6 +28,7 @@ private: VHDL_Tools::VHDL_AST_Node* rootNode; Ui::MainWindow *ui; VHDL_Tools::VHDL_File* file; + }; #endif // MAINWINDOW_H diff --git a/vhdlparser/scanner/Flex_Bison_FIles/vhdl.l b/vhdlparser/scanner/Flex_Bison_FIles/vhdl.l --- a/vhdlparser/scanner/Flex_Bison_FIles/vhdl.l +++ b/vhdlparser/scanner/Flex_Bison_FIles/vhdl.l @@ -14,8 +14,7 @@ /* msvc2010 requires that we exclude this header file. */ #define YY_NO_UNISTD_H -/* handle locations */ -int yycolumn = 1; + #define YY_USER_ACTION yycolumn += yyleng; @@ -36,34 +35,27 @@ int yycolumn = 1; /*-----------------------------------------------------------*/ \n {yycolumn=1;} +\x0d\x0a {yycolumn=1;} + /*comment*/ --.* { - //this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::comment,yylineno, yycolumn-yyleng)); + this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::comment,yylineno, yycolumn-yyleng)); } /*-----------------------------------------------------------*/ /*Reserved words*/ abs | -access | after | -alias | all | and | -array | assert | -attribute | -begin | -body | buffer | bus | disconnect | -downto | else | elsif | exit | -file | -function | generate | /* don't parse generate as block! just look for "if" or "for" */ group | guarded | @@ -71,7 +63,6 @@ impure | in | inertial | inout | -is | label | linkage | literal | @@ -82,7 +73,6 @@ next | nor | not | null | -of | on | open | or | @@ -90,80 +80,119 @@ others | out | postponed | pure | -range | register | reject | rem | -report | -return | rol | ror | select | severity | -shared | sla | sll | sra | srl | then | -to | transport | unaffected | until | -wait | when | -while | with | xnor | xor | (true|false) {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::keyword,yylineno, yycolumn-yyleng));} +return {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::return_t,yylineno, yycolumn-yyleng));} + +when {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::when,yylineno, yycolumn-yyleng));} + +begin {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::begin,yylineno, yycolumn-yyleng));} + +is {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::is,yylineno, yycolumn-yyleng));} + port {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::port,yylineno, yycolumn-yyleng));} generic {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::generic,yylineno, yycolumn-yyleng));} map {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::map,yylineno, yycolumn-yyleng));} -architecture | +loop {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::loop,yylineno, yycolumn-yyleng));} + +range {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::range,yylineno, yycolumn-yyleng));} + +array {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::array,yylineno, yycolumn-yyleng));} + +access {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::access,yylineno, yycolumn-yyleng));} + +file {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::file,yylineno, yycolumn-yyleng));} + +alias {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::alias,yylineno, yycolumn-yyleng));} + +report {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::report,yylineno, yycolumn-yyleng));} + +body {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::body,yylineno, yycolumn-yyleng));} + +of {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::of,yylineno, yycolumn-yyleng));} + +to | +downto {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::direction,yylineno, yycolumn-yyleng));} + block | -case | configuration | -component | for | if | -loop | -package | -procedure | -process | -protected | -record { +while | +protected { this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::block,yylineno, yycolumn-yyleng)); } -entity {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::entity,yylineno, yycolumn-yyleng));} +case {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::caseKw,yylineno, yycolumn-yyleng));} -units { - this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::units,yylineno, yycolumn-yyleng)); - } +wait {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::wait,yylineno, yycolumn-yyleng));} + +process {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::process,yylineno, yycolumn-yyleng));} + +component {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::component,yylineno, yycolumn-yyleng));} + +package {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::package,yylineno, yycolumn-yyleng));} + +architecture {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::architecture,yylineno, yycolumn-yyleng));} -constant | +record {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::record,yylineno, yycolumn-yyleng));} + +entity {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::entity,yylineno, yycolumn-yyleng));} + +procedure {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::procedure,yylineno, yycolumn-yyleng));} + +function {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::function,yylineno, yycolumn-yyleng));} + +units { this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::units,yylineno, yycolumn-yyleng));} + library | -signal | -subtype | -type | -use | -variable {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::clause,yylineno, yycolumn-yyleng));} +use {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::clause,yylineno, yycolumn-yyleng));} + +constant {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::constant,yylineno, yycolumn-yyleng));} + +subtype {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::subtype,yylineno, yycolumn-yyleng));} + +type {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::type,yylineno, yycolumn-yyleng));} +attribute {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::attribute,yylineno, yycolumn-yyleng));} +variable {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::variable,yylineno, yycolumn-yyleng));} + +signal {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::signal,yylineno, yycolumn-yyleng));} + +shared {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::shared,yylineno, yycolumn-yyleng));} end {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::endKw,yylineno, yycolumn-yyleng));} + /*-----------------------------------------------------------*/ /*identifier (may be a reserved word)*/ -[a-z][a-z0-9\_\.]+[a-z0-9]+ | +[a-z][a-z0-9\_\.]*[a-z0-9]+ | [a-z]+ | \\.*\\ {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::identifier,yylineno, yycolumn-yyleng));} @@ -171,6 +200,9 @@ end {this->appendNode(new VHDL_Tools::VH /*abstract literal (integer or floating point type)*/ /*Numerical literals*/ + +[0-9]+\#[a-f0-9]+\# {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} + (\+|\-)?([0-9\_]+)|(\+|\-)?([0-9\_]+E[0-9\_]+)|((2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)\#[0-9\_]\#) {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} (\+|\-)?[0-9\_]+\.[0-9\_]+|[0-9\_]+\.[0-9\_]+E[0-9\_]+ {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} @@ -183,15 +215,15 @@ end {this->appendNode(new VHDL_Tools::VH (\+|\-)?([0-9\_]+)(fs|ps|ns|us|ms|sec|min|hr) {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} /*Bit string literals*/ -\"[0-1\_]+\" {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} +[\"\”][0-1\_\-]+[\"\”] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} + + +x[\"\”][0-9A-F\_]+[\"\”] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} + +o[\"\”][0-7\_]+[\"\”] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} /*String literals*/ -\".*\" {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} - -x\"[0-9A-F\_]+\" {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} - -o\"[0-7\_]+\" {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} - +[\"\”][^\"\n]*[\"\”] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} /*The NULL literal*/ \[NULL\] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} @@ -208,9 +240,11 @@ o\"[0-7\_]+\" {this->appendNode(new VHDL /*-----------------------------------------------------------*/ /* delimiter*/ -\. | \| | \[ | \] | -\:= | \>\= | -\<\= | +\. | +\| | +\[ | +\] | +\>\= | \/\= | \= | \> | @@ -218,15 +252,23 @@ o\"[0-7\_]+\" {this->appendNode(new VHDL \& | \‘ | \' | -\=\> | -\<\> | -\, | +\’ | \* | \+ | \- | \/ | \*\* {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::separator,yylineno, yycolumn-yyleng)); } +\<\= {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::leSym,yylineno, yycolumn-yyleng)); } + +\=\> {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::arrow,yylineno, yycolumn-yyleng)); } + +\:= {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::varAsgn,yylineno, yycolumn-yyleng)); } + +\<\> {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::box,yylineno, yycolumn-yyleng)); } + +\, {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::comma,yylineno, yycolumn-yyleng)); } + \: {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::colon,yylineno, yycolumn-yyleng)); } diff --git a/vhdlparser/scanner/vhdl_ast_node.cpp b/vhdlparser/scanner/vhdl_ast_node.cpp --- a/vhdlparser/scanner/vhdl_ast_node.cpp +++ b/vhdlparser/scanner/vhdl_ast_node.cpp @@ -24,17 +24,49 @@ VHDL_Tools::VHDL_AST_Node::VHDL_AST_Node(const QString &value, VHDL_Tools::VHDL_AST_Node_type type, int line, int column) - :a_value(value),type(type),line(line),column(column) + :a_value(value),type(type),line(line),column(column),p_parent(NULL) { } +VHDL_Tools::VHDL_AST_Node::~VHDL_AST_Node() +{ + for(int i=0;iparent->childs.removeOne(this); + if(this->p_parent) + { + this->p_parent->childs.removeOne(this); + } parentNode->childs.append(this); - this->parent=parentNode; + this->p_parent=parentNode; } } + +void VHDL_Tools::VHDL_AST_Node::moveWithoutChilds(VHDL_Tools::VHDL_AST_Node *parentNode) +{ + if(parentNode!=NULL) + { + if(this->p_parent) + { + this->p_parent->childs.removeOne(this); + } + while(Q_UNLIKELY(this->childs.isEmpty())) + { + VHDL_Tools::VHDL_AST_Node *child = this->childs.first(); + this->childs.removeAll(child); + this->p_parent->childs.append(child); + } + parentNode->childs.append(this); + this->p_parent=parentNode; + } +} diff --git a/vhdlparser/scanner/vhdl_ast_node.h b/vhdlparser/scanner/vhdl_ast_node.h --- a/vhdlparser/scanner/vhdl_ast_node.h +++ b/vhdlparser/scanner/vhdl_ast_node.h @@ -26,9 +26,9 @@ namespace VHDL_Tools{ -#define closedByEnd 0x100 -#define closedBySemicolon 0x200 -#define closedByRightParen 0x300 +#define closedByEnd (0x100) +#define closedBySemicolon (0x200) +#define closedByRightParen (0x300) #define IS_CLOSED_BY_END(type) (((type)&0xF00)==closedByEnd) #define IS_CLOSED_BY_SEMICOLON(type) (((type)&0xF00)==closedBySemicolon) @@ -36,27 +36,64 @@ namespace VHDL_Tools{ #define IS_CLOSED_BY(openType,type) ((type)==ExpectedCloseTypeLookUp[((openType)&0xF00)>>8]) +#define FORCE_CLOSETYPE(node,closetype) (node)->type = static_cast(((node)->type & 0x0FF) | (closetype)) + enum VHDL_AST_Node_type { - none=0, - separator=1, - keyword=2, - leftParen=3|closedByRightParen, - rightParen=4, - block=5|closedByEnd, - units=6|closedByEnd, - entity=7|closedByEnd, - clause=8|closedBySemicolon, - semicolon=9, - colon=10, - generic=11, - port=12, - map=13, - endKw=14, - virtualGroup=15, - identifier=16, - literal=17, - rootNode=18, - comment=19 + none=0xF00000, //to force to at least 32 bits + rootNode=1, + separator=2, + keyword=3, + leftParen=4|closedByRightParen, + rightParen=5, + semicolon=6, + colon=7, + generic=8|closedBySemicolon, + port=9|closedBySemicolon, + map=10, + endKw=11, + virtualGroup=112, + identifier=13, + literal=14, + comment=15, + block=16|closedByEnd, + units=17|closedByEnd, + entity=18|closedByEnd, + record=19|closedByEnd, + clause=20|closedBySemicolon, + signal=21|closedBySemicolon, + variable=22|closedBySemicolon, + shared=23|closedBySemicolon, + type=24|closedBySemicolon, + attribute=25|closedBySemicolon, + constant=26|closedBySemicolon, + function=27, + procedure=28, + is=29, + return_t=30, + begin=31, + loop=32, + architecture=33|closedByEnd, + package=34|closedByEnd, + subtype=35|closedBySemicolon, + component=36|closedByEnd, + range=37, + comma=38, + box=39, + direction=40, + array=41, + access=42, + file=43|closedBySemicolon, + alias=44|closedBySemicolon, + report=45|closedBySemicolon, + body=46|closedByEnd, + of=47, + process=48|closedByEnd, + arrow=49, + varAsgn=50, + wait=51|closedBySemicolon, + leSym=52, + caseKw=53|closedByEnd, + when=54 }; const VHDL_AST_Node_type ExpectedCloseTypeLookUp[]={none,endKw,semicolon,rightParen,none,none,none,none,none,none,none,none,none,none,none,none}; @@ -65,13 +102,19 @@ class VHDL_AST_Node { public: VHDL_AST_Node(const QString& value,VHDL_Tools::VHDL_AST_Node_type type,int line=0, int column=0); + ~VHDL_AST_Node(); QString a_value; VHDL_Tools::VHDL_AST_Node_type type; int line; int column; - VHDL_Tools::VHDL_AST_Node* parent; QList childs; void move(VHDL_Tools::VHDL_AST_Node* parentNode); + void moveWithoutChilds(VHDL_Tools::VHDL_AST_Node* parentNode); + VHDL_Tools::VHDL_AST_Node* parent(){return p_parent;} + void setParent(VHDL_Tools::VHDL_AST_Node* parent){this->p_parent=parent;} +private: + VHDL_Tools::VHDL_AST_Node* p_parent; + }; } diff --git a/vhdlparser/scanner/vhdl_fragment.cpp b/vhdlparser/scanner/vhdl_fragment.cpp deleted file mode 100644 --- a/vhdlparser/scanner/vhdl_fragment.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/*------------------------------------------------------------------------------ --- This file is a part of the VHDL Tools Software --- Copyright (C) 2014, Plasma Physics Laboratory - CNRS --- --- This program 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 of the License, or --- (at your option) any later version. --- --- This program 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 this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --------------------------------------------------------------------------------*/ -/*-- Author : Alexis Jeandet --- Mail : alexis.jeandet@member.fsf.org -----------------------------------------------------------------------------*/ -#include "vhdl_fragment.h" - -VHDL_Tools::VHDL_Fragment::VHDL_Fragment() -{ -} diff --git a/vhdlparser/scanner/vhdl_fragment.h b/vhdlparser/scanner/vhdl_fragment.h deleted file mode 100644 --- a/vhdlparser/scanner/vhdl_fragment.h +++ /dev/null @@ -1,131 +0,0 @@ -/*------------------------------------------------------------------------------ --- This file is a part of the VHDL Tools Software --- Copyright (C) 2014, Plasma Physics Laboratory - CNRS --- --- This program 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 of the License, or --- (at your option) any later version. --- --- This program 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 this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --------------------------------------------------------------------------------*/ -/*-- Author : Alexis Jeandet --- Mail : alexis.jeandet@member.fsf.org -----------------------------------------------------------------------------*/ -#ifndef VHDL_FRAGMENT_H -#define VHDL_FRAGMENT_H -#include "vhdl_ast_node.h" -namespace VHDL_Tools { -class VHDL_Fragment -{ -public: - VHDL_Fragment(); - virtual void pushNode(VHDL_Tools::VHDL_AST_Node* node)=0; - VHDL_Tools::VHDL_AST_Node* node; -}; - -class VHDL_packaget: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_packaget() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_entity: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_entity() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_architecture: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_architecture() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_component: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_component() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_Library: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_Library() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_useClose: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_useClose() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_generic: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_generic() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_port: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_port() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_type: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_type() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_subtype: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_subtype() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_constant: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_constant() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -class VHDL_signal: public VHDL_Tools::VHDL_Fragment -{ -public: - VHDL_signal() {} - void pushNode(VHDL_Tools::VHDL_AST_Node* node); - QString name; -}; - -} -#endif // VHDL_FRAGMENT_H diff --git a/vhdlparser/scanner/vhdl_scanner.cpp b/vhdlparser/scanner/vhdl_scanner.cpp --- a/vhdlparser/scanner/vhdl_scanner.cpp +++ b/vhdlparser/scanner/vhdl_scanner.cpp @@ -27,12 +27,12 @@ VHDL_Tools::vhdl_Scanner::vhdl_Scanner(s { this->rootNode = new VHDL_Tools::VHDL_AST_Node(fileName,VHDL_Tools::rootNode); this->currentNode = rootNode; - this->rootNode->parent = this->rootNode; + this->rootNode->setParent(this->rootNode); } VHDL_Tools::vhdl_Scanner::~vhdl_Scanner() { - deleteNode(rootNode); + delete rootNode; } @@ -45,27 +45,20 @@ int VHDL_Tools::vhdl_Scanner::newFile(st { switch_streams(in); if(trashPreviousTree) - deleteNode(rootNode); + delete rootNode; + this->yylineno=1; + this->yycolumn=1; this->rootNode = new VHDL_Tools::VHDL_AST_Node(fileName,VHDL_Tools::rootNode); this->currentNode = rootNode; - this->rootNode->parent = this->rootNode; + this->rootNode->setParent(this->rootNode); return 1; } void VHDL_Tools::vhdl_Scanner::appendNode(VHDL_Tools::VHDL_AST_Node *node) { - this->currentNode->childs.append(node); - node->parent = this->currentNode; + node->move(currentNode); +// this->currentNode->childs.append(node); +// node->parent = this->currentNode; this->currentNode = node; } - -void VHDL_Tools::vhdl_Scanner::deleteNode(VHDL_Tools::VHDL_AST_Node *node) -{ - for(int i=0;ichilds.count();i++) - { - deleteNode(node->childs.at(i)); - } - node->parent->childs.removeAll(node); - delete node; -} diff --git a/vhdlparser/scanner/vhdl_scanner.h b/vhdlparser/scanner/vhdl_scanner.h --- a/vhdlparser/scanner/vhdl_scanner.h +++ b/vhdlparser/scanner/vhdl_scanner.h @@ -31,8 +31,6 @@ #include #include #include "vhdl_ast_node.h" -#include "vhdl_fragment.h" - #undef YY_DECL #define YY_DECL int VHDL_Tools::vhdl_Scanner::yylex() @@ -59,8 +57,9 @@ public: private: /* hide this one from public view */ int yylex(); + /* handle locations */ + int yycolumn; void appendNode(VHDL_Tools::VHDL_AST_Node* node); - void deleteNode(VHDL_Tools::VHDL_AST_Node* node); VHDL_Tools::VHDL_AST_Node* rootNode,*currentNode; }; } diff --git a/vhdlparser/vhdl_element_parser.cpp b/vhdlparser/vhdl_element_parser.cpp new file mode 100644 --- /dev/null +++ b/vhdlparser/vhdl_element_parser.cpp @@ -0,0 +1,1128 @@ +#include "vhdl_element_parser.h" +#include + +#define ERROR_EXPECTING(node,expectedKW) qDebug()<<"Error expected "<< (expectedKW) <<" @line " <<(node)->line <<" column "<<(node)->column<<"\n" + +#define CHECK_TOKEN(rootNode,node,expectedType,expectedTypeText) \ + if(Q_UNLIKELY((node)->type!=(expectedType))) \ +{\ + ERROR_EXPECTING((node),expectedTypeText); \ + } + +#define CHECK_TOKEN_EXIT(rootNode,node,expectedType,expectedTypeText) \ + if(Q_UNLIKELY((node)->type!=(expectedType))) \ +{\ + ERROR_EXPECTING((node),expectedTypeText); \ + *(rootNode)=(node); \ + return -1; \ + }\ + + + +bool VHDL_Tools::isInContext(QStack openBlocksContext, VHDL_Tools::VHDL_AST_Node_type type) +{ + while (openBlocksContext.count()) + { + //Copy of the stack -> pop() is safe + if(openBlocksContext.pop()->type==type) + { + return true; + } + } + return false; +} + +int VHDL_Tools::parse_Entity(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->append(currentNode); + VHDL_AST_Node *startNode = currentNode; + walk_forward(¤tNode,-1); + CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); + walk_forward(¤tNode,-1); + CHECK_TOKEN_EXIT(rootNode,currentNode,is,"\"is\" keyword"); + walk_forward(¤tNode,-1); + if(currentNode->type==generic) + { + parse_Port_or_Generic(¤tNode,openBlocksContext); + } + if(currentNode->type==port) + { + parse_Port_or_Generic(¤tNode,openBlocksContext); + } + if(currentNode->type!=endKw) + { + parse_DeclarativeBlock(¤tNode,openBlocksContext,false); + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==leftParen)) + { + openBlocksContext->push(currentNode); + } + else + { + if(Q_UNLIKELY(currentNode->type==rightParen)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + } + }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + } + closeAndMatchBlock(¤tNode,openBlocksContext,QList()< *openBlocksContext) +{ + VHDL_AST_Node* startNode = *rootNode; + VHDL_AST_Node* currentNode = *rootNode; + openBlocksContext->push(startNode); + walk_forward(¤tNode,-1); // skip Function + walk_forward(¤tNode,-1); // skip Name + parse_InterfaceList(¤tNode,openBlocksContext); + if(Q_UNLIKELY(currentNode->type!=return_t) ) + { + qDebug()<<"Error expected return Keyword @line " <line <<" column "<column<<"\n"; + } + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type!=identifier)) + { + qDebug()<<"Error expected return type @line " <line <<" column "<column<<"\n"; + } + walk_forward(¤tNode,-1); + *rootNode=currentNode; + if(currentNode->type==is) + { + walk_forward(rootNode,-1); //skip is + parse_DeclarativeBlock(rootNode,openBlocksContext); + startNode->type=static_cast(startNode->type | closedByEnd); + return parse_body(rootNode,openBlocksContext); + } + else + { + startNode->type=static_cast(currentNode->type | closedBySemicolon); + closeAndMatchBlock(rootNode,openBlocksContext,QList()); + } + return -1; +} + +int VHDL_Tools::parse_Attribute(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node* startNode = *rootNode; + VHDL_AST_Node* currentNode = *rootNode; + openBlocksContext->push(startNode); + while(currentNode->type!=semicolon) + { + walk_forward(¤tNode,-1); + } + *rootNode=currentNode; + closeAndMatchBlock(rootNode,openBlocksContext,QList()); + return 0; +} + +int VHDL_Tools::parse_Package(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->append(currentNode); + parse_DeclarativeBlock(¤tNode,openBlocksContext,false); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()<* openBlocksContext,QListskipTypes,bool skipOpenType,bool endWithSemicolon) +{ + if(openBlocksContext->size()) + { + VHDL_AST_Node* startNode = openBlocksContext->pop(); + + if( IS_CLOSED_BY(startNode->type,(*currentNode)->type)) + { + walk_forward(currentNode,-1); + if(skipOpenType) + { + skipTokens((*currentNode),(startNode->type)); + } + for(int i=0;itype==semicolon)) + { + if(walk_forward(currentNode,-1)!=-1) + (*currentNode)->move(startNode->parent()); + } + else + { + (*currentNode)->move(startNode->parent()); + } + } + else + { + // TODO improve message ! + qDebug() << "Got unexpected close token! @ line:" << (*currentNode)->line << " column:"<< (*currentNode)->column; + } + } + else + { + walk_forward(currentNode,-1); + return -1; + } + return 0; +} + +int VHDL_Tools::parse_body(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + VHDL_AST_Node *startNode=openBlocksContext->top(); + if(Q_UNLIKELY(currentNode->type!=begin)) + { + qDebug()<<"Error expected begin keyword @line " <line <<" column "<column<<"\n"; + return -1; + } + walk_forward(¤tNode,-1); + while (currentNode->childs.count()) + { + switch (currentNode->type) + { + case block: + if(!isInContext(*openBlocksContext,attribute)) + openBlocksContext->push(currentNode); + walk_forward(¤tNode,-1); + break; + case process: + if(!isInContext(*openBlocksContext,attribute)) + parse_Process(¤tNode,openBlocksContext); + // openBlocksContext->push(currentNode); + walk_forward(¤tNode,-1); + break; + case wait: + parse_Wait(¤tNode,openBlocksContext); + break; + case component: + parse_Component(¤tNode,openBlocksContext); + break; + case endKw: + if(openBlocksContext->top()==startNode) + { + *rootNode=currentNode; + closeAndMatchBlock(rootNode,openBlocksContext,QList()<()<push(currentNode); + walk_forward(¤tNode,-1); + break; + case signal: + parse_Signal_or_Constant(¤tNode,openBlocksContext); + break; + case variable: + if(!isInContext(*openBlocksContext,procedure) && !isInContext(*openBlocksContext,function) && !isInContext(*openBlocksContext,attribute)) + openBlocksContext->push(currentNode); + walk_forward(¤tNode,-1); + break; + case semicolon: + if( (openBlocksContext->size()) && (IS_CLOSED_BY_SEMICOLON(openBlocksContext->top()->type))) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList(),false); + } + else + { + walk_forward(¤tNode,-1); + } + break; + default: + walk_forward(¤tNode,-1); + break; + } + } + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_InterfaceList(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + /* interface-list –› [ constant | signal | file ] identifier { ‘,’ identifier } ‘:’ [ in ] subtype-indication [ := static_expression ]*/ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + walk_forward(¤tNode,-1); + if(currentNode->type!=rightParen) + { + FORCE_CLOSETYPE(currentNode, closedBySemicolon); + openBlocksContext->push(currentNode); + VHDL_AST_Node *currentLine=currentNode; + while((currentNode->type!=rightParen) || openBlocksContext->top()!=currentLine) + { + switch (currentNode->type) + { + case semicolon: + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + if(currentNode->childs.first()->type!=rightParen) + { + FORCE_CLOSETYPE(currentNode, closedBySemicolon); + openBlocksContext->push(currentNode); + currentLine = currentNode; + } + walk_forward(¤tNode,-1); + break; + case leftParen: + openBlocksContext->push(currentNode); + walk_forward(¤tNode,-1); + break; + case rightParen: + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + break; + default: + walk_forward(¤tNode,-1); + break; + } + } + } + openBlocksContext->pop(); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + *rootNode=currentNode; + return 0; +} + +int __private_parse_Architecture_Identifier(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_Tools::VHDL_AST_Node *currentNode=*rootNode; + VHDL_Tools::VHDL_AST_Node *startNode = currentNode; + VHDL_Tools::walk_forward(¤tNode,-1); + switch (currentNode->type) + { + case VHDL_Tools::colon: + VHDL_Tools::parse_Block(¤tNode,openBlocksContext); + break; + case VHDL_Tools::leSym: + currentNode = currentNode->parent(); + VHDL_Tools::parse_Assignment(¤tNode,openBlocksContext); + break; + case VHDL_Tools::leftParen: //function/procedure call + FORCE_CLOSETYPE(currentNode->parent(),closedBySemicolon); + openBlocksContext->push(currentNode->parent()); + VHDL_Tools::parse_AssociationList(¤tNode,openBlocksContext); + VHDL_Tools::closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + break; + case VHDL_Tools::varAsgn: + VHDL_Tools::parse_Assignment(¤tNode,openBlocksContext); + break; + default: + break; + } + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Architecture(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->append(currentNode); + VHDL_AST_Node *startNode = currentNode; + walk_forward(¤tNode,-1); + CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); + walk_forward(¤tNode,-1); + CHECK_TOKEN_EXIT(rootNode,currentNode,of,"\"of\" keyword"); + walk_forward(¤tNode,-1); + CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); + walk_forward(¤tNode,-1); + CHECK_TOKEN_EXIT(rootNode,currentNode,is,"\"is\" keyword"); + walk_forward(¤tNode,-1); + parse_DeclarativeBlock(¤tNode,openBlocksContext,true); + /*if(currentNode->type!=endKw) + { + do + { + walk_forward(¤tNode,-1); + switch (currentNode->type) { + case identifier: + __private_parse_Architecture_Identifier(¤tNode,openBlocksContext); + case block: + break; + default: + break; + } + }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + }*/ + parse_body(¤tNode,openBlocksContext); + // closeAndMatchBlock(¤tNode,openBlocksContext,QList()< *openBlocksContext) +{ + VHDL_AST_Node* startNode = *rootNode; + VHDL_AST_Node* currentNode = *rootNode; + openBlocksContext->push(startNode); + walk_forward(¤tNode,-1); // skip Procedure + walk_forward(¤tNode,-1); // skip Name + if(currentNode->type==leftParen) + { + parse_InterfaceList(¤tNode,openBlocksContext); + } + if(Q_UNLIKELY(currentNode->type!=return_t) ) + { + if(Q_UNLIKELY(currentNode->type!=is)) + { + if(Q_UNLIKELY(currentNode->type!=semicolon)) + { + qDebug()<<"Error expected semicolon or \"return\" or \"is\" Keyword @line " <line <<" column "<column<<"\n"; + } + } + } + else + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type!=identifier)) + { + qDebug()<<"Error expected return type @line " <line <<" column "<column<<"\n"; + } + walk_forward(¤tNode,-1); + } + *rootNode=currentNode; + if(currentNode->type==is) + { + walk_forward(rootNode,-1); //skip is + parse_DeclarativeBlock(rootNode,openBlocksContext); + startNode->type=static_cast(startNode->type | closedByEnd); + return parse_body(rootNode,openBlocksContext); + } + else + { + startNode->type=static_cast(currentNode->type | closedBySemicolon); + closeAndMatchBlock(rootNode,openBlocksContext,QList()); + } + return -1; +} + +int VHDL_Tools::parse_DeclarativeBlock(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext, bool mustHaveBegin) +{ + //Parse until begin or end + VHDL_AST_Node *currentNode=*rootNode; + VHDL_AST_Node *startNode=openBlocksContext->top(); + while(( ((currentNode->type!=begin) && (currentNode->type!=endKw)) || (openBlocksContext->top()!=startNode) ) && (currentNode->childs.count())) + { + switch(currentNode->type) + { + case block: + parse_Block(¤tNode,openBlocksContext); + break; + case function: + parse_Function(¤tNode,openBlocksContext); + break; + case procedure: + parse_Procedure(¤tNode,openBlocksContext); + break; + case clause: //use / lib / subtype + parse_Clause(¤tNode,openBlocksContext); + break; + case constant: + parse_Signal_or_Constant(¤tNode,openBlocksContext); + break; + case signal: + parse_Signal_or_Constant(¤tNode,openBlocksContext); + break; + case type: + parse_Type(¤tNode,openBlocksContext); + break; + case file: + parse_File(¤tNode,openBlocksContext); + break; + case subtype: + parse_Subtype(¤tNode,openBlocksContext); + break; + case component: + parse_Component(¤tNode,openBlocksContext); + break; + case alias: + parse_Alias(¤tNode,openBlocksContext); + break; + case report: + parse_Report(¤tNode,openBlocksContext); + break; + default: + walk_forward(¤tNode,0); + break; + } + } + if(Q_UNLIKELY(mustHaveBegin && (currentNode->type!=begin))) + { + qDebug()<<"Error expected \"begin\" keyword and got " << currentNode->a_value << " @line " <line <<" column "<column<<"\n"; + } + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Type(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + VHDL_AST_Node *startNode=openBlocksContext->top(); + VHDL_AST_Node *startNode2; + walk_forward(¤tNode,-1); // skip type + CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); + walk_forward(¤tNode,-1); // got Type identifier + CHECK_TOKEN_EXIT(rootNode,currentNode,is,"is"); + walk_forward(¤tNode,-1); // got is + switch (currentNode->type) + { + case array: + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==leftParen)) + { + openBlocksContext->push(currentNode); + } + else + { + if(Q_UNLIKELY(currentNode->type==rightParen)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + } + }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + if(currentNode->type == semicolon) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + break; + case record: + parse_Record(¤tNode,openBlocksContext); + break; + case access: + walk_forward(¤tNode,-1); + CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); + walk_forward(¤tNode,-1); + CHECK_TOKEN_EXIT(rootNode,currentNode,semicolon,"semicolon"); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + break; + case file: + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==leftParen)) + { + openBlocksContext->push(currentNode); + } + else + { + if(Q_UNLIKELY(currentNode->type==rightParen)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + } + }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + if(currentNode->type == semicolon) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + break; + case range: + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==leftParen)) + { + openBlocksContext->push(currentNode); + } + else + { + if(Q_UNLIKELY(currentNode->type==rightParen)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + } + }while((((currentNode->type!=semicolon) && (currentNode->type!=units)) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + if(currentNode->type == semicolon) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + else + { + if(currentNode->type == units) + { + parse_Units(¤tNode,openBlocksContext); + } + } + break; + case leftParen: + openBlocksContext->push(currentNode); + startNode2 = currentNode; + walk_forward(¤tNode,-1); + openBlocksContext->push(currentNode); + do + { + if(Q_UNLIKELY(currentNode->type==comma)) + { + walk_forward(¤tNode,-1); + currentNode->move(openBlocksContext->pop()->parent()); + openBlocksContext->push(currentNode); + } + else + { + walk_forward(¤tNode,-1); + } + }while(currentNode->childs.count() && ((currentNode->type!=rightParen))); + if(openBlocksContext->top()!=startNode2) + { + openBlocksContext->pop(); + } + CHECK_TOKEN_EXIT(rootNode,currentNode,rightParen,"\")\""); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + CHECK_TOKEN_EXIT(rootNode,currentNode,semicolon,"\";\""); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + break; + default: + break; + } + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Subtype(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + /*========================================================================================== + SUBTYPE MyArray IS BIT_VECTOR(7 DOWNTO 3); + subtype-declaration –› + subtype identifier is subtype-indication ';' + + subtype-indication, type-indication –› + [ resolution-function-name ] type-name [ range-constraint | index-constraint ] +=============================================================================================*/ + VHDL_AST_Node *currentNode=*rootNode; + //VHDL_AST_Node *startNode=openBlocksContext->top(); + openBlocksContext->append(currentNode); + walk_forward(¤tNode,-1); // skip subtype + CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Subtype identifier"); + walk_forward(¤tNode,-1); // got Subtype identifier + CHECK_TOKEN_EXIT(rootNode,currentNode,is,"is"); + walk_forward(¤tNode,-1); // got is + CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"type name"); + walk_forward(¤tNode,-1); + switch (currentNode->type) { + case leftParen: + parse_ConstrainedRange(¤tNode,openBlocksContext); + break; + case identifier: + walk_forward(¤tNode,-1); + break; + case range: + parse_ConstrainedRange(¤tNode,openBlocksContext); + break; + default: + break; + } + CHECK_TOKEN_EXIT(rootNode,currentNode,semicolon,"\";\""); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Component(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->append(currentNode); + walk_forward(¤tNode,-1); + CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); + walk_forward(¤tNode,-1); + if(Q_LIKELY(currentNode->type==is)) + { + walk_forward(¤tNode,-1); + } + do + { + switch (currentNode->type) + { + case port: + parse_Port_or_Generic(¤tNode,openBlocksContext); + break; + case generic: + parse_Port_or_Generic(¤tNode,openBlocksContext); + break; + default: + walk_forward(¤tNode,-1); + break; + } + }while(currentNode->type!=endKw); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()< *openBlocksContext) +{ + //range 0 to 9 + //(1 to 20) + //(20 dowto 1) + VHDL_AST_Node *currentNode=*rootNode; + VHDL_AST_Node *startNode=openBlocksContext->top(); + switch (currentNode->type) + { + case range: + //Expecting a constrained range so must get an identifier or a literal or an expression + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==leftParen)) + { + openBlocksContext->push(currentNode); + } + else + { + if(Q_UNLIKELY(currentNode->type==rightParen)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + } + }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + break; + case leftParen: + openBlocksContext->push(currentNode); + startNode = currentNode; + walk_forward(¤tNode,-1); + do + { + if(Q_UNLIKELY(currentNode->type==leftParen)) + { + openBlocksContext->push(currentNode); + } + else + { + if(Q_UNLIKELY(currentNode->type==rightParen)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + } + walk_forward(¤tNode,-1); + }while(((currentNode->type!=rightParen) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + break; + default: + break; + } + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Units(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + openBlocksContext->push(currentNode->childs.first()); + FORCE_CLOSETYPE(currentNode->childs.first(),closedBySemicolon); + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==semicolon)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + if(currentNode->type!=endKw) + { + FORCE_CLOSETYPE(currentNode,closedBySemicolon); + openBlocksContext->push(currentNode); + } + } + }while((currentNode->type!=endKw) && currentNode->childs.count()); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()<move(openBlocksContext->pop()->parent()); + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Record(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + openBlocksContext->push(currentNode->childs.first()); + FORCE_CLOSETYPE(currentNode->childs.first(),closedBySemicolon); + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==semicolon)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + if(currentNode->type!=endKw) + { + FORCE_CLOSETYPE(currentNode,closedBySemicolon); + openBlocksContext->push(currentNode); + } + } + }while((currentNode->type!=endKw) && currentNode->childs.count()); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()<move(openBlocksContext->pop()->parent()); + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_File(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + VHDL_AST_Node *startNode=openBlocksContext->top(); + FORCE_CLOSETYPE(currentNode->childs.first(),closedBySemicolon); + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==leftParen)) + { + openBlocksContext->push(currentNode); + } + else + { + if(Q_UNLIKELY(currentNode->type==rightParen)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + } + }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + if(currentNode->type == semicolon) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Alias(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + VHDL_AST_Node *startNode=openBlocksContext->top(); + FORCE_CLOSETYPE(currentNode->childs.first(),closedBySemicolon); + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==leftParen)) + { + openBlocksContext->push(currentNode); + } + else + { + if(Q_UNLIKELY(currentNode->type==rightParen)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + } + }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + if(currentNode->type == semicolon) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Report(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + VHDL_AST_Node *startNode=openBlocksContext->top(); + FORCE_CLOSETYPE(currentNode->childs.first(),closedBySemicolon); + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==leftParen)) + { + openBlocksContext->push(currentNode); + } + else + { + if(Q_UNLIKELY(currentNode->type==rightParen)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + } + }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + if(currentNode->type == semicolon) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Process(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + if(currentNode->parent()->type==colon) + { + if(currentNode->parent()->parent()->type==identifier) + { + FORCE_CLOSETYPE(currentNode->parent()->parent(),closedByEnd); + openBlocksContext->append(currentNode->parent()->parent()); + } + } + else + { + openBlocksContext->append(currentNode); + } + VHDL_AST_Node *startNode=openBlocksContext->top(); + parse_DeclarativeBlock(¤tNode,openBlocksContext,true); + if(currentNode->type!=endKw) + { + do + { + switch (currentNode->type) + { + case identifier: + if(currentNode->childs.count() && currentNode->childs.first()->type==colon) + { + openBlocksContext->push(currentNode); + walk_forward(¤tNode,-1); + walk_forward(¤tNode,-1); + if(currentNode->type==block) + { + FORCE_CLOSETYPE(openBlocksContext->top(),closedByEnd); + } + else + { + FORCE_CLOSETYPE(openBlocksContext->top(),closedBySemicolon); + } + } + else + { + walk_forward(¤tNode,-1); + } + break; + case block: + parse_Block(¤tNode,openBlocksContext); + break; + case semicolon: + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + openBlocksContext->push(currentNode); + break; + case caseKw: + break; + default: + walk_forward(¤tNode,-1); + break; + } + }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + } + closeAndMatchBlock(¤tNode,openBlocksContext,QList()< *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + VHDL_AST_Node *startNode=openBlocksContext->top(); + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type==leftParen)) + { + openBlocksContext->push(currentNode); + } + else + { + if(Q_UNLIKELY(currentNode->type==rightParen)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + } + }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + if(Q_LIKELY(currentNode->type == semicolon)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Port_or_Generic(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + walk_forward(¤tNode,-1); + if(currentNode->type==leftParen) + { + parse_InterfaceList(¤tNode,openBlocksContext); + } + if(Q_LIKELY(currentNode->type == semicolon)) + { + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + } + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Block(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + VHDL_AST_Node *startNode=currentNode; + walk_forward(¤tNode,-1); + if(currentNode->type!=endKw) + { + do + { + switch (currentNode->type) + { + case identifier: + __private_parse_Architecture_Identifier(¤tNode,openBlocksContext); + break; + case block: + parse_Block(¤tNode,openBlocksContext); + break; + case wait: + parse_Wait(¤tNode,openBlocksContext); + break; + case semicolon: + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + openBlocksContext->push(currentNode); + break; + default: + walk_forward(¤tNode,-1); + break; + } + }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); + } + closeAndMatchBlock(¤tNode,openBlocksContext,QList()< *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + VHDL_AST_Node *startNode = currentNode; + FORCE_CLOSETYPE(currentNode,closedBySemicolon); + while (currentNode->type!=semicolon) + { + if(Q_UNLIKELY(walk_forward(¤tNode,-1))) + { + openBlocksContext->pop(); + *rootNode=currentNode; + return 0; + } + } + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Wait(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + while(currentNode->type!=semicolon) + { + if(Q_UNLIKELY(walk_forward(¤tNode,-1))) + { + *rootNode=currentNode; + return -1; + } + } + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_AssociationList(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + /* association-list –› [ formal-part ‘=>’ ] actual-part { ‘,’ [ formal-part ‘=>’ ] actual-part }*/ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + walk_forward(¤tNode,-1); + if(currentNode->type!=rightParen) + { + FORCE_CLOSETYPE(currentNode, closedBySemicolon); + openBlocksContext->push(currentNode); + VHDL_AST_Node *currentLine=currentNode; + while((currentNode->type!=rightParen) || openBlocksContext->top()!=currentLine) + { + switch (currentNode->type) + { + case colon: + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + if(currentNode->childs.first()->type!=rightParen) + { + FORCE_CLOSETYPE(currentNode, closedBySemicolon); + openBlocksContext->push(currentNode); + currentLine = currentNode; + } + walk_forward(¤tNode,-1); + break; + case leftParen: + openBlocksContext->push(currentNode); + walk_forward(¤tNode,-1); + break; + case rightParen: + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + break; + default: + walk_forward(¤tNode,-1); + break; + } + } + } + openBlocksContext->pop(); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_Case(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + /* + case-statement –› [ case-label ‘:’ ] case expression is + when choices ‘=>’ { sequential-statement } + { when choices ‘=>’ { sequential-statement }} + end case [ case-label ] ‘;’ + choices –› choice { | choice } +*/ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + do + { + walk_forward(¤tNode); + }while(currentNode->type!=is); + do{ + if(currentNode->type==when) + { + parse_When_case(¤tNode,openBlocksContext); + } + else + { + walk_forward(¤tNode,-1); + } + }while(currentNode!=endKw); + closeAndMatchBlock(¤tNode,openBlocksContext,QList()); + *rootNode=currentNode; + return 0; +} + +int VHDL_Tools::parse_When_case(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + VHDL_AST_Node *startNode=*rootNode; + + *rootNode=currentNode; + return 0; +} + + + + + + + + + + + diff --git a/vhdlparser/vhdl_element_parser.h b/vhdlparser/vhdl_element_parser.h new file mode 100644 --- /dev/null +++ b/vhdlparser/vhdl_element_parser.h @@ -0,0 +1,120 @@ +#ifndef ELEMENTPARSER_H +#define ELEMENTPARSER_H +#include "scanner/vhdl_ast_node.h" +#include +#include +#include +namespace VHDL_Tools { + +#define WALK_FORWARD( node , code ) \ + while((node)->childs.count())\ + {\ + (node) = (node)->childs.first();\ + if(Q_UNLIKELY((node)->type==comment))\ + {\ + while(((node)->type==comment) && (node)->childs.count())\ + {\ + (node) = (node)->childs.first(); /*get next node*/ \ + (node)->move((node)->parent()->parent()); \ + }\ + }\ + else\ + {\ + break;\ + }\ + }\ + return (code); + + + +#define PARSE_COMMENT(node)\ + WALK_FORWARD((node),0);\ + (node)->move((node)->parent()->parent()); + +inline int walk_forward(VHDL_AST_Node **rootNode,int code) +{ + VHDL_AST_Node *node = *rootNode; + int retcode=code; + while(node->childs.count()) + { + node = node->childs.first(); + retcode=0; + if(Q_UNLIKELY(node->type==comment)) + { + while((node->type==comment) && node->childs.count()) + { + node = node->childs.first(); /*get next node*/ + node->moveWithoutChilds(node->parent()->parent()); + } + break; + } + else + { + break; + } + } + *rootNode=node; + return (retcode); +} +#define skipTokens(node,TokenType) while (((node)->type & 0x0FF )==(TokenType & 0x0FF)){walk_forward(&(node),-1);} + +bool isInContext(QStack openBlocksContext, VHDL_Tools::VHDL_AST_Node_type type); +int closeAndMatchBlock(VHDL_Tools::VHDL_AST_Node** currentNode,QStack* openBlocksContext,QListskipTypes,bool skipOpenType=false,bool endWithSemicolon=false); + +inline int parse_Clause(VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + openBlocksContext->push(currentNode); + do + { + walk_forward(¤tNode,-1); + if(Q_UNLIKELY(currentNode->type!=identifier)) + { + qDebug()<<"Error expecting identifier, got "<< currentNode->a_value << " @line " <line <<" column "<column<<"\n"; + *rootNode=currentNode; + return -1; + } + walk_forward(¤tNode,-1); + }while ((currentNode->type==comma) && currentNode->childs.count()); + if(Q_UNLIKELY(currentNode->type!=semicolon)) + { + qDebug()<<"Error expecting \';\', got "<< currentNode->a_value << " @line " <line <<" column "<column<<"\n"; + *rootNode=currentNode; + return -1; + } + *rootNode=currentNode; + closeAndMatchBlock(rootNode,openBlocksContext,QList()); + return 0; +} + + +int parse_Alias(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Architecture(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Assignment(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_AssociationList(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Attribute(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_body(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Block(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Case(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Component(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_ConstrainedRange(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_DeclarativeBlock(VHDL_AST_Node **rootNode, QStack *openBlocksContext,bool mustHaveBegin=true); +int parse_Entity(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_File(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Function(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_InterfaceList(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Package(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Port_or_Generic(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Procedure(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Process(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Record(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Report(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Signal_or_Constant(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Subtype(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Type(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Units(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_Wait(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +int parse_When_case(VHDL_AST_Node **rootNode, QStack *openBlocksContext); +} + +#endif // ELEMENTPARSER_H diff --git a/vhdlparser/vhdl_file.cpp b/vhdlparser/vhdl_file.cpp --- a/vhdlparser/vhdl_file.cpp +++ b/vhdlparser/vhdl_file.cpp @@ -6,35 +6,11 @@ VHDL_Tools::VHDL_File::VHDL_File() this->scanner = NULL; } -#define walkForward( node , code ) \ - if((node)->childs.count())\ -{\ - (node) = (node)->childs.first();\ - }\ - else\ -{\ - return (code);\ - }\ - - -#define skipTokens(node,TokenType) while ((node)->type==(TokenType)){walkForward((node),-1);} bool VHDL_Tools::VHDL_File::parseFile(const QString &file, bool trashPreviousTree) { std::ifstream in_file( file.toStdString().c_str() ); if( ! in_file.good() ) return false; - // if(scanner) - // delete(scanner); - // try - // { - // scanner = new VHDL_Tools::vhdl_Scanner( &in_file ,file); - // } - // catch( std::bad_alloc &ba ) - // { - // std::cerr << "Failed to allocate scanner: (" << - // ba.what() << ")\n"; - // return false; - // } if(scanner==NULL) { try @@ -48,6 +24,7 @@ bool VHDL_Tools::VHDL_File::parseFile(co return false; } } + qDebug()<<"Parsing File "<newFile(&in_file,file,trashPreviousTree); while (scanner->scan()!=0); makeParseTree(scanner->getScanTree()); @@ -65,105 +42,46 @@ int VHDL_Tools::VHDL_File::makeParseTree VHDL_AST_Node *currentNode=rootNode; QStack openBlocks; openBlocks.push(rootNode); - while (currentNode) + do + { + parseNext(¤tNode,&openBlocks); + }while(currentNode->childs.count()); + return 0; +} + +int VHDL_Tools::VHDL_File::parseNext(VHDL_Tools::VHDL_AST_Node **rootNode, QStack *openBlocksContext) +{ + VHDL_AST_Node *currentNode=*rootNode; + if(currentNode) { switch (currentNode->type) { - case block: - openBlocks.push(currentNode); - walkForward(currentNode,-1); - break; case entity: - //Declaration or instanciation? - if(!((currentNode->parent->type == colon) && (currentNode->parent->parent->type==identifier))) - { - openBlocks.push(currentNode); - } - walkForward(currentNode,-1); + parse_Entity(¤tNode,openBlocksContext); break; - case units: - if(openBlocks.top()->type==clause) - { - openBlocks.top()->type=units; - walkForward(currentNode,-1); - } - break; - case port: - currentNode->type = static_cast(currentNode->type | closedBySemicolon); - openBlocks.push(currentNode); - break; - case generic: - if(!(currentNode->childs.first()->type==map)) - { - currentNode->type = static_cast(currentNode->type | closedBySemicolon); - openBlocks.push(currentNode); - } - walkForward(currentNode,-1); + case architecture: + parse_Architecture(¤tNode,openBlocksContext); break; case clause: - openBlocks.push(currentNode); - walkForward(currentNode,-1); - break; - case endKw: - closeAndMatchBlock(¤tNode,&openBlocks,QList()<parent->type==port)||(openBlocks.top()->parent->type==generic)) - closeAndMatchBlock(¤tNode,&openBlocks,QList(),false); - else - closeAndMatchBlock(¤tNode,&openBlocks,QList(),false); - break; - case semicolon: - if(IS_CLOSED_BY_SEMICOLON(openBlocks.top()->type)) - { - closeAndMatchBlock(¤tNode,&openBlocks,QList(),false); - } - else - { - walkForward(currentNode,0); - } + case package: + parse_Package(¤tNode,openBlocksContext); break; default: - walkForward(currentNode,0); + walk_forward(¤tNode,0); break; } } - return 0; -} - -int VHDL_Tools::VHDL_File::closeAndMatchBlock(VHDL_Tools::VHDL_AST_Node **currentNode, QStack *openBlocksContext, QList skipTypes, bool endWithSemicolon) -{ - VHDL_AST_Node* startNode = openBlocksContext->pop(); - - if( IS_CLOSED_BY(startNode->type,(*currentNode)->type)) - { - walkForward((*currentNode),-1); - for(int i=0;itype==semicolon)) - { - walkForward((*currentNode),-1); - (*currentNode)->move(startNode->parent); - - } - else - { - (*currentNode)->move(startNode->parent); - } - } - else - { - // TODO improve message ! - qDebug() << "Got unexpected close token! @ line:" << (*currentNode)->line << " column:"<< (*currentNode)->column; - } + *rootNode =currentNode; return 0; } + + + + + + diff --git a/vhdlparser/vhdl_file.h b/vhdlparser/vhdl_file.h --- a/vhdlparser/vhdl_file.h +++ b/vhdlparser/vhdl_file.h @@ -1,10 +1,13 @@ -#ifndef VHDL_FILE_H +#ifndef VHDL_FILE_H #define VHDL_FILE_H #include "vhdlparser_global.h" #include "scanner/vhdl_scanner.h" +#include "vhdl_element_parser.h" +#include #include namespace VHDL_Tools { + class VHDL_File { @@ -15,7 +18,8 @@ public: private: VHDL_Tools::vhdl_Scanner *scanner; int makeParseTree(VHDL_Tools::VHDL_AST_Node* rootNode); - int closeAndMatchBlock(VHDL_Tools::VHDL_AST_Node** currentNode,QStack* openBlocksContext,QListskipTypes,bool endWithSemicolon=false); + int parsePackage(VHDL_Tools::VHDL_AST_Node** rootNode,QStack* openBlocksContext); + int parseNext(VHDL_Tools::VHDL_AST_Node** rootNode,QStack* openBlocksContext); VHDL_Tools::VHDL_AST_Node* rootNode; }; diff --git a/vhdlparser/vhdlparser.pro b/vhdlparser/vhdlparser.pro --- a/vhdlparser/vhdlparser.pro +++ b/vhdlparser/vhdlparser.pro @@ -24,14 +24,14 @@ INCLUDEPATH += \ SOURCES += vhdl_file.cpp \ scanner/vhdl_scanner.cpp \ - scanner/vhdl_fragment.cpp \ - scanner/vhdl_ast_node.cpp + scanner/vhdl_ast_node.cpp \ + vhdl_element_parser.cpp HEADERS += vhdl_file.h\ libvhdlparser_global.h \ scanner/vhdl_scanner.h \ - scanner/vhdl_fragment.h \ - scanner/vhdl_ast_node.h + scanner/vhdl_ast_node.h \ + vhdl_element_parser.h unix { target.path = /usr/lib