1 // Copyright (C) 2009 Free Software Foundation, Inc.
2 // Contributed by Jan Sjodin <jan.sjodin@amd.com>.
4 // This file is part of the Polyhedral Compilation Package Library (libpcp).
6 // Libpcp is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU Lesser General Public License as published by
8 // the Free Software Foundation; either version 2.1 of the License, or
9 // (at your option) any later version.
11 // Libpcp is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with libpcp; see the file COPYING.LIB. If not, write to the
18 // Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 // MA 02110-1301, USA.
21 // As a special exception, if you link this library with other files, some
22 // of which are compiled with GCC, to produce an executable, this library
23 // does not by itself cause the resulting executable to be covered by the
24 // GNU General Public License. This exception does not however invalidate
25 // any other reasons why the executable file might be covered by the GNU
26 // General Public License.
28 #include "pcp_error.h"
29 #include "pcp_alloc.h"
31 #include "pcp_string_buffer.h"
32 #include "pcp_dynamic_array.h"
33 #include "pcp_emitter.h"
34 #include "pcp_parser.h"
66 PCP_TOKEN_CLOSE_PAREN
,
69 PCP_TOKEN_CLOSE_BRACE
,
70 PCP_TOKEN_VERTICAL_BAR
,
83 static PcpToken
* sequenceToken
;
84 static PcpArray
<PcpToken
*>* delimiters
;
85 static PcpArray
<PcpToken
*>* keywords
;
90 // Set sequence token to SEQUENCETOKEN.
91 static void setSequenceToken(PcpToken
* sequenceToken
)
93 PcpToken::sequenceToken
= sequenceToken
;
96 // Set delimiters to DELIMITERS.
97 static void setDelimiters(PcpArray
<PcpToken
*>* delimiters
)
99 PcpToken::delimiters
= delimiters
;
103 static PcpArray
<PcpToken
*>* getDelimiters()
105 return PcpToken::delimiters
;
108 // Set keywords to KEYWORDS.
109 static void setKeywords(PcpArray
<PcpToken
*>* keywords
)
111 PcpToken::keywords
= keywords
;
115 static PcpArray
<PcpToken
*>* getKeywords()
117 return PcpToken::keywords
;
127 // Set string to STRING.
129 setString(const char* string
)
131 this->string
= string
;
134 // Set line number to LINENUMBER.
136 setLineNumber(int lineNumber
)
138 this->lineNumber
= lineNumber
;
141 // Initialize delimiters to PCP delimiters.
142 static void initializeDelimiters()
144 PcpDynamicArray
<PcpToken
*>* delimiters
= new PcpDynamicArray
<PcpToken
*>(7);
145 delimiters
->add(new PcpToken(PCP_TOKEN_ARROW
, "<-", -1));
146 delimiters
->add(new PcpToken(PCP_TOKEN_OPEN_PAREN
, "(", -1));
147 delimiters
->add(new PcpToken(PCP_TOKEN_CLOSE_PAREN
, ")", -1));
148 delimiters
->add(new PcpToken(PCP_TOKEN_COMMA
, ",", -1));
149 delimiters
->add(new PcpToken(PCP_TOKEN_OPEN_BRACE
, "{", -1));
150 delimiters
->add(new PcpToken(PCP_TOKEN_CLOSE_BRACE
, "}", -1));
151 delimiters
->add(new PcpToken(PCP_TOKEN_VERTICAL_BAR
, "|", -1));
152 PcpToken::setDelimiters(delimiters
);
155 // Initialize keywords to PCP keywords and operators.
156 static void initializeKeywords()
158 PcpDynamicArray
<PcpToken
*>* keywords
= new PcpDynamicArray
<PcpToken
*>(25);
159 keywords
->add(new PcpToken(PCP_TOKEN_GUARD
, "guard", -1));
160 keywords
->add(new PcpToken(PCP_TOKEN_LOOP
, "loop", -1));
161 keywords
->add(new PcpToken(PCP_TOKEN_COPY
, "copy", -1));
162 keywords
->add(new PcpToken(PCP_TOKEN_EQ
, "eq", -1));
163 keywords
->add(new PcpToken(PCP_TOKEN_GE
, "ge", -1));
164 keywords
->add(new PcpToken(PCP_TOKEN_AND
, "and", -1));
165 keywords
->add(new PcpToken(PCP_TOKEN_OR
, "or", -1));
166 keywords
->add(new PcpToken(PCP_TOKEN_DEF
, "def", -1));
167 keywords
->add(new PcpToken(PCP_TOKEN_USE
, "use", -1));
168 keywords
->add(new PcpToken(PCP_TOKEN_MAYDEF
, "maydef", -1));
169 keywords
->add(new PcpToken(PCP_TOKEN_ARRAY
, "array", -1));
170 keywords
->add(new PcpToken(PCP_TOKEN_IV
, "iv", -1));
171 keywords
->add(new PcpToken(PCP_TOKEN_PARAMETER
, "parameter", -1));
172 keywords
->add(new PcpToken(PCP_TOKEN_VARIABLE
, "variable", -1));
173 keywords
->add(new PcpToken(PCP_TOKEN_MULTIPLY
, "*", -1));
174 keywords
->add(new PcpToken(PCP_TOKEN_ADD
, "+", -1));
175 keywords
->add(new PcpToken(PCP_TOKEN_SUBTRACT
, "-", -1));
176 keywords
->add(new PcpToken(PCP_TOKEN_SCOP
, "scop", -1));
177 keywords
->add(new PcpToken(PCP_TOKEN_INPUT
, "inputs", -1));
178 keywords
->add(new PcpToken(PCP_TOKEN_OUTPUT
, "outputs", -1));
179 keywords
->add(new PcpToken(PCP_TOKEN_FLOOR
, "floor", -1));
180 keywords
->add(new PcpToken(PCP_TOKEN_CEIL
, "ceil", -1));
181 keywords
->add(new PcpToken(PCP_TOKEN_MIN
, "min", -1));
182 keywords
->add(new PcpToken(PCP_TOKEN_MAX
, "max", -1));
183 keywords
->add(new PcpToken(PCP_TOKEN_PARAMETERS
, "parameters", -1));
184 PcpToken::setKeywords(keywords
);
189 // Get sequence token.
190 static PcpToken
* getSequenceToken()
192 if(PcpToken::sequenceToken
== NULL
)
193 PcpToken::setSequenceToken(new PcpToken(PCP_TOKEN_SEQUENCE
,
196 return PcpToken::sequenceToken
;
206 // Get an iterator over the delimiters.
207 static PcpIterator
<PcpToken
*>* getDelimitersIterator()
209 PcpArray
<PcpToken
*>* delimiters
= PcpToken::getDelimiters();
210 if(delimiters
== NULL
)
211 PcpToken::initializeDelimiters();
212 return PcpToken::getDelimiters()->getIterator();
215 // Get an iterator over the keywords.
216 static PcpIterator
<PcpToken
*>* getKeywordsIterator()
218 PcpArray
<PcpToken
*>* keywords
= PcpToken::getKeywords();
220 PcpToken::initializeKeywords();
221 return PcpToken::getKeywords()->getIterator();
235 return this->lineNumber
;
238 // Get name. This function is for debug purposes.
244 case PCP_TOKEN_NUMERAL
:
246 case PCP_TOKEN_IDENTIFIER
:
248 case PCP_TOKEN_GUARD
:
266 case PCP_TOKEN_MAYDEF
:
268 case PCP_TOKEN_ARRAY
:
271 return "InductionVariable";
272 case PCP_TOKEN_PARAMETER
:
274 case PCP_TOKEN_VARIABLE
:
276 case PCP_TOKEN_PARAMETERS
:
278 case PCP_TOKEN_MULTIPLY
:
282 case PCP_TOKEN_SUBTRACT
:
284 case PCP_TOKEN_ARROW
:
286 case PCP_TOKEN_OPEN_PAREN
:
288 case PCP_TOKEN_CLOSE_PAREN
:
290 case PCP_TOKEN_COMMA
:
292 case PCP_TOKEN_OPEN_BRACE
:
294 case PCP_TOKEN_CLOSE_BRACE
:
296 case PCP_TOKEN_VERTICAL_BAR
:
297 return "VerticalBar";
300 case PCP_TOKEN_INPUT
:
302 case PCP_TOKEN_FLOOR
:
310 case PCP_TOKEN_OUTPUT
:
312 case PCP_TOKEN_ERROR
:
314 case PCP_TOKEN_SEQUENCE
:
317 return "Unknown Token";
321 // Return true if this is a numeral.
325 return this->getKind() == PCP_TOKEN_NUMERAL
;
328 // Return true if this is an identifier.
332 return this->getKind() == PCP_TOKEN_IDENTIFIER
;
335 // Return true if this is a guard.
339 return this->getKind() == PCP_TOKEN_GUARD
;
342 // Return true if this is a loop.
346 return this->getKind() == PCP_TOKEN_LOOP
;
349 // Return true if this is a copy.
353 return this->getKind() == PCP_TOKEN_COPY
;
356 // Return true if this is an equality.
360 return this->getKind() == PCP_TOKEN_EQ
;
363 // Return true if this is a greater or equals
367 return this->getKind() == PCP_TOKEN_GE
;
370 // Return true if this is an and.
374 return this->getKind() == PCP_TOKEN_AND
;
377 // Return true if this is an or.
381 return this->getKind() == PCP_TOKEN_OR
;
384 // Return true if this is a def.
388 return this->getKind() == PCP_TOKEN_DEF
;
391 // Return true if this is a use.
395 return this->getKind() == PCP_TOKEN_USE
;
398 // Return true if this is a maydef.
402 return this->getKind() == PCP_TOKEN_MAYDEF
;
405 // Return true if this is an array.
409 return this->getKind() == PCP_TOKEN_ARRAY
;
412 // Return true if this is an iv.
416 return this->getKind() == PCP_TOKEN_IV
;
419 // Return true if this is a parameter.
423 return this->getKind() == PCP_TOKEN_PARAMETER
;
426 // Return true if this is a variable.
430 return this->getKind() == PCP_TOKEN_VARIABLE
;
433 // Return true if this is parameters.
437 return this->getKind() == PCP_TOKEN_PARAMETERS
;
440 // Return true if this is an arrow.
444 return this->getKind() == PCP_TOKEN_ARROW
;
447 // Return true if this is a multiply.
451 return this->getKind() == PCP_TOKEN_MULTIPLY
;
454 // Return true if this is an add.
458 return this->getKind() == PCP_TOKEN_ADD
;
461 // Return true if this is a subtract.
465 return this->getKind() == PCP_TOKEN_SUBTRACT
;
468 // Return true if this is an open paren.
472 return this->getKind() == PCP_TOKEN_OPEN_PAREN
;
475 // Return true if this is a close paren.
479 return this->getKind() == PCP_TOKEN_CLOSE_PAREN
;
482 // Return true if this is a comma.
486 return this->getKind() == PCP_TOKEN_COMMA
;
489 // Return true if this is an open brace.
493 return this->getKind() == PCP_TOKEN_OPEN_BRACE
;
496 // Return true if this is a close brace.
500 return this->getKind() == PCP_TOKEN_CLOSE_BRACE
;
503 // Return true if this is a verticalBar.
507 return this->getKind() == PCP_TOKEN_VERTICAL_BAR
;
510 // Return true if this is a scop.
514 return this->getKind() == PCP_TOKEN_SCOP
;
517 // Return true if this is an input.
521 return this->getKind() == PCP_TOKEN_INPUT
;
524 // Return true if this is an floor.
528 return this->getKind() == PCP_TOKEN_FLOOR
;
530 // Return true if this is an ceil.
534 return this->getKind() == PCP_TOKEN_CEIL
;
536 // Return true if this is an min.
540 return this->getKind() == PCP_TOKEN_MIN
;
542 // Return true if this is an max.
546 return this->getKind() == PCP_TOKEN_MAX
;
549 // Return true if this is an output.
553 return this->getKind() == PCP_TOKEN_OUTPUT
;
556 // Return true if this is an error.
560 return this->getKind() == PCP_TOKEN_ERROR
;
563 // Return true if this is a sequence.
567 return this->getKind() == PCP_TOKEN_SEQUENCE
;
570 // Return true if this is a functor (supposed to take arguments).
575 switch(this->getKind())
577 case PcpToken::PCP_TOKEN_GUARD
:
578 case PcpToken::PCP_TOKEN_LOOP
:
579 case PcpToken::PCP_TOKEN_COPY
:
580 case PcpToken::PCP_TOKEN_EQ
:
581 case PcpToken::PCP_TOKEN_GE
:
582 case PcpToken::PCP_TOKEN_AND
:
583 case PcpToken::PCP_TOKEN_OR
:
584 case PcpToken::PCP_TOKEN_DEF
:
585 case PcpToken::PCP_TOKEN_USE
:
586 case PcpToken::PCP_TOKEN_MAYDEF
:
587 case PcpToken::PCP_TOKEN_ARRAY
:
588 case PcpToken::PCP_TOKEN_IV
:
589 case PcpToken::PCP_TOKEN_PARAMETER
:
590 case PcpToken::PCP_TOKEN_VARIABLE
:
591 case PcpToken::PCP_TOKEN_PARAMETERS
:
592 case PcpToken::PCP_TOKEN_MULTIPLY
:
593 case PcpToken::PCP_TOKEN_ADD
:
594 case PcpToken::PCP_TOKEN_SUBTRACT
:
595 case PcpToken::PCP_TOKEN_SCOP
:
596 case PcpToken::PCP_TOKEN_INPUT
:
597 case PcpToken::PCP_TOKEN_FLOOR
:
598 case PcpToken::PCP_TOKEN_CEIL
:
599 case PcpToken::PCP_TOKEN_MIN
:
600 case PcpToken::PCP_TOKEN_MAX
:
601 case PcpToken::PCP_TOKEN_OUTPUT
:
611 // Create new token of given KIND and STRING.
612 PcpToken(Kind kind
, const char* string
, int lineNumber
)
616 setLineNumber(lineNumber
);
621 PcpToken
* PcpToken::sequenceToken
;
622 template <> PcpArray
<PcpToken
*>* PcpToken::delimiters
;
623 template <> PcpArray
<PcpToken
*>* PcpToken::keywords
;
635 // Set row in TOKENIZER to ROW.
642 // Get row in TOKENIZER.
649 // Increment row in TOKENIZER by 1.
653 this->setRow(this->getRow() + 1);
656 // Set index of TOKENIZER to INDEX.
663 // Get index of TOKENIZER.
670 // Set source length of TOKENIZER to SOURCE_LENGTH.
672 setSourceLength(int sourceLength
)
674 this->sourceLength
= sourceLength
;
677 // Get source length of TOKENIZER.
681 return this->sourceLength
;
684 // Set source of TOKENIZER to SOURCE.
686 setSource(const char* source
)
688 this->source
= source
;
691 // Get source of TOKENIZER.
698 // Get next char in TOKENIZER with OFFSET from the last consumed
704 int index
= this->getIndex() + offset
;
706 if(index
>= this->getSourceLength())
708 result
= this->getSource()[index
];
712 // Get the next char in TOKENIZER that has not been consumed.
716 return this->peekChar(0);
719 // Consume the next charachter in TOKENIZER.
723 this->setIndex(this->getIndex() + 1);
726 // Return true if CHARACHTER is a newline.
728 charIsNewline(char character
)
730 return character
== '\n';
733 // Return true if CHARACTER is a whitespace.
735 charIsWhitespace(char character
)
737 return(character
== '\t'
739 || this->charIsNewline(character
));
742 // Return true if CHARACTER is end of source.
744 charIsEndOfSource(char character
)
746 return character
== '\0';
749 // Return true if TOKENIZER has reached end of source.
753 return this->charIsEndOfSource(this->peekNextChar());
756 // Return true if CHARACTER will end a token.
758 charIsTokenBreak(char character
)
760 return this->charIsWhitespace(character
)
761 || this->charIsEndOfSource(character
);
764 // Return true if CHARACTER is a digit.
766 charIsDigit(char character
)
768 return(character
>= '0' && character
<= '9');
771 // Return true if CHARACTER is a letter.
773 charIsLetter(char character
)
775 return(character
>= 'A' && character
<= 'Z')
776 || (character
>= 'a' && character
<= 'z');
779 // Return true if CHARACTER is a symbol.
781 charIsSymbol(char character
)
783 return character
== '!'
801 // Return true if CHARACTER is illegal.
803 charIsIllegal(char character
)
805 return !this->charIsWhitespace(character
)
806 && !this->charIsDigit(character
)
807 && !this->charIsLetter(character
)
808 && !this->charIsSymbol(character
)
809 && !this->charIsEndOfSource(character
);
812 // Consume all white space character in TOKENIZER until a
813 // non-whitespace chararacter is encountered.
819 for(character
= this->peekNextChar();
820 this->charIsWhitespace(character
);)
822 if(this->charIsNewline(character
))
823 this->incrementRow();
825 character
= this->peekNextChar();
829 // Match STRING in TOKENIZER with at OFFSET.
831 matchStringAtOffset(int offset
, const char* string
)
833 int length
= strlen(string
);
835 bool mismatch
= false;
837 for(index
= 0; !mismatch
&& index
< length
; index
++)
839 char peekChar
= this->peekChar(index
+ offset
);
840 char stringChar
= string
[index
];
841 if(stringChar
!= peekChar
)
847 // Match STRING in TOKENIZER at curent location.
849 matchString(const char* string
)
851 return this->matchStringAtOffset(0, string
);
854 // Match any delimiter in TOKENIZER at given OFFSET.
856 matchDelimiterAtOffset(int offset
)
858 PcpIterator
<PcpToken
*>* delimIter
= PcpToken::getDelimitersIterator();
859 for(;delimIter
->hasNext(); delimIter
->next())
861 PcpToken
* delimiter
= delimIter
->get();
863 mismatch
= this->matchStringAtOffset(
865 delimiter
->getString());
872 // Match any delimiter in TOKENIZER.
876 return this->matchDelimiterAtOffset(0);
879 // Return true if a token break exists in TOKEN at given OFFSET.
881 hasTokenBreakAtOffset(int offset
)
884 this->charIsTokenBreak(this->peekChar
886 || this->matchDelimiterAtOffset(offset
);
890 // Match any keyword in TOKENIZER.
895 PcpIterator
<PcpToken
*>* delimIter
= PcpToken::getKeywordsIterator();
896 for(;delimIter
->hasNext(); delimIter
->next())
898 PcpToken
* keyword
= delimIter
->get();
899 const char* keywordString
= keyword
->getString();
900 bool mismatch
= this->matchString(keywordString
);
901 if(!mismatch
&& this->hasTokenBreakAtOffset(strlen(keywordString
)))
902 return new PcpToken(keyword
->getKind(),
903 keyword
->getString(),
909 // Write all characters in TOKENIZER from OFFSET into BUFFER until a token
912 fillBufferUntilTokenBreak(int offset
,
913 PcpStringBuffer
* buffer
)
916 for(i
= offset
; !this->hasTokenBreakAtOffset(i
);
919 buffer
->appendChar(this->peekChar(i
));
923 // Match a numeral from TOKENIZER.
928 PcpStringBuffer
* buffer
= new PcpStringBuffer();
929 char peekChar
= this->peekChar(i
);
930 while(this->charIsDigit(peekChar
))
932 buffer
->appendChar(peekChar
);
934 if(this->hasTokenBreakAtOffset(i
))
935 return new PcpToken(PcpToken::PCP_TOKEN_NUMERAL
,
938 peekChar
= this->peekChar(i
);
940 if(buffer
->getLength() != 0)
942 this->fillBufferUntilTokenBreak(i
, buffer
);
943 return new PcpToken(PcpToken::PCP_TOKEN_ERROR
,
950 // Match an identifier from TOKENIZER.
955 PcpStringBuffer
* buffer
= new PcpStringBuffer();
956 char peekChar
= this->peekChar(i
);
957 if(this->charIsLetter(peekChar
))
959 buffer
->appendChar(peekChar
);
961 peekChar
= this->peekChar(i
);
962 while(this->charIsLetter(peekChar
)
963 || this->charIsDigit(peekChar
)
964 || this->charIsSymbol(peekChar
))
966 buffer
->appendChar(peekChar
);
968 if(this->hasTokenBreakAtOffset(i
))
969 return new PcpToken(PcpToken::PCP_TOKEN_IDENTIFIER
,
972 peekChar
= this->peekChar(i
);
974 if(buffer
->getLength() != 0)
976 return new PcpToken(PcpToken::PCP_TOKEN_IDENTIFIER
,
987 // Create new tokenizer with given SOURCE.
988 PcpTokenizer(const char* source
)
993 setSourceLength(strlen(source
));
996 // Consume TOKEN in TOKENIZER. This increments the index with the
997 // token string length.
999 consumeToken(PcpToken
* token
)
1001 int length
= strlen(token
->getString());
1002 this->setIndex(getIndex() + length
);
1006 // Get next token from TOKENIZER(without consuming it).
1011 if(this->endOfSource())
1014 this->skipWhitespaces();
1016 token
= this->matchDelimiter();
1020 token
= this->matchKeyword();
1024 token
= this->matchNumeral();
1028 token
= this->matchIdentifier();
1032 // Get and consume the next token from TOKENIZER.
1036 PcpToken
* token
= this->peekNextToken();
1037 this->consumeToken(token
);
1046 // Report parse error.
1048 pcpParseError(const char* error
)
1050 printf("Error: %s\n", error
);
1059 PcpDynamicArray
<PcpAst
*>* children
;
1060 PcpDynamicArray
<PcpAst
*>* annots
;
1062 // Set children of AST to CHILDREN.
1064 setChildren(PcpDynamicArray
<PcpAst
*>* children
)
1066 this->children
= children
;
1069 // Get children of AST.
1070 PcpDynamicArray
<PcpAst
*>*
1073 return this->children
;
1077 setAnnots(PcpDynamicArray
<PcpAst
*>* annots
)
1079 this->annots
= annots
;
1082 PcpDynamicArray
<PcpAst
*>*
1085 return this->annots
;
1089 // Write AST into BUFFER.
1091 toStringInBuffer(PcpStringBuffer
* buffer
)
1093 PcpToken
* token
= this->getToken();
1094 PcpToken
* name
= this->getName();
1095 int numChildren
= this->getNumChildren();
1100 buffer
->append(name
->getString());
1101 buffer
->append(" <- ");
1105 buffer
->append("NULL");
1107 buffer
->append(token
->getString());
1109 if(this->getHasChildren())
1112 buffer
->append("(");
1113 for(i
= 0; i
< numChildren
; i
++)
1118 buffer
->append(", ");
1119 this->getChild(i
)->toStringInBuffer(buffer
);
1121 buffer
->append(")");
1125 // Parse functor list surrounded by '{' '}'.
1127 parseStmtList(PcpTokenizer
* tokenizer
)
1129 PcpToken
* token
= tokenizer
->getNextToken();
1130 PcpAst
* result
= NULL
;
1131 if(!token
->isOpenBrace())
1133 pcpParseError("Expected argument list");
1135 result
= PcpAst::parseStmtListHelper(tokenizer
);
1136 token
= tokenizer
->peekNextToken();
1137 if(token
!= NULL
&& token
->isCloseBrace())
1138 tokenizer
->consumeToken(token
);
1140 pcpParseError("Expected close brace");
1145 parseObjectList1(PcpTokenizer
* tokenizer
, PcpAst
* root
,
1148 PcpToken
* peek
= tokenizer
->peekNextToken();
1149 PcpAst
* object
= NULL
;
1151 object
= PcpAst::parseObject(tokenizer
);
1153 root
->addAnnot(object
);
1155 root
->addChild(object
);
1156 peek
= tokenizer
->peekNextToken();
1159 pcpParseError("Unexpected end of stream");
1163 while(peek
->isComma())
1165 tokenizer
->consumeToken(peek
);
1166 object
= PcpAst::parseObject(tokenizer
);
1168 root
->addAnnot(object
);
1170 root
->addChild(object
);
1172 peek
= tokenizer
->peekNextToken();
1175 pcpParseError("Unexpected end of stream");
1181 // Parse comma separated object list.
1183 parseObjectList(PcpTokenizer
* tokenizer
)
1185 PcpToken
* token
= tokenizer
->getNextToken();
1187 PcpAst
* result
= new PcpAst(PcpToken::getSequenceToken());
1188 result
->setHasChildren(true);
1190 if(!token
->isOpenParen())
1192 pcpParseError("Expected argument list");
1195 peek
= tokenizer
->peekNextToken();
1196 if(peek
->isCloseParen())
1198 tokenizer
->consumeToken(token
);
1202 if(peek
->isVerticalBar())
1204 tokenizer
->consumeToken(peek
);
1205 peek
= tokenizer
->peekNextToken();
1206 if(!peek
->isCloseParen())
1207 PcpAst::parseObjectList1(tokenizer
, result
, true);
1211 PcpAst::parseObjectList1(tokenizer
, result
, false);
1212 peek
= tokenizer
->peekNextToken();
1213 if(peek
->isVerticalBar())
1215 tokenizer
->consumeToken(peek
);
1216 PcpAst::parseObjectList1(tokenizer
, result
, true);
1220 peek
= tokenizer
->peekNextToken();
1221 if(peek
->isCloseParen())
1222 tokenizer
->consumeToken(token
);
1224 pcpParseError("Error, expected close paren");
1232 parseObject(PcpTokenizer
* tokenizer
)
1234 PcpToken
* token
= tokenizer
->getNextToken();
1235 if(token
->isFunctor())
1237 PcpAst
* result
= PcpAst::parseObjectList(tokenizer
);
1238 PcpToken
* peek
= tokenizer
->peekNextToken();
1239 result
->setToken(token
);
1240 // We may have a body to parse as well.
1241 if(peek
!= NULL
&& peek
->isOpenBrace())
1243 // Stmt list is a non comma separated object list.
1244 PcpAst
* body
= PcpAst::parseStmtList(tokenizer
);
1245 result
->addChild(body
);
1249 else if(token
->isIdentifier())
1251 PcpToken
* peek
= tokenizer
->peekNextToken();
1252 if(peek
->isOpenParen())
1254 PcpAst
* result
= PcpAst::parseObjectList(tokenizer
);
1255 result
->setToken(token
);
1258 else if(peek
->isArrow())
1260 PcpAst
* result
= PcpAst::parseBinding(tokenizer
, token
);
1264 return new PcpAst(token
);
1266 else if(token
->isNumeral())
1267 return new PcpAst(token
);
1270 pcpParseError("Unexpected token");
1275 // Parse "identifier <- object" sequence.
1277 parseBinding(PcpTokenizer
* tokenizer
, PcpToken
* name
)
1279 PcpToken
* token
= tokenizer
->getNextToken();
1281 pcpAssert(name
!= NULL
);
1282 if(token
->isArrow())
1284 PcpAst
* result
= PcpAst::parseObject(tokenizer
);
1285 result
->setName(name
);
1289 pcpParseError("Expected '<-' after identifier");
1293 // Parse list of functor strings.
1295 parseStmtListHelper(PcpTokenizer
* tokenizer
)
1297 PcpToken
* peek
= tokenizer
->peekNextToken();
1298 PcpAst
* result
= new PcpAst(PcpToken::getSequenceToken());
1299 PcpAst
* object
= NULL
;
1301 result
->setHasChildren(true);
1303 if(peek
->isFunctor() || peek
->isIdentifier())
1306 object
= PcpAst::parseObject(tokenizer
);
1307 result
->addChild(object
);
1308 token
= tokenizer
->peekNextToken();
1309 while(token
!= NULL
&& (token
->isFunctor() || token
->isIdentifier()))
1311 object
= PcpAst::parseObject(tokenizer
);
1312 result
->addChild(object
);
1313 token
= tokenizer
->peekNextToken();
1322 // Convert AST to string.
1326 PcpStringBuffer
* buffer
= new PcpStringBuffer();
1327 this->toStringInBuffer(buffer
);
1328 return buffer
->toString();
1334 return this->getAnnots()->getSize();
1340 return this->getAnnots()->get(index
);
1344 // Get number of childern in AST.
1348 return this->getChildren()->getSize();
1351 // Get child with CHILDIndex from AST.
1353 getChild(int childIndex
)
1355 return this->getChildren()->get(childIndex
);
1358 // Set name of AST to NAME.
1360 setName(PcpToken
* name
)
1372 // Set token of AST to TOKEN.
1374 setToken(PcpToken
* token
)
1376 this->token
= token
;
1379 // Get token of AST.
1386 // Set if AST HASChildren.
1388 setHasChildren(bool hasChildren
)
1390 this->hasChildren
= hasChildren
;
1393 // Return true if AST has children.
1397 return this->hasChildren
;
1401 addAnnot(PcpAst
* annot
)
1403 this->getAnnots()->add(annot
);
1406 // Add CHILD to AST.
1408 addChild(PcpAst
* child
)
1410 this->getChildren()->add(child
);
1413 // Create a new token ast from TOKEN.
1414 PcpAst(PcpToken
* token
)
1416 PcpDynamicArray
<PcpAst
*>* children
= new PcpDynamicArray
<PcpAst
*>(1);
1417 PcpDynamicArray
<PcpAst
*>* annots
= new PcpDynamicArray
<PcpAst
*>(1);
1418 this->setName(NULL
);
1419 this->setToken(token
);
1420 this->setChildren(children
);
1421 this->setHasChildren(false);
1422 this->setAnnots(annots
);
1425 // Parse list of functor strings.
1427 parse(PcpTokenizer
* tokenizer
)
1429 return PcpAst::parseStmtListHelper(tokenizer
);
1434 // Pcp Parser (Token stream to AST)
1436 // Return true if token is a functor(token that must take
1442 PcpDynamicArray
<PcpObject
*>* entries
;
1444 // Set entries of SYMTAB to ENTRIES.
1446 setEntries(PcpDynamicArray
<PcpObject
*>* entries
)
1448 this->entries
= entries
;
1451 // Get entries of SYMTAB.
1452 PcpDynamicArray
<PcpObject
*>*
1455 return this->entries
;
1460 // Return object with given NAME in SYMTAB, if it does not exist
1463 lookupName(const char* name
)
1465 PcpIterator
<PcpObject
*>* symtabIter
= this->getEntries()->getIterator();
1466 for(;symtabIter
->hasNext(); symtabIter
->next())
1468 PcpObject
* entry
= symtabIter
->get();
1469 const char* entryName
= entry
->getName();
1470 if(strcmp(name
, entryName
) == 0)
1476 // Lookup TOKEN's string in SYMTAB.
1478 lookup(PcpToken
* token
)
1480 const char* name
= token
->getString();
1481 return this->lookupName(name
);
1485 // Insert OBJECT in SYMTAB.
1487 insert(PcpObject
* object
)
1489 PcpObject
* existingObject
=
1490 this->lookupName(object
->getName());
1491 pcpAssert(object
->getName() != NULL
);
1492 pcpAssert(existingObject
== NULL
|| existingObject
== object
);
1493 this->getEntries()->add(object
);
1496 // Create new symbol table.
1499 this->setEntries(new PcpDynamicArray
<PcpObject
*>(5));
1507 PcpParser::setSymtab(PcpSymtab
* symtab
)
1509 this->symtab
= symtab
;
1512 // Get symbol table in CONTEXT.
1514 PcpParser::getSymtab()
1516 return this->symtab
;
1519 // Set parser CONTEXT to add annotations to ADDLineAnnots.
1521 PcpParser::setAddLineAnnots(bool addLineAnnots
)
1523 this->addLineAnnots
= addLineAnnots
;
1526 // Return if parser CONTEXT should insert line annotations.
1528 PcpParser::getAddLineAnnots()
1530 return this->addLineAnnots
;
1533 // Set file name in CONTEXT to FILEName.
1535 PcpParser::setFileName(const char* fileName
)
1537 this->fileName
= fileName
;
1540 // Get file name in CONTEXT.
1542 PcpParser::getFileName()
1544 return this->fileName
;
1548 // Parse NUMERAL and return created constant.
1550 PcpParser::parseNumeral(PcpAst
* numeral
)
1553 PcpConstant
* result
;
1554 PcpToken
* token
= numeral
->getToken();
1556 if(!token
->isNumeral())
1557 pcpParseError("Expected numeral");
1558 sscanf(token
->getString(), "%d", &value
);
1559 result
= new PcpConstant(value
);
1565 PcpParser::addLineAnnot(PcpObject
* object
, PcpAst
* ast
)
1567 if(this->getAddLineAnnots() && !object
->containsAnnotWithTag("lineinfo"))
1569 PcpAnnotTermBuilder
* termBuilder
= new PcpAnnotTermBuilder();
1570 const char* filename
= this->getFileName();
1571 PcpAnnotString
* filenameAnnot
= new PcpAnnotString(filename
);
1572 PcpAnnotInt
* lineNumberAnnot
=
1573 new PcpAnnotInt(ast
->getToken()->getLineNumber());
1574 PcpAnnotTerm
* lineinfoAnnot
= NULL
;
1576 termBuilder
->setTag("lineinfo");
1577 termBuilder
->addArgument(filenameAnnot
);
1578 termBuilder
->addArgument(lineNumberAnnot
);
1579 lineinfoAnnot
= termBuilder
->createAnnot();
1581 object
->addAnnot(lineinfoAnnot
);
1585 // Register OBJECT in SYMTAB with TOKENAst's token string. If
1586 // TOKENAst is NULL or the string is NULL do nothing.
1588 PcpParser::parseCommonObjectAttributes(PcpAst
* ast
,
1591 PcpSymtab
* symtab
= this->getSymtab();
1592 PcpToken
* tokenName
= ast
->getName();
1593 if(tokenName
!= NULL
&& tokenName
->getString() != NULL
)
1595 const char* name
= tokenName
->getString();
1596 object
->setName(name
);
1597 symtab
->insert(object
);
1599 this->parseAnnots(object
, ast
);
1600 this->addLineAnnot(object
, ast
);
1603 // Parse MULTIPLY and return the created pcp multiply object.
1605 PcpParser::parseMultiply(PcpAst
* multiply
)
1607 int numChildren
= multiply
->getNumChildren();
1608 if(numChildren
!= 2)
1609 pcpParseError("Expected two arguments for multiply");
1612 PcpSymtab
* symtab
= this->getSymtab();
1613 PcpAst
* lhsAst
= multiply
->getChild(0);
1614 PcpToken
* lhsToken
= lhsAst
->getToken();
1615 PcpAst
* rhsAst
= multiply
->getChild(1);
1616 PcpToken
* rhsToken
= rhsAst
->getToken();
1617 PcpObject
* rhsObject
;
1619 if(!lhsToken
->isNumeral())
1620 pcpParseError("Expected constant as lhs of multiply");
1622 if(!rhsToken
->isIdentifier())
1623 pcpParseError("Expected iv as rhs of multiply");
1625 rhsObject
= symtab
->lookup(rhsToken
);
1627 if(rhsObject
== NULL
|| !rhsObject
->isIv())
1628 pcpParseError("Expected iv as rhs of multiply");
1631 PcpArith
* multiplyObject
=
1632 PcpArith::pcpArithBinaryCreate(PcpArithOperator::multiply(),
1633 this->parseNumeral(lhsAst
),
1635 return multiplyObject
;
1641 // Parse AST and return the created pcp expression.
1643 PcpParser::parseScalarIdentifier(PcpAst
* ast
)
1645 PcpSymtab
* symtab
= this->getSymtab();
1646 PcpToken
* token
= ast
->getToken();
1647 PcpObject
* result
= symtab
->lookup(token
);
1648 if(ast
->getHasChildren()
1650 || (!result
->isParameter() && !result
->isIv()))
1651 pcpParseError("Expected scalar value");
1652 return result
->toExpr();
1656 PcpParser::parseArithOperator(PcpToken
* operatorToken
)
1658 if(operatorToken
->isAdd())
1659 return PcpArithOperator::add();
1660 else if(operatorToken
->isSubtract())
1661 return PcpArithOperator::subtract();
1662 else if(operatorToken
->isFloor())
1663 return PcpArithOperator::floor();
1664 else if(operatorToken
->isCeil())
1665 return PcpArithOperator::ceiling();
1666 else if(operatorToken
->isMin())
1667 return PcpArithOperator::min();
1668 else if(operatorToken
->isMax())
1669 return PcpArithOperator::max();
1671 return PcpArithOperator::unknown();
1674 bool PcpParser::pcpTokenIsOperator(PcpToken
* operatorToken
)
1676 return !this->parseArithOperator(operatorToken
).isUnknown();
1679 // Parse AST(add or subtract ast) and return the created pcp expression.
1681 PcpParser::parseArith(PcpAst
* ast
)
1683 int numChildren
= ast
->getNumChildren();
1684 PcpArithOperator oper
=
1685 this->parseArithOperator(ast
->getToken());
1688 PcpArithBuilder
* arithBuilder
= new PcpArithBuilder();
1690 if(oper
.isUnknown())
1691 pcpParseError("Not a valid operator");
1692 if(oper
.isSubtract() && (numChildren
> 2 || numChildren
< 1))
1693 pcpParseError("Wrong number of arguments to subtract");
1695 pcpParseError("Too few arguments to arith");
1697 arithBuilder
->setOperator(oper
);
1699 for(i
= 0; i
< numChildren
; i
++)
1701 PcpExpr
* operand
= this->parseLinearExpr(ast
->getChild(i
));
1702 arithBuilder
->addOperand(operand
);
1704 arith
= arithBuilder
->createArith();
1708 // Parse AST and return the created pcp expression.
1710 PcpParser::parseLinearExpr(PcpAst
* ast
)
1713 PcpToken
* token
= ast
->getToken();
1714 if(token
->isNumeral())
1715 result
= this->parseNumeral(ast
);
1716 else if(token
->isIdentifier())
1717 result
= this->parseScalarIdentifier(ast
);
1718 else if(pcpTokenIsOperator(token
))
1719 result
= this->parseArith(ast
);
1720 else if(token
->isMultiply())
1721 result
= this->parseMultiply(ast
);
1724 pcpParseError("Not a linear expr");
1728 if(!token
->isNumeral() && !token
->isIdentifier())
1729 this->parseCommonObjectAttributes(ast
, result
);
1733 // Parse AST and return the created comparison(eq or ge).
1735 PcpParser::parseComparison(PcpAst
* ast
)
1737 int numChildren
= ast
->getNumChildren();
1738 PcpToken
* token
= ast
->getToken();
1742 if(numChildren
!= 2)
1743 pcpParseError("Wrong number of arguments to eq/ge");
1745 lhs
= this->parseLinearExpr(ast
->getChild(0));
1746 rhs
= this->parseLinearExpr(ast
->getChild(1));
1748 return new PcpCompare(PcpCompareOperator::equal(), lhs
, rhs
);
1749 else if(token
->isGe())
1750 return new PcpCompare(PcpCompareOperator::greaterEqual(), lhs
, rhs
);
1752 pcpParseError("Not eq/ge expr");
1756 PcpBoolArithOperator
1757 PcpParser::parseBoolArithOperator(PcpToken
* operatorToken
)
1759 if(operatorToken
->isAnd())
1760 return PcpBoolArithOperator::boolAnd();
1761 else if(operatorToken
->isOr())
1762 return PcpBoolArithOperator::boolOr();
1764 return PcpBoolArithOperator::unknown();
1767 bool PcpParser::pcpTokenIsBoolArithOperator(PcpToken
* operatorToken
)
1769 return !this->parseBoolArithOperator(operatorToken
).isUnknown();
1773 PcpParser::parseBoolArith(PcpAst
* ast
)
1775 int numChildren
= ast
->getNumChildren();
1776 PcpBoolArithOperator oper
=
1777 this->parseBoolArithOperator(ast
->getToken());
1778 PcpBoolArith
* boolArith
;
1780 PcpBoolArithBuilder
* boolArithBuilder
= new PcpBoolArithBuilder();
1782 if(oper
.isUnknown())
1783 pcpParseError("Not a valid operator");
1785 pcpParseError("Too few arguments to bool arith");
1787 boolArithBuilder
->setOperator(oper
);
1789 for(i
= 0; i
< numChildren
; i
++)
1791 PcpBoolExpr
* operand
=
1792 this->parseBoolExpr(ast
->getChild(i
));
1793 boolArithBuilder
->addOperand(operand
);
1795 boolArith
= boolArithBuilder
->createBoolArith();
1799 // Parse ast and return the created pcp boolean expression.
1801 PcpParser::parseBoolExpr(PcpAst
* ast
)
1803 PcpToken
* token
= ast
->getToken();
1804 PcpBoolExpr
* result
= NULL
;
1805 if(token
->isEq() || token
->isGe())
1806 result
= this->parseComparison(ast
);
1807 if(token
->isAnd() || token
->isOr())
1808 result
= this->parseBoolArith(ast
);
1812 pcpParseError("Not a boolean expression");
1815 this->parseCommonObjectAttributes(ast
, result
);
1819 // Parse AST(identifier) and return the corresponding object from
1820 // SYMTAB. If the identifier does not exist in SYMTAB
1821 // report as error and return NULL.
1823 PcpParser::parseIdentifier(PcpAst
* ast
)
1825 PcpObject
* result
= NULL
;
1826 PcpToken
* token
= ast
->getToken();
1828 if(!ast
->getHasChildren())
1830 PcpSymtab
* symtab
= this->getSymtab();
1831 result
= symtab
->lookup(token
);
1833 pcpParseError("Unknown identifier");
1838 // Parse ast(array access ast) and return the created array access.
1840 PcpParser::parseArrayAccess(PcpAst
* ast
)
1842 int numChildren
= ast
->getNumChildren();
1843 PcpToken
* token
= ast
->getToken();
1844 PcpArrayAccessBuilder
* builder
;
1846 PcpArrayAccess
* result
;
1851 pcpParseError("Wrong number of arguments to array access");
1854 base
= this->parseIdentifier(ast
->getChild(0));
1855 if(!base
->isVariable())
1856 pcpParseError("Base object is not a variable in array access");
1858 builder
= new PcpArrayAccessBuilder(base
->toVariable());
1860 for(i
= 1; i
< numChildren
; i
++)
1862 PcpExpr
* subscript
=
1863 this->parseLinearExpr(ast
->getChild(i
));
1864 builder
->addSubscript(subscript
);
1868 builder
->setOperator(PcpArrayOperator::use());
1869 else if(token
->isDef())
1870 builder
->setOperator(PcpArrayOperator::def());
1871 else if(token
->isMaydef())
1872 builder
->setOperator(PcpArrayOperator::maydef());
1875 pcpParseError("Unknown array access token");
1879 result
= builder
->createAccess();
1880 this->parseCommonObjectAttributes(ast
, result
);
1884 // Return true if TOKEN is empty or an unknown symbol in
1887 PcpParser::parseTokenIsUnknownSymbol(PcpToken
* token
)
1889 PcpSymtab
* symtab
= this->getSymtab();
1890 return(token
->getString() != NULL
1891 && token
->isIdentifier()
1892 && symtab
->lookup(token
) == NULL
);
1896 // Parse USERStmt and return the created pcp user statement.
1898 PcpParser::parseUserStmt(PcpAst
* userStmt
)
1900 PcpUserStmt
* result
;
1901 PcpUserStmtBuilder
* builder
;
1902 int numChildren
= userStmt
->getNumChildren();
1903 PcpToken
* token
= userStmt
->getToken();
1904 const char* tokenName
= token
->getString();
1907 if(!this->parseTokenIsUnknownSymbol(token
))
1909 pcpParseError("User stmt name is invalid");
1913 builder
= new PcpUserStmtBuilder();
1915 builder
->setName(tokenName
);
1917 for(i
= 0; i
< numChildren
; i
++)
1919 PcpArrayAccess
* access
=
1920 this->parseArrayAccess(userStmt
->getChild(i
));
1921 builder
->addAccess(access
);
1923 result
= builder
->createUserStmt();
1924 this->parseCommonObjectAttributes(userStmt
, result
);
1928 // Parse COPY and return the created pcp copy.
1930 PcpParser::parseCopy(PcpAst
* copy
)
1932 PcpToken
* token
= copy
->getToken();
1933 int numChildren
= copy
->getNumChildren();
1934 PcpArrayAccess
* dest
;
1935 PcpArrayAccess
* src
;
1938 if(!token
->isCopy())
1940 pcpParseError("Token is not a copy");
1943 if(numChildren
!= 2)
1945 pcpParseError("Wrong number of arguments to copy stmt");
1950 this->parseArrayAccess(copy
->getChild(0));
1952 this->parseArrayAccess(copy
->getChild(1));
1954 if(!dest
->isDef() || !src
->isUse())
1957 ("Expected def as first argument and use as second argument in copy");
1961 result
= new PcpCopy(dest
, src
);
1962 this->parseCommonObjectAttributes(copy
, result
);
1966 // Parse SEQUENCE and return the created pcp statement sequence.
1968 PcpParser::parseSequence(PcpAst
* sequence
)
1970 PcpToken
* token
= sequence
->getToken();
1971 int numChildren
= sequence
->getNumChildren();
1972 PcpSequenceBuilder
* builder
;
1973 PcpSequence
* result
;
1976 if(!token
->isSequence())
1978 pcpParseError("Statement list is not valid sequence");
1981 builder
= new PcpSequenceBuilder();
1982 for(i
= 0; i
< numChildren
; i
++)
1984 PcpStmt
* stmt
= this->parseStmt(sequence
->getChild(i
));
1987 result
= builder
->createSequence();
1991 // Parse GUARD and return the created pcp guard.
1993 PcpParser::parseGuard(PcpAst
* guard
)
1995 PcpToken
* token
= guard
->getToken();
1996 int numChildren
= guard
->getNumChildren();
1997 PcpBoolExpr
* condition
;
2001 if(!token
->isGuard())
2003 pcpParseError("Invalid guard stmt");
2007 if(numChildren
!= 2)
2009 pcpParseError("Condition or Body missing in guard");
2012 condition
= this->parseBoolExpr(guard
->getChild(0));
2013 body
= this->parseStmt(guard
->getChild(1));
2014 result
= new PcpGuard(condition
, body
);
2015 this->parseCommonObjectAttributes(guard
, result
);
2019 // Parse IV and return the created pcp iv.
2021 PcpParser::parseIv(PcpAst
* iv
)
2023 PcpToken
* token
= iv
->getToken();
2024 int numChildren
= iv
->getNumChildren();
2025 const char* tokenString
= token
->getString();
2030 pcpParseError("Not an iv declaration");
2033 if(!iv
->getHasChildren() || !numChildren
== 0)
2035 pcpParseError("Wrong number of arguments to iv declaration");
2038 if(tokenString
== NULL
)
2040 pcpParseError("No name given to iv");
2043 result
= new PcpIv(tokenString
);
2044 this->parseCommonObjectAttributes(iv
, result
);
2048 // Parse LOOP and return the created pcp loop.
2050 PcpParser::parseLoop(PcpAst
* loop
)
2052 PcpToken
* token
= loop
->getToken();
2053 int numChildren
= loop
->getNumChildren();
2057 PcpConstant
* stride
;
2061 if(!token
->isLoop())
2063 pcpParseError("Expected loop construct");
2067 if(numChildren
!= 5)
2069 pcpParseError("Wrong number of arguments to loop");
2073 iv
= this->parseIv(loop
->getChild(0));
2075 this->parseLinearExpr(loop
->getChild(1));
2076 end
= this->parseBoolExpr(loop
->getChild(2));
2077 stride
= this->parseNumeral(loop
->getChild(3));
2078 body
= this->parseStmt(loop
->getChild(4));
2080 result
= new PcpLoop(iv
, start
, end
, stride
, body
);
2081 this->parseCommonObjectAttributes(loop
, result
);
2087 // Parse STMT and return the created pcp statement.
2089 PcpParser::parseStmt(PcpAst
* stmt
)
2091 PcpToken
* token
= stmt
->getToken();
2092 PcpStmt
* result
= NULL
;
2094 result
= this->parseCopy(stmt
);
2095 else if(this->parseTokenIsUnknownSymbol(token
))
2096 result
= this->parseUserStmt(stmt
);
2097 else if(token
->isGuard())
2098 result
= this->parseGuard(stmt
);
2099 else if(token
->isSequence())
2100 result
= this->parseSequence(stmt
);
2101 else if(token
->isLoop())
2102 result
= this->parseLoop(stmt
);
2105 pcpParseError("Invalid statement in sequence");
2113 PcpParser::parseScopInoutput(PcpAst
* inoutput
,
2114 PcpScopBuilder
* builder
)
2116 PcpToken
* token
= inoutput
->getToken();
2117 int numChildren
= inoutput
->getNumChildren();
2120 if(!token
->isInput() && !token
->isOutput())
2122 pcpParseError("Not an input or output list");
2126 for(i
= 0; i
< numChildren
; i
++)
2128 PcpAst
* child
= inoutput
->getChild(i
);
2129 PcpToken
* childToken
= child
->getToken();
2130 if(childToken
->isIdentifier())
2132 PcpObject
* object
= this->parseIdentifier(child
);
2134 pcpParseError("Unknown identifier in scop input/output list");
2135 else if(!object
->isVariable())
2136 pcpParseError("Non variable found in scop input/output list");
2139 PcpVariable
* variable
= object
->toVariable();
2140 builder
->addVariable(variable
);
2141 if(token
->isInput())
2142 variable
->setIsInput(true);
2144 variable
->setIsOutput(true);
2148 pcpParseError("Expected identifier in scop inputs/outputs list");
2153 PcpParser::parseScopParameters(PcpAst
* parameters
,
2154 PcpScopBuilder
* builder
)
2156 PcpToken
* token
= parameters
->getToken();
2157 int numChildren
= parameters
->getNumChildren();
2160 if(!token
->isParameters())
2162 pcpParseError("Not a parameter list");
2166 for(i
= 0; i
< numChildren
; i
++)
2168 PcpAst
* child
= parameters
->getChild(i
);
2169 PcpToken
* childToken
= child
->getToken();
2170 if(childToken
->isIdentifier())
2172 PcpObject
* object
= this->parseIdentifier(child
);
2174 pcpParseError("Unknown identifier in scop parameter list");
2175 else if(!object
->isParameter())
2176 pcpParseError("Non parameter found in scop parameter list");
2179 PcpParameter
* parameter
= object
->toParameter();
2180 builder
->addParameter(parameter
);
2184 pcpParseError("Expected identifier in scop parameter list");
2189 PcpParser::parseScop(PcpAst
* scop
)
2191 PcpScop
* result
= NULL
;
2192 PcpToken
* token
= scop
->getToken();
2193 int numChildren
= scop
->getNumChildren();
2194 PcpScopBuilder
* builder
;
2198 if(!token
->isScop())
2200 pcpParseError("Construct is not a scop");
2204 if(numChildren
> 4 || numChildren
< 1)
2206 pcpParseError("Wrong number of arguments to scop or missing body");
2209 builder
= new PcpScopBuilder();
2211 // Parse everythin except the body.
2212 for(i
= 0; i
< numChildren
- 1; i
++)
2214 PcpAst
* child
= scop
->getChild(i
);
2215 PcpToken
* childToken
= child
->getToken();
2216 if(childToken
->isInput() || childToken
->isOutput())
2217 this->parseScopInoutput(child
, builder
);
2218 else if(childToken
->isParameters())
2219 this->parseScopParameters(child
, builder
);
2223 body
= this->parseStmt(scop
->getChild(numChildren
- 1));
2224 builder
->setBody(body
);
2225 result
= builder
->createScop();
2226 this->parseCommonObjectAttributes(scop
, result
);
2231 PcpParser::parseArrayType(PcpAst
* arrayType
)
2233 PcpToken
* token
= arrayType
->getToken();
2234 int numChildren
= arrayType
->getNumChildren();
2235 PcpArrayTypeBuilder
* builder
;
2239 if(!token
->isArray())
2241 pcpParseError("Expected array construct");
2245 builder
= new PcpArrayTypeBuilder();
2247 for(i
= 0; i
< numChildren
; i
++)
2249 PcpAst
* child
= arrayType
->getChild(i
);
2250 PcpToken
* childToken
= child
->getToken();
2251 PcpExpr
* dim
= NULL
;
2252 if(childToken
->isNumeral())
2253 dim
= this->parseNumeral(child
);
2254 else if(childToken
->isIdentifier())
2256 PcpObject
* object
= this->parseIdentifier(child
);
2257 if(!object
->isParameter())
2258 pcpParseError("Array type dimension is not a constant or parameter");
2259 dim
= object
->toExpr();
2263 pcpParseError("unexpected token in array dimension list");
2266 builder
->addDimension(dim
);
2269 type
= builder
->createType();
2270 this->parseCommonObjectAttributes(arrayType
, type
);
2275 PcpParser::parseVariable(PcpAst
* array
)
2277 PcpToken
* token
= array
->getToken();
2278 int numChildren
= array
->getNumChildren();
2280 PcpVariable
* result
;
2281 PcpToken
* nameToken
= array
->getName();
2282 const char* name
= nameToken
!= NULL
? nameToken
->getString() : NULL
;
2284 PcpToken
* typeToken
;
2286 if(!token
->isVariable())
2288 pcpParseError("Expected variable construct");
2292 if(numChildren
!= 1)
2293 pcpParseError("Wrong number of arguments to variable");
2297 pcpParseError("No name given to variable");
2301 typeAst
= array
->getChild(0);
2302 typeToken
= typeAst
->getToken();
2304 if(typeToken
->isIdentifier())
2305 type
= this->parseIdentifier(typeAst
)->toArrayType();
2306 else if(typeToken
->isArray())
2307 type
= this->parseArrayType(typeAst
);
2312 pcpParseError("Illegal type construct given to varaible");
2314 result
= new PcpVariable(type
, name
);
2315 this->parseCommonObjectAttributes(array
, result
);
2320 PcpParser::pcpParseAnnotTerm(PcpAst
* termAst
)
2322 int numChildren
= termAst
->getNumChildren();
2323 PcpToken
* token
= termAst
->getToken();
2324 PcpAnnotTermBuilder
* termBuilder
= NULL
;
2326 if(!token
->isIdentifier())
2328 pcpParseError("Expected identifier as tag for annotation");
2332 termBuilder
= new PcpAnnotTermBuilder();
2333 termBuilder
->setTag(token
->getString());
2334 for(i
= 0; i
< numChildren
; i
++)
2336 PcpAnnot
* annot
= pcpParseAnnot(termAst
->getChild(i
));
2337 termBuilder
->addArgument(annot
);
2339 return termBuilder
->createAnnot();
2343 PcpParser::pcpParseAnnot(PcpAst
* annotAst
)
2345 PcpToken
* token
= annotAst
->getToken();
2346 if(!annotAst
->getHasChildren())
2348 if(token
->isNumeral())
2350 PcpConstant
* constant
= this->parseNumeral(annotAst
);
2351 int value
= constant
->getValue();
2352 return new PcpAnnotInt(value
);
2354 else if(token
->isIdentifier())
2356 PcpSymtab
* symtab
= this->getSymtab();
2357 const char* tokenString
= token
->getString();
2358 PcpObject
* object
= symtab
->lookup(token
);
2360 return new PcpAnnotObject(object
);
2362 return new PcpAnnotString(tokenString
);
2366 pcpParseError("Unexpected token in optional arg list");
2371 return pcpParseAnnotTerm(annotAst
);
2375 PcpParser::parseAnnots(PcpObject
* object
, PcpAst
* objectAst
)
2377 int numAnnots
= objectAst
->getNumAnnots();
2379 for(i
= 0; i
< numAnnots
; i
++)
2381 PcpAst
* annotAst
= objectAst
->getAnnot(i
);
2382 PcpAnnotTerm
* annot
= pcpParseAnnotTerm(annotAst
);
2385 object
->addAnnot(annot
);
2391 PcpParser::parseParameter(PcpAst
* parameter
)
2393 PcpToken
* token
= parameter
->getToken();
2394 int numChildren
= parameter
->getNumChildren();
2395 PcpToken
* nameToken
= parameter
->getName();
2396 PcpParameter
* result
= NULL
;
2397 const char* name
= nameToken
!= NULL
? nameToken
->getString() : NULL
;
2399 if(!token
->isParameter())
2401 pcpParseError("Expected parameter construct");
2405 if(numChildren
!= 0)
2408 ("Wrong number of arguments to parameter, expected zero");
2414 pcpParseError("No name given to parameter");
2418 result
= new PcpParameter(name
);
2419 this->parseCommonObjectAttributes(parameter
, result
);
2425 PcpParser::pcpAstParseTopLevel(PcpAst
* program
)
2427 PcpToken
* token
= program
->getToken();
2428 int numChildren
= program
->getNumChildren();
2431 if(!token
->isSequence())
2433 pcpParseError("Program is not a sequence of statements");
2436 for(i
= 0; i
< numChildren
; i
++)
2438 PcpAst
* child
= program
->getChild(i
);
2439 PcpToken
* childToken
= child
->getToken();
2441 // We allow parameter, array and scop constructs.
2442 if(childToken
->isVariable())
2443 this->parseVariable(child
);
2444 else if(childToken
->isArray())
2445 this->parseArrayType(child
);
2446 else if(childToken
->isParameter())
2447 this->parseParameter(child
);
2448 else if(childToken
->isScop())
2449 return this->parseScop(child
);
2451 pcpParseError("Illegal top level construct.");
2454 pcpParseError("No scop found in source");
2458 PcpParser::PcpParser()
2460 PcpSymtab
* symtab
= new PcpSymtab();
2461 this->setSymtab(symtab
);
2462 this->setFileName("unknown");
2463 this->setAddLineAnnots(true);
2467 PcpParser::parse(const char* source
)
2469 PcpTokenizer
* tokenizer
= new PcpTokenizer(source
);
2470 PcpAst
* ast
= PcpAst::parse(tokenizer
);
2472 PcpParser
* parser
= new PcpParser();
2473 scop
= parser
->pcpAstParseTopLevel(ast
);
2478 PcpParser::parseFile(const char* filename
)
2481 FILE* file
= fopen(filename
, "r");
2486 pcpParseError("Unable to open file");
2490 fseek(file
, 0 , SEEK_END
);
2494 buffer
=(char*) PCP_NEWVEC(char, size
);
2497 pcpParseError("Memory error");
2501 readsize
= fread(buffer
,1,size
,file
);
2502 if(readsize
!= size
)
2504 pcpParseError("Unable to read file");
2507 return PcpParser::parse(buffer
);