OpenASIP 2.2
Loading...
Searching...
No Matches
OperationDAGLanguageParser.hh
Go to the documentation of this file.
1/**
2 * @file OperationDAGLanguageParser.hh
3 *
4 * OsalDAGLanguage parser based on Ansi C grammar checker.
5 *
6 * Modified to do other things that just validating.
7 *
8 * @author Mikael Lepistö 2007 (mikael.lepisto-no.spam-tut.fi)
9 * @author Pekka Jääskeläinen 2009
10 * @rating red
11 */
12
13#ifndef TTA_OPERATION_DAG_LANGUAGE_PARSER
14#define TTA_OPERATION_DAG_LANGUAGE_PARSER
15
16/*===========================================================================
17 C Grammar checker
18 Requires Spirit v1.6.0 or later
19
20 Copyright (c) 2001-2004 Hartmut Kaiser
21 http://spirit.sourceforge.net/
22
23 Adapted from:
24 http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
25 http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
26
27 Use, modification and distribution is subject to the Boost Software
28 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
29 http://www.boost.org/LICENSE_1_0.txt)
30============================================================================*/
31
32//////////////////////////////////////////////////////////////////////////////
33// version history
34//
35// TODO: Handling typedef's, without that we can't correctly parse
36// auxilliary valid C sources. But hey it's a sample.
37//
38// Modified: 20.09.2002 21:58:45
39// Ported to Spirit V1.5
40//
41// Modified: 18.10.2001 16:36:07
42// Corrected: String literals may be splitted in several strings: "abc" "def"
43// Corrected: String literals may have length 0 ("")
44//
45// Modified: 17.10.2001 10:56:57
46// Rewritten: *_CONSTANT rules
47// Introduced: operator '||' where possible
48// Corrected: IDENTIFIER can start with '_' and can contain '$'
49// Added: Skipping of '#line' and '#pragma' directives, which contained
50// in preprocessed files of the Intel V5.0.1 compiler
51//
52// Modified: 16.10.2001 21:12:05
53// Corrected: missing lexeme_d[] statements for *_CONSTANT
54// Corrected: missing longest_d[] for CONSTANT
55
56#include <iostream>
57#include <iomanip>
58#include <fstream>
59#include <vector>
60#include <map>
61
62#if defined(_DEBUG)
63// LLVM svn builds want to define _DEBUG which causes massive
64// debug spam
65//#define BOOST_SPIRIT_DEBUG
66#endif // defined(_DEBUG)
67
68#include <boost/version.hpp>
69
70#include "CompilerWarnings.hh"
71IGNORE_COMPILER_WARNING("-Wunused-parameter")
72IGNORE_CLANG_WARNING("-Wunused-local-typedef")
73#if BOOST_VERSION >= 103800
74
75#define PHOENIX_LIMIT 10
76
77#include <boost/spirit/include/classic.hpp>
78#include <boost/spirit/include/classic_utility.hpp>
79#include <boost/spirit/include/classic_symbols.hpp>
80#include <boost/spirit/include/classic_assign_actor.hpp>
81#include <boost/spirit/include/classic_assign_key_actor.hpp>
82#include <boost/spirit/include/classic_clear_actor.hpp>
83#include <boost/spirit/include/classic_decrement_actor.hpp>
84#include <boost/spirit/include/classic_erase_actor.hpp>
85#include <boost/spirit/include/classic_increment_actor.hpp>
86#include <boost/spirit/include/classic_insert_key_actor.hpp>
87#include <boost/spirit/include/classic_insert_at_actor.hpp>
88#include <boost/spirit/include/classic_push_back_actor.hpp>
89#include <boost/spirit/include/classic_push_front_actor.hpp>
90#include <boost/spirit/include/classic_swap_actor.hpp>
91
92using namespace boost::spirit::classic;
93
94#else
95
96#include <boost/spirit/core.hpp>
97#include <boost/spirit/utility.hpp>
98#include <boost/spirit/symbols.hpp>
99#include <boost/spirit/actor/assign_actor.hpp>
100#include <boost/spirit/actor/assign_key_actor.hpp>
101#include <boost/spirit/actor/clear_actor.hpp>
102#include <boost/spirit/actor/decrement_actor.hpp>
103#include <boost/spirit/actor/erase_actor.hpp>
104#include <boost/spirit/actor/increment_actor.hpp>
105#include <boost/spirit/actor/insert_key_actor.hpp>
106#include <boost/spirit/actor/insert_at_actor.hpp>
107#include <boost/spirit/actor/push_back_actor.hpp>
108#include <boost/spirit/actor/push_front_actor.hpp>
109#include <boost/spirit/actor/swap_actor.hpp>
110
111using namespace boost::spirit;
112
113#endif
116
117#include "Conversion.hh"
118
119// There is a g++ (3.1 and 3.2) bug on MINGW that prohibits
120// the use of the identifiers below. The following is a workaround.
121
122#if ((__GNUC__ == 3) && (__GNUC_MINOR__ == 1 || __GNUC_MINOR__ == 2) \
123 && defined(_WINNT_H))
124# ifdef CONST
125# undef CONST
126# endif
127# ifdef VOID
128# undef VOID
129# endif
130# define CHAR CHAR_RULE
131# define CONST CONST_RULE
132# define FLOAT FLOAT_RULE
133# define INT INT_RULE
134# define VOID VOID_RULE
135#endif
136
137/////////////////////////////////////////////////////////////////////////////
138// used namespaces
139using namespace boost::spirit;
140using namespace std;
141
142
143/**
144 * Class which is used by Spirit parser to create tokenized
145 * tree form of the source code.
146 */
147
149public:
150
151 /**
152 * List of different type tokens.
153 */
222
223 /**
224 * Prints string value for each token.
225 *
226 * @param id Token type.
227 * @return String for token type.
228 */
229 static std::string idString(OperationID id) {
230 switch (id) {
231 case IDENTIFIER: return "IDENTIFIER:";
232 case STRING_LITERAL: return "STRING_LITERAL:";
233 case INTEGER_LITERAL: return "INTEGER_LITERAL:";
234 case FLOAT_LITERAL: return "FLOAT_LITERAL:";
235 case PRIMARY_EXPRESSION: return "PRIMARY_EXPRESSION:";
236 case UNARY_EXPRESSION: return "UNARY_EXPRESSION:";
237 case UNARY_ADDROF: return "UNARY_ADDROF:";
238 case UNARY_STAR: return "UNARY_STAR:";
239 case UNARY_PLUS: return "UNARY_PLUS:";
240 case UNARY_MINUS: return "UNARY_MINUS:";
241 case UNARY_TILDE: return "UNARY_TILDE:";
242 case UNARY_BANG: return "UNARY_BANG:";
243 case POSTFIX_EXPRESSION: return "POSTFIX_EXPRESSION:";
244 case CAST_EXPRESSION: return "CAST_EXPRESSION:";
245 case MULTIPLICATIVE_EXPRESSION: return "MULTIPLICATIVE_EXPRESSION:";
246 case ADDITIVE_EXPRESSION: return "ADDITIVE_EXPRESSION:";
247 case SHIFT_EXPRESSION: return "SHIFT_EXPRESSION:";
248 case RELATIONAL_EXPRESSION: return "RELATIONAL_EXPRESSION:";
249 case EQUALITY_EXPRESSION: return "EQUALITY_EXPRESSION:";
250 case AND_EXPRESSION: return "AND_EXPRESSION:";
251 case EXCLUSIVE_EXPRESSION: return "EXCLUSIVE_EXPRESSION:";
252 case INCLUSIVE_EXPRESSION: return "INCLUSIVE_EXPRESSION:";
253 case LOGICAL_AND_EXPRESSION: return "LOGICAL_AND_EXPRESSION:";
254 case LOGICAL_OR_EXPRESSION: return "LOGICAL_OR_EXPRESSION:";
255 case CONDITIONAL_EXPRESSION: return "CONDITIONAL_EXPRESSION:";
256 case ASSIGNMENT_EXPRESSION: return "ASSIGNMENT_EXPRESSION:";
257 case ASSIGNMENT_OPERATOR: return "ASSIGNMENT_OPERATOR:";
258 case EXPRESSION: return "EXPRESSION:";
259 case CONSTANT_EXPRESSION: return "CONSTANT_EXPRESSION:";
260 case DECLARATION: return "DECLARATION:";
261 case DECLARATION_SPECIFIERS: return "DECLARATION_SPECIFIERS:";
262 case INIT_DECLARATOR: return "INIT_DECLARATOR:";
263 case STORAGE_CLASS_SPECIFIER: return "STORAGE_CLASS_SPECIFIER:";
264 case TYPE_SPECIFIER: return "TYPE_SPECIFIER:";
265 case STRUCT_OR_UNION_SPECIFIER: return "STRUCT_OR_UNION_SPECIFIER:";
266 case STRUCT_OR_UNION: return "STRUCT_OR_UNION:";
267 case STRUCT_DECLARATION: return "STRUCT_DECLARATION:";
268 case STRUCT_DECLARATOR: return "STRUCT_DECLARATOR:";
269 case ENUM_SPECIFIER: return "ENUM_SPECIFIER:";
270 case ENUMERATOR: return "ENUMERATOR:";
271 case CONST_QUALIFER: return "CONST_QUALIFER:";
272 case VOLATILE_QUALIFER: return "VOLATILE_QUALIFER:";
273 case TYPE_QUALIFER: return "TYPE_QUALIFER:";
274 case DECLARATOR: return "DECLARATOR:";
275 case INITIALIZER: return "INITIALIZER:";
276 case DIRECT_DECLARATOR: return "DIRECT_DECLARATOR:";
277 case POINTER: return "POINTER:";
278 case PARAMETER_TYPE_LIST: return "PARAMETER_TYPE_LIST:";
279 case PARAMETER_LIST: return "PARAMETER_LIST:";
280 case PARAMETER_DECLARATION: return "PARAMETER_DECLARATION:";
281 case IDENTIFIER_LIST: return "IDENTIFIER_LIST:";
282 case TYPE_NAME: return "TYPE_NAME:";
283 case ABSTRACT_DECLARATOR: return "ABSTRACT_DECLARATOR:";
284 case DIRECT_ABSTRACT_DECLARATOR: return "DIRECT_ABSTRACT_DECLARATOR:";
285 case INITIALIZER_LIST: return "INITIALIZER_LIST:";
286 case STATEMENT: return "STATEMENT:";
287 case LABELED_STATEMENT: return "LABELED_STATEMENT:";
288 case COMPOUND_STATEMENT: return "COMPOUND_STATEMENT:";
289 case STATEMENT_LIST: return "STATEMENT_LIST:";
290 case EXPRESSION_STATEMENT: return "EXPRESSION_STATEMENT:";
291 case SELECTION_STATEMENT: return "SELECTION_STATEMENT:";
292 case ITERATION_STATEMENT: return "ITERATION_STATEMENT:";
293 case JUMP_STATEMENT: return "JUMP_STATEMENT:";
294 case FUNCTION_DEFINITION: return "FUNCTION_DEFINITION:";
295 case EXTERNAL_DECLARATION: return "EXTERNAL_DECLARATION:";
296 case INVALID_TOKEN: return "INVALID_TOKEN:";
297 default: return "UNKNOWN_ID:";
298 }
299 }
300
301 /**
302 * Represents one token of source code.
303 */
304 class Token {
305 public:
306 Token(unsigned long start, unsigned long end, std::string& strValue) :
307 start_(start), end_(end), strValue_(strValue),
320
321 bool isIdentifier() const {return isIdentifier_;}
322 bool isStringLiteral() const {return isStringLiteral_;}
323 bool isIntegerLiteral() const {return isIntegerLiteral_;}
324 bool isFloatLiteral() const {return isFloatLiteral_;}
326 bool isAddrofOperator() const {return isAddrofOperator_;}
328 bool isPlusOperator() const {return isPlusOperator_;}
329 bool isMinusOperator() const {return isMinusOperator_;}
330 bool isTildeOperator() const {return isTildeOperator_;}
331 bool isBangOperator() const {return isBangOperator_;}
332
333 long intValue() const {
334 if (!isIntegerLiteral()) {
335 // TODO: throw exception
336 assert(false && "Node is not integer literal.");
337 }
339 }
340
341 std::string stringValue() const {
342 return strValue_;
343 }
344
345 bool isPostfixExpression() const {return false;}
346
348 switch (id) {
349 case IDENTIFIER: isIdentifier_ = true; break;
350 case STRING_LITERAL: isStringLiteral_ = true; break;
351 case INTEGER_LITERAL: isIntegerLiteral_ = true; break;
352 case FLOAT_LITERAL: isFloatLiteral_ = true; break;
353 case UNARY_EXPRESSION: isUnaryExpression_ = true; break;
354 case UNARY_ADDROF: isAddrofOperator_ = true; break;
355 case UNARY_STAR: isAsteriskOperator_ = true; break;
356 case UNARY_PLUS: isPlusOperator_ = true; break;
357 case UNARY_MINUS: isMinusOperator_ = true; break;
358 case UNARY_TILDE: isTildeOperator_ = true; break;
359 case UNARY_BANG: isBangOperator_ = true; break;
360 default: ;
361 }
362
363 type_ = id;
364 }
365
366 unsigned long start_;
367 unsigned long end_;
368 std::string strValue_;
370
382 };
383
384 /**
385 * One node of tree of tokens.
386 *
387 * Each node contains reference to it's token and it's sub-token-nodes..
388 *
389 * root
390 * \
391 * function
392 * / \
393 * name postfix
394 * / |
395 * name name
396 */
398 public:
399 TokenTreeNode() : data_(NULL) {}
401
402 /**
403 * Returns true if node contain tokens of function call.
404 *
405 * leafs must be:
406 * PRIMARY_EXPRESSION, POSTFIX_EXPRESSION
407 *
408 * @return true if node is function call.
409 */
410 bool isFunctionCall() const {
411 if (leafCount() == 2 &&
412 leaf(0).token().type_ == PRIMARY_EXPRESSION &&
413 leaf(1).token().type_ == POSTFIX_EXPRESSION) {
414 return true;
415 }
416 return false;
417 }
418
419 /**
420 * Returns true if node contain tokens of assignment
421 *
422 * leafs must be:
423 * ANY, ASSIGNMENT_OPERATOR, ANY
424 *
425 * @return true if node is assginment.
426 */
427 bool isAssignment() const {
428 if (leafCount() == 3 &&
429 leaf(1).token().type_ == ASSIGNMENT_OPERATOR) {
430 return true;
431 }
432 return false;
433 }
434
435 /**
436 * Returns true if node contain integer value.
437 *
438 * leafs must be: none, or (+|-, isIntegerLiteral)
439 *
440 * @return true if node is integer value.
441 */
442 bool isInteger() const {
443 if (
444 // if two part integer e.g. -1 or +1
445 (leafCount() == 2 &&
446 leaf(1).token().isIntegerLiteral() &&
447 (leaf(0).token().isPlusOperator() ||
448 leaf(0).token().isMinusOperator())) ||
449
450 // or if just number without prefix
451 (leafCount() == 0 && token().isIntegerLiteral())
452 ) {
453
454 return true;
455 }
456
457 return false;
458 }
459
460 long intValue() const {
461 if (!isInteger()) {
462 // TODO: throw exception
463 assert(false && "Node is not integer.");
464 }
465
466 long retVal = 0;
467
468 if (leafCount() == 2) {
469 retVal = leaf(1).token().intValue();
470 if (leaf(0).token().isMinusOperator()) {
471 retVal = -retVal;
472 }
473 } else {
474 retVal = token().intValue();
475 }
476
477 return retVal;
478 }
479
480 /**
481 * Adds newly parsed token to tree under this token tree node.
482 *
483 * @param token Token to add token tree.
484 */
488
489 /**
490 * Returns referred token of token tree node.
491 *
492 * @returns Referred token of token tree node.
493 */
494 const Token& token() const {
495 return *data_;
496 }
497
498 /**
499 * Returns number of leafs that this token tree node has.
500 *
501 * @return Number of leafs that this token tree node has.
502 */
503 int leafCount() const {
504 return leafs_.size();
505 }
506
507 /**
508 * Returns leaf of requested index.
509 *
510 * @param index Index of leaf to return.
511 * @return leaf of requested index.
512 */
513 TokenTreeNode& leaf(int index) const {
514 assert(index < leafCount());
515 return *leafs_[index];
516 }
517
518
519 /**
520 * Returns node and its sub nodes as a string.
521 *
522 * @return Node and its sub nodes as a string.
523 */
524 std::string toStr() const {
525 static int recursioLevel = 0;
526
527 recursioLevel++;
528 std::stringstream retVal;
529
530 if (data_ == NULL) {
531 retVal << "Root node" << std::endl;
532 } else {
533 retVal << setw(5) << data_->start_ << ":"
534 << setw(5) << std::left << data_->end_ << std::right
535 << setw(30) << TokenizerData::idString(data_->type_)
536 << " ";
537
538 for (int fill = 0; fill < (recursioLevel-2)*2; fill++) {
539 retVal << "*";
540 }
541
542 retVal << " " << data_->strValue_ << std::endl;
543 }
544
545 for (int i = 0; i < leafCount(); i++) {
546 retVal << " " << leaf(i).toStr();
547 }
548
549 recursioLevel--;
550 return retVal.str();
551 }
552
553 private:
554
555 /**
556 * Adds token tree node to under other token tree node.
557 *
558 * @param currNode Node where to add new node.
559 * @param newToken Token tree node to add to currNode.
560 */
561 static void addToTokenTree(
562 TokenTreeNode* currNode, TokenTreeNode* newToken) {
563
564 // check if token should be part of one of the leafs
565 for (std::vector<TokenTreeNode*>::iterator i =
566 currNode->leafs_.begin() ;
567 i != currNode->leafs_.end();i++) {
568 TokenTreeNode *currLeaf = *i;
569
570 // if this token should be part of current leaf
571 if (newToken->data_->start_ >= currLeaf->data_->start_ &&
572 newToken->data_->end_ <= currLeaf->data_->end_) {
573
574 addToTokenTree(currLeaf, newToken);
575 return;
576 }
577
578 // move current leafs to inside this token
579 // if necessary
580 if (newToken->data_->start_ <= currLeaf->data_->start_ &&
581 newToken->data_->end_ >= currLeaf->data_->end_) {
582
583 // remove from original
584 std::vector<TokenTreeNode*>::iterator temp = i;
585 i--;
586 currNode->leafs_.erase(temp);
587
588 // add to new...
589 newToken->leafs_.push_back(currLeaf);
590 }
591
592 // if start of current leaf is after end of this..
593 // add token to this point.
594 if (newToken->data_->end_ <= currLeaf->data_->start_) {
595 currNode->leafs_.insert(i, newToken);
596 return;
597 }
598 }
599
600 // if there wasn't any sub nodes where value could go, add it to
601 // end of current node
602 currNode->leafs_.push_back(newToken);
603 return;
604 }
605
606 /// Token of token tree node.
608
609 /// Leafs of this node.
610 std::vector<TokenTreeNode*> leafs_;
611 };
612
614
615 /**
616 * Deletes all the parsed data.
617 */
619 while (!parsedTokens_.empty()) {
620 delete (parsedTokens_.begin()->second);
621 parsedTokens_.erase(parsedTokens_.begin());
622 }
623 // TODO: delete TokenTreeNodes
624 }
625
626
627 /**
628 * Creates new token based on parsed data or updates new type info
629 * for old token.
630 *
631 * @param start Start position of token.
632 * @param end End position of token.
633 * @param id Type of token.
634 * @param strVal String of token.
635 */
636 void addToken(const char* start, const char* end,
637 OperationID id, std::string strVal) {
638
639 unsigned long startPos, endPos;
640
641 if (parsedTokens_.empty()) {
642 startPos = 0;
643 endPos = end - start;
644 } else {
645 // in parsedTokens_.begin()->first.second is actually stored value
646 // (-start) of first parsed token. So we can add it to current
647 // start address for getting relative end and start positions.
648 startPos =
649 reinterpret_cast<unsigned long>(start) +
650 reinterpret_cast<unsigned long>(
651 parsedTokens_.begin()->first.second);
652
653 endPos =
654 reinterpret_cast<unsigned long>(end) +
655 reinterpret_cast<unsigned long>(
656 parsedTokens_.begin()->first.second);
657 }
658
659 // key for map is selected (end, -start) for automatically organizase
660 // tokens
661 std::pair<const char*, const char*>
662 tokenKey(end, (const char*)(-reinterpret_cast<unsigned long>(start)));
663
664 if (parsedTokens_.find(tokenKey) == parsedTokens_.end()) {
665 parsedTokens_[tokenKey] = new Token(startPos, endPos, strVal);
667 }
668
669 parsedTokens_[tokenKey]->setProperty(id);
670 }
671
672 /**
673 * Shows source code parsed to tokens.
674 */
676
677 for (TokenContainerType::iterator i = parsedTokens_.begin();
678 i != parsedTokens_.end(); i++) {
679
680 std::cerr << std::hex
681 << std::setw(4) << i->second->start_
682 << " - "
683 << std::setw(4) << i->second->end_
684
685 << " : "
686 << std::setw(30) << idString(i->second->type_)
687
688 << " : "
689 << i->second->strValue_
690 << std::endl;
691 }
692 }
693
694 /**
695 * Returns root node of token tree.
696 *
697 * @return Root node of token tree.
698 */
699 const TokenTreeNode* tokenTree() const {
700 return &root;
701 }
702
703private:
704 typedef std::map<
705 std::pair<const char*, const char*>, Token*> TokenContainerType;
706
709};
710
711
712/**
713 * Spirit actor for adding data to TokenizerData during parsing.
714 */
716
719
722
723 void operator()(const char* start, const char* end) const {
724 std::string temp(start,end);
725 data_.addToken(start, end, id_, temp);
726
727 // std::cerr << "found: " << setw(10) << TokenizerData::idString(id_)
728 // << " " << temp << std::endl;
729 }
730};
731
732/**
733 * Spirit actor for book keeping stripped strings.
734 */
736
737 SetStripPairActor(std::pair<const char*, const char*> &aPair) :
738 thePair_(aPair) {}
739
740 std::pair<const char*, const char*> &thePair_;
741
742 void operator()(const char* start, const char* end) const {
743 thePair_ = std::pair<const char*, const char*>(start, end);
744 }
745};
746
747/////////////////////////////////////////////////////////////////////////////
748// parsing helper function
749
750// Here's our comment rule
751struct skip_grammar : public grammar<skip_grammar>
752{
753 template <typename ScannerT>
755 {
757 {
758 skip =
759 (str_p("//") >> *(anychar_p - '\n') >> ch_p('\n'))
761 [push_back_a(self.strippedParts, self.lastStrip)]
762
763 |
764 ("/*" >> *(anychar_p - "*/") >> "*/")
766 [push_back_a(self.strippedParts, self.lastStrip)]
767
768 |
769 (+space_p)
771 [push_back_a(self.strippedParts, self.lastStrip)]
772 ;
773
774 }
775
776 rule<ScannerT> skip;
777
778 rule<ScannerT> const&
779 start() const { return skip; }
780 };
781
782public:
783 mutable std::vector<std::pair<const char*, const char*> > strippedParts;
784 mutable std::pair<const char*, const char*> lastStrip;
785};
786
788 public grammar<OperationDAGLanguageGrammar>
789{
790 template <typename ScannerT>
791 struct definition {
793 ELLIPSIS("..."), RIGHT_ASSIGN(">>="), LEFT_ASSIGN("<<="),
794 ADD_ASSIGN("+="), SUB_ASSIGN("-="), MUL_ASSIGN("*="),
795 DIV_ASSIGN("/="), MOD_ASSIGN("%="), AND_ASSIGN("&="),
796 XOR_ASSIGN("^="), OR_ASSIGN("|="), RIGHT_OP(">>"), LEFT_OP("<<"),
797 INC_OP("++"), DEC_OP("--"), PTR_OP("->"), AND_OP("&&"),
798 OR_OP("||"), LE_OP("<="), GE_OP(">="), EQ_OP("=="), NE_OP("!="),
799// SEMICOLON(';'),
800// COMMA(','), COLON(':'), ASSIGN('='), LEFT_PAREN('('),
801// RIGHT_PAREN(')'), DOT('.'), ADDROF('&'), BANG('!'), TILDE('~'),
802// MINUS('-'), PLUS('+'), STAR('*'), SLASH('/'), PERCENT('%'),
803// LT_OP('<'), GT_OP('>'), XOR('^'), OR('|'), QUEST('?') {
804 SEMICOLON(";"),
805 COMMA(","), COLON(":"), ASSIGN("="), LEFT_PAREN("("),
806 RIGHT_PAREN(")"), DOT("."), ADDROF("&"), BANG("!"), TILDE("~"),
807 MINUS("-"), PLUS("+"), STAR("*"), SLASH("/"), PERCENT("%"),
808 LT_OP("<"), GT_OP(">"), XOR("^"), OR("|"), QUEST("?") {
809
810 // C keywords
811 keywords =
812 "auto", "break", "case", "char", "const", "continue",
813 "default", "do", "double", "else", "enum", "extern",
814 "float", "for", "goto", "if", "int", "long", "register",
815 "return", "short", "signed", "sizeof", "static", "struct",
816 "switch", "typedef", "union", "unsigned", "void",
817 "volatile", "while";
818
819 // C operators
820// LEFT_BRACE = chlit<>('{') | strlit<>("<%");
821// RIGHT_BRACE = chlit<>('}') | strlit<>("%>");
822// LEFT_BRACKET = chlit<>('[') | strlit<>("<:");
823// RIGHT_BRACKET = chlit<>(']') | strlit<>(":>");
824 LEFT_BRACE = strlit<>("{") | strlit<>("<%");
825 RIGHT_BRACE = strlit<>("}") | strlit<>("%>");
826 LEFT_BRACKET = strlit<>("[") | strlit<>("<:");
827 RIGHT_BRACKET = strlit<>("]") | strlit<>(":>");
828
829 // Tokens
830 AUTO = strlit<>("auto");
831 BREAK = strlit<>("break");
832 CASE = strlit<>("case");
833 CHAR = strlit<>("char");
834 CONST = strlit<>("const");
835 CONTINUE = strlit<>("continue");
836 DEFAULT = strlit<>("default");
837 DO = strlit<>("do");
838 DOUBLE = strlit<>("double");
839 ELSE = strlit<>("else");
840 ENUM = strlit<>("enum");
841 EXTERN = strlit<>("extern");
842 FOR = strlit<>("for");
843 FLOAT = strlit<>("float");
844 GOTO = strlit<>("goto");
845 IF = strlit<>("if");
846 INT = strlit<>("int");
847 LONG = strlit<>("long");
848 REGISTER = strlit<>("register");
849 RETURN = strlit<>("return");
850 SHORT = strlit<>("short");
851 SIGNED = strlit<>("signed");
852 SIZEOF = strlit<>("sizeof");
853 STATIC = strlit<>("static");
854 STRUCT = strlit<>("struct");
855 SWITCH = strlit<>("switch");
856 TYPEDEF = strlit<>("typedef");
857 UNION = strlit<>("union");
858 UNSIGNED = strlit<>("unsigned");
859 VOID = strlit<>("void");
860 VOLATILE = strlit<>("volatile");
861 WHILE = strlit<>("while");
862
863 // C identifiers
864 IDENTIFIER =
865 (lexeme_d[
866 ((alpha_p | '_' | '$') >> *(alnum_p | '_' | '$'))
867 - (keywords >> (anychar_p - (alnum_p | '_' | '$')))
868 ])
871
872 ;
873
874 // string literals
876 lexeme_d[
877 !chlit<>('L') >> chlit<>('\"') >>
878 *( strlit<>("\\\"") | ( anychar_p - chlit<>('\"') )) >>
879 chlit<>('\"')
880 ]
881 ;
882
887 ;
888
889 // integer constants
891 lexeme_d[
892 chlit<>('0') >>
893 as_lower_d[chlit<>('x')] >>
894 +xdigit_p >>
895 !as_lower_d[chlit<>('l') | chlit<>('u')]
896 ]
897 ;
898
900 = lexeme_d[
901 chlit<>('0')
902 >> +range<>('0', '7')
903 >> !as_lower_d[chlit<>('l') | chlit<>('u')]
904 ]
905 ;
906
908 = lexeme_d[
909 +digit_p
910 >> !as_lower_d[chlit<>('l') | chlit<>('u')]
911 ]
912 ;
913
915 = lexeme_d[
916 !chlit<>('L') >> chlit<>('\'') >>
917 longest_d[
918 anychar_p
919 | ( chlit<>('\\')
920 >> chlit<>('0')
921 >> repeat_p(0, 2)[range<>('0', '7')]
922 )
923 | (chlit<>('\\') >> anychar_p)
924 ] >>
925 chlit<>('\'')
926 ]
927 ;
928
936 ;
937
938 // float constants
939 FLOAT_CONSTANT_1 // 12345[eE][+-]123[lLfF]?
940 = lexeme_d[
941 +digit_p
942 >> (chlit<>('e') | chlit<>('E'))
943 >> !(chlit<>('+') | chlit<>('-'))
944 >> +digit_p
945 >> !as_lower_d[chlit<>('l') | chlit<>('f')]
946 ]
947 ;
948
949 FLOAT_CONSTANT_2 // .123([[eE][+-]123)?[lLfF]?
950 = lexeme_d[
951 *digit_p
952 >> chlit<>('.')
953 >> +digit_p
954 >> !((chlit<>('e') | chlit<>('E'))
955 >> !(chlit<>('+') | chlit<>('-'))
956 >> +digit_p
957 )
958 >> !as_lower_d[chlit<>('l') | chlit<>('f')]
959 ]
960 ;
961
962 FLOAT_CONSTANT_3 // 12345.([[eE][+-]123)?[lLfF]?
963 = lexeme_d[
964 +digit_p
965 >> chlit<>('.')
966 >> *digit_p
967 >> !((chlit<>('e') | chlit<>('E'))
968 >> !(chlit<>('+') | chlit<>('-'))
969 >> +digit_p
970 )
971 >> !as_lower_d[chlit<>('l') | chlit<>('f')]
972 ]
973 ;
974
981 ;
982
983 CONSTANT =
984 (longest_d[FLOAT_CONSTANT | INT_CONSTANT])
985 ;
986
987 // debug support for terminals
988 BOOST_SPIRIT_DEBUG_RULE(AUTO);
989 BOOST_SPIRIT_DEBUG_RULE(BREAK);
990 BOOST_SPIRIT_DEBUG_RULE(CASE);
991 BOOST_SPIRIT_DEBUG_RULE(CHAR);
992 BOOST_SPIRIT_DEBUG_RULE(CONST);
993 BOOST_SPIRIT_DEBUG_RULE(CONTINUE);
994 BOOST_SPIRIT_DEBUG_RULE(DEFAULT);
995 BOOST_SPIRIT_DEBUG_RULE(DO);
996 BOOST_SPIRIT_DEBUG_RULE(DOUBLE);
997 BOOST_SPIRIT_DEBUG_RULE(ELSE);
998 BOOST_SPIRIT_DEBUG_RULE(ENUM);
999 BOOST_SPIRIT_DEBUG_RULE(EXTERN);
1000 BOOST_SPIRIT_DEBUG_RULE(FOR);
1001 BOOST_SPIRIT_DEBUG_RULE(FLOAT);
1002 BOOST_SPIRIT_DEBUG_RULE(GOTO);
1003 BOOST_SPIRIT_DEBUG_RULE(IF);
1004 BOOST_SPIRIT_DEBUG_RULE(INT);
1005 BOOST_SPIRIT_DEBUG_RULE(LONG);
1006 BOOST_SPIRIT_DEBUG_RULE(REGISTER);
1007 BOOST_SPIRIT_DEBUG_RULE(RETURN);
1008 BOOST_SPIRIT_DEBUG_RULE(SHORT);
1009 BOOST_SPIRIT_DEBUG_RULE(SIGNED);
1010 BOOST_SPIRIT_DEBUG_RULE(SIZEOF);
1011 BOOST_SPIRIT_DEBUG_RULE(STATIC);
1012 BOOST_SPIRIT_DEBUG_RULE(STRUCT);
1013 BOOST_SPIRIT_DEBUG_RULE(SWITCH);
1014 BOOST_SPIRIT_DEBUG_RULE(TYPEDEF);
1015 BOOST_SPIRIT_DEBUG_RULE(UNION);
1016 BOOST_SPIRIT_DEBUG_RULE(UNSIGNED);
1017 BOOST_SPIRIT_DEBUG_RULE(VOID);
1018 BOOST_SPIRIT_DEBUG_RULE(VOLATILE);
1019 BOOST_SPIRIT_DEBUG_RULE(WHILE);
1020 BOOST_SPIRIT_DEBUG_RULE(IDENTIFIER);
1021 BOOST_SPIRIT_DEBUG_RULE(STRING_LITERAL);
1022 BOOST_SPIRIT_DEBUG_RULE(INT_CONSTANT_HEX);
1023 BOOST_SPIRIT_DEBUG_RULE(INT_CONSTANT_OCT);
1024 BOOST_SPIRIT_DEBUG_RULE(INT_CONSTANT_DEC);
1025 BOOST_SPIRIT_DEBUG_RULE(INT_CONSTANT_CHAR);
1026 BOOST_SPIRIT_DEBUG_RULE(INT_CONSTANT);
1027 BOOST_SPIRIT_DEBUG_RULE(FLOAT_CONSTANT_1);
1028 BOOST_SPIRIT_DEBUG_RULE(FLOAT_CONSTANT_2);
1029 BOOST_SPIRIT_DEBUG_RULE(FLOAT_CONSTANT_3);
1030 BOOST_SPIRIT_DEBUG_RULE(FLOAT_CONSTANT);
1031 BOOST_SPIRIT_DEBUG_RULE(CONSTANT);
1032
1033 // debug support for non terminals
1034 BOOST_SPIRIT_DEBUG_RULE(primary_expression);
1035 BOOST_SPIRIT_DEBUG_RULE(postfix_expression);
1036 BOOST_SPIRIT_DEBUG_RULE(postfix_expression_helper);
1037 BOOST_SPIRIT_DEBUG_RULE(argument_expression_list);
1038 BOOST_SPIRIT_DEBUG_RULE(unary_expression);
1039 BOOST_SPIRIT_DEBUG_RULE(unary_operator);
1040 BOOST_SPIRIT_DEBUG_RULE(cast_expression);
1041 BOOST_SPIRIT_DEBUG_RULE(multiplicative_expression);
1042 BOOST_SPIRIT_DEBUG_RULE(multiplicative_expression_helper);
1043 BOOST_SPIRIT_DEBUG_RULE(additive_expression);
1044 BOOST_SPIRIT_DEBUG_RULE(additive_expression_helper);
1045 BOOST_SPIRIT_DEBUG_RULE(shift_expression);
1046 BOOST_SPIRIT_DEBUG_RULE(shift_expression_helper);
1047 BOOST_SPIRIT_DEBUG_RULE(relational_expression);
1048 BOOST_SPIRIT_DEBUG_RULE(relational_expression_helper);
1049 BOOST_SPIRIT_DEBUG_RULE(equality_expression);
1050 BOOST_SPIRIT_DEBUG_RULE(equality_expression_helper);
1051 BOOST_SPIRIT_DEBUG_RULE(and_expression);
1052 BOOST_SPIRIT_DEBUG_RULE(and_expression_helper);
1053 BOOST_SPIRIT_DEBUG_RULE(exclusive_or_expression);
1054 BOOST_SPIRIT_DEBUG_RULE(exclusive_or_expression_helper);
1055 BOOST_SPIRIT_DEBUG_RULE(inclusive_or_expression);
1056 BOOST_SPIRIT_DEBUG_RULE(inclusive_or_expression_helper);
1057 BOOST_SPIRIT_DEBUG_RULE(logical_and_expression);
1058 BOOST_SPIRIT_DEBUG_RULE(logical_and_expression_helper);
1059 BOOST_SPIRIT_DEBUG_RULE(logical_or_expression);
1060 BOOST_SPIRIT_DEBUG_RULE(logical_or_expression_helper);
1061 BOOST_SPIRIT_DEBUG_RULE(conditional_expression);
1062 BOOST_SPIRIT_DEBUG_RULE(conditional_expression_helper);
1063 BOOST_SPIRIT_DEBUG_RULE(assignment_expression);
1064 BOOST_SPIRIT_DEBUG_RULE(assignment_operator);
1065 BOOST_SPIRIT_DEBUG_RULE(expression);
1066 BOOST_SPIRIT_DEBUG_RULE(constant_expression);
1067 BOOST_SPIRIT_DEBUG_RULE(declaration);
1068 BOOST_SPIRIT_DEBUG_RULE(declaration_specifiers);
1069 BOOST_SPIRIT_DEBUG_RULE(init_declarator_list);
1070 BOOST_SPIRIT_DEBUG_RULE(init_declarator);
1071 BOOST_SPIRIT_DEBUG_RULE(storage_class_specifier);
1072 BOOST_SPIRIT_DEBUG_RULE(type_specifier);
1073 BOOST_SPIRIT_DEBUG_RULE(struct_or_union_specifier);
1074 BOOST_SPIRIT_DEBUG_RULE(struct_or_union);
1075 BOOST_SPIRIT_DEBUG_RULE(struct_declaration_list);
1076 BOOST_SPIRIT_DEBUG_RULE(struct_declaration);
1077 BOOST_SPIRIT_DEBUG_RULE(specifier_qualifier_list);
1078 BOOST_SPIRIT_DEBUG_RULE(struct_declarator_list);
1079 BOOST_SPIRIT_DEBUG_RULE(struct_declarator);
1080 BOOST_SPIRIT_DEBUG_RULE(enum_specifier);
1081 BOOST_SPIRIT_DEBUG_RULE(enumerator_list);
1082 BOOST_SPIRIT_DEBUG_RULE(enumerator);
1083 BOOST_SPIRIT_DEBUG_RULE(type_qualifier);
1084 BOOST_SPIRIT_DEBUG_RULE(declarator);
1085 BOOST_SPIRIT_DEBUG_RULE(direct_declarator);
1086 BOOST_SPIRIT_DEBUG_RULE(direct_declarator_helper);
1087 BOOST_SPIRIT_DEBUG_RULE(pointer);
1088 BOOST_SPIRIT_DEBUG_RULE(type_qualifier_list);
1089 BOOST_SPIRIT_DEBUG_RULE(parameter_type_list);
1090 BOOST_SPIRIT_DEBUG_RULE(parameter_list);
1091 BOOST_SPIRIT_DEBUG_RULE(parameter_declaration);
1092 BOOST_SPIRIT_DEBUG_RULE(identifier_list);
1093 BOOST_SPIRIT_DEBUG_RULE(type_name);
1094 BOOST_SPIRIT_DEBUG_RULE(abstract_declarator);
1095 BOOST_SPIRIT_DEBUG_RULE(direct_abstract_declarator);
1096 BOOST_SPIRIT_DEBUG_RULE(direct_abstract_declarator_helper);
1097 BOOST_SPIRIT_DEBUG_RULE(initializer);
1098 BOOST_SPIRIT_DEBUG_RULE(initializer_list);
1099 BOOST_SPIRIT_DEBUG_RULE(statement);
1100 BOOST_SPIRIT_DEBUG_RULE(labeled_statement);
1101 BOOST_SPIRIT_DEBUG_RULE(compound_statement);
1102 BOOST_SPIRIT_DEBUG_RULE(declaration_list);
1103 BOOST_SPIRIT_DEBUG_RULE(statement_list);
1104 BOOST_SPIRIT_DEBUG_RULE(expression_statement);
1105 BOOST_SPIRIT_DEBUG_RULE(selection_statement);
1106 BOOST_SPIRIT_DEBUG_RULE(iteration_statement);
1107 BOOST_SPIRIT_DEBUG_RULE(jump_statement);
1108 BOOST_SPIRIT_DEBUG_RULE(translation_unit);
1109 BOOST_SPIRIT_DEBUG_RULE(external_declaration);
1110 BOOST_SPIRIT_DEBUG_RULE(function_definition);
1111
1112 // Rules
1114 (IDENTIFIER
1115 | CONSTANT
1120 ;
1121
1122 // left recursion --> right recursion
1123 // postfix_expression
1124 // = primary_expression
1125 // | postfix_expression >>
1126 // (
1127 // LEFT_BRACKET >> expression >> RIGHT_BRACKET
1128 // | LEFT_PAREN >> !argument_expression_list >> RIGHT_PAREN
1129 // | DOT >> IDENTIFIER
1130 // | PTR_OP >> IDENTIFIER
1131 // | INC_OP
1132 // | DEC_OP
1133 // )
1134 // ;
1137 ;
1138
1142 | DOT >> IDENTIFIER
1143 | PTR_OP >> IDENTIFIER
1144 | INC_OP
1145 | DEC_OP) >>
1149 | epsilon_p
1150 ;
1151
1154
1160 | SIZEOF >>
1161
1166 ;
1167
1169 ADDROF
1172
1173 | STAR
1176
1177 | PLUS
1180
1181 | MINUS
1184
1185 | TILDE
1188
1189 | BANG
1192
1193 ;
1194
1201
1202 ;
1203
1204 // left recursion --> right recursion
1205 // multiplicative_expression
1206 // = cast_expression
1207 // | multiplicative_expression >>
1208 // (
1209 // STAR >> cast_expression
1210 // | SLASH >> cast_expression
1211 // | PERCENT >> cast_expression
1212 // )
1213 // ;
1216 ;
1217
1221 | PERCENT >> cast_expression) >>
1225 | epsilon_p
1226 ;
1227
1228 // left recursion --> right recursion
1229 // additive_expression
1230 // = multiplicative_expression
1231 // | additive_expression >>
1232 // (
1233 // PLUS >> multiplicative_expression
1234 // | MINUS >> multiplicative_expression
1235 // )
1236 // ;
1239 ;
1240
1247
1248 | epsilon_p
1249 ;
1250
1251 // left recursion --> right recursion
1252 // shift_expression
1253 // = additive_expression
1254 // | shift_expression >>
1255 // (
1256 // LEFT_OP >> additive_expression
1257 // | RIGHT_OP >> additive_expression
1258 // )
1259 // ;
1262 ;
1263
1270 | epsilon_p
1271 ;
1272
1273 // left recursion --> right recursion
1274 // relational_expression
1275 // = shift_expression
1276 // | relational_expression >>
1277 // (
1278 // LT_OP >> shift_expression
1279 // | GT_OP >> shift_expression
1280 // | LE_OP >> shift_expression
1281 // | GE_OP >> shift_expression
1282 // )
1283 // ;
1286 ;
1287
1292 | GE_OP >> shift_expression) >>
1296 | epsilon_p
1297 ;
1298
1299 // left recursion --> right recursion
1300 // equality_expression
1301 // = relational_expression
1302 // | equality_expression >>
1303 // (
1304 // EQ_OP >> relational_expression
1305 // | NE_OP >> relational_expression
1306 // )
1307 // ;
1310 ;
1311
1318 | epsilon_p
1319 ;
1320
1321 // left recursion --> right recursion
1322 // and_expression
1323 // = equality_expression
1324 // | and_expression >> ADDROF >> equality_expression
1325 // ;
1328 ;
1329
1335 | epsilon_p
1336 ;
1337
1338 // left recursion --> right recursion
1339 // exclusive_or_expression
1340 // = and_expression
1341 // | exclusive_or_expression >> XOR >> and_expression
1342 // ;
1345 ;
1346
1348 (XOR >> and_expression >>
1352 | epsilon_p
1353 ;
1354
1355 // left recursion --> right recursion
1356 // inclusive_or_expression
1357 // = exclusive_or_expression
1358 // | inclusive_or_expression >> OR >> exclusive_or_expression
1359 // ;
1362 ;
1363
1369 | epsilon_p
1370 ;
1371
1372 // left recursion --> right recursion
1373 // logical_and_expression
1374 // = inclusive_or_expression
1375 // | logical_and_expression >> AND_OP >> inclusive_or_expression
1376 // ;
1379 ;
1380
1386 | epsilon_p
1387 ;
1388
1389 // left recursion --> right recursion
1390 // logical_or_expression
1391 // = logical_and_expression
1392 // | logical_or_expression >> OR_OP >> logical_and_expression
1393 // ;
1396 ;
1397
1403 | epsilon_p
1404 ;
1405
1406 // left recursion --> right recursion
1407 // conditional_expression
1408 // = logical_or_expression
1409 // | logical_or_expression >> QUEST >> expression >> COLON >>
1410 // conditional_expression
1411 // ;
1414 ;
1415
1417 (QUEST >> expression >> COLON >>
1421 | epsilon_p
1422 ;
1423
1424 // assignment_expression =
1425 // (unary_expression >>
1426 // assignment_operator >>
1427 // assignment_expression
1428 // | conditional_expression)
1429 // [TokenizerActor(self.tokenData_,
1430 // TokenizerData::ASSIGNMENT_EXPRESSION)]
1431 // ;
1432
1434 (unary_expression >>
1440 ;
1441
1443 (ASSIGN
1444 | MUL_ASSIGN
1445 | DIV_ASSIGN
1446 | MOD_ASSIGN
1447 | ADD_ASSIGN
1448 | SUB_ASSIGN
1449 | LEFT_ASSIGN
1450 | RIGHT_ASSIGN
1451 | AND_ASSIGN
1452 | XOR_ASSIGN
1453 | OR_ASSIGN)
1456 ;
1457
1458 // left recursion --> right recursion
1459 // expression
1460 // = assignment_expression
1461 // | expression >> COMMA >> assignment_expression
1462 // ;
1463 expression =
1465 ;
1466
1471 | epsilon_p
1472 ;
1473
1478 ;
1479
1480 declaration =
1484 ;
1485
1489 | type_qualifier) >>
1490
1494 ;
1495
1498
1500 (declarator >> !(ASSIGN >> initializer))
1503 ;
1504
1509 ;
1510
1511 // type_specifier =
1512 // (VOID
1513 // | CHAR
1514 // | SHORT
1515 // | INT
1516 // | LONG
1517 // | FLOAT
1518 // | DOUBLE
1519 // | SIGNED
1520 // | UNSIGNED
1521 // | struct_or_union_specifier
1522 // | enum_specifier
1523 // // | TYPE_NAME
1524 // )
1525 // [TokenizerActor(self.tokenData_,
1526 // TokenizerData::TYPE_SPECIFIER)]
1527 // ;
1528
1530 (str_p("IntWord")
1531 | str_p("FloatWord")
1532 | str_p("DoubleWord")
1533 | str_p("SimValue")
1534 | str_p("Var")
1539 ;
1540
1542 (struct_or_union >>
1543 (IDENTIFIER >>
1549 ;
1550
1552 (STRUCT | UNION)
1555 ;
1556
1559
1562 SEMICOLON)
1565
1569
1572 ;
1573
1578 ;
1579
1581 (ENUM >> !IDENTIFIER >> LEFT_BRACE >>
1582 enumerator_list >>
1586 ;
1587
1589 enumerator >> *(COMMA >> enumerator)
1590 ;
1591
1592 enumerator =
1596 ;
1597
1599 (CONST
1602
1603 | VOLATILE
1606
1609 ;
1610
1611 declarator =
1614 ;
1615
1616 // left recursion --> right recursion
1617 // direct_declarator
1618 // = IDENTIFIER
1619 // | LEFT_PAREN >> declarator >> RIGHT_PAREN
1620 // | direct_declarator >>
1621 // (
1622 // LEFT_BRACKET >> !constant_expression >> RIGHT_BRACKET
1623 // | LEFT_PAREN >>
1624 // (
1625 // parameter_type_list >> RIGHT_PAREN
1626 // | identifier_list >> RIGHT_PAREN
1627 // | RIGHT_PAREN
1628 // )
1629 // )
1630 // ;
1632 ((IDENTIFIER
1635 ;
1636
1639 | LEFT_PAREN >>
1641 | identifier_list) >>
1642 RIGHT_PAREN) >>
1646 | epsilon_p
1647 ;
1648
1649 pointer =
1653 ;
1654
1657 ;
1658
1660 (parameter_list >> !(COMMA >> ELLIPSIS))
1663 ;
1664
1669 ;
1670
1676 ;
1677
1679 (IDENTIFIER >> *(COMMA >> IDENTIFIER))
1682 ;
1683
1684 type_name =
1688 ;
1689
1694 ;
1695
1696 // left recursion --> right recursion
1697 // direct_abstract_declarator
1698 // = LEFT_PAREN >>
1699 // (
1700 // abstract_declarator >> RIGHT_PAREN
1701 // | !parameter_type_list >> RIGHT_PAREN
1702 // )
1703 // | LEFT_BRACKET >> !constant_expression >> RIGHT_BRACKET
1704 // | direct_abstract_declarator >>
1705 // (
1706 // LEFT_BRACKET >> !constant_expression >> RIGHT_BRACKET
1707 // | LEFT_PAREN >> !parameter_type_list >> RIGHT_PAREN
1708 // )
1709 // ;
1711 ((LEFT_PAREN >>
1712
1715
1717
1719 ;
1720
1727 | epsilon_p
1728 ;
1729
1730 initializer =
1735 ;
1736
1738 (initializer >> *(COMMA >> initializer))
1741 ;
1742
1743 statement =
1752
1753 ;
1754
1758 | DEFAULT >> COLON >> statement)
1761 ;
1762
1764 (LEFT_BRACE >>
1769 ;
1770
1772 ;
1773
1775 (+statement)
1778 ;
1779
1781 (!expression >> SEMICOLON)
1784 ;
1785
1787 (IF >> LEFT_PAREN >> expression >> RIGHT_PAREN >>
1788 statement >> !(ELSE >> statement)
1789
1791 statement)
1794 ;
1795
1797 (WHILE >>
1799
1800 | DO >> statement >> WHILE >>
1801 LEFT_PAREN >> expression >>
1803
1804 | FOR >> LEFT_PAREN >>
1810 ;
1811
1814 | CONTINUE >> SEMICOLON
1815 | BREAK >> SEMICOLON
1816 | RETURN >> !expression >> SEMICOLON)
1819
1820 ;
1821
1824 declarator >>
1825 !declaration_list >>
1829 ;
1830
1835 ;
1836
1837 // Original..
1838 // parser start symbol
1839 // translation_unit = *external_declaration ;
1840 //
1841
1842 // We are only interested about expressions ended with semicolon
1844 ;
1845 }
1846
1847 // keywords
1848 symbols<> keywords;
1849
1850 // operators
1851 strlit<>
1856// chit<>
1857 strlit<>
1861
1862 rule<ScannerT>
1864
1865 // terminals
1866 rule<ScannerT>
1875
1876 // nonterminals
1877 rule<ScannerT>
1909 // function_definition, last_comment_spirit_bugfix;
1911
1912 rule<ScannerT> const&
1913 start() const { return translation_unit; }
1914 };
1915
1916public:
1918};
1919
1920#endif
#define assert(condition)
#define IGNORE_COMPILER_WARNING(X)
#define POP_CLANG_DIAGS
#define POP_COMPILER_DIAGS
#define IGNORE_CLANG_WARNING(X)
find Finds info of the inner loops in the false
static SLongWord toLong(const T &source)
std::vector< TokenTreeNode * > leafs_
Leafs of this node.
Token * data_
Token of token tree node.
TokenTreeNode & leaf(int index) const
static void addToTokenTree(TokenTreeNode *currNode, TokenTreeNode *newToken)
Token(unsigned long start, unsigned long end, std::string &strValue)
std::map< std::pair< const char *, const char * >, Token * > TokenContainerType
TokenContainerType parsedTokens_
static std::string idString(OperationID id)
const TokenTreeNode * tokenTree() const
void addToken(const char *start, const char *end, OperationID id, std::string strVal)
definition(OperationDAGLanguageGrammar const &self)
std::pair< const char *, const char * > & thePair_
SetStripPairActor(std::pair< const char *, const char * > &aPair)
void operator()(const char *start, const char *end) const
TokenizerActor(TokenizerData &data, TokenizerData::OperationID id)
TokenizerData::OperationID id_
void operator()(const char *start, const char *end) const
definition(skip_grammar const &self)
rule< ScannerT > const & start() const
std::vector< std::pair< const char *, const char * > > strippedParts
std::pair< const char *, const char * > lastStrip