Remove outermost loop parameter.
[official-gcc/graphite-test-results.git] / libpcp / pcp_parser.cc
blobad66d9edde955797575e79966b9d06233c5d367e
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
14 // more details.
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"
30 #include "pcp.h"
31 #include "pcp_string_buffer.h"
32 #include "pcp_dynamic_array.h"
33 #include "pcp_emitter.h"
34 #include "pcp_parser.h"
35 #include <string.h>
38 // Parser Token
39 class PcpToken
41 public:
42 enum Kind
44 PCP_TOKEN_NUMERAL,
45 PCP_TOKEN_IDENTIFIER,
46 PCP_TOKEN_GUARD,
47 PCP_TOKEN_LOOP,
48 PCP_TOKEN_COPY,
49 PCP_TOKEN_EQ,
50 PCP_TOKEN_GE,
51 PCP_TOKEN_AND,
52 PCP_TOKEN_OR,
53 PCP_TOKEN_DEF,
54 PCP_TOKEN_USE,
55 PCP_TOKEN_MAYDEF,
56 PCP_TOKEN_ARRAY,
57 PCP_TOKEN_IV,
58 PCP_TOKEN_PARAMETER,
59 PCP_TOKEN_VARIABLE,
60 PCP_TOKEN_PARAMETERS,
61 PCP_TOKEN_MULTIPLY,
62 PCP_TOKEN_ADD,
63 PCP_TOKEN_SUBTRACT,
64 PCP_TOKEN_ARROW,
65 PCP_TOKEN_OPEN_PAREN,
66 PCP_TOKEN_CLOSE_PAREN,
67 PCP_TOKEN_COMMA,
68 PCP_TOKEN_OPEN_BRACE,
69 PCP_TOKEN_CLOSE_BRACE,
70 PCP_TOKEN_VERTICAL_BAR,
71 PCP_TOKEN_SCOP,
72 PCP_TOKEN_INPUT,
73 PCP_TOKEN_OUTPUT,
74 PCP_TOKEN_FLOOR,
75 PCP_TOKEN_CEIL,
76 PCP_TOKEN_MIN,
77 PCP_TOKEN_MAX,
78 PCP_TOKEN_ERROR,
79 PCP_TOKEN_SEQUENCE
82 protected:
83 static PcpToken* sequenceToken;
84 static PcpArray<PcpToken*>* delimiters;
85 static PcpArray<PcpToken*>* keywords;
86 Kind kind;
87 const char* string;
88 int lineNumber;
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;
102 // Get 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;
114 // Get keywords.
115 static PcpArray<PcpToken*>* getKeywords()
117 return PcpToken::keywords;
120 // Set kind to KIND.
121 void
122 setKind(Kind kind)
124 this->kind = kind;
127 // Set string to STRING.
128 void
129 setString(const char* string)
131 this->string = string;
134 // Set line number to LINENUMBER.
135 void
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);
187 public:
189 // Get sequence token.
190 static PcpToken* getSequenceToken()
192 if(PcpToken::sequenceToken == NULL)
193 PcpToken::setSequenceToken(new PcpToken(PCP_TOKEN_SEQUENCE,
194 "SEQUENCE",
195 -1));
196 return PcpToken::sequenceToken;
199 // Get kind.
200 Kind
201 getKind()
203 return this->kind;
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();
219 if(keywords == NULL)
220 PcpToken::initializeKeywords();
221 return PcpToken::getKeywords()->getIterator();
224 // Get string.
225 const char*
226 getString()
228 return this->string;
231 // Get line number.
233 getLineNumber()
235 return this->lineNumber;
238 // Get name. This function is for debug purposes.
239 const char*
240 getTokenKindName()
242 switch(getKind())
244 case PCP_TOKEN_NUMERAL:
245 return "Numeral";
246 case PCP_TOKEN_IDENTIFIER:
247 return "Identifier";
248 case PCP_TOKEN_GUARD:
249 return "Guard";
250 case PCP_TOKEN_LOOP:
251 return "Loop";
252 case PCP_TOKEN_COPY:
253 return "Copy";
254 case PCP_TOKEN_EQ:
255 return "Eq";
256 case PCP_TOKEN_GE:
257 return "Ge";
258 case PCP_TOKEN_AND:
259 return "And";
260 case PCP_TOKEN_OR:
261 return "Or";
262 case PCP_TOKEN_DEF:
263 return "Def";
264 case PCP_TOKEN_USE:
265 return "Use";
266 case PCP_TOKEN_MAYDEF:
267 return "MayDef";
268 case PCP_TOKEN_ARRAY:
269 return "array";
270 case PCP_TOKEN_IV:
271 return "InductionVariable";
272 case PCP_TOKEN_PARAMETER:
273 return "Parameter";
274 case PCP_TOKEN_VARIABLE:
275 return "Variable";
276 case PCP_TOKEN_PARAMETERS:
277 return "Parameters";
278 case PCP_TOKEN_MULTIPLY:
279 return "Multiply";
280 case PCP_TOKEN_ADD:
281 return "Add";
282 case PCP_TOKEN_SUBTRACT:
283 return "Subtract";
284 case PCP_TOKEN_ARROW:
285 return "Arrow";
286 case PCP_TOKEN_OPEN_PAREN:
287 return "OpenParen";
288 case PCP_TOKEN_CLOSE_PAREN:
289 return "CloseParen";
290 case PCP_TOKEN_COMMA:
291 return "Comma";
292 case PCP_TOKEN_OPEN_BRACE:
293 return "OpenBrace";
294 case PCP_TOKEN_CLOSE_BRACE:
295 return "CloseBrace";
296 case PCP_TOKEN_VERTICAL_BAR:
297 return "VerticalBar";
298 case PCP_TOKEN_SCOP:
299 return "Scop";
300 case PCP_TOKEN_INPUT:
301 return "Input";
302 case PCP_TOKEN_FLOOR:
303 return "Floor";
304 case PCP_TOKEN_CEIL:
305 return "Ceil";
306 case PCP_TOKEN_MIN:
307 return "Min";
308 case PCP_TOKEN_MAX:
309 return "Max";
310 case PCP_TOKEN_OUTPUT:
311 return "Output";
312 case PCP_TOKEN_ERROR:
313 return "ERROR";
314 case PCP_TOKEN_SEQUENCE:
315 return "SEQUENCE";
316 default:
317 return "Unknown Token";
321 // Return true if this is a numeral.
322 bool
323 isNumeral()
325 return this->getKind() == PCP_TOKEN_NUMERAL;
328 // Return true if this is an identifier.
329 bool
330 isIdentifier()
332 return this->getKind() == PCP_TOKEN_IDENTIFIER;
335 // Return true if this is a guard.
336 bool
337 isGuard()
339 return this->getKind() == PCP_TOKEN_GUARD;
342 // Return true if this is a loop.
343 bool
344 isLoop()
346 return this->getKind() == PCP_TOKEN_LOOP;
349 // Return true if this is a copy.
350 bool
351 isCopy()
353 return this->getKind() == PCP_TOKEN_COPY;
356 // Return true if this is an equality.
357 bool
358 isEq()
360 return this->getKind() == PCP_TOKEN_EQ;
363 // Return true if this is a greater or equals
364 bool
365 isGe()
367 return this->getKind() == PCP_TOKEN_GE;
370 // Return true if this is an and.
371 bool
372 isAnd()
374 return this->getKind() == PCP_TOKEN_AND;
377 // Return true if this is an or.
378 bool
379 isOr()
381 return this->getKind() == PCP_TOKEN_OR;
384 // Return true if this is a def.
385 bool
386 isDef()
388 return this->getKind() == PCP_TOKEN_DEF;
391 // Return true if this is a use.
392 bool
393 isUse()
395 return this->getKind() == PCP_TOKEN_USE;
398 // Return true if this is a maydef.
399 bool
400 isMaydef()
402 return this->getKind() == PCP_TOKEN_MAYDEF;
405 // Return true if this is an array.
406 bool
407 isArray()
409 return this->getKind() == PCP_TOKEN_ARRAY;
412 // Return true if this is an iv.
413 bool
414 isIv()
416 return this->getKind() == PCP_TOKEN_IV;
419 // Return true if this is a parameter.
420 bool
421 isParameter()
423 return this->getKind() == PCP_TOKEN_PARAMETER;
426 // Return true if this is a variable.
427 bool
428 isVariable()
430 return this->getKind() == PCP_TOKEN_VARIABLE;
433 // Return true if this is parameters.
434 bool
435 isParameters()
437 return this->getKind() == PCP_TOKEN_PARAMETERS;
440 // Return true if this is an arrow.
441 bool
442 isArrow()
444 return this->getKind() == PCP_TOKEN_ARROW;
447 // Return true if this is a multiply.
448 bool
449 isMultiply()
451 return this->getKind() == PCP_TOKEN_MULTIPLY;
454 // Return true if this is an add.
455 bool
456 isAdd()
458 return this->getKind() == PCP_TOKEN_ADD;
461 // Return true if this is a subtract.
462 bool
463 isSubtract()
465 return this->getKind() == PCP_TOKEN_SUBTRACT;
468 // Return true if this is an open paren.
469 bool
470 isOpenParen()
472 return this->getKind() == PCP_TOKEN_OPEN_PAREN;
475 // Return true if this is a close paren.
476 bool
477 isCloseParen()
479 return this->getKind() == PCP_TOKEN_CLOSE_PAREN;
482 // Return true if this is a comma.
483 bool
484 isComma()
486 return this->getKind() == PCP_TOKEN_COMMA;
489 // Return true if this is an open brace.
490 bool
491 isOpenBrace()
493 return this->getKind() == PCP_TOKEN_OPEN_BRACE;
496 // Return true if this is a close brace.
497 bool
498 isCloseBrace()
500 return this->getKind() == PCP_TOKEN_CLOSE_BRACE;
503 // Return true if this is a verticalBar.
504 bool
505 isVerticalBar()
507 return this->getKind() == PCP_TOKEN_VERTICAL_BAR;
510 // Return true if this is a scop.
511 bool
512 isScop()
514 return this->getKind() == PCP_TOKEN_SCOP;
517 // Return true if this is an input.
518 bool
519 isInput()
521 return this->getKind() == PCP_TOKEN_INPUT;
524 // Return true if this is an floor.
525 bool
526 isFloor()
528 return this->getKind() == PCP_TOKEN_FLOOR;
530 // Return true if this is an ceil.
531 bool
532 isCeil()
534 return this->getKind() == PCP_TOKEN_CEIL;
536 // Return true if this is an min.
537 bool
538 isMin()
540 return this->getKind() == PCP_TOKEN_MIN;
542 // Return true if this is an max.
543 bool
544 isMax()
546 return this->getKind() == PCP_TOKEN_MAX;
549 // Return true if this is an output.
550 bool
551 isOutput()
553 return this->getKind() == PCP_TOKEN_OUTPUT;
556 // Return true if this is an error.
557 bool
558 isError()
560 return this->getKind() == PCP_TOKEN_ERROR;
563 // Return true if this is a sequence.
564 bool
565 isSequence()
567 return this->getKind() == PCP_TOKEN_SEQUENCE;
570 // Return true if this is a functor (supposed to take arguments).
571 bool
572 isFunctor()
574 bool result;
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:
602 result = true;
603 break;
604 default:
605 result = false;
606 break;
608 return result;
611 // Create new token of given KIND and STRING.
612 PcpToken(Kind kind, const char* string, int lineNumber)
614 setKind(kind);
615 setString(string);
616 setLineNumber(lineNumber);
621 PcpToken* PcpToken::sequenceToken;
622 template <> PcpArray<PcpToken*>* PcpToken::delimiters;
623 template <> PcpArray<PcpToken*>* PcpToken::keywords;
625 // PCP Tokenizer
627 class PcpTokenizer
629 protected:
630 int row;
631 int index;
632 const char* source;
633 int sourceLength;
635 // Set row in TOKENIZER to ROW.
636 void
637 setRow(int row)
639 this->row = row;
642 // Get row in TOKENIZER.
644 getRow()
646 return this->row;
649 // Increment row in TOKENIZER by 1.
650 void
651 incrementRow()
653 this->setRow(this->getRow() + 1);
656 // Set index of TOKENIZER to INDEX.
657 void
658 setIndex(int index)
660 this->index = index;
663 // Get index of TOKENIZER.
665 getIndex()
667 return this->index;
670 // Set source length of TOKENIZER to SOURCE_LENGTH.
671 void
672 setSourceLength(int sourceLength)
674 this->sourceLength = sourceLength;
677 // Get source length of TOKENIZER.
679 getSourceLength()
681 return this->sourceLength;
684 // Set source of TOKENIZER to SOURCE.
685 void
686 setSource(const char* source)
688 this->source = source;
691 // Get source of TOKENIZER.
692 const char*
693 getSource()
695 return this->source;
698 // Get next char in TOKENIZER with OFFSET from the last consumed
699 // charater.
700 char
701 peekChar(int offset)
704 int index = this->getIndex() + offset;
705 char result;
706 if(index >= this->getSourceLength())
707 return '\0';
708 result = this->getSource()[index];
709 return result;
712 // Get the next char in TOKENIZER that has not been consumed.
713 char
714 peekNextChar()
716 return this->peekChar(0);
719 // Consume the next charachter in TOKENIZER.
720 void
721 consumeChar()
723 this->setIndex(this->getIndex() + 1);
726 // Return true if CHARACHTER is a newline.
727 bool
728 charIsNewline(char character)
730 return character == '\n';
733 // Return true if CHARACTER is a whitespace.
734 bool
735 charIsWhitespace(char character)
737 return(character == '\t'
738 || character == ' '
739 || this->charIsNewline(character));
742 // Return true if CHARACTER is end of source.
743 bool
744 charIsEndOfSource(char character)
746 return character == '\0';
749 // Return true if TOKENIZER has reached end of source.
750 bool
751 endOfSource()
753 return this->charIsEndOfSource(this->peekNextChar());
756 // Return true if CHARACTER will end a token.
757 bool
758 charIsTokenBreak(char character)
760 return this->charIsWhitespace(character)
761 || this->charIsEndOfSource(character);
764 // Return true if CHARACTER is a digit.
765 bool
766 charIsDigit(char character)
768 return(character >= '0' && character <= '9');
771 // Return true if CHARACTER is a letter.
772 bool
773 charIsLetter(char character)
775 return(character >= 'A' && character <= 'Z')
776 || (character >= 'a' && character <= 'z');
779 // Return true if CHARACTER is a symbol.
780 bool
781 charIsSymbol(char character)
783 return character == '!'
784 || character == '#'
785 || character == '$'
786 || character == '%'
787 || character == '&'
788 || character == '*'
789 || character == '+'
790 || character == '-'
791 || character == '/'
792 || character == '<'
793 || character == '='
794 || character == '>'
795 || character == '?'
796 || character == '@'
797 || character == '\\'
798 || character == '_';
801 // Return true if CHARACTER is illegal.
802 bool
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.
814 void
815 skipWhitespaces()
817 char character;
819 for(character = this->peekNextChar();
820 this->charIsWhitespace(character);)
822 if(this->charIsNewline(character))
823 this->incrementRow();
824 this->consumeChar();
825 character = this->peekNextChar();
829 // Match STRING in TOKENIZER with at OFFSET.
830 bool
831 matchStringAtOffset(int offset, const char* string)
833 int length = strlen(string);
834 int index = 0;
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)
842 mismatch = true;
844 return mismatch;
847 // Match STRING in TOKENIZER at curent location.
848 bool
849 matchString(const char* string)
851 return this->matchStringAtOffset(0, string);
854 // Match any delimiter in TOKENIZER at given OFFSET.
855 PcpToken*
856 matchDelimiterAtOffset(int offset)
858 PcpIterator<PcpToken*>* delimIter = PcpToken::getDelimitersIterator();
859 for(;delimIter->hasNext(); delimIter->next())
861 PcpToken* delimiter = delimIter->get();
862 bool mismatch;
863 mismatch = this->matchStringAtOffset(
864 offset,
865 delimiter->getString());
866 if(!mismatch)
867 return delimiter;
869 return NULL;
872 // Match any delimiter in TOKENIZER.
873 PcpToken*
874 matchDelimiter()
876 return this->matchDelimiterAtOffset(0);
879 // Return true if a token break exists in TOKEN at given OFFSET.
880 bool
881 hasTokenBreakAtOffset(int offset)
883 return
884 this->charIsTokenBreak(this->peekChar
885 (offset))
886 || this->matchDelimiterAtOffset(offset);
890 // Match any keyword in TOKENIZER.
891 PcpToken*
892 matchKeyword()
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(),
904 this->getRow());
906 return NULL;
909 // Write all characters in TOKENIZER from OFFSET into BUFFER until a token
910 // break is found.
911 void
912 fillBufferUntilTokenBreak(int offset,
913 PcpStringBuffer* buffer)
915 int i;
916 for(i = offset; !this->hasTokenBreakAtOffset(i);
917 i++)
919 buffer->appendChar(this->peekChar(i));
923 // Match a numeral from TOKENIZER.
924 PcpToken*
925 matchNumeral()
927 int i = 0;
928 PcpStringBuffer* buffer = new PcpStringBuffer();
929 char peekChar = this->peekChar(i);
930 while(this->charIsDigit(peekChar))
932 buffer->appendChar(peekChar);
933 i = i + 1;
934 if(this->hasTokenBreakAtOffset(i))
935 return new PcpToken(PcpToken::PCP_TOKEN_NUMERAL,
936 buffer->toString(),
937 this->getRow());
938 peekChar = this->peekChar(i);
940 if(buffer->getLength() != 0)
942 this->fillBufferUntilTokenBreak(i, buffer);
943 return new PcpToken(PcpToken::PCP_TOKEN_ERROR,
944 buffer->toString(),
945 this->getRow());
947 return NULL;
950 // Match an identifier from TOKENIZER.
951 PcpToken*
952 matchIdentifier()
954 int i = 0;
955 PcpStringBuffer* buffer = new PcpStringBuffer();
956 char peekChar = this->peekChar(i);
957 if(this->charIsLetter(peekChar))
959 buffer->appendChar(peekChar);
960 i = i + 1;
961 peekChar = this->peekChar(i);
962 while(this->charIsLetter(peekChar)
963 || this->charIsDigit(peekChar)
964 || this->charIsSymbol(peekChar))
966 buffer->appendChar(peekChar);
967 i = i + 1;
968 if(this->hasTokenBreakAtOffset(i))
969 return new PcpToken(PcpToken::PCP_TOKEN_IDENTIFIER,
970 buffer->toString(),
971 this->getRow());
972 peekChar = this->peekChar(i);
974 if(buffer->getLength() != 0)
976 return new PcpToken(PcpToken::PCP_TOKEN_IDENTIFIER,
977 buffer->toString(),
978 this->getRow());
980 return NULL;
982 return NULL;
985 public:
987 // Create new tokenizer with given SOURCE.
988 PcpTokenizer(const char* source)
990 setRow(1);
991 setIndex(0);
992 setSource(source);
993 setSourceLength(strlen(source));
996 // Consume TOKEN in TOKENIZER. This increments the index with the
997 // token string length.
998 void
999 consumeToken(PcpToken* token)
1001 int length = strlen(token->getString());
1002 this->setIndex(getIndex() + length);
1006 // Get next token from TOKENIZER(without consuming it).
1007 PcpToken*
1008 peekNextToken()
1010 PcpToken* token;
1011 if(this->endOfSource())
1012 return NULL;
1014 this->skipWhitespaces();
1016 token = this->matchDelimiter();
1017 if(token != NULL)
1018 return token;
1020 token = this->matchKeyword();
1021 if(token != NULL)
1022 return token;
1024 token = this->matchNumeral();
1025 if(token != NULL)
1026 return token;
1028 token = this->matchIdentifier();
1029 return token;
1032 // Get and consume the next token from TOKENIZER.
1033 PcpToken*
1034 getNextToken()
1036 PcpToken* token = this->peekNextToken();
1037 this->consumeToken(token);
1038 return token;
1046 // Report parse error.
1047 static void
1048 pcpParseError(const char* error)
1050 printf("Error: %s\n", error);
1053 class PcpAst
1055 protected:
1056 PcpToken* name;
1057 PcpToken* token;
1058 bool hasChildren;
1059 PcpDynamicArray<PcpAst*>* children;
1060 PcpDynamicArray<PcpAst*>* annots;
1062 // Set children of AST to CHILDREN.
1063 void
1064 setChildren(PcpDynamicArray<PcpAst*>* children)
1066 this->children = children;
1069 // Get children of AST.
1070 PcpDynamicArray<PcpAst*>*
1071 getChildren()
1073 return this->children;
1076 void
1077 setAnnots(PcpDynamicArray<PcpAst*>* annots)
1079 this->annots = annots;
1082 PcpDynamicArray<PcpAst*>*
1083 getAnnots()
1085 return this->annots;
1089 // Write AST into BUFFER.
1090 void
1091 toStringInBuffer(PcpStringBuffer* buffer)
1093 PcpToken* token = this->getToken();
1094 PcpToken* name = this->getName();
1095 int numChildren = this->getNumChildren();
1096 int i;
1098 if(name != NULL)
1100 buffer->append(name->getString());
1101 buffer->append(" <- ");
1104 if(token == NULL)
1105 buffer->append("NULL");
1106 else
1107 buffer->append(token->getString());
1109 if(this->getHasChildren())
1111 bool first = true;
1112 buffer->append("(");
1113 for(i = 0; i < numChildren; i++)
1115 if(first)
1116 first = false;
1117 else
1118 buffer->append(", ");
1119 this->getChild(i)->toStringInBuffer(buffer);
1121 buffer->append(")");
1125 // Parse functor list surrounded by '{' '}'.
1126 static PcpAst*
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);
1139 else
1140 pcpParseError("Expected close brace");
1141 return result;
1144 static void
1145 parseObjectList1(PcpTokenizer* tokenizer, PcpAst* root,
1146 bool isAnnot)
1148 PcpToken* peek = tokenizer->peekNextToken();
1149 PcpAst* object = NULL;
1151 object = PcpAst::parseObject(tokenizer);
1152 if(isAnnot)
1153 root->addAnnot(object);
1154 else
1155 root->addChild(object);
1156 peek = tokenizer->peekNextToken();
1157 if(peek == NULL)
1159 pcpParseError("Unexpected end of stream");
1160 return;
1163 while(peek->isComma())
1165 tokenizer->consumeToken(peek);
1166 object = PcpAst::parseObject(tokenizer);
1167 if(isAnnot)
1168 root->addAnnot(object);
1169 else
1170 root->addChild(object);
1172 peek = tokenizer->peekNextToken();
1173 if(peek == NULL)
1175 pcpParseError("Unexpected end of stream");
1176 return;
1181 // Parse comma separated object list.
1182 static PcpAst*
1183 parseObjectList(PcpTokenizer* tokenizer)
1185 PcpToken* token = tokenizer->getNextToken();
1186 PcpToken* peek;
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);
1199 return result;
1202 if(peek->isVerticalBar())
1204 tokenizer->consumeToken(peek);
1205 peek = tokenizer->peekNextToken();
1206 if(!peek->isCloseParen())
1207 PcpAst::parseObjectList1(tokenizer, result, true);
1209 else
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);
1223 else
1224 pcpParseError("Error, expected close paren");
1227 return result;
1230 // Parse object.
1231 static PcpAst*
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);
1247 return result;
1249 else if(token->isIdentifier())
1251 PcpToken* peek = tokenizer->peekNextToken();
1252 if(peek->isOpenParen())
1254 PcpAst* result = PcpAst::parseObjectList(tokenizer);
1255 result->setToken(token);
1256 return result;
1258 else if(peek->isArrow())
1260 PcpAst* result = PcpAst::parseBinding(tokenizer, token);
1261 return result;
1264 return new PcpAst(token);
1266 else if(token->isNumeral())
1267 return new PcpAst(token);
1268 else
1270 pcpParseError("Unexpected token");
1271 return NULL;
1275 // Parse "identifier <- object" sequence.
1276 static PcpAst*
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);
1286 return result;
1288 else
1289 pcpParseError("Expected '<-' after identifier");
1290 return NULL;
1293 // Parse list of functor strings.
1294 static PcpAst*
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())
1305 PcpToken* token;
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();
1317 return result;
1320 public:
1322 // Convert AST to string.
1323 const char*
1324 toString()
1326 PcpStringBuffer* buffer = new PcpStringBuffer();
1327 this->toStringInBuffer(buffer);
1328 return buffer->toString();
1332 getNumAnnots()
1334 return this->getAnnots()->getSize();
1337 PcpAst*
1338 getAnnot(int index)
1340 return this->getAnnots()->get(index);
1344 // Get number of childern in AST.
1346 getNumChildren()
1348 return this->getChildren()->getSize();
1351 // Get child with CHILDIndex from AST.
1352 PcpAst*
1353 getChild(int childIndex)
1355 return this->getChildren()->get(childIndex);
1358 // Set name of AST to NAME.
1359 void
1360 setName(PcpToken* name)
1362 this->name = name;
1365 // Get name of AST.
1366 PcpToken*
1367 getName()
1369 return this->name;
1372 // Set token of AST to TOKEN.
1373 void
1374 setToken(PcpToken* token)
1376 this->token = token;
1379 // Get token of AST.
1380 PcpToken*
1381 getToken()
1383 return this->token;
1386 // Set if AST HASChildren.
1387 void
1388 setHasChildren(bool hasChildren)
1390 this->hasChildren = hasChildren;
1393 // Return true if AST has children.
1394 bool
1395 getHasChildren()
1397 return this->hasChildren;
1400 void
1401 addAnnot(PcpAst* annot)
1403 this->getAnnots()->add(annot);
1406 // Add CHILD to AST.
1407 void
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.
1426 static PcpAst*
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
1437 // arguments).
1439 class PcpSymtab
1441 protected:
1442 PcpDynamicArray<PcpObject*>* entries;
1444 // Set entries of SYMTAB to ENTRIES.
1445 void
1446 setEntries(PcpDynamicArray<PcpObject*>* entries)
1448 this->entries = entries;
1451 // Get entries of SYMTAB.
1452 PcpDynamicArray<PcpObject*>*
1453 getEntries()
1455 return this->entries;
1458 public:
1460 // Return object with given NAME in SYMTAB, if it does not exist
1461 // return NULL.
1462 PcpObject*
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)
1471 return entry;
1473 return NULL;
1476 // Lookup TOKEN's string in SYMTAB.
1477 PcpObject*
1478 lookup(PcpToken* token)
1480 const char* name = token->getString();
1481 return this->lookupName(name);
1485 // Insert OBJECT in SYMTAB.
1486 void
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.
1497 PcpSymtab()
1499 this->setEntries(new PcpDynamicArray<PcpObject*>(5));
1504 // PCP Ast Parser
1506 void
1507 PcpParser::setSymtab(PcpSymtab* symtab)
1509 this->symtab = symtab;
1512 // Get symbol table in CONTEXT.
1513 PcpSymtab*
1514 PcpParser::getSymtab()
1516 return this->symtab;
1519 // Set parser CONTEXT to add annotations to ADDLineAnnots.
1520 void
1521 PcpParser::setAddLineAnnots(bool addLineAnnots)
1523 this->addLineAnnots = addLineAnnots;
1526 // Return if parser CONTEXT should insert line annotations.
1527 bool
1528 PcpParser::getAddLineAnnots()
1530 return this->addLineAnnots;
1533 // Set file name in CONTEXT to FILEName.
1534 void
1535 PcpParser::setFileName(const char* fileName)
1537 this->fileName = fileName;
1540 // Get file name in CONTEXT.
1541 const char*
1542 PcpParser::getFileName()
1544 return this->fileName;
1548 // Parse NUMERAL and return created constant.
1549 PcpConstant*
1550 PcpParser::parseNumeral(PcpAst* numeral)
1552 int value;
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);
1561 return result;
1564 void
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.
1587 void
1588 PcpParser::parseCommonObjectAttributes(PcpAst* ast,
1589 PcpObject* object)
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.
1604 PcpArith*
1605 PcpParser::parseMultiply(PcpAst* multiply)
1607 int numChildren = multiply->getNumChildren();
1608 if(numChildren != 2)
1609 pcpParseError("Expected two arguments for multiply");
1610 else
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");
1629 else
1631 PcpArith* multiplyObject =
1632 PcpArith::pcpArithBinaryCreate(PcpArithOperator::multiply(),
1633 this->parseNumeral(lhsAst),
1634 rhsObject->toIv());
1635 return multiplyObject;
1638 return NULL;
1641 // Parse AST and return the created pcp expression.
1642 PcpExpr*
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()
1649 || result == NULL
1650 || (!result->isParameter() && !result->isIv()))
1651 pcpParseError("Expected scalar value");
1652 return result->toExpr();
1655 PcpArithOperator
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();
1670 else
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.
1680 PcpExpr*
1681 PcpParser::parseArith(PcpAst* ast)
1683 int numChildren = ast->getNumChildren();
1684 PcpArithOperator oper =
1685 this->parseArithOperator(ast->getToken());
1686 PcpArith* arith;
1687 int i;
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");
1694 if(numChildren < 2)
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();
1705 return arith;
1708 // Parse AST and return the created pcp expression.
1709 PcpExpr*
1710 PcpParser::parseLinearExpr(PcpAst* ast)
1712 PcpExpr* result;
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);
1722 else
1724 pcpParseError("Not a linear expr");
1725 return NULL;
1728 if(!token->isNumeral() && !token->isIdentifier())
1729 this->parseCommonObjectAttributes(ast, result);
1730 return result;
1733 // Parse AST and return the created comparison(eq or ge).
1734 PcpBoolExpr*
1735 PcpParser::parseComparison(PcpAst* ast)
1737 int numChildren = ast->getNumChildren();
1738 PcpToken* token = ast->getToken();
1739 PcpExpr* lhs;
1740 PcpExpr* rhs;
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));
1747 if(token->isEq())
1748 return new PcpCompare(PcpCompareOperator::equal(), lhs, rhs);
1749 else if(token->isGe())
1750 return new PcpCompare(PcpCompareOperator::greaterEqual(), lhs, rhs);
1751 else
1752 pcpParseError("Not eq/ge expr");
1753 return NULL;
1756 PcpBoolArithOperator
1757 PcpParser::parseBoolArithOperator(PcpToken* operatorToken)
1759 if(operatorToken->isAnd())
1760 return PcpBoolArithOperator::boolAnd();
1761 else if(operatorToken->isOr())
1762 return PcpBoolArithOperator::boolOr();
1763 else
1764 return PcpBoolArithOperator::unknown();
1767 bool PcpParser::pcpTokenIsBoolArithOperator(PcpToken* operatorToken)
1769 return !this->parseBoolArithOperator(operatorToken).isUnknown();
1772 PcpBoolExpr*
1773 PcpParser::parseBoolArith(PcpAst* ast)
1775 int numChildren = ast->getNumChildren();
1776 PcpBoolArithOperator oper =
1777 this->parseBoolArithOperator(ast->getToken());
1778 PcpBoolArith* boolArith;
1779 int i;
1780 PcpBoolArithBuilder* boolArithBuilder = new PcpBoolArithBuilder();
1782 if(oper.isUnknown())
1783 pcpParseError("Not a valid operator");
1784 if(numChildren < 2)
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();
1796 return boolArith;
1799 // Parse ast and return the created pcp boolean expression.
1800 PcpBoolExpr*
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);
1810 if(result == NULL)
1812 pcpParseError("Not a boolean expression");
1813 return result;
1815 this->parseCommonObjectAttributes(ast, result);
1816 return 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.
1822 PcpObject*
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);
1832 if(result == NULL)
1833 pcpParseError("Unknown identifier");
1835 return result;
1838 // Parse ast(array access ast) and return the created array access.
1839 PcpArrayAccess*
1840 PcpParser::parseArrayAccess(PcpAst* ast)
1842 int numChildren = ast->getNumChildren();
1843 PcpToken* token = ast->getToken();
1844 PcpArrayAccessBuilder* builder;
1845 int i;
1846 PcpArrayAccess* result;
1847 PcpObject* base;
1849 if(numChildren < 1)
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);
1867 if(token->isUse())
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());
1873 else
1875 pcpParseError("Unknown array access token");
1876 return NULL;
1879 result = builder->createAccess();
1880 this->parseCommonObjectAttributes(ast, result);
1881 return result;
1884 // Return true if TOKEN is empty or an unknown symbol in
1885 // SYMTAB.
1886 bool
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.
1897 PcpUserStmt*
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();
1905 int i;
1907 if(!this->parseTokenIsUnknownSymbol(token))
1909 pcpParseError("User stmt name is invalid");
1910 return NULL;
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);
1925 return result;
1928 // Parse COPY and return the created pcp copy.
1929 PcpCopy*
1930 PcpParser::parseCopy(PcpAst* copy)
1932 PcpToken* token = copy->getToken();
1933 int numChildren = copy->getNumChildren();
1934 PcpArrayAccess* dest;
1935 PcpArrayAccess* src;
1936 PcpCopy* result;
1938 if(!token->isCopy())
1940 pcpParseError("Token is not a copy");
1941 return NULL;
1943 if(numChildren != 2)
1945 pcpParseError("Wrong number of arguments to copy stmt");
1946 return NULL;
1949 dest =
1950 this->parseArrayAccess(copy->getChild(0));
1951 src =
1952 this->parseArrayAccess(copy->getChild(1));
1954 if(!dest->isDef() || !src->isUse())
1956 pcpParseError
1957 ("Expected def as first argument and use as second argument in copy");
1958 return NULL;
1961 result = new PcpCopy(dest, src);
1962 this->parseCommonObjectAttributes(copy, result);
1963 return result;
1966 // Parse SEQUENCE and return the created pcp statement sequence.
1967 PcpSequence*
1968 PcpParser::parseSequence(PcpAst* sequence)
1970 PcpToken* token = sequence->getToken();
1971 int numChildren = sequence->getNumChildren();
1972 PcpSequenceBuilder* builder;
1973 PcpSequence* result;
1974 int i;
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));
1985 builder->add(stmt);
1987 result = builder->createSequence();
1988 return result;
1991 // Parse GUARD and return the created pcp guard.
1992 PcpGuard*
1993 PcpParser::parseGuard(PcpAst* guard)
1995 PcpToken* token = guard->getToken();
1996 int numChildren = guard->getNumChildren();
1997 PcpBoolExpr* condition;
1998 PcpStmt* body;
1999 PcpGuard* result;
2001 if(!token->isGuard())
2003 pcpParseError("Invalid guard stmt");
2004 return NULL;
2007 if(numChildren != 2)
2009 pcpParseError("Condition or Body missing in guard");
2010 return NULL;
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);
2016 return result;
2019 // Parse IV and return the created pcp iv.
2020 PcpIv*
2021 PcpParser::parseIv(PcpAst* iv)
2023 PcpToken* token = iv->getToken();
2024 int numChildren = iv->getNumChildren();
2025 const char* tokenString = token->getString();
2026 PcpIv* result;
2028 if(!token->isIv())
2030 pcpParseError("Not an iv declaration");
2031 return NULL;
2033 if(!iv->getHasChildren() || !numChildren == 0)
2035 pcpParseError("Wrong number of arguments to iv declaration");
2036 return NULL;
2038 if(tokenString == NULL)
2040 pcpParseError("No name given to iv");
2041 return NULL;
2043 result = new PcpIv(tokenString);
2044 this->parseCommonObjectAttributes(iv, result);
2045 return result;
2048 // Parse LOOP and return the created pcp loop.
2049 PcpLoop*
2050 PcpParser::parseLoop(PcpAst* loop)
2052 PcpToken* token = loop->getToken();
2053 int numChildren = loop->getNumChildren();
2054 PcpIv* iv;
2055 PcpExpr* start;
2056 PcpBoolExpr* end;
2057 PcpConstant* stride;
2058 PcpStmt* body;
2059 PcpLoop* result;
2061 if(!token->isLoop())
2063 pcpParseError("Expected loop construct");
2064 return NULL;
2067 if(numChildren != 5)
2069 pcpParseError("Wrong number of arguments to loop");
2070 return NULL;
2073 iv = this->parseIv(loop->getChild(0));
2074 start =
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);
2083 return result;
2087 // Parse STMT and return the created pcp statement.
2088 PcpStmt*
2089 PcpParser::parseStmt(PcpAst* stmt)
2091 PcpToken* token = stmt->getToken();
2092 PcpStmt* result = NULL;
2093 if(token->isCopy())
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);
2103 else
2105 pcpParseError("Invalid statement in sequence");
2106 return NULL;
2108 return result;
2112 void
2113 PcpParser::parseScopInoutput(PcpAst* inoutput,
2114 PcpScopBuilder* builder)
2116 PcpToken* token = inoutput->getToken();
2117 int numChildren = inoutput->getNumChildren();
2118 int i;
2120 if(!token->isInput() && !token->isOutput())
2122 pcpParseError("Not an input or output list");
2123 return;
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);
2133 if(object == NULL)
2134 pcpParseError("Unknown identifier in scop input/output list");
2135 else if(!object->isVariable())
2136 pcpParseError("Non variable found in scop input/output list");
2137 else
2139 PcpVariable* variable = object->toVariable();
2140 builder->addVariable(variable);
2141 if(token->isInput())
2142 variable->setIsInput(true);
2143 else
2144 variable->setIsOutput(true);
2147 else
2148 pcpParseError("Expected identifier in scop inputs/outputs list");
2152 void
2153 PcpParser::parseScopParameters(PcpAst* parameters,
2154 PcpScopBuilder* builder)
2156 PcpToken* token = parameters->getToken();
2157 int numChildren = parameters->getNumChildren();
2158 int i;
2160 if(!token->isParameters())
2162 pcpParseError("Not a parameter list");
2163 return;
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);
2173 if(object == NULL)
2174 pcpParseError("Unknown identifier in scop parameter list");
2175 else if(!object->isParameter())
2176 pcpParseError("Non parameter found in scop parameter list");
2177 else
2179 PcpParameter* parameter = object->toParameter();
2180 builder->addParameter(parameter);
2183 else
2184 pcpParseError("Expected identifier in scop parameter list");
2188 PcpScop*
2189 PcpParser::parseScop(PcpAst* scop)
2191 PcpScop* result = NULL;
2192 PcpToken* token = scop->getToken();
2193 int numChildren = scop->getNumChildren();
2194 PcpScopBuilder* builder;
2195 PcpStmt* body;
2196 int i;
2198 if(!token->isScop())
2200 pcpParseError("Construct is not a scop");
2201 return NULL;
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);
2222 // Parse body.
2223 body = this->parseStmt(scop->getChild(numChildren - 1));
2224 builder->setBody(body);
2225 result = builder->createScop();
2226 this->parseCommonObjectAttributes(scop, result);
2227 return result;
2230 PcpArrayType*
2231 PcpParser::parseArrayType(PcpAst* arrayType)
2233 PcpToken* token = arrayType->getToken();
2234 int numChildren = arrayType->getNumChildren();
2235 PcpArrayTypeBuilder* builder;
2236 PcpArrayType* type;
2237 int i;
2239 if(!token->isArray())
2241 pcpParseError("Expected array construct");
2242 return NULL;
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();
2261 else
2263 pcpParseError("unexpected token in array dimension list");
2264 return NULL;
2266 builder->addDimension(dim);
2269 type = builder->createType();
2270 this->parseCommonObjectAttributes(arrayType, type);
2271 return type;
2274 PcpVariable*
2275 PcpParser::parseVariable(PcpAst* array)
2277 PcpToken* token = array->getToken();
2278 int numChildren = array->getNumChildren();
2279 PcpArrayType* type;
2280 PcpVariable* result;
2281 PcpToken* nameToken = array->getName();
2282 const char* name = nameToken != NULL ? nameToken->getString() : NULL;
2283 PcpAst* typeAst;
2284 PcpToken* typeToken;
2286 if(!token->isVariable())
2288 pcpParseError("Expected variable construct");
2289 return NULL;
2292 if(numChildren != 1)
2293 pcpParseError("Wrong number of arguments to variable");
2295 if(name == NULL)
2297 pcpParseError("No name given to variable");
2298 return NULL;
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);
2308 else
2309 type = NULL;
2311 if(type == NULL)
2312 pcpParseError("Illegal type construct given to varaible");
2314 result = new PcpVariable(type, name);
2315 this->parseCommonObjectAttributes(array, result);
2316 return result;
2319 PcpAnnotTerm*
2320 PcpParser::pcpParseAnnotTerm(PcpAst* termAst)
2322 int numChildren = termAst->getNumChildren();
2323 PcpToken* token = termAst->getToken();
2324 PcpAnnotTermBuilder* termBuilder = NULL;
2325 int i;
2326 if(!token->isIdentifier())
2328 pcpParseError("Expected identifier as tag for annotation");
2329 return NULL;
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();
2342 PcpAnnot*
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);
2359 if(object != NULL)
2360 return new PcpAnnotObject(object);
2361 else
2362 return new PcpAnnotString(tokenString);
2364 else
2366 pcpParseError("Unexpected token in optional arg list");
2367 return NULL;
2370 else
2371 return pcpParseAnnotTerm(annotAst);
2374 void
2375 PcpParser::parseAnnots(PcpObject* object, PcpAst* objectAst)
2377 int numAnnots = objectAst->getNumAnnots();
2378 int i;
2379 for(i = 0; i < numAnnots; i++)
2381 PcpAst* annotAst = objectAst->getAnnot(i);
2382 PcpAnnotTerm* annot = pcpParseAnnotTerm(annotAst);
2383 if(annot != NULL)
2385 object->addAnnot(annot);
2390 PcpParameter*
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");
2402 return NULL;
2405 if(numChildren != 0)
2407 pcpParseError
2408 ("Wrong number of arguments to parameter, expected zero");
2409 return NULL;
2412 if(name == NULL)
2414 pcpParseError("No name given to parameter");
2415 return NULL;
2418 result = new PcpParameter(name);
2419 this->parseCommonObjectAttributes(parameter, result);
2421 return result;
2424 PcpScop*
2425 PcpParser::pcpAstParseTopLevel(PcpAst* program)
2427 PcpToken* token = program->getToken();
2428 int numChildren = program->getNumChildren();
2429 int i;
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);
2450 else
2451 pcpParseError("Illegal top level construct.");
2454 pcpParseError("No scop found in source");
2455 return NULL;
2458 PcpParser::PcpParser()
2460 PcpSymtab* symtab = new PcpSymtab();
2461 this->setSymtab(symtab);
2462 this->setFileName("unknown");
2463 this->setAddLineAnnots(true);
2466 PcpScop*
2467 PcpParser::parse(const char* source)
2469 PcpTokenizer* tokenizer = new PcpTokenizer(source);
2470 PcpAst* ast = PcpAst::parse(tokenizer);
2471 PcpScop* scop;
2472 PcpParser* parser = new PcpParser();
2473 scop = parser->pcpAstParseTopLevel(ast);
2474 return scop;
2477 PcpScop*
2478 PcpParser::parseFile(const char* filename)
2480 char* buffer;
2481 FILE* file = fopen(filename, "r");
2482 long size;
2483 long readsize;
2484 if(file == NULL)
2486 pcpParseError("Unable to open file");
2487 return NULL;
2490 fseek(file , 0 , SEEK_END);
2491 size = ftell(file);
2492 rewind(file);
2494 buffer =(char*) PCP_NEWVEC(char, size);
2495 if(buffer == NULL)
2497 pcpParseError("Memory error");
2498 return NULL;
2501 readsize = fread(buffer,1,size,file);
2502 if(readsize != size)
2504 pcpParseError("Unable to read file");
2505 return NULL;
2507 return PcpParser::parse(buffer);